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

ntlm: Moved the identity generation into shared SSPI code

parent ff853960
Loading
Loading
Loading
Loading
+11 −77
Original line number Diff line number Diff line
@@ -346,18 +346,16 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
{
  Curl_safefree(ntlm->type_2);

  if(ntlm->has_handles) {
    s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
    s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
    ntlm->has_handles = 0;
  }
  if(ntlm->p_identity) {
    Curl_safefree(ntlm->identity.User);
    Curl_safefree(ntlm->identity.Password);
    Curl_safefree(ntlm->identity.Domain);

  Curl_sspi_free_identity(ntlm->p_identity);
  ntlm->p_identity = NULL;
}
}
#endif

#ifndef USE_WINDOWS_SSPI
@@ -420,84 +418,20 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp,
  SecBufferDesc desc;
  SECURITY_STATUS status;
  unsigned long attrs;
  xcharp_u useranddomain;
  xcharp_u user, dup_user;
  xcharp_u domain, dup_domain;
  xcharp_u passwd, dup_passwd;
  size_t domlen = 0;
  TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */

  domain.const_tchar_ptr = TEXT("");

  Curl_ntlm_sspi_cleanup(ntlm);

  if(userp && *userp) {
    CURLcode result;

    /* null initialize ntlm identity's data to allow proper cleanup */
    ntlm->p_identity = &ntlm->identity;
    memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));

    useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
    if(!useranddomain.tchar_ptr)
      return CURLE_OUT_OF_MEMORY;

    user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
    if(!user.const_tchar_ptr)
      user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));

    if(user.tchar_ptr) {
      domain.tchar_ptr = useranddomain.tchar_ptr;
      domlen = user.tchar_ptr - useranddomain.tchar_ptr;
      user.tchar_ptr++;
    }
    else {
      user.tchar_ptr = useranddomain.tchar_ptr;
      domain.const_tchar_ptr = TEXT("");
      domlen = 0;
    }
    /* Populate our identity structure */
    result = Curl_create_sspi_identity(userp, passwdp, &ntlm->identity);
    if(result)
      return result;

    /* setup ntlm identity's user and length */
    dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
    if(!dup_user.tchar_ptr) {
      Curl_unicodefree(useranddomain.tchar_ptr);
      return CURLE_OUT_OF_MEMORY;
    }
    ntlm->identity.User = dup_user.tbyte_ptr;
    ntlm->identity.UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
    dup_user.tchar_ptr = NULL;

    /* setup ntlm identity's domain and length */
    dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
    if(!dup_domain.tchar_ptr) {
      Curl_unicodefree(useranddomain.tchar_ptr);
      return CURLE_OUT_OF_MEMORY;
    }
    _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
    *(dup_domain.tchar_ptr + domlen) = TEXT('\0');
    ntlm->identity.Domain = dup_domain.tbyte_ptr;
    ntlm->identity.DomainLength = curlx_uztoul(domlen);
    dup_domain.tchar_ptr = NULL;

    Curl_unicodefree(useranddomain.tchar_ptr);

    /* setup ntlm identity's password and length */
    passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
    if(!passwd.tchar_ptr)
      return CURLE_OUT_OF_MEMORY;
    dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
    if(!dup_passwd.tchar_ptr) {
      Curl_unicodefree(passwd.tchar_ptr);
      return CURLE_OUT_OF_MEMORY;
    }
    ntlm->identity.Password = dup_passwd.tbyte_ptr;
    ntlm->identity.PasswordLength =
      curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
    dup_passwd.tchar_ptr = NULL;

    Curl_unicodefree(passwd.tchar_ptr);

    /* setup ntlm identity's flags */
    ntlm->identity.Flags = SECFLAG_WINNT_AUTH_IDENTITY;
    /* Allow proper cleanup of the identity structure */
    ntlm->p_identity = &ntlm->identity;
  }
  else
    ntlm->p_identity = NULL;
+0 −8
Original line number Diff line number Diff line
@@ -170,14 +170,6 @@ void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm);
#define NTLMFLAG_NEGOTIATE_56                    (1<<31)
/* Indicates that 56-bit encryption is supported. */

#ifdef UNICODE
#  define SECFLAG_WINNT_AUTH_IDENTITY \
     (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
#else
#  define SECFLAG_WINNT_AUTH_IDENTITY \
     (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
#endif

#endif /* BUILDING_CURL_NTLM_MSGS_C */

#endif /* USE_NTLM */
+104 −0
Original line number Diff line number Diff line
@@ -32,6 +32,9 @@
#include <curl/mprintf.h>

#include "curl_memory.h"
#include "curl_multibyte.h"
#include "warnless.h"

/* The last #include file should be: */
#include "memdebug.h"

@@ -150,4 +153,105 @@ void Curl_sspi_global_cleanup(void)
  }
}

