diff options
| author | Steve Holme <steve_holme@hotmail.com> | 2012-06-03 17:21:49 +0100 | 
|---|---|---|
| committer | Steve Holme <steve_holme@hotmail.com> | 2012-06-03 17:21:49 +0100 | 
| commit | c12a414b21f22fca0b1b6860b464d45368152d56 (patch) | |
| tree | 83f9e408738ea444827efa5ee49fb18a0da7231a /lib | |
| parent | b5bb61ee697b9a12e37c15b3bcbad33d808961d5 (diff) | |
sasl: Moved cram-md5 authentication message creation from smtp.c
Moved the cram-md5 message creation from smtp.c into the sasl module
to allow for use by other modules such as pop3.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/curl_sasl.c | 80 | ||||
| -rw-r--r-- | lib/curl_sasl.h | 9 | ||||
| -rw-r--r-- | lib/smtp.c | 44 | 
3 files changed, 92 insertions, 41 deletions
| diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 1725af86e..1889a208e 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -18,6 +18,7 @@   * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY   * KIND, either express or implied.   * + * RFC2195 CRAM-MD5 authentication   * RFC4616 PLAIN authentication   *   ***************************************************************************/ @@ -28,8 +29,14 @@  #include "urldata.h"  #include "curl_base64.h" +#include "curl_md5.h" +#include "curl_hmac.h"  #include "curl_ntlm_msgs.h"  #include "curl_sasl.h" +#include "warnless.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include <curl/mprintf.h>  /* The last #include file should be: */  #include "memdebug.h" @@ -115,6 +122,79 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,    return Curl_base64_encode(data, valuep, vlen, outptr, outlen);  } +#ifndef CURL_DISABLE_CRYPTO_AUTH +/* + * Curl_sasl_create_cram_md5_message() + * + * This is used to generate an already encoded CRAM-MD5 message ready for + * sending to the recipient. + * + * Parameters: + * + * data    [in]     - The session handle. + * chlg64  [in]     - Pointer to the input buffer. + * userp   [in]     - The user name in the format User or Domain\User. + * passdwp [in]     - The user's password. + * 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_create_cram_md5_message(struct SessionHandle *data, +                                           const char* chlg64, +                                           const char* user, +                                           const char* passwdp, +                                           char **outptr, size_t *outlen) +{ +  CURLcode result = CURLE_OK; +  size_t chlg64len = strlen(chlg64); +  size_t len = 0; +  unsigned char *chlg = (unsigned char *) NULL; +  size_t chlglen = 0; +  HMAC_context *ctxt; +  unsigned char digest[MD5_DIGEST_LEN]; +  char reply[MAX_CURL_USER_LENGTH + 2 * MD5_DIGEST_LEN + 1]; + +  /* Decode the challenge if necessary */ +  if(chlg64len && *chlg64 != '=') { +    result = Curl_base64_decode(chlg64, &chlg, &chlglen); + +    if(result) +      return result; +  } + +  /* 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); +    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); + +  /* Finalise the digest */ +  Curl_HMAC_final(ctxt, digest); + +  /* Prepare the reply */ +  snprintf(reply, sizeof(reply), +      "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", +           user, digest[0], digest[1], digest[2], digest[3], digest[4], +           digest[5], digest[6], digest[7], digest[8], digest[9], digest[10], +           digest[11], digest[12], digest[13], digest[14], digest[15]); + +  /* Base64 encode the reply */ +  return Curl_base64_encode(data, reply, 0, outptr, outlen); +} +#endif +  #ifdef USE_NTLM  /*   * Curl_sasl_create_ntlm_type1_message() diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h index 572eaed74..567b44bb6 100644 --- a/lib/curl_sasl.h +++ b/lib/curl_sasl.h @@ -45,6 +45,15 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data,                                          const char* valuep, char **outptr,                                          size_t *outlen); +#ifndef CURL_DISABLE_CRYPTO_AUTH +/* This is used to generate a base64 encoded CRAM-MD5 message */ +CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, +                                           const char* chlg64, +                                           const char* user, +                                           const char* passwdp, +                                           char **outptr, size_t *outlen); +#endif +  #ifdef USE_NTLM  /* This is used to generate a base64 encoded NTLM type-1 message */  CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp, diff --git a/lib/smtp.c b/lib/smtp.c index 0bee641cb..ee3811881 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -85,7 +85,6 @@  #include "curl_base64.h"  #include "curl_rand.h"  #include "curl_md5.h" -#include "curl_hmac.h"  #include "curl_gethostname.h"  #include "curl_sasl.h"  #include "warnless.h" @@ -710,7 +709,6 @@ static CURLcode smtp_state_authpasswd_resp(struct connectdata *conn,  }  #ifndef CURL_DISABLE_CRYPTO_AUTH -  /* for AUTH CRAM-MD5 responses */  static CURLcode smtp_state_authcram_resp(struct connectdata *conn,                                           int smtpcode, @@ -719,13 +717,8 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,    CURLcode result = CURLE_OK;    struct SessionHandle *data = conn->data;    char *chlg64 = data->state.buffer; -  unsigned char *chlg; -  size_t chlglen;    size_t len = 0;    char *rplyb64 = NULL; -  HMAC_context *ctxt; -  unsigned char digest[MD5_DIGEST_LEN]; -  char reply[MAX_CURL_USER_LENGTH + 2 * MD5_DIGEST_LEN + 1];    (void)instate; /* no use for this yet */ @@ -738,9 +731,7 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,    for(chlg64 += 4; *chlg64 == ' ' || *chlg64 == '\t'; chlg64++)      ; -  chlg = (unsigned char *) NULL; -  chlglen = 0; - +  /* Terminate the challenge */    if(*chlg64 != '=') {      for(len = strlen(chlg64); len--;)        if(chlg64[len] != '\r' && chlg64[len] != '\n' && chlg64[len] != ' ' && @@ -749,40 +740,11 @@ static CURLcode smtp_state_authcram_resp(struct connectdata *conn,      if(++len) {        chlg64[len] = '\0'; - -      result = Curl_base64_decode(chlg64, &chlg, &chlglen); -      if(result) -        return result;      }    } -  /* Compute digest */ -  ctxt = Curl_HMAC_init(Curl_HMAC_MD5, -                        (const unsigned char *) conn->passwd, -                        curlx_uztoui(strlen(conn->passwd))); - -  if(!ctxt) { -    Curl_safefree(chlg); -    return CURLE_OUT_OF_MEMORY; -  } - -  if(chlglen > 0) -    Curl_HMAC_update(ctxt, chlg, curlx_uztoui(chlglen)); - -  Curl_safefree(chlg); - -  Curl_HMAC_final(ctxt, digest); - -  /* Prepare the reply */ -  snprintf(reply, sizeof(reply), -   "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", -           conn->user, digest[0], digest[1], digest[2], digest[3], digest[4], -           digest[5], -           digest[6], digest[7], digest[8], digest[9], digest[10], digest[11], -           digest[12], digest[13], digest[14], digest[15]); - -  /* Encode it to base64 and send it */ -  result = Curl_base64_encode(data, reply, 0, &rplyb64, &len); +  result = Curl_sasl_create_cram_md5_message(data, chlg64, conn->user, +                                             conn->passwd, &rplyb64, &len);    if(!result) {      if(rplyb64) { | 
