1
0
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:
toughengineer 2017-07-08 02:10:08 +02:00 committed by Marcel Raad
parent 2d4c2152c9
commit bc4b8c9717
No known key found for this signature in database
GPG Key ID: 07ADACB610D796DA
6 changed files with 41 additions and 10 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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];

View File

@ -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);

View File

@ -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 */

View File

@ -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);