]> granicus.if.org Git - curl/commitdiff
email: Added support for canceling CRAM-MD5 authentication
authorSteve Holme <steve_holme@hotmail.com>
Sun, 27 Oct 2013 12:34:56 +0000 (12:34 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Sun, 27 Oct 2013 12:42:30 +0000 (12:42 +0000)
lib/curl_sasl.c
lib/curl_sasl.h
lib/imap.c
lib/pop3.c
lib/smtp.c

index 044060ff8460eb49eda2c1ebf71b4b7e0e608a67..15a197cab6cc7941248303917f4bef9c1dd6a15c 100644 (file)
@@ -168,7 +168,37 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
 }
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
-/*
+ /*
+ * Curl_sasl_decode_cram_md5_message()
+ *
+ * This is used to decode an already encoded CRAM-MD5 challenge message.
+ *
+ * Parameters:
+ *
+ * chlg64  [in]     - Pointer to the base64 encoded challenge message.
+ * outptr  [in/out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen  [out]    - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                           size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+  size_t chlg64len = strlen(chlg64);
+
+  *outptr = NULL;
+  *outlen = 0;
+
+  /* Decode the challenge if necessary */
+  if(chlg64len && *chlg64 != '=')
+    result = Curl_base64_decode(chlg64, (unsigned char **) outptr, outlen);
+
+    return result;
+ }
+
+ /*
  * Curl_sasl_create_cram_md5_message()
  *
  * This is used to generate an already encoded CRAM-MD5 response message ready
@@ -177,7 +207,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
  * Parameters:
  *
  * data    [in]     - The session handle.
- * chlg64  [in]     - Pointer to the base64 encoded challenge buffer.
+ * chlg    [in]     - The challenge.
  * userp   [in]     - The user name.
  * passdwp [in]     - The user's password.
  * outptr  [in/out] - The address where a pointer to newly allocated memory
@@ -187,42 +217,31 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
  * Returns CURLE_OK on success.
  */
 CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
-                                           const char *chlg64,
+                                           const char *chlg,
                                            const char *userp,
                                            const char *passwdp,
                                            char **outptr, size_t *outlen)
 {
   CURLcode result = CURLE_OK;
-  size_t chlg64len = strlen(chlg64);
-  unsigned char *chlg = (unsigned char *) NULL;
   size_t chlglen = 0;
   HMAC_context *ctxt;
   unsigned char digest[MD5_DIGEST_LEN];
   char *response;
 
-  /* Decode the challenge if necessary */
-  if(chlg64len && *chlg64 != '=') {
-    result = Curl_base64_decode(chlg64, &chlg, &chlglen);
-
-    if(result)
-      return result;
-  }
+  if(chlg)
+    chlglen = strlen(chlg);
 
   /* Compute the digest using the password as the key */
   ctxt = Curl_HMAC_init(Curl_HMAC_MD5,
                         (const unsigned char *) passwdp,
                         curlx_uztoui(strlen(passwdp)));
-
-  if(!ctxt) {
-    Curl_safefree(chlg);
+  if(!ctxt)
     return CURLE_OUT_OF_MEMORY;
-  }
 
   /* Update the digest with the given challenge */
   if(chlglen > 0)
-    Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen));
-
-  Curl_safefree(chlg);
+    Curl_HMAC_update(ctxt, (const unsigned char *) chlg,
+                     curlx_uztoui(chlglen));
 
   /* Finalise the digest */
   Curl_HMAC_final(ctxt, digest);
@@ -240,6 +259,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
   result = Curl_base64_encode(data, response, 0, outptr, outlen);
 
   Curl_safefree(response);
+
   return result;
 }
 
index 2b6a5a26aab0755bc1d5b2dcf368295641d8fe26..63888ffacd7c5eb1054442cbde7150594ea42753 100644 (file)
@@ -66,6 +66,10 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,
                                         size_t *outlen);
 
 #ifndef CURL_DISABLE_CRYPTO_AUTH
+/* This is used to decode a base64 encoded CRAM-MD5 challange message */
+CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr,
+                                           size_t *outlen);
+
 /* This is used to generate a base64 encoded CRAM-MD5 response message */
 CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
                                            const char *chlg64,
@@ -75,7 +79,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
 
 /* This is used to generate a base64 encoded DIGEST-MD5 response message */
 CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
-                                             const char *chlg64,
+                                             const char *chlg,
                                              const char *user,
                                              const char *passwdp,
                                              const char *service,
