Commit f7e24683 authored by Steve Holme's avatar Steve Holme
Browse files

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 607883f1 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.
parent 276741af
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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 <user:password>"
+20 −18
Original line number Diff line number Diff line
@@ -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,6 +179,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
    return CURLE_OUT_OF_MEMORY;
  }

  if(userp && *userp) {
    /* Populate our identity structure */
    result = Curl_create_sspi_identity(userp, passwdp, &identity);
    if(result) {
@@ -195,15 +190,22 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data,
      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);