pop3: Fixed APOP being determined by CAPA response rather than by timestamp
authorSteve Holme <steve_holme@hotmail.com>
Tue, 24 Dec 2013 16:32:48 +0000 (16:32 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Tue, 24 Dec 2013 16:34:55 +0000 (16:34 +0000)
This commit replaces that of 9f260b5d6610f3 because according to RFC-2449,
section 6, there is no APOP capability "...even though APOP is an
optional command in [POP3].  Clients discover server support of APOP by
the presence in the greeting banner of an initial challenge enclosed in
angle brackets."

RELEASE-NOTES
lib/pop3.c
tests/ftpserver.pl

index 2e4da90..5b2cb47 100644 (file)
@@ -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:
index 2fc4e4e..5ea50e3 100644 (file)
@@ -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
index 97b8366..3ade82f 100755 (executable)
@@ -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";