2023-01-15 16:14:19 +01:00
|
|
|
// SPDX-FileCopyrightText: 2022-2023 The go-mail Authors
|
2022-06-17 15:05:54 +02:00
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
|
2022-03-10 10:53:38 +01:00
|
|
|
package mail
|
|
|
|
|
2024-10-21 22:24:21 +02:00
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
2022-03-10 10:53:38 +01:00
|
|
|
|
2024-10-04 19:45:37 +02:00
|
|
|
// SMTPAuthType is a type wrapper for a string type. It represents the type of SMTP authentication
|
|
|
|
// mechanism to be used.
|
2022-03-10 10:53:38 +01:00
|
|
|
type SMTPAuthType string
|
|
|
|
|
|
|
|
const (
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthCramMD5 is the "CRAM-MD5" SASL authentication mechanism as described in RFC 4954.
|
2024-10-04 20:00:49 +02:00
|
|
|
// https://datatracker.ietf.org/doc/html/rfc4954/
|
2024-10-04 19:44:41 +02:00
|
|
|
//
|
|
|
|
// CRAM-MD5 is not secure by modern standards. The vulnerabilities of MD5 and the lack of
|
|
|
|
// advanced security features make it inappropriate for protecting sensitive communications
|
|
|
|
// today.
|
|
|
|
//
|
|
|
|
// It was recommended to deprecate the standard in 20 November 2008. As an alternative it
|
|
|
|
// recommends e.g. SCRAM or SASL Plain protected by TLS instead.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
2024-10-04 19:44:41 +02:00
|
|
|
// https://datatracker.ietf.org/doc/html/draft-ietf-sasl-crammd5-to-historic-00.html
|
2024-02-22 15:24:19 +01:00
|
|
|
SMTPAuthCramMD5 SMTPAuthType = "CRAM-MD5"
|
|
|
|
|
2024-10-04 22:33:42 +02:00
|
|
|
// SMTPAuthCustom is a custom SMTP AUTH mechanism provided by the user. If a user provides
|
|
|
|
// a custom smtp.Auth function to the Client, the Client will its smtpAuthType to this type.
|
|
|
|
//
|
|
|
|
// Do not use this SMTPAuthType without setting a custom smtp.Auth function on the Client.
|
|
|
|
SMTPAuthCustom SMTPAuthType = "CUSTOM"
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthLogin is the "LOGIN" SASL authentication mechanism. This authentication mechanism
|
|
|
|
// does not have an official RFC that could be followed. There is a spec by Microsoft and an
|
|
|
|
// IETF draft. The IETF draft is more lax than the MS spec, therefore we follow the I-D, which
|
|
|
|
// automatically matches the MS spec.
|
|
|
|
//
|
2024-10-16 10:38:13 +02:00
|
|
|
// Since the "LOGIN" SASL authentication mechanism transmits the username and password in
|
2024-10-04 19:44:41 +02:00
|
|
|
// plaintext over the internet connection, we only allow this mechanism over a TLS secured
|
|
|
|
// connection.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
|
|
|
// https://msopenspecs.azureedge.net/files/MS-XLOGIN/%5bMS-XLOGIN%5d.pdf
|
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/draft-murchison-sasl-login-00
|
2022-03-10 10:53:38 +01:00
|
|
|
SMTPAuthLogin SMTPAuthType = "LOGIN"
|
|
|
|
|
2024-10-22 15:38:51 +02:00
|
|
|
// SMTPAuthLoginNoEnc is the "LOGIN" SASL authentication mechanism. This authentication mechanism
|
|
|
|
// does not have an official RFC that could be followed. There is a spec by Microsoft and an
|
|
|
|
// IETF draft. The IETF draft is more lax than the MS spec, therefore we follow the I-D, which
|
|
|
|
// automatically matches the MS spec.
|
|
|
|
//
|
|
|
|
// Since the "LOGIN" SASL authentication mechanism transmits the username and password in
|
|
|
|
// plaintext over the internet connection, by default we only allow this mechanism over
|
|
|
|
// a TLS secured connection. This authentiation mechanism overrides this default and will
|
|
|
|
// allow LOGIN authentication via an unencrypted channel. This can be useful if the
|
|
|
|
// connection has already been secured in a different way (e. g. a SSH tunnel)
|
|
|
|
//
|
|
|
|
// Note: Use this authentication method with caution. If used in the wrong way, you might
|
|
|
|
// expose your authentication information over unencrypted channels!
|
|
|
|
//
|
|
|
|
// https://msopenspecs.azureedge.net/files/MS-XLOGIN/%5bMS-XLOGIN%5d.pdf
|
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/draft-murchison-sasl-login-00
|
|
|
|
SMTPAuthLoginNoEnc SMTPAuthType = "LOGIN-NOENC"
|
|
|
|
|
2024-02-22 15:24:19 +01:00
|
|
|
// SMTPAuthNoAuth is equivalent to performing no authentication at all. It is a convenience
|
|
|
|
// option and should not be used. Instead, for mail servers that do no support/require
|
2024-10-04 19:44:41 +02:00
|
|
|
// authentication, the Client should not be passed the WithSMTPAuth option at all.
|
2024-10-11 11:21:56 +02:00
|
|
|
SMTPAuthNoAuth SMTPAuthType = "NOAUTH"
|
2024-02-22 15:24:19 +01:00
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthPlain is the "PLAIN" authentication mechanism as described in RFC 4616.
|
|
|
|
//
|
2024-10-16 10:38:13 +02:00
|
|
|
// Since the "PLAIN" SASL authentication mechanism transmits the username and password in
|
2024-10-04 19:44:41 +02:00
|
|
|
// plaintext over the internet connection, we only allow this mechanism over a TLS secured
|
|
|
|
// connection.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc4616/
|
2022-03-10 10:53:38 +01:00
|
|
|
SMTPAuthPlain SMTPAuthType = "PLAIN"
|
|
|
|
|
2024-10-22 15:30:15 +02:00
|
|
|
// SMTPAuthPlainNoEnc is the "PLAIN" authentication mechanism as described in RFC 4616.
|
|
|
|
//
|
|
|
|
// Since the "PLAIN" SASL authentication mechanism transmits the username and password in
|
2024-10-22 15:38:51 +02:00
|
|
|
// plaintext over the internet connection, by default we only allow this mechanism over
|
2024-10-22 15:30:15 +02:00
|
|
|
// a TLS secured connection. This authentiation mechanism overrides this default and will
|
|
|
|
// allow PLAIN authentication via an unencrypted channel. This can be useful if the
|
|
|
|
// connection has already been secured in a different way (e. g. a SSH tunnel)
|
|
|
|
//
|
|
|
|
// Note: Use this authentication method with caution. If used in the wrong way, you might
|
|
|
|
// expose your authentication information over unencrypted channels!
|
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc4616/
|
|
|
|
SMTPAuthPlainNoEnc SMTPAuthType = "PLAIN-NOENC"
|
|
|
|
|
2023-05-29 18:19:01 +02:00
|
|
|
// SMTPAuthXOAUTH2 is the "XOAUTH2" SASL authentication mechanism.
|
|
|
|
// https://developers.google.com/gmail/imap/xoauth2-protocol
|
2023-05-28 14:31:04 +02:00
|
|
|
SMTPAuthXOAUTH2 SMTPAuthType = "XOAUTH2"
|
2024-10-01 11:03:44 +02:00
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthSCRAMSHA1 is the "SCRAM-SHA-1" SASL authentication mechanism as described in RFC 5802.
|
|
|
|
//
|
|
|
|
// SCRAM-SHA-1 is still considered secure for certain applications, particularly when used as part
|
|
|
|
// of a challenge-response authentication mechanism (as we use it). However, it is generally
|
|
|
|
// recommended to prefer stronger alternatives like SCRAM-SHA-256(-PLUS), as SHA-1 has known
|
|
|
|
// vulnerabilities in other contexts, although it remains effective in HMAC constructions.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc5802
|
2024-10-01 17:00:43 +02:00
|
|
|
SMTPAuthSCRAMSHA1 SMTPAuthType = "SCRAM-SHA-1"
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthSCRAMSHA1PLUS is the "SCRAM-SHA-1-PLUS" SASL authentication mechanism as described in RFC 5802.
|
|
|
|
//
|
|
|
|
// SCRAM-SHA-X-PLUS authentication require TLS channel bindings to protect against MitM attacks and
|
|
|
|
// to guarantee that the integrity of the transport layer is preserved throughout the authentication
|
2024-10-16 10:38:13 +02:00
|
|
|
// process. Therefore we only allow this mechanism over a TLS secured connection.
|
2024-10-04 19:44:41 +02:00
|
|
|
//
|
|
|
|
// SCRAM-SHA-1-PLUS is still considered secure for certain applications, particularly when used as part
|
|
|
|
// of a challenge-response authentication mechanism (as we use it). However, it is generally
|
|
|
|
// recommended to prefer stronger alternatives like SCRAM-SHA-256(-PLUS), as SHA-1 has known
|
|
|
|
// vulnerabilities in other contexts, although it remains effective in HMAC constructions.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc5802
|
2024-10-01 17:00:43 +02:00
|
|
|
SMTPAuthSCRAMSHA1PLUS SMTPAuthType = "SCRAM-SHA-1-PLUS"
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthSCRAMSHA256 is the "SCRAM-SHA-256" SASL authentication mechanism as described in RFC 7677.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
2024-10-01 17:00:43 +02:00
|
|
|
// https://datatracker.ietf.org/doc/html/rfc7677
|
|
|
|
SMTPAuthSCRAMSHA256 SMTPAuthType = "SCRAM-SHA-256"
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// SMTPAuthSCRAMSHA256PLUS is the "SCRAM-SHA-256-PLUS" SASL authentication mechanism as described in RFC 7677.
|
|
|
|
//
|
|
|
|
// SCRAM-SHA-X-PLUS authentication require TLS channel bindings to protect against MitM attacks and
|
|
|
|
// to guarantee that the integrity of the transport layer is preserved throughout the authentication
|
2024-10-16 10:38:13 +02:00
|
|
|
// process. Therefore we only allow this mechanism over a TLS secured connection.
|
2024-10-05 13:39:21 +02:00
|
|
|
//
|
|
|
|
// https://datatracker.ietf.org/doc/html/rfc7677
|
2024-10-01 11:03:44 +02:00
|
|
|
SMTPAuthSCRAMSHA256PLUS SMTPAuthType = "SCRAM-SHA-256-PLUS"
|
2024-11-16 14:29:34 +01:00
|
|
|
|
|
|
|
// SMTPAuthAutoDiscover is a mechanism that dynamically discovers all authentication mechanisms
|
|
|
|
// supported by the SMTP server and selects the strongest available one.
|
|
|
|
//
|
|
|
|
// This type simplifies authentication by automatically negotiating the most secure mechanism
|
|
|
|
// offered by the server, based on a predefined security ranking. For instance, mechanisms like
|
|
|
|
// SCRAM-SHA-256(-PLUS) or XOAUTH2 are prioritized over weaker mechanisms such as CRAM-MD5 or PLAIN.
|
|
|
|
//
|
|
|
|
// The negotiation process ensures that mechanisms requiring additional capabilities (e.g.,
|
|
|
|
// SCRAM-SHA-X-PLUS with TLS channel binding) are only selected when the necessary prerequisites
|
|
|
|
// are in place, such as an active TLS-secured connection.
|
|
|
|
//
|
|
|
|
// By automating mechanism selection, SMTPAuthAutoDiscover minimizes configuration effort while
|
|
|
|
// maximizing security and compatibility with a wide range of SMTP servers.
|
|
|
|
SMTPAuthAutoDiscover SMTPAuthType = "AUTODISCOVER"
|
2022-03-10 10:53:38 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// SMTP Auth related static errors
|
|
|
|
var (
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrPlainAuthNotSupported is returned when the server does not support the "PLAIN" SMTP
|
|
|
|
// authentication type.
|
2022-03-10 10:53:38 +01:00
|
|
|
ErrPlainAuthNotSupported = errors.New("server does not support SMTP AUTH type: PLAIN")
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrLoginAuthNotSupported is returned when the server does not support the "LOGIN" SMTP
|
|
|
|
// authentication type.
|
2022-03-10 10:53:38 +01:00
|
|
|
ErrLoginAuthNotSupported = errors.New("server does not support SMTP AUTH type: LOGIN")
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrCramMD5AuthNotSupported is returned when the server does not support the "CRAM-MD5" SMTP
|
|
|
|
// authentication type.
|
2022-03-10 10:53:38 +01:00
|
|
|
ErrCramMD5AuthNotSupported = errors.New("server does not support SMTP AUTH type: CRAM-MD5")
|
2023-05-28 14:31:04 +02:00
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrXOauth2AuthNotSupported is returned when the server does not support the "XOAUTH2" schema.
|
2023-05-28 14:31:04 +02:00
|
|
|
ErrXOauth2AuthNotSupported = errors.New("server does not support SMTP AUTH type: XOAUTH2")
|
2024-10-01 11:03:44 +02:00
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrSCRAMSHA1AuthNotSupported is returned when the server does not support the "SCRAM-SHA-1" SMTP
|
|
|
|
// authentication type.
|
2024-10-01 11:03:44 +02:00
|
|
|
ErrSCRAMSHA1AuthNotSupported = errors.New("server does not support SMTP AUTH type: SCRAM-SHA-1")
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrSCRAMSHA1PLUSAuthNotSupported is returned when the server does not support the "SCRAM-SHA-1-PLUS" SMTP
|
|
|
|
// authentication type.
|
2024-10-01 11:03:44 +02:00
|
|
|
ErrSCRAMSHA1PLUSAuthNotSupported = errors.New("server does not support SMTP AUTH type: SCRAM-SHA-1-PLUS")
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrSCRAMSHA256AuthNotSupported is returned when the server does not support the "SCRAM-SHA-256" SMTP
|
|
|
|
// authentication type.
|
2024-10-01 11:03:44 +02:00
|
|
|
ErrSCRAMSHA256AuthNotSupported = errors.New("server does not support SMTP AUTH type: SCRAM-SHA-256")
|
|
|
|
|
2024-10-04 19:44:41 +02:00
|
|
|
// ErrSCRAMSHA256PLUSAuthNotSupported is returned when the server does not support the "SCRAM-SHA-256-PLUS" SMTP
|
|
|
|
// authentication type.
|
2024-10-01 11:03:44 +02:00
|
|
|
ErrSCRAMSHA256PLUSAuthNotSupported = errors.New("server does not support SMTP AUTH type: SCRAM-SHA-256-PLUS")
|
2024-11-16 14:29:34 +01:00
|
|
|
|
|
|
|
// ErrNoSupportedAuthDiscovered is returned when the SMTP Auth AutoDiscover process fails to identify
|
|
|
|
// any supported authentication mechanisms offered by the server.
|
|
|
|
ErrNoSupportedAuthDiscovered = errors.New("SMTP Auth autodiscover was not able to detect a supported " +
|
|
|
|
"authentication mechanism")
|
2022-03-10 10:53:38 +01:00
|
|
|
)
|
2024-10-21 22:24:21 +02:00
|
|
|
|
|
|
|
// UnmarshalString satisfies the fig.StringUnmarshaler interface for the SMTPAuthType type
|
|
|
|
// https://pkg.go.dev/github.com/kkyr/fig#StringUnmarshaler
|
|
|
|
func (sa *SMTPAuthType) UnmarshalString(value string) error {
|
|
|
|
switch strings.ToLower(value) {
|
|
|
|
case "cram-md5", "crammd5", "cram":
|
|
|
|
*sa = SMTPAuthCramMD5
|
|
|
|
case "custom":
|
|
|
|
*sa = SMTPAuthCustom
|
|
|
|
case "login":
|
|
|
|
*sa = SMTPAuthLogin
|
2024-10-22 16:09:12 +02:00
|
|
|
case "login-noenc":
|
|
|
|
*sa = SMTPAuthLoginNoEnc
|
2024-10-21 22:24:21 +02:00
|
|
|
case "none", "noauth", "no":
|
|
|
|
*sa = SMTPAuthNoAuth
|
|
|
|
case "plain":
|
|
|
|
*sa = SMTPAuthPlain
|
2024-10-22 16:09:12 +02:00
|
|
|
case "plain-noenc":
|
|
|
|
*sa = SMTPAuthPlainNoEnc
|
2024-10-21 22:24:21 +02:00
|
|
|
case "scram-sha-1", "scram-sha1", "scramsha1":
|
|
|
|
*sa = SMTPAuthSCRAMSHA1
|
|
|
|
case "scram-sha-1-plus", "scram-sha1-plus", "scramsha1plus":
|
|
|
|
*sa = SMTPAuthSCRAMSHA1PLUS
|
|
|
|
case "scram-sha-256", "scram-sha256", "scramsha256":
|
|
|
|
*sa = SMTPAuthSCRAMSHA256
|
|
|
|
case "scram-sha-256-plus", "scram-sha256-plus", "scramsha256plus":
|
|
|
|
*sa = SMTPAuthSCRAMSHA256PLUS
|
|
|
|
case "xoauth2", "oauth2":
|
|
|
|
*sa = SMTPAuthXOAUTH2
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported SMTP auth type: %s", value)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|