]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
imap: Fixed incorrect fallback to clear text authentication
authorSteve Holme <steve_holme@hotmail.com>
Fri, 13 Dec 2013 22:57:13 +0000 (22:57 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Fri, 13 Dec 2013 23:15:43 +0000 (23:15 +0000)
If a specific SASL authentication mechanism was requested by the user
as part of the login options but wasn't supported by the server then
curl would fallback to clear text, when it shouldn't, rather than
reporting "No known authentication mechanisms supported" as the POP3
and SMTP protocols do.

lib/imap.c
lib/imap.h

index 0e558ae1a4f8e95a0d2d11ddc0f913f5954a722b..3cb1e8f844bdda0e997ba4a56a1777b161dfc8f6 100644 (file)
@@ -653,7 +653,7 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
   }
 
   if(!result) {
-    if(mech) {
+    if(mech && (imapc->preftype & IMAP_TYPE_SASL)) {
       /* Perform SASL based authentication */
       if(initresp) {
         result = imap_sendf(conn, "AUTHENTICATE %s %s", mech, initresp);
@@ -670,7 +670,8 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn)
 
       Curl_safefree(initresp);
     }
-    else if(!imapc->login_disabled)
+    else if((!imapc->login_disabled) &&
+            (imapc->preftype & IMAP_TYPE_CLEARTEXT))
       /* Perform clear text authentication */
       result = imap_perform_login(conn);
     else {
@@ -1837,7 +1838,8 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
   pp->endofresp = imap_endofresp;
   pp->conn = conn;
 
-  /* Set the default preferred authentication mechanism */
+  /* Set the default preferred authentication type and mechanism */
+  imapc->preftype = IMAP_TYPE_ANY;
   imapc->prefmech = SASL_AUTH_ANY;
 
   /* Initialise the pingpong layer */
@@ -2331,24 +2333,42 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
     if(strnequal(key, "AUTH", 4)) {
       const char *value = ptr + 1;
 
-      if(strequal(value, "*"))
+      if(strequal(value, "*")) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_AUTH_ANY;
-      else if(strequal(value, SASL_MECH_STRING_LOGIN))
+      }
+      else if(strequal(value, SASL_MECH_STRING_LOGIN)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_LOGIN;
-      else if(strequal(value, SASL_MECH_STRING_PLAIN))
+      }
+      else if(strequal(value, SASL_MECH_STRING_PLAIN)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_PLAIN;
-      else if(strequal(value, SASL_MECH_STRING_CRAM_MD5))
+      }
+      else if(strequal(value, SASL_MECH_STRING_CRAM_MD5)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_CRAM_MD5;
-      else if(strequal(value, SASL_MECH_STRING_DIGEST_MD5))
+      }
+      else if(strequal(value, SASL_MECH_STRING_DIGEST_MD5)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_DIGEST_MD5;
-      else if(strequal(value, SASL_MECH_STRING_GSSAPI))
+      }
+      else if(strequal(value, SASL_MECH_STRING_GSSAPI)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_GSSAPI;
-      else if(strequal(value, SASL_MECH_STRING_NTLM))
+      }
+      else if(strequal(value, SASL_MECH_STRING_NTLM)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_NTLM;
-      else if(strequal(value, SASL_MECH_STRING_XOAUTH2))
+      }
+      else if(strequal(value, SASL_MECH_STRING_XOAUTH2)) {
+        imapc->preftype = IMAP_TYPE_SASL;
         imapc->prefmech = SASL_MECH_XOAUTH2;
-      else
+      }
+      else {
+        imapc->preftype = IMAP_TYPE_NONE;
         imapc->prefmech = SASL_AUTH_NONE;
+      }
     }
     else
       result = CURLE_URL_MALFORMAT;
index 7c9a72066ccd89703ff8cd57368b3e86da2ba731..95e55bef724b4631fd452c031841bbb3b97216d2 100644 (file)
@@ -78,6 +78,7 @@ struct imap_conn {
   imapstate state;            /* Always use imap.c:state() to change state! */
   bool ssldone;               /* Is connect() over SSL done? */
   unsigned int authmechs;     /* Accepted authentication mechanisms */
+  unsigned int preftype;      /* Preferred authentication type */
   unsigned int prefmech;      /* Preferred authentication mechanism */
   unsigned int authused;      /* Auth mechanism used for the connection */
   int cmdid;                  /* Last used command ID */
@@ -92,4 +93,12 @@ struct imap_conn {
 extern const struct Curl_handler Curl_handler_imap;
 extern const struct Curl_handler Curl_handler_imaps;
 
+/* Authentication type flags */
+#define IMAP_TYPE_CLEARTEXT (1 << 0)
+#define IMAP_TYPE_SASL      (1 << 1)
+
+/* Authentication type values */
+#define IMAP_TYPE_NONE      0
+#define IMAP_TYPE_ANY       ~0U
+
 #endif /* HEADER_CURL_IMAP_H */