diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 2e4da90e1..5b2cb47ba 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -15,7 +15,7 @@ This release includes the following changes: This release includes the following bugfixes: o curl_easy_setopt: Fixed OAuth 2.0 Bearer option name [1] - o pop3: Fixed selection of APOP when server replies with an invalid timestamp + o pop3: pop3: Fixed APOP being determined by CAPA response rather than by timestamp o This release includes the following known bugs: diff --git a/lib/pop3.c b/lib/pop3.c index 2fc4e4e88..5ea50e369 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -561,8 +561,7 @@ static CURLcode pop3_perform_authentication(struct connectdata *conn) } #ifndef CURL_DISABLE_CRYPTO_AUTH else if((pop3c->authtypes & POP3_TYPE_APOP) && - (pop3c->preftype & POP3_TYPE_APOP) && - (pop3c->apoptimestamp)) + (pop3c->preftype & POP3_TYPE_APOP)) /* Perform APOP authentication */ result = pop3_perform_apop(conn); #endif @@ -658,8 +657,9 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn, result = CURLE_FTP_WEIRD_SERVER_REPLY; } else { - /* Look for the APOP timestamp */ + /* Does the server support APOP authentication? */ if(len >= 4 && line[len - 2] == '>') { + /* Look for the APOP timestamp */ for(i = 3; i < len - 2; ++i) { if(line[i] == '<') { /* Calculate the length of the timestamp */ @@ -676,6 +676,9 @@ static CURLcode pop3_state_servergreet_resp(struct connectdata *conn, /* Copy the timestamp */ memcpy(pop3c->apoptimestamp, line + i, timestamplen); pop3c->apoptimestamp[timestamplen] = '\0'; + + /* Store the APOP capability */ + pop3c->authtypes |= POP3_TYPE_APOP; break; } } @@ -710,10 +713,6 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code, else if(len >= 4 && !memcmp(line, "USER", 4)) pop3c->authtypes |= POP3_TYPE_CLEARTEXT; - /* Does the server support APOP authentication? */ - else if(len >= 4 && !memcmp(line, "APOP", 4)) - pop3c->authtypes |= POP3_TYPE_APOP; - /* Does the server support SASL based authentication? */ else if(len >= 5 && !memcmp(line, "SASL ", 5)) { pop3c->authtypes |= POP3_TYPE_SASL; @@ -1201,8 +1200,7 @@ static CURLcode pop3_state_auth_cancel_resp(struct connectdata *conn, } #ifndef CURL_DISABLE_CRYPTO_AUTH else if((pop3c->authtypes & POP3_TYPE_APOP) && - (pop3c->preftype & POP3_TYPE_APOP) && - (pop3c->apoptimestamp)) + (pop3c->preftype & POP3_TYPE_APOP)) /* Perform APOP authentication */ result = pop3_perform_apop(conn); #endif diff --git a/tests/ftpserver.pl b/tests/ftpserver.pl index 97b8366ef..3ade82fc3 100755 --- a/tests/ftpserver.pl +++ b/tests/ftpserver.pl @@ -1707,32 +1707,39 @@ my $username; sub CAPA_pop3 { my ($testno) = @_; + my @list = (); + my $mechs; - if((!@capabilities) && (!@auth_mechs)) { + # Calculate the capability list based on the specified capabilities + # (except APOP) and any authentication mechanisms + for my $c (@capabilities) { + push @list, "$c\r\n" unless $c eq "APOP"; + } + + for my $am (@auth_mechs) { + if(!$mechs) { + $mechs = "$am"; + } + else { + $mechs .= " $am"; + } + } + + if($mechs) { + push @list, "SASL $mechs\r\n"; + } + + if(!@list) { sendcontrol "-ERR Unrecognized command\r\n"; } else { my @data = (); - my $mechs; # Calculate the CAPA response push @data, "+OK List of capabilities follows\r\n"; - for my $c (@capabilities) { - push @data, "$c\r\n"; - } - - for my $am (@auth_mechs) { - if(!$mechs) { - $mechs = "$am"; - } - else { - $mechs .= " $am"; - } - } - - if($mechs) { - push @data, "SASL $mechs\r\n"; + for my $l (@list) { + push @data, "$l\r\n"; } push @data, "IMPLEMENTATION POP3 pingpong test server\r\n";