From dd39b35e89007726edffc98be5297b248fe34e90 Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:40:39 +0200 Subject: [PATCH] Fix anonymous authentication with empty trace information string With anonymous authentication according to RFC4505 the trace information string is optional, and SMTP authentication extension described in RFC4954 states that: If the client is transmitting an initial response of zero length, it MUST instead transmit the response as a single equals sign ("="). This indicates that the response is present, but contains no data. --- client.go | 9 +++++++-- conn.go | 26 +++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/client.go b/client.go index 2d9e082..66249b5 100644 --- a/client.go +++ b/client.go @@ -356,8 +356,13 @@ func (c *Client) Auth(a sasl.Client) error { if err != nil { return err } - resp64 := make([]byte, encoding.EncodedLen(len(resp))) - encoding.Encode(resp64, resp) + var resp64 []byte + if len(resp) > 0 { + resp64 = make([]byte, encoding.EncodedLen(len(resp))) + encoding.Encode(resp64, resp) + } else if resp != nil { + resp64 = []byte{'='} + } code, msg64, err := c.cmd(0, strings.TrimSpace(fmt.Sprintf("AUTH %s %s", mech, resp64))) for err == nil { var msg []byte diff --git a/conn.go b/conn.go index 713eecb..57e7c9c 100644 --- a/conn.go +++ b/conn.go @@ -773,11 +773,15 @@ func (c *Conn) handleAuth(arg string) { // Parse client initial response if there is one var ir []byte if len(parts) > 1 { - var err error - ir, err = base64.StdEncoding.DecodeString(parts[1]) - if err != nil { - c.writeResponse(454, EnhancedCode{4, 7, 0}, "Invalid base64 data") - return + if parts[1] == "=" { + ir = []byte{} + } else { + var err error + ir, err = base64.StdEncoding.DecodeString(parts[1]) + if err != nil { + c.writeResponse(454, EnhancedCode{4, 7, 0}, "Invalid base64 data") + return + } } } @@ -816,10 +820,14 @@ func (c *Conn) handleAuth(arg string) { return } - response, err = base64.StdEncoding.DecodeString(encoded) - if err != nil { - c.writeResponse(454, EnhancedCode{4, 7, 0}, "Invalid base64 data") - return + if encoded == "=" { + response = []byte{} + } else { + response, err = base64.StdEncoding.DecodeString(encoded) + if err != nil { + c.writeResponse(454, EnhancedCode{4, 7, 0}, "Invalid base64 data") + return + } } }