summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeorgeok <giorgos.n.oikonomou@gmail.com>2019-01-29 18:26:31 +0100
committerMarcel Raad <Marcel.Raad@teamviewer.com>2019-02-01 09:56:27 +0100
commita730432e59754df97c8985eb3094ca1cdd3e4955 (patch)
tree3e19c162afb855193a7ef4db1419a3f80b0d9392
parent463f16d188f9e7fae2e71a6b3160d391fbe8ff18 (diff)
downloadcurl-a730432e59754df97c8985eb3094ca1cdd3e4955.tar.gz
spnego_sspi: add support for channel binding
Attempt to add support for Secure Channel binding when negotiate authentication is used. The problem to solve is that by default IIS accepts channel binding and curl doesn't utilise them. The result was a 401 response. Scope affects only the Schannel(winssl)-SSPI combination. Fixes https://github.com/curl/curl/issues/3503 Closes https://github.com/curl/curl/pull/3509
-rw-r--r--lib/http_negotiate.c5
-rw-r--r--lib/http_ntlm.c3
-rw-r--r--lib/urldata.h6
-rw-r--r--lib/vauth/spnego_sspi.c41
-rw-r--r--lib/vtls/schannel.c2
5 files changed, 49 insertions, 8 deletions
diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c
index 4713d1bd5..2a97707eb 100644
--- a/lib/http_negotiate.c
+++ b/lib/http_negotiate.c
@@ -89,6 +89,11 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
}
}
+ /* Supports SSL channel binding for Windows ISS extended protection */
+#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS)
+ neg_ctx->sslContext = conn->sslContext;
+#endif
+
/* Initialize the security context and decode our challenge */
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
host, header, neg_ctx);
diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c
index a9b33f98e..aaf8a3deb 100644
--- a/lib/http_ntlm.c
+++ b/lib/http_ntlm.c
@@ -175,6 +175,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
if(s_hSecDll == NULL)
return err;
}
+#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
+ ntlm->sslContext = conn->sslContext;
+#endif
#endif
switch(ntlm->state) {
diff --git a/lib/urldata.h b/lib/urldata.h
index b71a843b4..ff3cc9a65 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -364,6 +364,9 @@ struct negotiatedata {
gss_buffer_desc output_token;
#else
#ifdef USE_WINDOWS_SSPI
+#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
+ CtxtHandle *sslContext;
+#endif
DWORD status;
CredHandle *credentials;
CtxtHandle *context;
@@ -980,6 +983,9 @@ struct connectdata {
void *seek_client; /* pointer to pass to the seek() above */
/*************** Request - specific items ************/
+#if defined(USE_WINDOWS_SSPI) && defined(SECPKG_ATTR_ENDPOINT_BINDINGS)
+ CtxtHandle *sslContext;
+#endif
#if defined(USE_NTLM)
struct ntlmdata ntlm; /* NTLM differs from other authentication schemes
diff --git a/lib/vauth/spnego_sspi.c b/lib/vauth/spnego_sspi.c
index d3cb5cb0f..00d840465 100644
--- a/lib/vauth/spnego_sspi.c
+++ b/lib/vauth/spnego_sspi.c
@@ -92,7 +92,7 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
size_t chlglen = 0;
unsigned char *chlg = NULL;
PSecPkgInfo SecurityPackage;
- SecBuffer chlg_buf;
+ SecBuffer chlg_buf[2];
SecBuffer resp_buf;
SecBufferDesc chlg_desc;
SecBufferDesc resp_desc;
@@ -189,12 +189,39 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
}
/* Setup the challenge "input" security buffer */
- chlg_desc.ulVersion = SECBUFFER_VERSION;
- chlg_desc.cBuffers = 1;
- chlg_desc.pBuffers = &chlg_buf;
- chlg_buf.BufferType = SECBUFFER_TOKEN;
- chlg_buf.pvBuffer = chlg;
- chlg_buf.cbBuffer = curlx_uztoul(chlglen);
+ chlg_desc.ulVersion = SECBUFFER_VERSION;
+ chlg_desc.cBuffers = 1;
+ chlg_desc.pBuffers = &chlg_buf[0];
+ chlg_buf[0].BufferType = SECBUFFER_TOKEN;
+ chlg_buf[0].pvBuffer = chlg;
+ chlg_buf[0].cbBuffer = curlx_uztoul(chlglen);
+
+#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
+ /* ssl context comes from Schannel.
+ * When extended protection is used in IIS server,
+ * we have to pass a second SecBuffer to the SecBufferDesc
+ * otherwise IIS will not pass the authentication (401 response).
+ * Minimum supported version is Windows 7.
+ * https://docs.microsoft.com/en-us/security-updates
+ * /SecurityAdvisories/2009/973811
+ */
+ if(nego->sslContext) {
+ SEC_CHANNEL_BINDINGS channelBindings;
+ SecPkgContext_Bindings pkgBindings;
+ pkgBindings.Bindings = &channelBindings;
+ nego->status = s_pSecFn->QueryContextAttributes(
+ nego->sslContext,
+ SECPKG_ATTR_ENDPOINT_BINDINGS,
+ &pkgBindings
+ );
+ if(nego->status == SEC_E_OK) {
+ chlg_desc.cBuffers++;
+ chlg_buf[1].BufferType = SECBUFFER_CHANNEL_BINDINGS;
+ chlg_buf[1].cbBuffer = pkgBindings.BindingsLength;
+ chlg_buf[1].pvBuffer = pkgBindings.Bindings;
+ }
+ }
+#endif
}
/* Setup the response "output" security buffer */
diff --git a/lib/vtls/schannel.c b/lib/vtls/schannel.c
index 4c816fdda..c8574f56c 100644
--- a/lib/vtls/schannel.c
+++ b/lib/vtls/schannel.c
@@ -1428,7 +1428,7 @@ schannel_connect_common(struct connectdata *conn, int sockindex,
* binding to pass the IIS extended protection checks.
* Available on Windows 7 or later.
*/
- conn->ntlm.sslContext = &BACKEND->ctxt->ctxt_handle;
+ conn->sslContext = &BACKEND->ctxt->ctxt_handle;
#endif
*done = TRUE;