Commit 09662337 authored by georgeok's avatar georgeok Committed by Marcel Raad
Browse files

ntlm_sspi: add support for channel binding

Windows extended potection (aka ssl channel binding) is required
to login to ntlm IIS endpoint, otherwise the server returns 401
responses.

Fixes #3280
Closes #3321
parent 6ee67297
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -328,6 +328,12 @@ struct kerberos5data {
struct ntlmdata {
struct ntlmdata {
  curlntlm state;
  curlntlm state;
#ifdef USE_WINDOWS_SSPI
#ifdef USE_WINDOWS_SSPI
/* The sslContext is used for the Schannel bindings. The
 * api is available on the Windows 7 SDK and later.
 */
#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
  CtxtHandle *sslContext;
#endif
  CredHandle *credentials;
  CredHandle *credentials;
  CtxtHandle *context;
  CtxtHandle *context;
  SEC_WINNT_AUTH_IDENTITY identity;
  SEC_WINNT_AUTH_IDENTITY identity;
+35 −8
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 *
 * This software is licensed as described in the file COPYING, which
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * you should have received as part of this distribution. The terms
@@ -249,7 +249,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
                                             char **outptr, size_t *outlen)
                                             char **outptr, size_t *outlen)
{
{
  CURLcode result = CURLE_OK;
  CURLcode result = CURLE_OK;
  SecBuffer type_2_buf;
  SecBuffer type_2_bufs[2];
  SecBuffer type_3_buf;
  SecBuffer type_3_buf;
  SecBufferDesc type_2_desc;
  SecBufferDesc type_2_desc;
  SecBufferDesc type_3_desc;
  SecBufferDesc type_3_desc;
@@ -263,10 +263,37 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
  /* Setup the type-2 "input" security buffer */
  /* Setup the type-2 "input" security buffer */
  type_2_desc.ulVersion     = SECBUFFER_VERSION;
  type_2_desc.ulVersion     = SECBUFFER_VERSION;
  type_2_desc.cBuffers      = 1;
  type_2_desc.cBuffers      = 1;
  type_2_desc.pBuffers  = &type_2_buf;
  type_2_desc.pBuffers      = &type_2_bufs[0];
  type_2_buf.BufferType = SECBUFFER_TOKEN;
  type_2_bufs[0].BufferType = SECBUFFER_TOKEN;
  type_2_buf.pvBuffer   = ntlm->input_token;
  type_2_bufs[0].pvBuffer   = ntlm->input_token;
  type_2_buf.cbBuffer   = curlx_uztoul(ntlm->input_token_len);
  type_2_bufs[0].cbBuffer   = curlx_uztoul(ntlm->input_token_len);

#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(ntlm->sslContext) {
    SEC_CHANNEL_BINDINGS channelBindings;
    SecPkgContext_Bindings pkgBindings;
    pkgBindings.Bindings = &channelBindings;
    status = s_pSecFn->QueryContextAttributes(
      ntlm->sslContext,
      SECPKG_ATTR_ENDPOINT_BINDINGS,
      &pkgBindings
    );
    if(status == SEC_E_OK) {
      type_2_desc.cBuffers++;
      type_2_bufs[1].BufferType = SECBUFFER_CHANNEL_BINDINGS;
      type_2_bufs[1].cbBuffer = pkgBindings.BindingsLength;
      type_2_bufs[1].pvBuffer = pkgBindings.Bindings;
    }
  }
#endif


  /* Setup the type-3 "output" security buffer */
  /* Setup the type-3 "output" security buffer */
  type_3_desc.ulVersion = SECBUFFER_VERSION;
  type_3_desc.ulVersion = SECBUFFER_VERSION;
+10 −0
Original line number Original line Diff line number Diff line
@@ -1414,6 +1414,16 @@ schannel_connect_common(struct connectdata *conn, int sockindex,
    connssl->state = ssl_connection_complete;
    connssl->state = ssl_connection_complete;
    conn->recv[sockindex] = schannel_recv;
    conn->recv[sockindex] = schannel_recv;
    conn->send[sockindex] = schannel_send;
    conn->send[sockindex] = schannel_send;

#ifdef SECPKG_ATTR_ENDPOINT_BINDINGS
    /* When SSPI is used in combination with Schannel
     * we need the Schannel context to create the Schannel
     * binding to pass the IIS extended protection checks.
     * Available on Windows 7 or later.
     */
    conn->ntlm.sslContext = &BACKEND->ctxt->ctxt_handle;
#endif

    *done = TRUE;
    *done = TRUE;
  }
  }
  else
  else