[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [mpop-users] POP3 Authorization using SCRAM-SHA-1 fails



Hi Steffen!

On 11/01/11 14:39, Steffen Lehmann wrote:
> POP3 Authorization using SCRAM-SHA-1 fails, because mpop violates the rules 
> according to SASL RFC 4422, Section 3:
> "Where the mechanism specifies that the server is to return additional
> data to the client with a successful outcome and this field is
> unavailable or unused, the additional data is sent as a challenge
> whose response is empty. After receiving this response, the server
> then indicates the successful outcome."
> 
> RFC 5034, Section 4:
> "Note that POP3 does not allow for additional data to be sent
> with a message indicating a successfull outcome (see Section 3.6 of RFC 4422)."
> 
> Hence, the following message sequence according to SASL RFC 4422, Section 3 
> applies:
> 
> C: Request authentication exchange
> S: Initial challenge
> C: Initial response
> <additional challenge/response messages>
> S: Additional data challenge
> C: Empty Response
> S: Outcome of authentication exchange
> 
> But mpop behaves as following:
> 
> C: AUTH SCRAM-SHA-1  (POP3: command request)
> S: +                 (SASL: Initial challenge)
> C: biwsb...          (SASL: Initial response; RFC 5802 client-first-message) 
> S: + cj01b2t...      (SASL: additional challenge; RFC 5802 server-first-
> message)
> C: Yz1iaX...         (SASL: additional response; RFC 5802 client-final-message)
> S: + dj1mT...        (SASL: additional challenge; RFC 5802 server-final-
> message)
> C: STAT              (POP3: command request, unexpected here, the server waits 
> for the 'Empty Response')
> 
> Obviously, mpop takes the RFC 5802 server-final-message incorrectly as 
> successful outcome to the "AUTH SCRAM-SHA-1" POP3 command.
> 
> The right message sequence must be:
> 
> C: AUTH SCRAM-SHA-1  (POP3: command request)
> S: +                 (SASL: Initial challenge)
> C: biwsb...          (SASL: Initial response; RFC 5802 client-first-message) 
> S: + cj01b2t...      (SASL: additional challenge; RFC 5802 server-first-
> message)
> C: Yz1iaX...         (SASL: additional response; RFC 5802 client-final-message)
> S: + dj1mT...        (SASL: additional challenge; RFC 5802 server-final-
> message)
> C:                   (SASL: Empty Response, CRLF only)
> S: +OK Authenticated (POP3: command response)
> C: STAT              (POP3: command request)
> ...
> 
> See also RFC 5034, Section 6, Example 3 (that using 'AUTH DIGEST-MD5'), which 
> is also using a "Empty Response".
> 
> In any case, mpop has to wait for either a "+OK " or "-ERR " line after 
> issuing the "AUTH SCRAM-SHA-1" command.
> If it receives the SASL challenge containing the RFC 5802 server-final-
> message, it has to send a empty response.
> There is no statement in RFC5802/RFC4422/RFC5034 which justifies mpop's 
> behaviour.
> Or, if I am wrong, please let me know.
> Does anyone has successfully logged in using mpop with SCRAM-SHA-1 into a 
> public POP3 server? Which one?

Thanks for your detailed analysis. I blindly added SCRAM-SHA-1 to the
existing libgsasl-based pop3_auth() function in the hope that it would
fit the same gsasl flow that the other methods use, and does not need
any special handling. Due to lack of a POP3 server with SCRAM-SHA-1
support, I never was able to test this, and so we have another example
of "untested code is broken code"...

>From your analysis, it seems that SCRAM-SHA-1 needs the same exception
rule that DIGEST-MD5 needs, so the attached patch might fix the problem.
Would you please test it?

(BTW, msmtp is probably affected by the same problem with SMTP.)

Martin




diff --git a/src/pop3.c b/src/pop3.c
index f9278fd..d89e73c 100644
--- a/src/pop3.c
+++ b/src/pop3.c
@@ -2968,9 +2968,10 @@ int pop3_auth(pop3_session_t *session,
     }
     gsasl_finish(sctx);
     gsasl_done(ctx);
-    /* For DIGEST-MD5, we need to send an empty answer to the last 334
-     * response before we get 235. */
-    if (strcmp(auth_mech, "DIGEST-MD5") == 0)
+    /* For DIGEST-MD5 and SCRAM-SHA-1, we need to send an empty answer to the
+     * last response before we get an OK. */
+    if (strcmp(auth_mech, "DIGEST-MD5") == 0
+            || strcmp(auth_mech, "SCRAM-SHA-1") == 0)
     {
         if ((e = pop3_send_cmd(session, errstr, "")) != POP3_EOK)
         {