Loading lib/curl_sasl.c +67 −42 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ /* 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, static bool sasl_digest_get_key_value(const char *chlg, const char *key, char *value, size_t max_val_len, Loading @@ -64,7 +64,7 @@ static bool sasl_digest_get_key_value(const unsigned char *chlg, char *find_pos; size_t i; find_pos = strstr((const char *) chlg, key); find_pos = strstr(chlg, key); if(!find_pos) return FALSE; Loading Loading @@ -263,6 +263,66 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, return result; } /* * Curl_sasl_decode_digest_md5_message() * * This is used to decode an already encoded DIGEST-MD5 challenge message. * * Parameters: * * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * nonce [in/out] - The buffer where the nonce will be stored. * nlen [in] - The length of the nonce buffer. * realm [in/out] - The buffer where the realm will be stored. * rlen [in] - The length of the realm buffer. * alg [in/out] - The buffer where the algorithm will be stored. * alen [in] - The length of the algorithm buffer. * * Returns CURLE_OK on success. */ CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64, char *nonce, size_t nlen, char *realm, size_t rlen, char *alg, size_t alen) { CURLcode result = CURLE_OK; char *chlg = NULL; size_t chlglen = 0; size_t chlg64len = strlen(chlg64); if(chlg64len && *chlg64 != '=') { result = Curl_base64_decode(chlg64, (unsigned char **) &chlg, &chlglen); if(result) return result; } /* Ensure we have a valid challenge message */ if(!chlg) return CURLE_BAD_CONTENT_ENCODING; /* Retrieve nonce string from the challenge */ if(!sasl_digest_get_key_value(chlg, "nonce=\"", nonce, nlen, '\"')) { Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } /* Retrieve realm string from the challenge */ if(!sasl_digest_get_key_value(chlg, "realm=\"", realm, rlen, '\"')) { /* 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, alen, ',')) { Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } Curl_safefree(chlg); return CURLE_OK; } /* * Curl_sasl_create_digest_md5_message() * Loading @@ -272,10 +332,11 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * Parameters: * * data [in] - The session handle. * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * nonce [in] - The nonce. * realm [in] - The realm. * userp [in] - The user name. * passdwp [in] - The user's password. * service [in] - The service type such as www, smtp or pop * service [in] - The service type such as www, smtp, pop or imap. * 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. Loading @@ -283,7 +344,8 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * Returns CURLE_OK on success. */ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, const char *chlg64, const char *nonce, const char *realm, const char *userp, const char *passwdp, const char *service, Loading @@ -302,9 +364,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, 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"; Loading @@ -312,40 +371,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, char uri[128]; char response[512]; result = Curl_base64_decode(chlg64, &chlg, &chlglen); if(result) return result; if(!chlg) return CURLE_LOGIN_DENIED; /* 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; #ifndef DEBUGBUILD /* Generate 64 bits of random data */ for(i = 0; i < 8; i++) Loading lib/curl_sasl.h +8 −1 Original line number Diff line number Diff line Loading @@ -77,9 +77,16 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, const char *passwdp, char **outptr, size_t *outlen); /* This is used to decode a base64 encoded DIGEST-MD5 challange message */ CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64, char *nonce, size_t nlen, char *realm, size_t rlen, char *alg, size_t alen); /* 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 *nonce, const char *realm, const char *user, const char *passwdp, const char *service, Loading lib/imap.c +23 −9 Original line number Diff line number Diff line Loading @@ -1160,6 +1160,10 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(imapcode != '+') { Loading @@ -1170,22 +1174,32 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ imap_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "imap", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*"); if(!result) state(conn, IMAP_AUTHENTICATE_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "imap", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64); if(!result) state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading lib/pop3.c +23 −9 Original line number Diff line number Diff line Loading @@ -1018,6 +1018,10 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(pop3code != '+') { Loading @@ -1028,22 +1032,32 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ pop3_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "pop", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*"); if(!result) state(conn, POP3_AUTH_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "pop", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64); if(!result) state(conn, POP3_AUTH_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading lib/smtp.c +23 −9 Original line number Diff line number Diff line Loading @@ -998,6 +998,10 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(smtpcode != 334) { Loading @@ -1008,22 +1012,32 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ smtp_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "smtp", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*"); if(!result) state(conn, SMTP_AUTH_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "smtp", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64); if(!result) state(conn, SMTP_AUTH_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading Loading
lib/curl_sasl.c +67 −42 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ /* 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, static bool sasl_digest_get_key_value(const char *chlg, const char *key, char *value, size_t max_val_len, Loading @@ -64,7 +64,7 @@ static bool sasl_digest_get_key_value(const unsigned char *chlg, char *find_pos; size_t i; find_pos = strstr((const char *) chlg, key); find_pos = strstr(chlg, key); if(!find_pos) return FALSE; Loading Loading @@ -263,6 +263,66 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, return result; } /* * Curl_sasl_decode_digest_md5_message() * * This is used to decode an already encoded DIGEST-MD5 challenge message. * * Parameters: * * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * nonce [in/out] - The buffer where the nonce will be stored. * nlen [in] - The length of the nonce buffer. * realm [in/out] - The buffer where the realm will be stored. * rlen [in] - The length of the realm buffer. * alg [in/out] - The buffer where the algorithm will be stored. * alen [in] - The length of the algorithm buffer. * * Returns CURLE_OK on success. */ CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64, char *nonce, size_t nlen, char *realm, size_t rlen, char *alg, size_t alen) { CURLcode result = CURLE_OK; char *chlg = NULL; size_t chlglen = 0; size_t chlg64len = strlen(chlg64); if(chlg64len && *chlg64 != '=') { result = Curl_base64_decode(chlg64, (unsigned char **) &chlg, &chlglen); if(result) return result; } /* Ensure we have a valid challenge message */ if(!chlg) return CURLE_BAD_CONTENT_ENCODING; /* Retrieve nonce string from the challenge */ if(!sasl_digest_get_key_value(chlg, "nonce=\"", nonce, nlen, '\"')) { Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } /* Retrieve realm string from the challenge */ if(!sasl_digest_get_key_value(chlg, "realm=\"", realm, rlen, '\"')) { /* 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, alen, ',')) { Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } Curl_safefree(chlg); return CURLE_OK; } /* * Curl_sasl_create_digest_md5_message() * Loading @@ -272,10 +332,11 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * Parameters: * * data [in] - The session handle. * chlg64 [in] - Pointer to the base64 encoded challenge buffer. * nonce [in] - The nonce. * realm [in] - The realm. * userp [in] - The user name. * passdwp [in] - The user's password. * service [in] - The service type such as www, smtp or pop * service [in] - The service type such as www, smtp, pop or imap. * 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. Loading @@ -283,7 +344,8 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, * Returns CURLE_OK on success. */ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, const char *chlg64, const char *nonce, const char *realm, const char *userp, const char *passwdp, const char *service, Loading @@ -302,9 +364,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, 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"; Loading @@ -312,40 +371,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, char uri[128]; char response[512]; result = Curl_base64_decode(chlg64, &chlg, &chlglen); if(result) return result; if(!chlg) return CURLE_LOGIN_DENIED; /* 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; #ifndef DEBUGBUILD /* Generate 64 bits of random data */ for(i = 0; i < 8; i++) Loading
lib/curl_sasl.h +8 −1 Original line number Diff line number Diff line Loading @@ -77,9 +77,16 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, const char *passwdp, char **outptr, size_t *outlen); /* This is used to decode a base64 encoded DIGEST-MD5 challange message */ CURLcode Curl_sasl_decode_digest_md5_message(const char *chlg64, char *nonce, size_t nlen, char *realm, size_t rlen, char *alg, size_t alen); /* 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 *nonce, const char *realm, const char *user, const char *passwdp, const char *service, Loading
lib/imap.c +23 −9 Original line number Diff line number Diff line Loading @@ -1160,6 +1160,10 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(imapcode != '+') { Loading @@ -1170,22 +1174,32 @@ static CURLcode imap_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ imap_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "imap", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", "*"); if(!result) state(conn, IMAP_AUTHENTICATE_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "imap", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.imapc.pp, "%s", rplyb64); if(!result) state(conn, IMAP_AUTHENTICATE_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading
lib/pop3.c +23 −9 Original line number Diff line number Diff line Loading @@ -1018,6 +1018,10 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(pop3code != '+') { Loading @@ -1028,22 +1032,32 @@ static CURLcode pop3_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ pop3_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "pop", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*"); if(!result) state(conn, POP3_AUTH_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "pop", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64); if(!result) state(conn, POP3_AUTH_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading
lib/smtp.c +23 −9 Original line number Diff line number Diff line Loading @@ -998,6 +998,10 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn, char *rplyb64 = NULL; size_t len = 0; char nonce[64]; char realm[128]; char algorithm[64]; (void)instate; /* no use for this yet */ if(smtpcode != 334) { Loading @@ -1008,22 +1012,32 @@ static CURLcode smtp_state_auth_digest_resp(struct connectdata *conn, /* Get the challenge message */ smtp_get_message(data->state.buffer, &chlg64); /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, chlg64, conn->user, conn->passwd, "smtp", &rplyb64, &len); /* Decode the challange message */ result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce), realm, sizeof(realm), algorithm, sizeof(algorithm)); if(result || strcmp(algorithm, "md5-sess") != 0) { /* Send the cancellation */ result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", "*"); if(!result) state(conn, SMTP_AUTH_CANCEL); } else { /* Create the response message */ result = Curl_sasl_create_digest_md5_message(data, nonce, realm, conn->user, conn->passwd, "smtp", &rplyb64, &len); if(!result && rplyb64) { /* Send the response */ if(!result) { if(rplyb64) { result = Curl_pp_sendf(&conn->proto.smtpc.pp, "%s", rplyb64); if(!result) state(conn, SMTP_AUTH_DIGESTMD5_RESP); } } Curl_safefree(rplyb64); } return result; } Loading