From 0b5665c98a0f8b12023d73014b5bb5d4de41a243 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Tue, 8 Aug 2017 19:32:19 -0400 Subject: [PATCH] digest_sspi: Don't reuse context if the user/passwd has changed Bug: https://github.com/curl/curl/issues/1685 Reported-by: paulharris@users.noreply.github.com Assisted-by: Isaac Boukris Closes https://github.com/curl/curl/pull/1742 --- lib/urldata.h | 4 ++++ lib/vauth/digest_sspi.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/lib/urldata.h b/lib/urldata.h index 45ad04e0a..b4f18e7da 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -417,6 +417,10 @@ struct digestdata { BYTE *input_token; size_t input_token_len; CtxtHandle *http_context; + /* copy of user/passwd used to make the identity for http_context. + either may be NULL. */ + char *user; + char *passwd; #else char *nonce; char *cnonce; diff --git a/lib/vauth/digest_sspi.c b/lib/vauth/digest_sspi.c index 0bd94442d..f5d619c99 100644 --- a/lib/vauth/digest_sspi.c +++ b/lib/vauth/digest_sspi.c @@ -438,6 +438,20 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, return CURLE_OUT_OF_MEMORY; } + /* If the user/passwd that was used to make the identity for http_context + has changed then delete that context. */ + if((userp && !digest->user) || (!userp && digest->user) || + (passwdp && !digest->passwd) || (!passwdp && digest->passwd) || + (userp && digest->user && strcmp(userp, digest->user)) || + (passwdp && digest->passwd && strcmp(passwdp, digest->passwd))) { + if(digest->http_context) { + s_pSecFn->DeleteSecurityContext(digest->http_context); + Curl_safefree(digest->http_context); + } + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); + } + if(digest->http_context) { chlg_desc.ulVersion = SECBUFFER_VERSION; chlg_desc.cBuffers = 5; @@ -479,6 +493,10 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, TimeStamp expiry; /* For Windows 9x compatibility of SSPI calls */ TCHAR *spn; + /* free the copy of user/passwd used to make the previous identity */ + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); + if(userp && *userp) { /* Populate our identity structure */ if(Curl_create_sspi_identity(userp, passwdp, &identity)) { @@ -500,6 +518,25 @@ CURLcode Curl_auth_create_digest_http_message(struct Curl_easy *data, /* Use the current Windows user */ p_identity = NULL; + if(userp) { + digest->user = strdup(userp); + + if(!digest->user) { + free(output_token); + return CURLE_OUT_OF_MEMORY; + } + } + + if(passwdp) { + digest->passwd = strdup(passwdp); + + if(!digest->passwd) { + free(output_token); + Curl_safefree(digest->user); + return CURLE_OUT_OF_MEMORY; + } + } + /* Acquire our credentials handle */ status = s_pSecFn->AcquireCredentialsHandle(NULL, (TCHAR *) TEXT(SP_NAME_DIGEST), @@ -623,6 +660,10 @@ void Curl_auth_digest_cleanup(struct digestdata *digest) s_pSecFn->DeleteSecurityContext(digest->http_context); Curl_safefree(digest->http_context); } + + /* Free the copy of user/passwd used to make the identity for http_context */ + Curl_safefree(digest->user); + Curl_safefree(digest->passwd); } #endif /* USE_WINDOWS_SSPI && !CURL_DISABLE_CRYPTO_AUTH */