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:
parent
6a7261359b
commit
59f3f92ba6
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user