1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 08:08:50 -05:00

sasl_sspi: Populate domain from the realm in the challenge

Without this, SSPI based digest auth was broken.

Bug: https://github.com/bagder/curl/pull/141.patch
This commit is contained in:
Grant Pannell 2015-04-26 16:12:23 +02:00 committed by Daniel Stenberg
parent 6a7261359b
commit 59f3f92ba6
4 changed files with 95 additions and 6 deletions

View File

@ -76,9 +76,6 @@ const struct {
#define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int" #define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int"
#define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf" #define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf"
#define DIGEST_MAX_VALUE_LENGTH 256
#define DIGEST_MAX_CONTENT_LENGTH 1024
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines. /* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
It converts digest text to ASCII so the MD5 will be correct for It converts digest text to ASCII so the MD5 will be correct for
what ultimately goes over the network. what ultimately goes over the network.
@ -90,13 +87,16 @@ const struct {
return result; \ return result; \
} }
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
/* /*
* Returns 0 on success and then the buffers are filled in fine. * Returns 0 on success and then the buffers are filled in fine.
* *
* Non-zero means failure to parse. * Non-zero means failure to parse.
*/ */
static int sasl_digest_get_pair(const char *str, char *value, char *content, int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
const char **endptr) const char **endptr)
{ {
int c; int c;
bool starts_with_quote = FALSE; bool starts_with_quote = FALSE;
@ -157,7 +157,9 @@ static int sasl_digest_get_pair(const char *str, char *value, char *content,
return 0; /* all is fine! */ return 0; /* all is fine! */
} }
#endif
#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI)
/* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/ /* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/
static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */
unsigned char *dest) /* 33 bytes */ unsigned char *dest) /* 33 bytes */
@ -776,7 +778,7 @@ CURLcode Curl_sasl_decode_digest_http_message(const char *chlg,
chlg++; chlg++;
/* Extract a value=content pair */ /* Extract a value=content pair */
if(!sasl_digest_get_pair(chlg, value, content, &chlg)) { if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
if(Curl_raw_equal(value, "nonce")) { if(Curl_raw_equal(value, "nonce")) {
digest->nonce = strdup(content); digest->nonce = strdup(content);
if(!digest->nonce) if(!digest->nonce)

View File

@ -65,6 +65,11 @@ struct kerberos5data;
#define SASL_MECH_STRING_NTLM "NTLM" #define SASL_MECH_STRING_NTLM "NTLM"
#define SASL_MECH_STRING_XOAUTH2 "XOAUTH2" #define SASL_MECH_STRING_XOAUTH2 "XOAUTH2"
#if !defined(CURL_DISABLE_CRYPTO_AUTH)
#define DIGEST_MAX_VALUE_LENGTH 256
#define DIGEST_MAX_CONTENT_LENGTH 1024
#endif
enum { enum {
CURLDIGESTALGO_MD5, CURLDIGESTALGO_MD5,
CURLDIGESTALGO_MD5SESS CURLDIGESTALGO_MD5SESS
@ -136,6 +141,10 @@ char *Curl_sasl_build_spn(const char *service, const char *instance);
TCHAR *Curl_sasl_build_spn(const char *service, const char *instance); TCHAR *Curl_sasl_build_spn(const char *service, const char *instance);
#endif #endif
/* This is used to extract the realm from a challenge message */
int Curl_sasl_digest_get_pair(const char *str, char *value, char *content,
const char **endptr);
#if defined(HAVE_GSSAPI) #if defined(HAVE_GSSAPI)
char *Curl_sasl_build_gssapi_spn(const char *service, const char *host); char *Curl_sasl_build_gssapi_spn(const char *service, const char *host);
#endif #endif

View File

@ -40,6 +40,7 @@
#include "sendf.h" #include "sendf.h"
#include "strdup.h" #include "strdup.h"
#include "curl_printf.h" #include "curl_printf.h"
#include "rawstr.h"
/* The last #include files should be: */ /* The last #include files should be: */
#include "curl_memory.h" #include "curl_memory.h"
@ -273,6 +274,74 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
return result; return result;
} }
/*
* Curl_override_sspi_http_realm()
*
* This is used to populate the domain in a SSPI identity structure
* The realm is extracted from the challenge message and used as the
* domain if it is not already explicitly set.
*
* Parameters:
*
* chlg [in] - The challenge message.
* identity [in/out] - The identity structure.
*
* Returns CURLE_OK on success.
*/
CURLcode Curl_override_sspi_http_realm(const char *chlg,
SEC_WINNT_AUTH_IDENTITY *identity)
{
xcharp_u domain, dup_domain;
/* If domain is blank or unset, check challenge message for realm */
if(!identity->Domain || !identity->DomainLength) {
for(;;) {
char value[DIGEST_MAX_VALUE_LENGTH];
char content[DIGEST_MAX_CONTENT_LENGTH];
/* Pass all additional spaces here */
while(*chlg && ISSPACE(*chlg))
chlg++;
/* Extract a value=content pair */
if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) {
if(Curl_raw_equal(value, "realm")) {
/* Setup identity's domain and length */
domain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)content);
if(!domain.tchar_ptr)
return CURLE_OUT_OF_MEMORY;
dup_domain.tchar_ptr = _tcsdup(domain.tchar_ptr);
if(!dup_domain.tchar_ptr) {
Curl_unicodefree(domain.tchar_ptr);
return CURLE_OUT_OF_MEMORY;
}
identity->Domain = dup_domain.tbyte_ptr;
identity->DomainLength = curlx_uztoul(_tcslen(dup_domain.tchar_ptr));
dup_domain.tchar_ptr = NULL;
Curl_unicodefree(domain.tchar_ptr);
}
else {
/* unknown specifier, ignore it! */
}
}
else
break; /* we're done here */
/* Pass all additional spaces here */
while(*chlg && ISSPACE(*chlg))
chlg++;
/* Allow the list to be comma-separated */
if(',' == *chlg)
chlg++;
}
}
return CURLE_OK;
}
/* /*
* Curl_sasl_decode_digest_http_message() * Curl_sasl_decode_digest_http_message()
* *
@ -374,6 +443,11 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data,
if(Curl_create_sspi_identity(userp, passwdp, &identity)) if(Curl_create_sspi_identity(userp, passwdp, &identity))
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
/* Populate our identity domain */
if(Curl_override_sspi_http_realm((const char*)digest->input_token,
&identity))
return CURLE_OUT_OF_MEMORY;
/* Allow proper cleanup of the identity structure */ /* Allow proper cleanup of the identity structure */
p_identity = &identity; p_identity = &identity;
} }

View File

@ -43,6 +43,10 @@
CURLcode Curl_sspi_global_init(void); CURLcode Curl_sspi_global_init(void);
void Curl_sspi_global_cleanup(void); void Curl_sspi_global_cleanup(void);
/* This is used to populate the domain in a SSPI identity structure */
CURLcode Curl_override_sspi_http_realm(const char *chlg,
SEC_WINNT_AUTH_IDENTITY *identity);
/* This is used to generate an SSPI identity structure */ /* This is used to generate an SSPI identity structure */
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp, CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
SEC_WINNT_AUTH_IDENTITY *identity); SEC_WINNT_AUTH_IDENTITY *identity);