mirror of
https://github.com/curl/curl.git
synced 2026-08-26 13:23:43 +03:00
spnego_sspi: pass channel bindings on initial context
HTTP Negotiate can create and send a Kerberos token before receiving a server challenge. The SSPI backend only supplied Schannel endpoint bindings when a challenge token was present, causing IIS with EPA enabled to reject preemptive Kerberos authentication with STATUS_BAD_BINDINGS. Build the SSPI input descriptor independently of the challenge token so Schannel endpoint bindings are included on both initial and subsequent InitializeSecurityContext calls. Assisted-by: martin-fzi@users.noreply.github.com Fixes https://github.com/curl/curl/issues/22466 Closes https://github.com/curl/curl/pull/22537
This commit is contained in:
parent
67221a7882
commit
3ca86602ef
2 changed files with 42 additions and 28 deletions
|
|
@ -242,6 +242,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
SecBufferDesc type_3_desc;
|
||||
SECURITY_STATUS status;
|
||||
unsigned long attrs;
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
SecPkgContext_Bindings pkgBindings = { 0, NULL };
|
||||
#endif
|
||||
|
||||
(void)creds;
|
||||
|
||||
|
|
@ -262,9 +265,6 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
* https://learn.microsoft.com/security-updates/SecurityAdvisories/2009/973811
|
||||
*/
|
||||
if(ntlm->sslContext) {
|
||||
SEC_CHANNEL_BINDINGS channelBindings;
|
||||
SecPkgContext_Bindings pkgBindings;
|
||||
pkgBindings.Bindings = &channelBindings;
|
||||
status = Curl_pSecFn->QueryContextAttributes(
|
||||
ntlm->sslContext,
|
||||
SECPKG_ATTR_ENDPOINT_BINDINGS,
|
||||
|
|
@ -296,6 +296,12 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
|
|||
0, ntlm->context,
|
||||
&type_3_desc,
|
||||
&attrs, NULL);
|
||||
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
if(pkgBindings.Bindings)
|
||||
Curl_pSecFn->FreeContextBuffer(pkgBindings.Bindings);
|
||||
#endif
|
||||
|
||||
if(status != SEC_E_OK) {
|
||||
infof(data, "NTLM handshake failure (type-3 message): Status=0x%08lx",
|
||||
(unsigned long)status);
|
||||
|
|
|
|||
|
|
@ -93,6 +93,9 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
SecBufferDesc chlg_desc;
|
||||
SecBufferDesc resp_desc;
|
||||
unsigned long attrs;
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
SecPkgContext_Bindings pkgBindings = { 0, NULL };
|
||||
#endif
|
||||
|
||||
if(nego->context && nego->status == SEC_E_OK) {
|
||||
/* We finished successfully our part of authentication, but server
|
||||
|
|
@ -194,6 +197,10 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
chlg_desc.ulVersion = SECBUFFER_VERSION;
|
||||
chlg_desc.cBuffers = 0;
|
||||
chlg_desc.pBuffers = chlg_buf;
|
||||
|
||||
if(chlg64 && *chlg64) {
|
||||
/* Decode the base-64 encoded challenge message */
|
||||
if(*chlg64 != '=') {
|
||||
|
|
@ -209,38 +216,33 @@ 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[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 does not pass the authentication (401 response).
|
||||
* Minimum supported version is Windows 7.
|
||||
* https://learn.microsoft.com/security-updates/SecurityAdvisories/2009/973811
|
||||
*/
|
||||
if(nego->sslContext) {
|
||||
SEC_CHANNEL_BINDINGS channelBindings;
|
||||
SecPkgContext_Bindings pkgBindings;
|
||||
pkgBindings.Bindings = &channelBindings;
|
||||
nego->status = Curl_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;
|
||||
}
|
||||
/* SSL context comes from Schannel.
|
||||
* When extended protection is used in IIS server, pass its channel
|
||||
* bindings on the initial call too. HTTP Negotiate can create and send a
|
||||
* Kerberos token before receiving a challenge from the server.
|
||||
* Minimum supported version is Windows 7.
|
||||
* https://learn.microsoft.com/security-updates/SecurityAdvisories/2009/973811
|
||||
*/
|
||||
if(nego->sslContext) {
|
||||
nego->status = Curl_pSecFn->QueryContextAttributes(
|
||||
nego->sslContext,
|
||||
SECPKG_ATTR_ENDPOINT_BINDINGS,
|
||||
&pkgBindings);
|
||||
if(nego->status == SEC_E_OK) {
|
||||
SecBuffer *binding_buf = &chlg_buf[chlg_desc.cBuffers++];
|
||||
binding_buf->BufferType = SECBUFFER_CHANNEL_BINDINGS;
|
||||
binding_buf->cbBuffer = pkgBindings.BindingsLength;
|
||||
binding_buf->pvBuffer = pkgBindings.Bindings;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Setup the response "output" security buffer */
|
||||
resp_desc.ulVersion = SECBUFFER_VERSION;
|
||||
|
|
@ -261,11 +263,17 @@ CURLcode Curl_auth_decode_spnego_message(struct Curl_easy *data,
|
|||
nego->spn,
|
||||
sspi_flags,
|
||||
0, SECURITY_NATIVE_DREP,
|
||||
chlg ? &chlg_desc : NULL,
|
||||
chlg_desc.cBuffers ?
|
||||
&chlg_desc : NULL,
|
||||
0, nego->context,
|
||||
&resp_desc, &attrs, NULL);
|
||||
}
|
||||
|
||||
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
|
||||
if(pkgBindings.Bindings)
|
||||
Curl_pSecFn->FreeContextBuffer(pkgBindings.Bindings);
|
||||
#endif
|
||||
|
||||
/* Free the decoded challenge as it is not required anymore */
|
||||
curlx_free(chlg);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue