From 972a3c51c76091fe80015ccda4b235545f00f5bd Mon Sep 17 00:00:00 2001 From: Winni Neessen Date: Fri, 4 Oct 2024 22:33:42 +0200 Subject: [PATCH] Add custom SMTP authentication type support Introduce the SMTPAuthCustom type to represent user-defined SMTP authentication mechanisms. Updated relevant functions in client.go to handle the new type appropriately and made sure the client distinguishes between built-in and custom authentication methods. --- auth.go | 6 ++++++ client.go | 16 ++++++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/auth.go b/auth.go index 110e45e..fef7881 100644 --- a/auth.go +++ b/auth.go @@ -23,6 +23,12 @@ const ( // https://datatracker.ietf.org/doc/html/draft-ietf-sasl-crammd5-to-historic-00.html SMTPAuthCramMD5 SMTPAuthType = "CRAM-MD5" + // 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" + // 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 diff --git a/client.go b/client.go index b63b58d..5332cda 100644 --- a/client.go +++ b/client.go @@ -396,11 +396,12 @@ func WithSMTPAuth(authtype SMTPAuthType) Option { } } -// WithSMTPAuthCustom sets a custom SMTP authentication mechanism for the client instance. The provided +// WithSMTPAuthCustom sets a custom SMTP authentication mechanism for the Client. The provided // authentication mechanism has to satisfy the smtp.Auth interface. func WithSMTPAuthCustom(smtpAuth smtp.Auth) Option { return func(c *Client) error { c.smtpAuth = smtpAuth + c.smtpAuthType = SMTPAuthCustom return nil } } @@ -623,25 +624,28 @@ func (c *Client) SetTLSConfig(tlsconfig *tls.Config) error { return nil } -// SetUsername overrides the current username string with the given value +// SetUsername sets or overrides the username, the Client will use for the SMTP authentication. func (c *Client) SetUsername(username string) { c.user = username } -// SetPassword overrides the current password string with the given value +// SetPassword sets or overrides the password, the Client will use for the SMTP authentication. func (c *Client) SetPassword(password string) { c.pass = password } -// SetSMTPAuth overrides the current SMTP AUTH type setting with the given value +// SetSMTPAuth sets or overrides the SMTPAuthType that is currently set on the Client for the SMTP +// authentication. func (c *Client) SetSMTPAuth(authtype SMTPAuthType) { c.smtpAuthType = authtype c.smtpAuth = nil } -// SetSMTPAuthCustom overrides the current SMTP AUTH setting with the given custom smtp.Auth +// SetSMTPAuthCustom sets or overrides the custom SMTP authentication mechanism currently set for +// the Client. The provided authentication mechanism has to satisfy the smtp.Auth interface. func (c *Client) SetSMTPAuthCustom(smtpAuth smtp.Auth) { c.smtpAuth = smtpAuth + c.smtpAuthType = SMTPAuthCustom } // setDefaultHelo retrieves the current hostname and sets it as HELO/EHLO hostname @@ -827,7 +831,7 @@ func (c *Client) auth() error { if err := c.checkConn(); err != nil { return fmt.Errorf("failed to authenticate: %w", err) } - if c.smtpAuth == nil && c.smtpAuthType != "" { + if c.smtpAuth == nil && c.smtpAuthType != SMTPAuthCustom { hasSMTPAuth, smtpAuthType := c.smtpClient.Extension("AUTH") if !hasSMTPAuth { return fmt.Errorf("server does not support SMTP AUTH")