mirror of
https://github.com/moparisthebest/curl
synced 2024-12-24 00:58:48 -05:00
ntlm_sspi: fix authentication using Credential Manager
If you pass empty user/pass asking curl to use Windows Credential Storage (as stated in the docs) and it has valid credentials for the domain, e.g. curl -v -u : --ntlm example.com currently authentication fails. This change fixes it by providing proper SPN string to the SSPI API calls. Fixes https://github.com/curl/curl/issues/1622 Closes https://github.com/curl/curl/pull/1660
This commit is contained in:
parent
2d4c2152c9
commit
bc4b8c9717
@ -265,7 +265,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|||||||
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
|
||||||
conn->host.name;
|
conn->host.name;
|
||||||
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
|
||||||
#if defined(USE_KERBEROS5)
|
#if defined(USE_KERBEROS5) || defined(USE_NTLM)
|
||||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_SERVICE_NAME] :
|
data->set.str[STRING_SERVICE_NAME] :
|
||||||
sasl->params->service;
|
sasl->params->service;
|
||||||
@ -333,7 +333,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|||||||
if(force_ir || data->set.sasl_ir)
|
if(force_ir || data->set.sasl_ir)
|
||||||
result = Curl_auth_create_ntlm_type1_message(data,
|
result = Curl_auth_create_ntlm_type1_message(data,
|
||||||
conn->user, conn->passwd,
|
conn->user, conn->passwd,
|
||||||
&conn->ntlm, &resp, &len);
|
service,
|
||||||
|
hostname,
|
||||||
|
&conn->ntlm, &resp,
|
||||||
|
&len);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@ -419,13 +422,11 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
|||||||
char *chlg = NULL;
|
char *chlg = NULL;
|
||||||
size_t chlglen = 0;
|
size_t chlglen = 0;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5)
|
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
|
||||||
|
defined(USE_NTLM)
|
||||||
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
const char *service = data->set.str[STRING_SERVICE_NAME] ?
|
||||||
data->set.str[STRING_SERVICE_NAME] :
|
data->set.str[STRING_SERVICE_NAME] :
|
||||||
sasl->params->service;
|
sasl->params->service;
|
||||||
#endif
|
|
||||||
#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
|
|
||||||
defined(USE_NTLM)
|
|
||||||
char *serverdata;
|
char *serverdata;
|
||||||
#endif
|
#endif
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
@ -496,6 +497,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
|||||||
/* Create the type-1 message */
|
/* Create the type-1 message */
|
||||||
result = Curl_auth_create_ntlm_type1_message(data,
|
result = Curl_auth_create_ntlm_type1_message(data,
|
||||||
conn->user, conn->passwd,
|
conn->user, conn->passwd,
|
||||||
|
service, hostname,
|
||||||
&conn->ntlm, &resp, &len);
|
&conn->ntlm, &resp, &len);
|
||||||
newstate = SASL_NTLM_TYPE2MSG;
|
newstate = SASL_NTLM_TYPE2MSG;
|
||||||
break;
|
break;
|
||||||
|
@ -121,9 +121,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
|||||||
server, which is for a plain host or for a HTTP proxy */
|
server, which is for a plain host or for a HTTP proxy */
|
||||||
char **allocuserpwd;
|
char **allocuserpwd;
|
||||||
|
|
||||||
/* point to the name and password for this */
|
/* point to the username, password, service and host */
|
||||||
const char *userp;
|
const char *userp;
|
||||||
const char *passwdp;
|
const char *passwdp;
|
||||||
|
const char *service = NULL;
|
||||||
|
const char *hostname = NULL;
|
||||||
|
|
||||||
/* point to the correct struct with this */
|
/* point to the correct struct with this */
|
||||||
struct ntlmdata *ntlm;
|
struct ntlmdata *ntlm;
|
||||||
@ -141,6 +143,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
|||||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||||
userp = conn->http_proxy.user;
|
userp = conn->http_proxy.user;
|
||||||
passwdp = conn->http_proxy.passwd;
|
passwdp = conn->http_proxy.passwd;
|
||||||
|
service = conn->data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||||
|
conn->data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||||
|
hostname = conn->http_proxy.host.name;
|
||||||
ntlm = &conn->proxyntlm;
|
ntlm = &conn->proxyntlm;
|
||||||
authp = &conn->data->state.authproxy;
|
authp = &conn->data->state.authproxy;
|
||||||
}
|
}
|
||||||
@ -148,6 +153,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
|||||||
allocuserpwd = &conn->allocptr.userpwd;
|
allocuserpwd = &conn->allocptr.userpwd;
|
||||||
userp = conn->user;
|
userp = conn->user;
|
||||||
passwdp = conn->passwd;
|
passwdp = conn->passwd;
|
||||||
|
service = conn->data->set.str[STRING_SERVICE_NAME] ?
|
||||||
|
conn->data->set.str[STRING_SERVICE_NAME] : "HTTP";
|
||||||
|
hostname = conn->host.name;
|
||||||
ntlm = &conn->ntlm;
|
ntlm = &conn->ntlm;
|
||||||
authp = &conn->data->state.authhost;
|
authp = &conn->data->state.authhost;
|
||||||
}
|
}
|
||||||
@ -174,7 +182,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
|||||||
default: /* for the weird cases we (re)start here */
|
default: /* for the weird cases we (re)start here */
|
||||||
/* Create a type-1 message */
|
/* Create a type-1 message */
|
||||||
result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp,
|
result = Curl_auth_create_ntlm_type1_message(conn->data, userp, passwdp,
|
||||||
ntlm, &base64, &len);
|
service, hostname,
|
||||||
|
ntlm, &base64,
|
||||||
|
&len);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
@ -328,6 +328,7 @@ struct ntlmdata {
|
|||||||
BYTE *output_token;
|
BYTE *output_token;
|
||||||
BYTE *input_token;
|
BYTE *input_token;
|
||||||
size_t input_token_len;
|
size_t input_token_len;
|
||||||
|
TCHAR *spn;
|
||||||
#else
|
#else
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned char nonce[8];
|
unsigned char nonce[8];
|
||||||
|
@ -355,6 +355,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
|||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* userp [in] - The user name in the format User or Domain\User.
|
* userp [in] - The user name in the format User or Domain\User.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
|
* service [in] - The service type such as http, smtp, pop or imap.
|
||||||
|
* host [in] - The host name.
|
||||||
* ntlm [in/out] - The NTLM data struct being used and modified.
|
* ntlm [in/out] - The NTLM data struct being used and modified.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
* holding the result will be stored upon completion.
|
* holding the result will be stored upon completion.
|
||||||
@ -365,6 +367,8 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length)
|
|||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
|
const char *service,
|
||||||
|
const char *hostname,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
@ -394,6 +398,8 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||||||
domain are empty */
|
domain are empty */
|
||||||
(void)userp;
|
(void)userp;
|
||||||
(void)passwdp;
|
(void)passwdp;
|
||||||
|
(void)service,
|
||||||
|
(void)hostname,
|
||||||
|
|
||||||
/* Clean up any former leftovers and initialise to defaults */
|
/* Clean up any former leftovers and initialise to defaults */
|
||||||
Curl_auth_ntlm_cleanup(ntlm);
|
Curl_auth_ntlm_cleanup(ntlm);
|
||||||
|
@ -70,6 +70,8 @@ bool Curl_auth_is_ntlm_supported(void)
|
|||||||
* data [in] - The session handle.
|
* data [in] - The session handle.
|
||||||
* userp [in] - The user name in the format User or Domain\User.
|
* userp [in] - The user name in the format User or Domain\User.
|
||||||
* passdwp [in] - The user's password.
|
* passdwp [in] - The user's password.
|
||||||
|
* service [in] - The service type such as http, smtp, pop or imap.
|
||||||
|
* host [in] - The host name.
|
||||||
* ntlm [in/out] - The NTLM data struct being used and modified.
|
* ntlm [in/out] - The NTLM data struct being used and modified.
|
||||||
* outptr [in/out] - The address where a pointer to newly allocated memory
|
* outptr [in/out] - The address where a pointer to newly allocated memory
|
||||||
* holding the result will be stored upon completion.
|
* holding the result will be stored upon completion.
|
||||||
@ -80,6 +82,8 @@ bool Curl_auth_is_ntlm_supported(void)
|
|||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
|
const char *service,
|
||||||
|
const char *host,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr, size_t *outlen)
|
char **outptr, size_t *outlen)
|
||||||
{
|
{
|
||||||
@ -143,6 +147,10 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||||||
if(!ntlm->context)
|
if(!ntlm->context)
|
||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
ntlm->spn = Curl_auth_build_spn(service, host, NULL);
|
||||||
|
if(!ntlm->spn)
|
||||||
|
return CURLE_OUT_OF_MEMORY;
|
||||||
|
|
||||||
/* Setup the type-1 "output" security buffer */
|
/* Setup the type-1 "output" security buffer */
|
||||||
type_1_desc.ulVersion = SECBUFFER_VERSION;
|
type_1_desc.ulVersion = SECBUFFER_VERSION;
|
||||||
type_1_desc.cBuffers = 1;
|
type_1_desc.cBuffers = 1;
|
||||||
@ -153,7 +161,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
|||||||
|
|
||||||
/* Generate our type-1 message */
|
/* Generate our type-1 message */
|
||||||
status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL,
|
status = s_pSecFn->InitializeSecurityContext(ntlm->credentials, NULL,
|
||||||
(TCHAR *) TEXT(""),
|
ntlm->spn,
|
||||||
0, 0, SECURITY_NETWORK_DREP,
|
0, 0, SECURITY_NETWORK_DREP,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
ntlm->context, &type_1_desc,
|
ntlm->context, &type_1_desc,
|
||||||
@ -271,7 +279,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||||||
/* Generate our type-3 message */
|
/* Generate our type-3 message */
|
||||||
status = s_pSecFn->InitializeSecurityContext(ntlm->credentials,
|
status = s_pSecFn->InitializeSecurityContext(ntlm->credentials,
|
||||||
ntlm->context,
|
ntlm->context,
|
||||||
(TCHAR *) TEXT(""),
|
ntlm->spn,
|
||||||
0, 0, SECURITY_NETWORK_DREP,
|
0, 0, SECURITY_NETWORK_DREP,
|
||||||
&type_2_desc,
|
&type_2_desc,
|
||||||
0, ntlm->context,
|
0, ntlm->context,
|
||||||
@ -329,6 +337,8 @@ void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm)
|
|||||||
|
|
||||||
/* Reset any variables */
|
/* Reset any variables */
|
||||||
ntlm->token_max = 0;
|
ntlm->token_max = 0;
|
||||||
|
|
||||||
|
Curl_safefree(ntlm->spn);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* USE_WINDOWS_SSPI && USE_NTLM */
|
#endif /* USE_WINDOWS_SSPI && USE_NTLM */
|
||||||
|
@ -122,6 +122,8 @@ bool Curl_auth_is_ntlm_supported(void);
|
|||||||
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
|
||||||
const char *userp,
|
const char *userp,
|
||||||
const char *passwdp,
|
const char *passwdp,
|
||||||
|
const char *service,
|
||||||
|
const char *host,
|
||||||
struct ntlmdata *ntlm,
|
struct ntlmdata *ntlm,
|
||||||
char **outptr,
|
char **outptr,
|
||||||
size_t *outlen);
|
size_t *outlen);
|
||||||
|
Loading…
Reference in New Issue
Block a user