[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)
{