From f7e24683c47381ce32bfa5a3a01ff737483373c9 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Wed, 29 Oct 2014 14:05:21 +0000 Subject: [PATCH] sasl_sspi: Allow DIGEST-MD5 to use current windows credentials Fixed the ability to use the current log-in credentials with DIGEST-MD5. I had previously disabled this functionality in commit 607883f13c as I couldn't get this to work under Windows 8, however, from testing HTTP Digest authentication through Windows SSPI and then further testing of this code I have found it works in Windows 7. Some further investigation is required to see what the differences are between Windows 7 and 8, but for now enable this functionality as the code will return an error when AcquireCredentialsHandle() fails. --- docs/curl.1 | 6 +++--- lib/curl_sasl_sspi.c | 38 ++++++++++++++++++++------------------ 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/curl.1 b/docs/curl.1 index ca52b96c6..8f8e3d65f 100644 --- a/docs/curl.1 +++ b/docs/curl.1 @@ -1679,9 +1679,9 @@ Principal Name) formats. For example, EXAMPLE\\user and user@example.com respectively. If you use a Windows SSPI-enabled curl binary and perform Kerberos V5, -Negotiate or NTLM authentication then you can tell curl to select the user -name and password from your environment by specifying a single colon with this -option: "-u :". +Negotiate, NTLM or DIGEST-MD5 authentication then you can tell curl to select +the user name and password from your environment by specifying a single colon +with this option: "-u :". If this option is used several times, the last one will be used. .IP "-U, --proxy-user " diff --git a/lib/curl_sasl_sspi.c b/lib/curl_sasl_sspi.c index a5557b98a..9aa84d77f 100644 --- a/lib/curl_sasl_sspi.c +++ b/lib/curl_sasl_sspi.c @@ -128,6 +128,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, CtxtHandle ctx; PSecPkgInfo SecurityPackage; SEC_WINNT_AUTH_IDENTITY identity; + SEC_WINNT_AUTH_IDENTITY *p_identity; SecBuffer chlg_buf; SecBuffer resp_buf; SecBufferDesc chlg_desc; @@ -147,13 +148,6 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, if(!chlg) return CURLE_BAD_CONTENT_ENCODING; - /* Ensure we have some login credentials as DigestSSP cannot use the current - Windows user like NTLMSSP can */ - if(!userp || !*userp) { - Curl_safefree(chlg); - return CURLE_LOGIN_DENIED; - } - /* Query the security package for DigestSSP */ status = s_pSecFn->QuerySecurityPackageInfo((TCHAR *) TEXT("WDigest"), &SecurityPackage); @@ -185,25 +179,33 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; } - /* Populate our identity structure */ - result = Curl_create_sspi_identity(userp, passwdp, &identity); - if(result) { - Curl_safefree(spn); - Curl_safefree(resp); - Curl_safefree(chlg); + if(userp && *userp) { + /* Populate our identity structure */ + result = Curl_create_sspi_identity(userp, passwdp, &identity); + if(result) { + Curl_safefree(spn); + Curl_safefree(resp); + Curl_safefree(chlg); - return result; + return result; + } + + /* Allow proper cleanup of the identity structure */ + p_identity = &identity; } + else + /* Use the current Windows user */ + p_identity = NULL; /* Acquire our credentials handle */ status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT("WDigest"), SECPKG_CRED_OUTBOUND, NULL, - &identity, NULL, NULL, + p_identity, NULL, NULL, &handle, &expiry); if(status != SEC_E_OK) { - Curl_sspi_free_identity(&identity); + Curl_sspi_free_identity(p_identity); Curl_safefree(spn); Curl_safefree(resp); Curl_safefree(chlg); @@ -237,7 +239,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, s_pSecFn->CompleteAuthToken(&handle, &resp_desc); else if(status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { s_pSecFn->FreeCredentialsHandle(&handle); - Curl_sspi_free_identity(&identity); + Curl_sspi_free_identity(p_identity); Curl_safefree(spn); Curl_safefree(resp); Curl_safefree(chlg); @@ -254,7 +256,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, s_pSecFn->FreeCredentialsHandle(&handle); /* Free the identity structure */ - Curl_sspi_free_identity(&identity); + Curl_sspi_free_identity(p_identity); /* Free the SPN */ Curl_safefree(spn);