/*
 * Curl_create_sspi_identity()
 *
 * This is used to populate a SSPI identity structure based on the supplied
 * username and password.
 *
 * Parameters:
 *
 * userp    [in]     - The user name in the format User or Domain\User.
 * passdwp  [in]     - The user's password.
 * identity [in/out] - The identity structure.
 *
 * Returns CURLE_OK on success.
 */
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
                                   SEC_WINNT_AUTH_IDENTITY *identity)
{
  xcharp_u useranddomain;
  xcharp_u user, dup_user;
  xcharp_u domain, dup_domain;
  xcharp_u passwd, dup_passwd;
  size_t domlen = 0;

  domain.const_tchar_ptr = TEXT("");

  /* Initialize the identity */
  memset(identity, 0, sizeof(*identity));

  useranddomain.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)userp);
  if(!useranddomain.tchar_ptr)
    return CURLE_OUT_OF_MEMORY;

  user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('\\'));
  if(!user.const_tchar_ptr)
    user.const_tchar_ptr = _tcschr(useranddomain.const_tchar_ptr, TEXT('/'));

  if(user.tchar_ptr) {
    domain.tchar_ptr = useranddomain.tchar_ptr;
    domlen = user.tchar_ptr - useranddomain.tchar_ptr;
    user.tchar_ptr++;
  }
  else {
    user.tchar_ptr = useranddomain.tchar_ptr;
    domain.const_tchar_ptr = TEXT("");
    domlen = 0;
  }

  /* Setup the identity's user and length */
  dup_user.tchar_ptr = _tcsdup(user.tchar_ptr);
  if(!dup_user.tchar_ptr) {
    Curl_unicodefree(useranddomain.tchar_ptr);
    return CURLE_OUT_OF_MEMORY;
  }
  identity->User = dup_user.tbyte_ptr;
  identity->UserLength = curlx_uztoul(_tcslen(dup_user.tchar_ptr));
  dup_user.tchar_ptr = NULL;

  /* Setup the identity's domain and length */
  dup_domain.tchar_ptr = malloc(sizeof(TCHAR) * (domlen + 1));
  if(!dup_domain.tchar_ptr) {
    Curl_unicodefree(useranddomain.tchar_ptr);
    return CURLE_OUT_OF_MEMORY;
  }
  _tcsncpy(dup_domain.tchar_ptr, domain.tchar_ptr, domlen);
  *(dup_domain.tchar_ptr + domlen) = TEXT('\0');
  identity->Domain = dup_domain.tbyte_ptr;
  identity->DomainLength = curlx_uztoul(domlen);
  dup_domain.tchar_ptr = NULL;

  Curl_unicodefree(useranddomain.tchar_ptr);

  /* Setup ntlm identity's password and length */
  passwd.tchar_ptr = Curl_convert_UTF8_to_tchar((char *)passwdp);
  if(!passwd.tchar_ptr)
    return CURLE_OUT_OF_MEMORY;
  dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr);
  if(!dup_passwd.tchar_ptr) {
    Curl_unicodefree(passwd.tchar_ptr);
    return CURLE_OUT_OF_MEMORY;
  }
  identity->Password = dup_passwd.tbyte_ptr;
  identity->PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr));
  dup_passwd.tchar_ptr = NULL;

  Curl_unicodefree(passwd.tchar_ptr);

  /* Setup the identity's flags */
  identity->Flags = SECFLAG_WINNT_AUTH_IDENTITY;

  return CURLE_OK;
}

void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity)
{
  if(identity) {
    Curl_safefree(identity->User);
    Curl_safefree(identity->Password);
    Curl_safefree(identity->Domain);
  }
}

#endif /* USE_WINDOWS_SSPI */
+15 −0
Original line number Diff line number Diff line
@@ -43,6 +43,13 @@
CURLcode Curl_sspi_global_init(void);
void Curl_sspi_global_cleanup(void);

/* This is used to generate an SSPI identity structure */
CURLcode Curl_create_sspi_identity(const char *userp, const char *passwdp,
                                   SEC_WINNT_AUTH_IDENTITY *identity);

/* This is used to free an SSPI identity structure */
void Curl_sspi_free_identity(SEC_WINNT_AUTH_IDENTITY *identity);

/* Forward-declaration of global variables defined in curl_sspi.c */

extern HMODULE s_hSecDll;
@@ -289,5 +296,13 @@ extern PSecurityFunctionTable s_pSecFn;
# define SEC_I_SIGNATURE_NEEDED                ((HRESULT)0x0009035CL)
#endif

#ifdef UNICODE
#  define SECFLAG_WINNT_AUTH_IDENTITY \
     (unsigned long)SEC_WINNT_AUTH_IDENTITY_UNICODE
#else
#  define SECFLAG_WINNT_AUTH_IDENTITY \
     (unsigned long)SEC_WINNT_AUTH_IDENTITY_ANSI
#endif

#endif /* USE_WINDOWS_SSPI */
#endif /* HEADER_CURL_SSPI_H */