mirror of
https://github.com/moparisthebest/curl
synced 2025-02-28 09:21:50 -05:00
sas: Added DIGEST-MD5 qop-option validation in native challange handling
Given that we presently support "auth" and not "auth-int" or "auth-conf" for native challenge-response messages, added client side validation of the quality-of-protection options from the server's challenge message.
This commit is contained in:
parent
a700f9002c
commit
b574e83079
@ -40,6 +40,8 @@
|
|||||||
#include "curl_sasl.h"
|
#include "curl_sasl.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
|
#include "strtok.h"
|
||||||
|
#include "rawstr.h"
|
||||||
|
|
||||||
#ifdef USE_NSS
|
#ifdef USE_NSS
|
||||||
#include "vtls/nssg.h" /* for Curl_nss_force_init() */
|
#include "vtls/nssg.h" /* for Curl_nss_force_init() */
|
||||||
@ -52,6 +54,14 @@
|
|||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
|
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
|
||||||
|
#define DIGEST_QOP_VALUE_AUTH (1 << 0)
|
||||||
|
#define DIGEST_QOP_VALUE_AUTH_INT (1 << 1)
|
||||||
|
#define DIGEST_QOP_VALUE_AUTH_CONF (1 << 2)
|
||||||
|
|
||||||
|
#define DIGEST_QOP_VALUE_STRING_AUTH "auth"
|
||||||
|
#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int"
|
||||||
|
#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
|
||||||
|
|
||||||
/* Retrieves the value for a corresponding key from the challenge string
|
/* 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
|
* returns TRUE if the key could be found, FALSE if it does not exists
|
||||||
*/
|
*/
|
||||||
@ -76,6 +86,38 @@ static bool sasl_digest_get_key_value(const char *chlg,
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
char *token;
|
||||||
|
char *tok_buf;
|
||||||
|
|
||||||
|
/* Initialise the output */
|
||||||
|
*value = 0;
|
||||||
|
|
||||||
|
/* Tokenise the list of qop values. Use a temporary clone of the buffer since
|
||||||
|
strtok_r() ruins it. */
|
||||||
|
tmp = strdup(options);
|
||||||
|
if(!tmp)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
token = strtok_r(tmp, ",", &tok_buf);
|
||||||
|
while(token != NULL) {
|
||||||
|
if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH))
|
||||||
|
*value |= DIGEST_QOP_VALUE_AUTH;
|
||||||
|
else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_INT))
|
||||||
|
*value |= DIGEST_QOP_VALUE_AUTH_INT;
|
||||||
|
else if(Curl_raw_equal(token, DIGEST_QOP_VALUE_STRING_AUTH_CONF))
|
||||||
|
*value |= DIGEST_QOP_VALUE_AUTH_CONF;
|
||||||
|
|
||||||
|
token = strtok_r(NULL, ",", &tok_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
Curl_safefree(tmp);
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -279,13 +321,16 @@ CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data,
|
|||||||
* rlen [in] - The length of the realm buffer.
|
* rlen [in] - The length of the realm buffer.
|
||||||
* alg [in/out] - The buffer where the algorithm will be stored.
|
* alg [in/out] - The buffer where the algorithm will be stored.
|
||||||
* alen [in] - The length of the algorithm buffer.
|
* alen [in] - The length of the algorithm buffer.
|
||||||
|
* qop [in/out] - The buffer where the qop-options will be stored.
|
||||||
|
* qlen [in] - The length of the qop buffer.
|
||||||
*
|
*
|
||||||
* Returns CURLE_OK on success.
|
* Returns CURLE_OK on success.
|
||||||
*/
|
*/
|
||||||
static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
|
static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
|
||||||
char *nonce, size_t nlen,
|
char *nonce, size_t nlen,
|
||||||
char *realm, size_t rlen,
|
char *realm, size_t rlen,
|
||||||
char *alg, size_t alen)
|
char *alg, size_t alen,
|
||||||
|
char *qop, size_t qlen)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
unsigned char *chlg = NULL;
|
unsigned char *chlg = NULL;
|
||||||
@ -321,6 +366,12 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64,
|
|||||||
return CURLE_BAD_CONTENT_ENCODING;
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retrieve qop-options string from the challenge */
|
||||||
|
if(!sasl_digest_get_key_value((char *)chlg, "qop=\"", qop, qlen, '\"')) {
|
||||||
|
Curl_safefree(chlg);
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
}
|
||||||
|
|
||||||
Curl_safefree(chlg);
|
Curl_safefree(chlg);
|
||||||
|
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
@ -367,22 +418,35 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
|
|||||||
char nonce[64];
|
char nonce[64];
|
||||||
char realm[128];
|
char realm[128];
|
||||||
char algorithm[64];
|
char algorithm[64];
|
||||||
|
char qop_options[64];
|
||||||
|
int qop_values;
|
||||||
|
|
||||||
char nonceCount[] = "00000001";
|
char nonceCount[] = "00000001";
|
||||||
char cnonce[] = "12345678"; /* will be changed */
|
char cnonce[] = "12345678"; /* will be changed */
|
||||||
char method[] = "AUTHENTICATE";
|
char method[] = "AUTHENTICATE";
|
||||||
char qop[] = "auth";
|
char qop[] = DIGEST_QOP_VALUE_STRING_AUTH;
|
||||||
char uri[128];
|
char uri[128];
|
||||||
|
|
||||||
/* Decode the challange message */
|
/* Decode the challange message */
|
||||||
result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
result = sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
|
||||||
realm, sizeof(realm),
|
realm, sizeof(realm),
|
||||||
algorithm, sizeof(algorithm));
|
algorithm, sizeof(algorithm),
|
||||||
|
qop_options, sizeof(qop_options));
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* We only support md5 sessions */
|
/* We only support md5 sessions */
|
||||||
if(strcmp(algorithm, "md5-sess") != 0)
|
if(strcmp(algorithm, "md5-sess") != 0)
|
||||||
return CURLE_BAD_CONTENT_ENCODING;
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
|
/* Get the qop-values from the qop-options */
|
||||||
|
result = sasl_digest_get_qop_values(qop_options, &qop_values);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* We only support auth quality-of-protection */
|
||||||
|
if(!(qop_values & DIGEST_QOP_VALUE_AUTH))
|
||||||
|
return CURLE_BAD_CONTENT_ENCODING;
|
||||||
|
|
||||||
#ifndef DEBUGBUILD
|
#ifndef DEBUGBUILD
|
||||||
/* Generate 64 bits of random data */
|
/* Generate 64 bits of random data */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user