diff options
Diffstat (limited to 'libs/libcurl/src/vauth/digest.c')
-rw-r--r-- | libs/libcurl/src/vauth/digest.c | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/libs/libcurl/src/vauth/digest.c b/libs/libcurl/src/vauth/digest.c index 355cd74a6e..f945e8b6c9 100644 --- a/libs/libcurl/src/vauth/digest.c +++ b/libs/libcurl/src/vauth/digest.c @@ -49,6 +49,15 @@ #include "curl_memory.h" #include "memdebug.h" +#define SESSION_ALGO 1 /* for algos with this bit set */ + +#define ALGO_MD5 0 +#define ALGO_MD5SESS (ALGO_MD5 | SESSION_ALGO) +#define ALGO_SHA256 2 +#define ALGO_SHA256SESS (ALGO_SHA256 | SESSION_ALGO) +#define ALGO_SHA512_256 4 +#define ALGO_SHA512_256SESS (ALGO_SHA512_256 | SESSION_ALGO) + #if !defined(USE_WINDOWS_SSPI) #define DIGEST_QOP_VALUE_AUTH (1 << 0) #define DIGEST_QOP_VALUE_AUTH_INT (1 << 1) @@ -373,7 +382,7 @@ CURLcode Curl_auth_create_digest_md5_message(struct Curl_easy *data, if(!(qop_values & DIGEST_QOP_VALUE_AUTH)) return CURLE_BAD_CONTENT_ENCODING; - /* Generate 32 random hex chars, 32 bytes + 1 zero termination */ + /* Generate 32 random hex chars, 32 bytes + 1 null-termination */ result = Curl_rand_hex(data, (unsigned char *)cnonce, sizeof(cnonce)); if(result) return result; @@ -512,7 +521,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, char content[DIGEST_MAX_CONTENT_LENGTH]; /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Extract a value=content pair */ @@ -551,6 +560,9 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, token = strtok_r(tmp, ",", &tok_buf); while(token) { + /* Pass additional spaces here */ + while(*token && ISBLANK(*token)) + token++; if(strcasecompare(token, DIGEST_QOP_VALUE_STRING_AUTH)) { foundAuth = TRUE; } @@ -583,17 +595,17 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, return CURLE_OUT_OF_MEMORY; if(strcasecompare(content, "MD5-sess")) - digest->algo = CURLDIGESTALGO_MD5SESS; + digest->algo = ALGO_MD5SESS; else if(strcasecompare(content, "MD5")) - digest->algo = CURLDIGESTALGO_MD5; + digest->algo = ALGO_MD5; else if(strcasecompare(content, "SHA-256")) - digest->algo = CURLDIGESTALGO_SHA256; + digest->algo = ALGO_SHA256; else if(strcasecompare(content, "SHA-256-SESS")) - digest->algo = CURLDIGESTALGO_SHA256SESS; + digest->algo = ALGO_SHA256SESS; else if(strcasecompare(content, "SHA-512-256")) - digest->algo = CURLDIGESTALGO_SHA512_256; + digest->algo = ALGO_SHA512_256; else if(strcasecompare(content, "SHA-512-256-SESS")) - digest->algo = CURLDIGESTALGO_SHA512_256SESS; + digest->algo = ALGO_SHA512_256SESS; else return CURLE_BAD_CONTENT_ENCODING; } @@ -610,7 +622,7 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, break; /* We're done here */ /* Pass all additional spaces here */ - while(*chlg && ISSPACE(*chlg)) + while(*chlg && ISBLANK(*chlg)) chlg++; /* Allow the list to be comma-separated */ @@ -628,6 +640,10 @@ CURLcode Curl_auth_decode_digest_http_message(const char *chlg, if(!digest->nonce) return CURLE_BAD_CONTENT_ENCODING; + /* "<algo>-sess" protocol versions require "auth" or "auth-int" qop */ + if(!digest->qop && (digest->algo & SESSION_ALGO)) + return CURLE_BAD_CONTENT_ENCODING; + return CURLE_OK; } @@ -726,9 +742,7 @@ static CURLcode auth_create_digest_http_message( free(hashthis); convert_to_ascii(hashbuf, ha1); - if(digest->algo == CURLDIGESTALGO_MD5SESS || - digest->algo == CURLDIGESTALGO_SHA256SESS || - digest->algo == CURLDIGESTALGO_SHA512_256SESS) { + if(digest->algo & SESSION_ALGO) { /* nonce and cnonce are OUTSIDE the hash */ tmp = aprintf("%s:%s:%s", ha1, digest->nonce, digest->cnonce); if(!tmp) @@ -843,10 +857,8 @@ static CURLcode auth_create_digest_http_message( digest->qop, request_digest); - if(strcasecompare(digest->qop, "auth")) - digest->nc++; /* The nc (from RFC) has to be a 8 hex digit number 0 - padded which tells to the server how many times you are - using the same nonce in the qop=auth mode */ + /* Increment nonce-count to use another nc value for the next request */ + digest->nc++; } else { response = aprintf("username=\"%s\", " @@ -875,8 +887,9 @@ static CURLcode auth_create_digest_http_message( free(response); return CURLE_OUT_OF_MEMORY; } - tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque); + tmp = aprintf("%s, opaque=\"%s\"", response, opaque_quoted); free(response); + free(opaque_quoted); if(!tmp) return CURLE_OUT_OF_MEMORY; @@ -938,28 +951,18 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, struct digestdata *digest, char **outptr, size_t *outlen) { - switch(digest->algo) { - case CURLDIGESTALGO_MD5: - case CURLDIGESTALGO_MD5SESS: + if(digest->algo <= ALGO_MD5SESS) return auth_create_digest_http_message(data, userp, passwdp, request, uripath, digest, outptr, outlen, auth_digest_md5_to_ascii, Curl_md5it); - - case CURLDIGESTALGO_SHA256: - case CURLDIGESTALGO_SHA256SESS: - case CURLDIGESTALGO_SHA512_256: - case CURLDIGESTALGO_SHA512_256SESS: - return auth_create_digest_http_message(data, userp, passwdp, - request, uripath, digest, - outptr, outlen, - auth_digest_sha256_to_ascii, - Curl_sha256it); - - default: - return CURLE_UNSUPPORTED_PROTOCOL; - } + DEBUGASSERT(digest->algo <= ALGO_SHA512_256SESS); + return auth_create_digest_http_message(data, userp, passwdp, + request, uripath, digest, + outptr, outlen, + auth_digest_sha256_to_ascii, + Curl_sha256it); } /* @@ -982,7 +985,7 @@ void Curl_auth_digest_cleanup(struct digestdata *digest) Curl_safefree(digest->algorithm); digest->nc = 0; - digest->algo = CURLDIGESTALGO_MD5; /* default algorithm */ + digest->algo = ALGO_MD5; /* default algorithm */ digest->stale = FALSE; /* default means normal, not stale */ digest->userhash = FALSE; } |