From 8e860c16625d65b63042731f5c343775bcb34983 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Wed, 30 May 2012 20:52:52 +0100 Subject: sasl: Moved plain text authentication message creation from smtp.c Moved the plain text message creation from smtp.c into the sasl module to allow for use by other modules such as pop3. --- lib/curl_sasl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 lib/curl_sasl.c (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c new file mode 100644 index 000000000..e2e1e3e7a --- /dev/null +++ b/lib/curl_sasl.c @@ -0,0 +1,79 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * RFC4616 PLAIN authentication + * + ***************************************************************************/ + +#include "setup.h" + +#include +#include "urldata.h" + +#include "curl_base64.h" +#include "curl_sasl.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +/* + * Curl_sasl_create_plain_message() + * + * This is used to generate an already encoded plain message ready + * for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name. + * 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_plain_message(struct SessionHandle *data, + const char* userp, + const char* passwdp, + char **outptr, size_t *outlen) +{ + char plainauth[2 * MAX_CURL_USER_LENGTH + MAX_CURL_PASSWORD_LENGTH]; + size_t ulen; + size_t plen; + + ulen = strlen(userp); + plen = strlen(passwdp); + + if(2 * ulen + plen + 2 > sizeof(plainauth)) { + *outlen = 0; + *outptr = NULL; + return CURLE_OUT_OF_MEMORY; /* plainauth too small */ + } + + memcpy(plainauth, userp, ulen); + plainauth[ulen] = '\0'; + memcpy(plainauth + ulen + 1, userp, ulen); + plainauth[2 * ulen + 1] = '\0'; + memcpy(plainauth + 2 * ulen + 2, passwdp, plen); + + return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr, + outlen); +} -- cgit v1.2.1 From 54d484e136d43b50934cc906804662e780adc3fa Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Thu, 31 May 2012 23:11:54 +0100 Subject: sasl: Moved login authentication message creation from smtp.c Moved the login message creation from smtp.c into the sasl module to allow for use by other modules such as pop3. --- lib/curl_sasl.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index e2e1e3e7a..50baea97a 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -77,3 +77,39 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr, outlen); } + +/* + * Curl_sasl_create_login_message() + * + * This is used to generate an already encoded login message containing the + * user name or password ready for sending to the recipient. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name. + * 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_login_message(struct SessionHandle *data, + const char* valuep, char **outptr, + size_t *outlen) +{ + size_t vlen = strlen(valuep); + + if(!vlen) { + *outptr = strdup("="); + if(*outptr) { + *outlen = (size_t) 1; + return CURLE_OK; + } + + *outlen = 0; + return CURLE_OUT_OF_MEMORY; + } + + return Curl_base64_encode(data, valuep, vlen, outptr, outlen); +} -- cgit v1.2.1 From d9ca9e9869e8dd5559b36ffec608c847f154e40a Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sat, 2 Jun 2012 11:07:58 +0100 Subject: sasl: Moved ntlm authentication message handling from smtp.c Moved the ntlm message creation and decoding from smtp.c into the sasl module to allow for use by other modules such as pop3. --- lib/curl_sasl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 50baea97a..62d96133e 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -28,6 +28,7 @@ #include "urldata.h" #include "curl_base64.h" +#include "curl_ntlm_msgs.h" #include "curl_sasl.h" /* The last #include file should be: */ @@ -113,3 +114,94 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, return Curl_base64_encode(data, valuep, vlen, outptr, outlen); } + +#ifdef USE_NTLM +/* + * Curl_sasl_create_ntlm_type1_message() + * + * This is used to generate an already encoded NTLM type-1 message ready for + * sending to the recipient. + * + * Note: This is a simple wrapper of the NTLM function which means that any + * SASL based protocols don't have to include the NTLM functions directly. + * + * Parameters: + * + * userp [in] - The user name in the format User or Domain\User. + * passdwp [in] - The user's password. + * ntlm [in/out] - The ntlm data struct being used and modified. + * 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_ntlm_type1_message(const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) +{ + return Curl_ntlm_create_type1_message(userp, passwdp, ntlm, outptr, + outlen); +} + +/* + * Curl_sasl_decode_ntlm_type2_message() + * + * This is used to decode a ntlm type-2 message received from a recipient and + * generate the already encoded NTLM type-3 message ready for sending back. + * + * Parameters: + * + * data [in] - Pointer to session handle. + * header [in] - Pointer to the input buffer. + * userp [in] - The user name in the format User or Domain\User. + * passdwp [in] - The user's password. + * ntlm [in/out] - The ntlm data struct being used and modified. + * 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_ntlm_type2_message(struct SessionHandle *data, + const char *header, + const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr, size_t *outlen) +{ + CURLcode result = Curl_ntlm_decode_type2_message(data, header, ntlm); + + if(!result) + result = Curl_ntlm_create_type3_message(data, userp, passwdp, ntlm, + outptr, outlen); + + return result; +} +#endif /* USE_NTLM */ + +/* + * Curl_sasl_cleanup() + * + * This is used to cleanup any libraries or curl modules used by the sasl + * functions. + * + * Parameters: + * + * conn [in] - Pointer to the connection data. + * authused [in] - The authentication mechanism used. + */ +void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) +{ +#ifdef USE_NTLM + /* Cleanup the ntlm structure */ + if(authused == SASL_AUTH_NTLM) { + Curl_ntlm_sspi_cleanup(&conn->ntlm); + } +#else + /* Reserved for future use */ + (void)conn; + (void)authused; +#endif +} \ No newline at end of file -- cgit v1.2.1 From 6f964e4f0625177d9fdef61cc72de9d46328ace5 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sat, 2 Jun 2012 11:09:59 +0100 Subject: sasl: Small comment style tidy up following ntlm commit --- lib/curl_sasl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 62d96133e..343a1bb5d 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -37,7 +37,7 @@ /* * Curl_sasl_create_plain_message() * - * This is used to generate an already encoded plain message ready + * This is used to generate an already encoded PLAIN message ready * for sending to the recipient. * * Parameters: @@ -82,7 +82,7 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, /* * Curl_sasl_create_login_message() * - * This is used to generate an already encoded login message containing the + * This is used to generate an already encoded LOGIN message containing the * user name or password ready for sending to the recipient. * * Parameters: -- cgit v1.2.1 From cfa81b8fb00928a88ed4b76807f564d3a895a493 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sat, 2 Jun 2012 14:03:55 +0100 Subject: sasl: Corrected variable names in comments and parameters --- lib/curl_sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 343a1bb5d..e9a3c18d6 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -88,7 +88,7 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, * Parameters: * * data [in] - The session handle. - * userp [in] - The user name. + * valuep [in] - The user name or 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. -- cgit v1.2.1 From 273e9afcc8f42b549ed5bd06e902675045d6fa87 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sun, 3 Jun 2012 00:00:34 +0100 Subject: sasl.c: Fix to avoid warnings introduced in commit d9ca9e9869e8 Applied a fix to avoid warnings on systems where Curl_ntlm_sspi_cleanup() is just a nop. --- lib/curl_sasl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index e9a3c18d6..1725af86e 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -199,9 +199,10 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) if(authused == SASL_AUTH_NTLM) { Curl_ntlm_sspi_cleanup(&conn->ntlm); } + (void)conn; #else /* Reserved for future use */ (void)conn; (void)authused; #endif -} \ No newline at end of file +} -- cgit v1.2.1 From c12a414b21f22fca0b1b6860b464d45368152d56 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sun, 3 Jun 2012 17:21:49 +0100 Subject: 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. --- lib/curl_sasl.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'lib/curl_sasl.c') 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 /* 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() -- cgit v1.2.1 From 2b9ca12edf614877e39c426964e6d32bf34927c3 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sun, 3 Jun 2012 18:24:35 +0100 Subject: sasl: Small code tidy up Added some comments and removed an unreferenced variable. --- lib/curl_sasl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 1889a208e..c473fa378 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -73,15 +73,19 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, if(2 * ulen + plen + 2 > sizeof(plainauth)) { *outlen = 0; *outptr = NULL; - return CURLE_OUT_OF_MEMORY; /* plainauth too small */ + + /* Plainauth too small */ + return CURLE_OUT_OF_MEMORY; } + /* Calculate the reply */ memcpy(plainauth, userp, ulen); plainauth[ulen] = '\0'; memcpy(plainauth + ulen + 1, userp, ulen); plainauth[2 * ulen + 1] = '\0'; memcpy(plainauth + 2 * ulen + 2, passwdp, plen); + /* Base64 encode the reply */ return Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr, outlen); } @@ -109,6 +113,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, size_t vlen = strlen(valuep); if(!vlen) { + /* Calculate an empty reply */ *outptr = strdup("="); if(*outptr) { *outlen = (size_t) 1; @@ -119,6 +124,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } + /* Base64 encode the value */ return Curl_base64_encode(data, valuep, vlen, outptr, outlen); } @@ -149,7 +155,6 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, { 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; -- cgit v1.2.1 From 24f127027b7b320dd7438259dc24363d6ad33334 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sun, 3 Jun 2012 19:42:47 +0200 Subject: Curl_sasl_create_plain_message: remove TAB --- lib/curl_sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index c473fa378..e6064ed4d 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -74,7 +74,7 @@ CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, *outlen = 0; *outptr = NULL; - /* Plainauth too small */ + /* Plainauth too small */ return CURLE_OUT_OF_MEMORY; } -- cgit v1.2.1 From 58987556d5fecb6f634fbfd56c6f73ba0a4cedf2 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 4 Jun 2012 10:49:55 +0100 Subject: sasl: Small code tidy up before moving digest-md5 over Correction of comments and variable names. --- lib/curl_sasl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index e6064ed4d..d7360764b 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -132,14 +132,14 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, /* * Curl_sasl_create_cram_md5_message() * - * This is used to generate an already encoded CRAM-MD5 message ready for - * sending to the recipient. + * This is used to generate an already encoded CRAM-MD5 response 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. + * userp [in] - The user name. * 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. @@ -149,7 +149,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, */ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, const char* chlg64, - const char* user, + const char* userp, const char* passwdp, char **outptr, size_t *outlen) { @@ -191,7 +191,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, /* 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], + userp, 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]); -- cgit v1.2.1 From 665e16899ce6629097ce884722d9ef17b6708354 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 4 Jun 2012 10:53:18 +0100 Subject: sasl: Moved digest-md5 authentication message creation from smtp.c Moved the digest-md5 message creation from smtp.c into the sasl module to allow for use by other modules such as pop3. --- lib/curl_sasl.c | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index d7360764b..17529a627 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -19,6 +19,7 @@ * KIND, either express or implied. * * RFC2195 CRAM-MD5 authentication + * RFC2831 DIGEST-MD5 authentication * RFC4616 PLAIN authentication * ***************************************************************************/ @@ -30,6 +31,7 @@ #include "curl_base64.h" #include "curl_md5.h" +#include "curl_rand.h" #include "curl_hmac.h" #include "curl_ntlm_msgs.h" #include "curl_sasl.h" @@ -41,6 +43,33 @@ /* The last #include file should be: */ #include "memdebug.h" +#ifndef CURL_DISABLE_CRYPTO_AUTH +/* Retrieves the value for a corresponding key from the challenge string + * returns TRUE if the key could be found, FALSE if it does not exists + */ +static bool sasl_digest_get_key_value(const unsigned char *chlg, + const char *key, + char *value, + size_t max_val_len, + char end_char) +{ + char *find_pos; + size_t i; + + find_pos = strstr((const char *) chlg, key); + if(!find_pos) + return FALSE; + + find_pos += strlen(key); + + for(i = 0; *find_pos && *find_pos != end_char && i < max_val_len - 1; ++i) + value[i] = *find_pos++; + value[i] = '\0'; + + return TRUE; +} +#endif + /* * Curl_sasl_create_plain_message() * @@ -198,6 +227,183 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, /* Base64 encode the reply */ return Curl_base64_encode(data, reply, 0, outptr, outlen); } + +/* + * Curl_sasl_create_digest_md5_message() + * + * This is used to generate an already encoded DIGEST-MD5 response 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. + * 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_digest_md5_message(struct SessionHandle *data, + const char* chlg64, + const char* userp, + const char* passwdp, + char **outptr, size_t *outlen) +{ + static const char table16[] = "0123456789abcdef"; + + CURLcode result = CURLE_OK; + unsigned char *chlg = (unsigned char *) NULL; + size_t chlglen = 0; + size_t i; + MD5_context *ctxt; + unsigned char digest[MD5_DIGEST_LEN]; + char HA1_hex[2 * MD5_DIGEST_LEN + 1]; + char HA2_hex[2 * MD5_DIGEST_LEN + 1]; + char resp_hash_hex[2 * MD5_DIGEST_LEN + 1]; + + char nonce[64]; + char realm[128]; + char alg[64]; + char nonceCount[] = "00000001"; + char cnonce[] = "12345678"; /* will be changed */ + char method[] = "AUTHENTICATE"; + char qop[] = "auth"; + char uri[128] = "smtp/"; + char response[512]; + + result = Curl_base64_decode(chlg64, &chlg, &chlglen); + + if(result) + return result; + + /* Retrieve nonce string from the challenge */ + if(!sasl_digest_get_key_value(chlg, "nonce=\"", nonce, + sizeof(nonce), '\"')) { + Curl_safefree(chlg); + return CURLE_LOGIN_DENIED; + } + + /* Retrieve realm string from the challenge */ + if(!sasl_digest_get_key_value(chlg, "realm=\"", realm, + sizeof(realm), '\"')) { + /* Challenge does not have a realm, set empty string [RFC2831] page 6 */ + strcpy(realm, ""); + } + + /* Retrieve algorithm string from the challenge */ + if(!sasl_digest_get_key_value(chlg, "algorithm=", alg, sizeof(alg), ',')) { + Curl_safefree(chlg); + return CURLE_LOGIN_DENIED; + } + + Curl_safefree(chlg); + + /* We do not support other algorithms */ + if(strcmp(alg, "md5-sess") != 0) + return CURLE_LOGIN_DENIED; + + /* Generate 64 bits of random data */ + for(i = 0; i < 8; i++) + cnonce[i] = table16[Curl_rand()%16]; + + /* So far so good, now calculate A1 and H(A1) according to RFC 2831 */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) userp, + curlx_uztoui(strlen(userp))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) realm, + curlx_uztoui(strlen(realm))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) passwdp, + curlx_uztoui(strlen(passwdp))); + Curl_MD5_final(ctxt, digest); + + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) digest, MD5_DIGEST_LEN); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) nonce, + curlx_uztoui(strlen(nonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) cnonce, + curlx_uztoui(strlen(cnonce))); + Curl_MD5_final(ctxt, digest); + + /* Convert calculated 16 octet hex into 32 bytes string */ + for(i = 0; i < MD5_DIGEST_LEN; i++) + snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); + + /* Orepare URL string, append realm to the protocol */ + strcat(uri, realm); + + /* Calculate H(A2) */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) method, + curlx_uztoui(strlen(method))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) uri, + curlx_uztoui(strlen(uri))); + Curl_MD5_final(ctxt, digest); + + for(i = 0; i < MD5_DIGEST_LEN; i++) + snprintf(&HA2_hex[2 * i], 3, "%02x", digest[i]); + + /* Now calculate the response hash */ + ctxt = Curl_MD5_init(Curl_DIGEST_MD5); + if(!ctxt) + return CURLE_OUT_OF_MEMORY; + + Curl_MD5_update(ctxt, (const unsigned char *) HA1_hex, 2 * MD5_DIGEST_LEN); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) nonce, + curlx_uztoui(strlen(nonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + + Curl_MD5_update(ctxt, (const unsigned char *) nonceCount, + curlx_uztoui(strlen(nonceCount))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) cnonce, + curlx_uztoui(strlen(cnonce))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + Curl_MD5_update(ctxt, (const unsigned char *) qop, + curlx_uztoui(strlen(qop))); + Curl_MD5_update(ctxt, (const unsigned char *) ":", 1); + + Curl_MD5_update(ctxt, (const unsigned char *) HA2_hex, 2 * MD5_DIGEST_LEN); + Curl_MD5_final(ctxt, digest); + + for(i = 0; i < MD5_DIGEST_LEN; i++) + snprintf(&resp_hash_hex[2 * i], 3, "%02x", digest[i]); + + strcpy(response, "username=\""); + strcat(response, userp); + strcat(response, "\",realm=\""); + strcat(response, realm); + strcat(response, "\",nonce=\""); + strcat(response, nonce); + strcat(response, "\",cnonce=\""); + strcat(response, cnonce); + strcat(response, "\",nc="); + strcat(response, nonceCount); + strcat(response, ",digest-uri=\""); + strcat(response, uri); + strcat(response, "\",response="); + strcat(response, resp_hash_hex); + + /* Base64 encode the reply */ + return Curl_base64_encode(data, response, 0, outptr, outlen); +} #endif #ifdef USE_NTLM -- cgit v1.2.1 From f08721156627cfb599eaaad53a2b1761ef39787b Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 4 Jun 2012 11:02:03 +0100 Subject: sasl: Small code tidy up Reworked variable names in Curl_sasl_create_cram_md5_message() to match those in Curl_sasl_create_digest_md5_message() as they are more appropriate. --- lib/curl_sasl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 17529a627..18c2782bc 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -188,7 +188,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, size_t chlglen = 0; HMAC_context *ctxt; unsigned char digest[MD5_DIGEST_LEN]; - char reply[MAX_CURL_USER_LENGTH + 2 * MD5_DIGEST_LEN + 1]; + char response[MAX_CURL_USER_LENGTH + 2 * MD5_DIGEST_LEN + 1]; /* Decode the challenge if necessary */ if(chlg64len && *chlg64 != '=') { @@ -217,15 +217,15 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, /* Finalise the digest */ Curl_HMAC_final(ctxt, digest); - /* Prepare the reply */ - snprintf(reply, sizeof(reply), + /* Prepare the response */ + snprintf(response, sizeof(response), "%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", userp, 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); + return Curl_base64_encode(data, response, 0, outptr, outlen); } /* -- cgit v1.2.1 From bf51b8c07af9f6eb16c82673c66ce7402c067172 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 4 Jun 2012 20:22:06 +0100 Subject: sasl: Added service parameter to Curl_sasl_create_digest_md5_message() Added a service type parameter to Curl_sasl_create_digest_md5_message() to allow the function to be used by different services rather than being hard coded to "smtp". --- lib/curl_sasl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 18c2782bc..9f5fe95fb 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -240,6 +240,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * chlg64 [in] - Pointer to the input buffer. * userp [in] - The user name. * passdwp [in] - The user's password. + * service [in] - The service type such as www, smtp or pop * 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. @@ -250,6 +251,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, const char* chlg64, const char* userp, const char* passwdp, + const char* service, char **outptr, size_t *outlen) { static const char table16[] = "0123456789abcdef"; @@ -271,7 +273,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, char cnonce[] = "12345678"; /* will be changed */ char method[] = "AUTHENTICATE"; char qop[] = "auth"; - char uri[128] = "smtp/"; + char uri[128]; char response[512]; result = Curl_base64_decode(chlg64, &chlg, &chlglen); @@ -341,7 +343,9 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, for(i = 0; i < MD5_DIGEST_LEN; i++) snprintf(&HA1_hex[2 * i], 3, "%02x", digest[i]); - /* Orepare URL string, append realm to the protocol */ + /* Prepare the URL string */ + strcpy(uri, service); + strcat(uri, "/"); strcat(uri, realm); /* Calculate H(A2) */ -- cgit v1.2.1 From 64510fe917be0508bb4fa381af966ece7dfd4775 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 4 Jun 2012 22:25:45 +0100 Subject: sasl: Renamed Curl_sasl_decode_ntlm_type2_message() For consistency with other SASL based functions renamed this function to Curl_sasl_create_ntlm_type3_message() which better describes its usage. --- lib/curl_sasl.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 9f5fe95fb..7f81405c9 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -167,7 +167,7 @@ CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, * Parameters: * * data [in] - The session handle. - * chlg64 [in] - Pointer to the input buffer. + * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * userp [in] - The user name. * passdwp [in] - The user's password. * outptr [in/out] - The address where a pointer to newly allocated memory @@ -237,7 +237,7 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * Parameters: * * data [in] - The session handle. - * chlg64 [in] - Pointer to the input buffer. + * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * userp [in] - The user name. * passdwp [in] - The user's password. * service [in] - The service type such as www, smtp or pop @@ -441,15 +441,15 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp, } /* - * Curl_sasl_decode_ntlm_type2_message() + * Curl_sasl_create_ntlm_type3_message() * - * This is used to decode a ntlm type-2 message received from a recipient and - * generate the already encoded NTLM type-3 message ready for sending back. + * This is used to generate an already encoded NTLM type-3 message ready for + * sending to the recipient. * * Parameters: * * data [in] - Pointer to session handle. - * header [in] - Pointer to the input buffer. + * header [in] - Pointer to the base64 encoded type-2 message buffer. * userp [in] - The user name in the format User or Domain\User. * passdwp [in] - The user's password. * ntlm [in/out] - The ntlm data struct being used and modified. @@ -459,7 +459,7 @@ CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp, * * Returns CURLE_OK on success. */ -CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data, +CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data, const char *header, const char *userp, const char *passwdp, -- cgit v1.2.1 From 0cd8c287a46420768a5b11406638316f859a4873 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Fri, 8 Jun 2012 19:52:28 +0100 Subject: sasl: Re-factored mechanism constants in preparation for APOP work --- lib/curl_sasl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 7f81405c9..c5793f956 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -491,7 +491,7 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) { #ifdef USE_NTLM /* Cleanup the ntlm structure */ - if(authused == SASL_AUTH_NTLM) { + if(authused == SASL_MECH_NTLM) { Curl_ntlm_sspi_cleanup(&conn->ntlm); } (void)conn; -- cgit v1.2.1 From 46480bb9a1569eaf156012f33e3e7e8c3de18f87 Mon Sep 17 00:00:00 2001 From: Mark Salisbury Date: Fri, 15 Jun 2012 18:05:11 +0200 Subject: SSPI related code: Unicode support for WinCE SSPI related code now compiles with ANSI and WCHAR versions of security methods (WinCE requires WCHAR versions of methods). Pulled UTF8 to WCHAR conversion methods out of idn_win32.c into their own file. curl_sasl.c - include curl_memory.h to use correct memory functions. getenv.c and telnet.c - WinCE compatibility fix With some committer adjustments --- lib/curl_sasl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/curl_sasl.c') diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index c5793f956..ccb54a89f 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -36,6 +36,7 @@ #include "curl_ntlm_msgs.h" #include "curl_sasl.h" #include "warnless.h" +#include "curl_memory.h" #define _MPRINTF_REPLACE /* use our functions only */ #include -- cgit v1.2.1