index b17b7e533b3817f142e7c8d75aea3fc985b28733..a4e61622f957950087a61af380fa5765fdc9a8be 100644 (file)
@@ -1106,6 +1106,7 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
+  char *chlg = NULL;
   char *chlg64 = NULL;
   char *rplyb64 = NULL;
   size_t len = 0;
@@ -1120,22 +1121,31 @@ static CURLcode imap_state_auth_cram_resp(struct connectdata *conn,
   /* Get the challenge message */
   imap_get_message(data->state.buffer, &chlg64);
 
-  /* Create the response message */
-  result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
-                                             conn->passwd, &rplyb64, &len);
+  /* Decode the challenge message */
+  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
+  if(result) {
+    /* Send the cancellation */
+    result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*");
 
-  /* Send the response */
-  if(!result) {
-    if(rplyb64) {
+    if(!result)
+      state(conn, IMAP_AUTHENTICATE_CANCEL);
+  }
+  else {
+    /* Create the response message */
+    result = Curl_sasl_create_cram_md5_message(data, chlg, conn->user,
+                                               conn->passwd, &rplyb64, &len);
+    if(!result && rplyb64) {
+      /* Send the response */
       result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64);
 
       if(!result)
         state(conn, IMAP_AUTHENTICATE_FINAL);
     }
-
-    Curl_safefree(rplyb64);
   }
 
+  Curl_safefree(chlg);
+  Curl_safefree(rplyb64);
+
   return result;
 }
 
index f4dc5d1b3f55c1f9237349691dfd660b496898ef..d4075f4b3c4030db8d5253a85a0dc056d21f4d12 100644 (file)
@@ -964,6 +964,7 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
+  char *chlg = NULL;
   char *chlg64 = NULL;
   char *rplyb64 = NULL;
   size_t len = 0;
@@ -978,22 +979,31 @@ static CURLcode pop3_state_auth_cram_resp(struct connectdata *conn,
   /* Get the challenge message */
   pop3_get_message(data->state.buffer, &chlg64);
 
-  /* Create the response message */
-  result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
-                                             conn->passwd, &rplyb64, &len);
+  /* Decode the challenge message */
+  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
+  if(result) {
+    /* Send the cancellation */
+    result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
 
-  /* Send the response */
-  if(!result) {
-    if(rplyb64) {
+    if(!result)
+      state(conn, POP3_AUTH_CANCEL);
+  }
+  else {
+    /* Create the response message */
+    result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
+                                               conn->passwd, &rplyb64, &len);
+    if(!result && rplyb64) {
+      /* Send the response */
       result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
 
       if(!result)
         state(conn, POP3_AUTH_FINAL);
     }
-
-    Curl_safefree(rplyb64);
   }
 
+  Curl_safefree(chlg);
+  Curl_safefree(rplyb64);
+
   return result;
 }
 
index 7e07ba6d96925634e8fd8737feb2c778d5cccd9f..68537e74d4e7c342aa4c2bc9c80436c280c1b8c0 100644 (file)
@@ -944,6 +944,7 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
 {
   CURLcode result = CURLE_OK;
   struct SessionHandle *data = conn->data;
+  char *chlg = NULL;
   char *chlg64 = NULL;
   char *rplyb64 = NULL;
   size_t len = 0;
@@ -958,22 +959,31 @@ static CURLcode smtp_state_auth_cram_resp(struct connectdata *conn,
   /* Get the challenge message */
   smtp_get_message(data->state.buffer, &chlg64);
 
-  /* Create the response message */
-  result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
-                                             conn->passwd, &rplyb64, &len);
+  /* Decode the challenge message */
+  result = Curl_sasl_decode_cram_md5_message(chlg64, &chlg, &len);
+  if(result) {
+    /* Send the cancellation */
+    result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*");
 
-  /* Send the response */
-  if(!result) {
-    if(rplyb64) {
+    if(!result)
+      state(conn, SMTP_AUTH_CANCEL);
+  }
+  else {
+    /* Create the response message */
+    result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user,
+                                               conn->passwd, &rplyb64, &len);
+    if(!result && rplyb64) {
+      /* Send the response */
       result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64);
 
       if(!result)
         state(conn, SMTP_AUTH_FINAL);
     }
-
-    Curl_safefree(rplyb64);
   }
 
+  Curl_safefree(chlg);
+  Curl_safefree(rplyb64);
+
   return result;
 }