From 662c1d87f3933a7deece63d484f4c0c248a13ded Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 28 Aug 2011 02:00:02 +0200 Subject: NTLM: END of refactoring/splitting/moving First: File curl_ntlm.h renamed curl_ntlm_msgs.h File curl_ntlm.c renamed curl_ntlm_msgs.c Afterwards: File http_ntlm.c renamed curl_ntlm.c File http_ntlm.h renamed curl_ntlm.h --- lib/curl_ntlm_msgs.c | 997 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 997 insertions(+) create mode 100644 lib/curl_ntlm_msgs.c (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c new file mode 100644 index 000000000..732974b33 --- /dev/null +++ b/lib/curl_ntlm_msgs.c @@ -0,0 +1,997 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include "setup.h" + +/* NTLM details: + + http://davenport.sourceforge.net/ntlm.html + http://www.innovation.ch/java/ntlm.html +*/ + +#ifdef USE_NTLM + +#define DEBUG_ME 0 + +#ifdef HAVE_UNISTD_H +#include +#endif + +#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) +#include +#endif + +#define BUILDING_CURL_NTLM_MSGS_C + +#include "urldata.h" +#include "non-ascii.h" +#include "sendf.h" +#include "select.h" +#include "rawstr.h" +#include "curl_base64.h" +#include "curl_ntlm_msgs.h" +#include "url.h" +#include "strerror.h" +#include "curl_gethostname.h" +#include "curl_memory.h" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include + +#ifdef USE_SSLEAY +#include "ssluse.h" +# ifdef USE_OPENSSL +# include +# ifndef OPENSSL_NO_MD4 +# include +# endif +# include +# include +# include +# else +# include +# ifndef OPENSSL_NO_MD4 +# include +# endif +# include +# include +# include +# endif + +#ifndef OPENSSL_VERSION_NUMBER +#error "OPENSSL_VERSION_NUMBER not defined" +#endif + +#ifdef OPENSSL_NO_MD4 +/* This requires MD4, but OpenSSL was compiled without it */ +#define USE_NTRESPONSES 0 +#define USE_NTLM2SESSION 0 +#endif + +#elif defined(USE_GNUTLS) + +#include "gtls.h" +#include + +#define MD5_DIGEST_LENGTH 16 +#define MD4_DIGEST_LENGTH 16 + +#elif defined(USE_NSS) + +#include "curl_md4.h" +#include "nssg.h" +#include +#include +#include +#define MD5_DIGEST_LENGTH MD5_LENGTH + +#elif defined(USE_WINDOWS_SSPI) + +#include "curl_sspi.h" + +#else +# error "Can't compile NTLM support without a crypto library." +#endif + +#ifndef USE_NTRESPONSES +/* Define this to make the type-3 message include the NT response message */ +#define USE_NTRESPONSES 1 + +/* Define this to make the type-3 message include the NTLM2Session response + message, requires USE_NTRESPONSES. */ +#define USE_NTLM2SESSION 1 +#endif + +#include "curl_ntlm_core.h" + +/* The last #include file should be: */ +#include "memdebug.h" + +/* Hostname buffer size */ +#define HOSTNAME_MAX 1024 + +/* "NTLMSSP" signature is always in ASCII regardless of the platform */ +#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" + +#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff) +#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \ + (((x) >> 16) & 0xff), (((x) >> 24) & 0xff) + +#if DEBUG_ME +# define DEBUG_OUT(x) x +static void ntlm_print_flags(FILE *handle, unsigned long flags) +{ + if(flags & NTLMFLAG_NEGOTIATE_UNICODE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); + if(flags & NTLMFLAG_NEGOTIATE_OEM) + fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM "); + if(flags & NTLMFLAG_REQUEST_TARGET) + fprintf(handle, "NTLMFLAG_REQUEST_TARGET "); + if(flags & (1<<3)) + fprintf(handle, "NTLMFLAG_UNKNOWN_3 "); + if(flags & NTLMFLAG_NEGOTIATE_SIGN) + fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN "); + if(flags & NTLMFLAG_NEGOTIATE_SEAL) + fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL "); + if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE "); + if(flags & NTLMFLAG_NEGOTIATE_LM_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY "); + if(flags & NTLMFLAG_NEGOTIATE_NETWARE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE "); + if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY "); + if(flags & (1<<10)) + fprintf(handle, "NTLMFLAG_UNKNOWN_10 "); + if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS) + fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS "); + if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED) + fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED "); + if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED) + fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED "); + if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL) + fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL "); + if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN) + fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN "); + if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN "); + if(flags & NTLMFLAG_TARGET_TYPE_SERVER) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER "); + if(flags & NTLMFLAG_TARGET_TYPE_SHARE) + fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE "); + if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) + fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY "); + if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE) + fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE "); + if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE) + fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE "); + if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY) + fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY "); + if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) + fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO "); + if(flags & (1<<24)) + fprintf(handle, "NTLMFLAG_UNKNOWN_24 "); + if(flags & (1<<25)) + fprintf(handle, "NTLMFLAG_UNKNOWN_25 "); + if(flags & (1<<26)) + fprintf(handle, "NTLMFLAG_UNKNOWN_26 "); + if(flags & (1<<27)) + fprintf(handle, "NTLMFLAG_UNKNOWN_27 "); + if(flags & (1<<28)) + fprintf(handle, "NTLMFLAG_UNKNOWN_28 "); + if(flags & NTLMFLAG_NEGOTIATE_128) + fprintf(handle, "NTLMFLAG_NEGOTIATE_128 "); + if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE) + fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE "); + if(flags & NTLMFLAG_NEGOTIATE_56) + fprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); +} + +static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) +{ + const char *p = buf; + (void)handle; + fprintf(stderr, "0x"); + while(len-- > 0) + fprintf(stderr, "%02.2x", (unsigned int)*p++); +} +#else +# define DEBUG_OUT(x) +#endif + +#ifndef USE_WINDOWS_SSPI +/* + * This function converts from the little endian format used in the + * incoming package to whatever endian format we're using natively. + * Argument is a pointer to a 4 byte buffer. + */ +static unsigned int readint_le(unsigned char *buf) +{ + return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) | + ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24); +} +#endif + +/* + NTLM message structure notes: + + A 'short' is a 'network short', a little-endian 16-bit unsigned value. + + A 'long' is a 'network long', a little-endian, 32-bit unsigned value. + + A 'security buffer' represents a triplet used to point to a buffer, + consisting of two shorts and one long: + + 1. A 'short' containing the length of the buffer content in bytes. + 2. A 'short' containing the allocated space for the buffer in bytes. + 3. A 'long' containing the offset to the start of the buffer in bytes, + from the beginning of the NTLM message. +*/ + +/* + * Curl_ntlm_decode_type2_message() + * + * This is used to decode a ntlm type-2 message received from a: HTTP, SMTP + * or POP3 server. The message is first decoded from a base64 string into a + * raw ntlm message and checked for validity before the appropriate data for + * creating a type-3 message is written to the given ntlm data structure. + * + * Parameters: + * + * data [in] - Pointer to session handle. + * header [in] - Pointer to the input buffer. + * ntlm [in] - Pointer to ntlm data struct being used and modified. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data, + const char* header, + struct ntlmdata* ntlm) +{ +#ifndef USE_WINDOWS_SSPI + static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; +#endif + + /* NTLM type-2 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x02000000) + 12 Target Name security buffer + 20 Flags long + 24 Challenge 8 bytes + (32) Context 8 bytes (two consecutive longs) (*) + (40) Target Information security buffer (*) + (48) OS Version Structure 8 bytes (*) + 32 (48) (56) Start of data block (*) + (*) -> Optional + */ + + size_t size = 0; + unsigned char *buffer = NULL; + CURLcode error; + +#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI) + (void)data; +#endif + + error = Curl_base64_decode(header, &buffer, &size); + if(error) + return error; + + if(!buffer) { + infof(data, "NTLM handshake failure (unhandled condition)\n"); + return CURLE_REMOTE_ACCESS_DENIED; + } + +#ifdef USE_WINDOWS_SSPI + ntlm->type_2 = malloc(size + 1); + if(ntlm->type_2 == NULL) { + free(buffer); + return CURLE_OUT_OF_MEMORY; + } + ntlm->n_type_2 = (unsigned long)size; + memcpy(ntlm->type_2, buffer, size); +#else + ntlm->flags = 0; + + if((size < 32) || + (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) || + (memcmp(buffer + 8, type2_marker, sizeof(type2_marker)) != 0)) { + /* This was not a good enough type-2 message */ + free(buffer); + infof(data, "NTLM handshake failure (bad type-2 message)\n"); + return CURLE_REMOTE_ACCESS_DENIED; + } + + ntlm->flags = readint_le(&buffer[20]); + memcpy(ntlm->nonce, &buffer[24], 8); + + DEBUG_OUT({ + fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); + fprintf(stderr, "\n nonce="); + ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); + fprintf(stderr, "\n****\n"); + fprintf(stderr, "**** Header %s\n ", header); + }); +#endif + free(buffer); + + return CURLE_OK; +} + +#ifdef USE_WINDOWS_SSPI +void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm) +{ + if(ntlm->type_2) { + free(ntlm->type_2); + ntlm->type_2 = NULL; + } + if(ntlm->has_handles) { + s_pSecFn->DeleteSecurityContext(&ntlm->c_handle); + s_pSecFn->FreeCredentialsHandle(&ntlm->handle); + ntlm->has_handles = 0; + } + if(ntlm->p_identity) { + if(ntlm->identity.User) free(ntlm->identity.User); + if(ntlm->identity.Password) free(ntlm->identity.Password); + if(ntlm->identity.Domain) free(ntlm->identity.Domain); + ntlm->p_identity = NULL; + } +} +#endif + +#ifndef USE_WINDOWS_SSPI +/* copy the source to the destination and fill in zeroes in every + other destination byte! */ +static void unicodecpy(unsigned char *dest, + const char *src, size_t length) +{ + size_t i; + for(i = 0; i < length; i++) { + dest[2 * i] = (unsigned char)src[i]; + dest[2 * i + 1] = '\0'; + } +} +#endif + +/* + * Curl_ntlm_create_type1_message() + * + * This is used to generate an already encoded NTLM type-1 message ready + * for sending to the recipient, be it a: HTTP, SMTP or POP3 server, + * using the appropriate compile time crypo API. + * + * Parameters: + * + * userp [in] - The user name in the format User or Domain\User. + * passdwp [in] - The user's password. + * ntlm [in/out] - The ntlm data struct being used and modified. + * outptr [in/out] - The adress where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_ntlm_create_type1_message(const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr) +{ + /* NTLM type-1 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x01000000) + 12 Flags long + (16) Supplied Domain security buffer (*) + (24) Supplied Workstation security buffer (*) + (32) OS Version Structure 8 bytes (*) + (32) (40) Start of data block (*) + (*) -> Optional + */ + + unsigned char ntlmbuf[NTLM_BUFSIZE]; + size_t base64_sz = 0; + size_t size; + +#ifdef USE_WINDOWS_SSPI + + SecBuffer buf; + SecBufferDesc desc; + SECURITY_STATUS status; + ULONG attrs; + const char *dest = ""; + const char *user; + const char *domain = ""; + size_t userlen = 0; + size_t domlen = 0; + size_t passwdlen = 0; + TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */ + + Curl_ntlm_sspi_cleanup(ntlm); + + user = strchr(userp, '\\'); + if(!user) + user = strchr(userp, '/'); + + if(user) { + domain = userp; + domlen = user - userp; + user++; + } + else { + user = userp; + domain = ""; + domlen = 0; + } + + if(user) + userlen = strlen(user); + + if(passwdp) + passwdlen = strlen(passwdp); + + if(userlen > 0) { + /* note: initialize all of this before doing the mallocs so that + * it can be cleaned up later without leaking memory. + */ + ntlm->p_identity = &ntlm->identity; + memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity)); + if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL) + return CURLE_OUT_OF_MEMORY; + + ntlm->identity.UserLength = (unsigned long)userlen; + if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) + return CURLE_OUT_OF_MEMORY; + + ntlm->identity.PasswordLength = (unsigned long)strlen(passwdp); + if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL) + return CURLE_OUT_OF_MEMORY; + + strncpy((char *)ntlm->identity.Domain, domain, domlen); + ntlm->identity.Domain[domlen] = '\0'; + ntlm->identity.DomainLength = (unsigned long)domlen; + ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; + } + else + ntlm->p_identity = NULL; + + status = s_pSecFn->AcquireCredentialsHandleA(NULL, (void *)"NTLM", + SECPKG_CRED_OUTBOUND, NULL, + ntlm->p_identity, NULL, NULL, + &ntlm->handle, &tsDummy); + if(status != SEC_E_OK) + return CURLE_OUT_OF_MEMORY; + + desc.ulVersion = SECBUFFER_VERSION; + desc.cBuffers = 1; + desc.pBuffers = &buf; + buf.cbBuffer = NTLM_BUFSIZE; + buf.BufferType = SECBUFFER_TOKEN; + buf.pvBuffer = ntlmbuf; + + status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL, + (void *)dest, + ISC_REQ_CONFIDENTIALITY | + ISC_REQ_REPLAY_DETECT | + ISC_REQ_CONNECTION, + 0, SECURITY_NETWORK_DREP, + NULL, 0, + &ntlm->c_handle, &desc, + &attrs, &tsDummy); + + if(status == SEC_I_COMPLETE_AND_CONTINUE || + status == SEC_I_CONTINUE_NEEDED) + s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc); + else if(status != SEC_E_OK) { + s_pSecFn->FreeCredentialsHandle(&ntlm->handle); + return CURLE_RECV_ERROR; + } + + ntlm->has_handles = 1; + size = buf.cbBuffer; + +#else + + const char *host = ""; /* empty */ + const char *domain = ""; /* empty */ + size_t hostlen = 0; + size_t domlen = 0; + size_t hostoff = 0; + size_t domoff = hostoff + hostlen; /* This is 0: remember that host and + domain are empty */ + (void)userp; + (void)passwdp; + (void)ntlm; + +#if USE_NTLM2SESSION +#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY +#else +#define NTLM2FLAG 0 +#endif + snprintf((char *)ntlmbuf, NTLM_BUFSIZE, + NTLMSSP_SIGNATURE "%c" + "\x01%c%c%c" /* 32-bit type = 1 */ + "%c%c%c%c" /* 32-bit NTLM flag field */ + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host name offset */ + "%c%c" /* 2 zeroes */ + "%s" /* host name */ + "%s", /* domain string */ + 0, /* trailing zero */ + 0, 0, 0, /* part of type-1 long */ + + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0, 0, + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0, 0, + host, /* this is empty */ + domain /* this is empty */); + + /* Initial packet length */ + size = 32 + hostlen + domlen; + +#endif + + DEBUG_OUT({ + fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " + "0x%08.8x ", + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + ntlm_print_flags(stderr, + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + fprintf(stderr, "\n****\n"); + }); + + /* Return with binary blob encoded into base64 */ + return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); +} + +/* + * Curl_ntlm_create_type3_message() + * + * This is used to generate an already encoded NTLM type-3 message ready + * for sending to the recipient, be it a: HTTP, SMTP or POP3 server, + * using the appropriate compile time crypo API. + * + * Parameters: + * + * data [in] - The session handle. + * userp [in] - The user name in the format User or Domain\User. + * passdwp [in] - The user's password. + * ntlm [in/out] - The ntlm data struct being used and modified. + * outptr [in/out] - The adress where a pointer to newly allocated memory + * holding the result will be stored upon completion. + * + * Returns CURLE_OK on success. + */ +CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, + const char *userp, + const char *passwdp, + struct ntlmdata *ntlm, + char **outptr) +{ + /* NTLM type-3 message structure: + + Index Description Content + 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" + (0x4e544c4d53535000) + 8 NTLM Message Type long (0x03000000) + 12 LM/LMv2 Response security buffer + 20 NTLM/NTLMv2 Response security buffer + 28 Target Name security buffer + 36 User Name security buffer + 44 Workstation Name security buffer + (52) Session Key security buffer (*) + (60) Flags long (*) + (64) OS Version Structure 8 bytes (*) + 52 (64) (72) Start of data block + (*) -> Optional + */ + + unsigned char ntlmbuf[NTLM_BUFSIZE]; + size_t base64_sz = 0; + size_t size; + +#ifdef USE_WINDOWS_SSPI + const char *dest = ""; + SecBuffer type_2; + SecBuffer type_3; + SecBufferDesc type_2_desc; + SecBufferDesc type_3_desc; + SECURITY_STATUS status; + ULONG attrs; + TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */ + + (void)passwdp; + (void)userp; + (void)data; + + type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION; + type_2_desc.cBuffers = type_3_desc.cBuffers = 1; + type_2_desc.pBuffers = &type_2; + type_3_desc.pBuffers = &type_3; + + type_2.BufferType = SECBUFFER_TOKEN; + type_2.pvBuffer = ntlm->type_2; + type_2.cbBuffer = ntlm->n_type_2; + type_3.BufferType = SECBUFFER_TOKEN; + type_3.pvBuffer = ntlmbuf; + type_3.cbBuffer = NTLM_BUFSIZE; + + status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, + &ntlm->c_handle, + (void *)dest, + ISC_REQ_CONFIDENTIALITY | + ISC_REQ_REPLAY_DETECT | + ISC_REQ_CONNECTION, + 0, SECURITY_NETWORK_DREP, + &type_2_desc, + 0, &ntlm->c_handle, + &type_3_desc, + &attrs, &tsDummy); + if(status != SEC_E_OK) + return CURLE_RECV_ERROR; + + size = type_3.cbBuffer; + + Curl_ntlm_sspi_cleanup(ntlm); + +#else + int lmrespoff; + unsigned char lmresp[24]; /* fixed-size */ +#if USE_NTRESPONSES + int ntrespoff; + unsigned char ntresp[24]; /* fixed-size */ +#endif + bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; + char host[HOSTNAME_MAX + 1] = ""; + const char *user; + const char *domain = ""; + size_t hostoff = 0; + size_t useroff = 0; + size_t domoff = 0; + size_t hostlen = 0; + size_t userlen = 0; + size_t domlen = 0; + CURLcode res; + + user = strchr(userp, '\\'); + if(!user) + user = strchr(userp, '/'); + + if(user) { + domain = userp; + domlen = (user - domain); + user++; + } + else + user = userp; + + if(user) + userlen = strlen(user); + + if(Curl_gethostname(host, HOSTNAME_MAX)) { + infof(data, "gethostname() failed, continuing without!"); + hostlen = 0; + } + else { + /* If the workstation if configured with a full DNS name (i.e. + * workstation.somewhere.net) gethostname() returns the fully qualified + * name, which NTLM doesn't like. + */ + char *dot = strchr(host, '.'); + if(dot) + *dot = '\0'; + hostlen = strlen(host); + } + + if(unicode) { + domlen = domlen * 2; + userlen = userlen * 2; + hostlen = hostlen * 2; + } + +#if USE_NTLM2SESSION + /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { + unsigned char ntbuffer[0x18]; + unsigned char tmp[0x18]; + unsigned char md5sum[MD5_DIGEST_LENGTH]; + unsigned char entropy[8]; + + /* Need to create 8 bytes random data */ +#ifdef USE_SSLEAY + MD5_CTX MD5pw; + Curl_ossl_seed(data); /* Initiate the seed if not already done */ + RAND_bytes(entropy, 8); +#elif defined(USE_GNUTLS) + gcry_md_hd_t MD5pw; + Curl_gtls_seed(data); /* Initiate the seed if not already done */ + gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM); +#elif defined(USE_NSS) + PK11Context *MD5pw; + unsigned int outlen; + Curl_nss_seed(data); /* Initiate the seed if not already done */ + PK11_GenerateRandom(entropy, 8); +#endif + + /* 8 bytes random data as challenge in lmresp */ + memcpy(lmresp, entropy, 8); + + /* Pad with zeros */ + memset(lmresp + 8, 0, 0x10); + + /* Fill tmp with challenge(nonce?) + entropy */ + memcpy(tmp, &ntlm->nonce[0], 8); + memcpy(tmp + 8, entropy, 8); + +#ifdef USE_SSLEAY + MD5_Init(&MD5pw); + MD5_Update(&MD5pw, tmp, 16); + MD5_Final(md5sum, &MD5pw); +#elif defined(USE_GNUTLS) + gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); + gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH); + memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH); + gcry_md_close(MD5pw); +#elif defined(USE_NSS) + MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); + PK11_DigestOp(MD5pw, tmp, 16); + PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH); + PK11_DestroyContext(MD5pw, PR_TRUE); +#endif + + /* We shall only use the first 8 bytes of md5sum, but the des + code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */ + if(CURLE_OUT_OF_MEMORY == + Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer)) + return CURLE_OUT_OF_MEMORY; + Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp); + + /* End of NTLM2 Session code */ + } + else +#endif + { + +#if USE_NTRESPONSES + unsigned char ntbuffer[0x18]; +#endif + unsigned char lmbuffer[0x18]; + +#if USE_NTRESPONSES + if(CURLE_OUT_OF_MEMORY == + Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer)) + return CURLE_OUT_OF_MEMORY; + Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp); +#endif + + Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer); + Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp); + /* A safer but less compatible alternative is: + * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); + * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */ + } + + lmrespoff = 64; /* size of the message header */ +#if USE_NTRESPONSES + ntrespoff = lmrespoff + 0x18; + domoff = ntrespoff + 0x18; +#else + domoff = lmrespoff + 0x18; +#endif + useroff = domoff + domlen; + hostoff = useroff + userlen; + + /* Create the big type-3 message binary blob */ + size = snprintf((char *)ntlmbuf, NTLM_BUFSIZE, + NTLMSSP_SIGNATURE "%c" + "\x03%c%c%c" /* 32-bit type = 3 */ + + "%c%c" /* LanManager length */ + "%c%c" /* LanManager allocated space */ + "%c%c" /* LanManager offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* NT-response length */ + "%c%c" /* NT-response allocated space */ + "%c%c" /* NT-response offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* user length */ + "%c%c" /* user allocated space */ + "%c%c" /* user offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host offset */ + "%c%c" /* 2 zeroes */ + + "%c%c" /* session key length (unknown purpose) */ + "%c%c" /* session key allocated space (unknown purpose) */ + "%c%c" /* session key offset (unknown purpose) */ + "%c%c" /* 2 zeroes */ + + "%c%c%c%c", /* flags */ + + /* domain string */ + /* user string */ + /* host string */ + /* LanManager response */ + /* NT response */ + + 0, /* zero termination */ + 0, 0, 0, /* type-3 long, the 24 upper bits */ + + SHORTPAIR(0x18), /* LanManager response length, twice */ + SHORTPAIR(0x18), + SHORTPAIR(lmrespoff), + 0x0, 0x0, + +#if USE_NTRESPONSES + SHORTPAIR(0x18), /* NT-response length, twice */ + SHORTPAIR(0x18), + SHORTPAIR(ntrespoff), + 0x0, 0x0, +#else + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, +#endif + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0x0, 0x0, + + SHORTPAIR(userlen), + SHORTPAIR(userlen), + SHORTPAIR(useroff), + 0x0, 0x0, + + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0x0, 0x0, + + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + + LONGQUARTET(ntlm->flags)); + + DEBUGASSERT(size == 64); + DEBUGASSERT(size == (size_t)lmrespoff); + + /* We append the binary hashes */ + if(size < (NTLM_BUFSIZE - 0x18)) { + memcpy(&ntlmbuf[size], lmresp, 0x18); + size += 0x18; + } + + DEBUG_OUT({ + fprintf(stderr, "**** TYPE3 header lmresp="); + ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); + }); + +#if USE_NTRESPONSES + if(size < (NTLM_BUFSIZE - 0x18)) { + DEBUGASSERT(size == (size_t)ntrespoff); + memcpy(&ntlmbuf[size], ntresp, 0x18); + size += 0x18; + } + + DEBUG_OUT({ + fprintf(stderr, "\n ntresp="); + ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18); + }); + +#endif + + DEBUG_OUT({ + fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", + LONGQUARTET(ntlm->flags), ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); + fprintf(stderr, "\n****\n"); + }); + + /* Make sure that the domain, user and host strings fit in the + buffer before we copy them there. */ + if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) { + failf(data, "user + domain + host name too big"); + return CURLE_OUT_OF_MEMORY; + } + + DEBUGASSERT(size == domoff); + if(unicode) + unicodecpy(&ntlmbuf[size], domain, domlen / 2); + else + memcpy(&ntlmbuf[size], domain, domlen); + + size += domlen; + + DEBUGASSERT(size == useroff); + if(unicode) + unicodecpy(&ntlmbuf[size], user, userlen / 2); + else + memcpy(&ntlmbuf[size], user, userlen); + + size += userlen; + + DEBUGASSERT(size == hostoff); + if(unicode) + unicodecpy(&ntlmbuf[size], host, hostlen / 2); + else + memcpy(&ntlmbuf[size], host, hostlen); + + size += hostlen; + + /* Convert domain, user, and host to ASCII but leave the rest as-is */ + res = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff], + size - domoff); + if(res) + return CURLE_CONV_FAILED; + +#endif + + /* Return with binary blob encoded into base64 */ + return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); +} + +#endif /* USE_NTLM */ -- cgit v1.2.1 From 05ef245170fd71f2907b89e2d1361b2e70113199 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sun, 28 Aug 2011 07:15:46 +0200 Subject: NTLM: header inclusion cleanup --- lib/curl_ntlm_msgs.c | 129 +++++++++++++++++++-------------------------------- 1 file changed, 48 insertions(+), 81 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 732974b33..e27e947dd 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -22,106 +22,73 @@ #include "setup.h" -/* NTLM details: - - http://davenport.sourceforge.net/ntlm.html - http://www.innovation.ch/java/ntlm.html -*/ - #ifdef USE_NTLM -#define DEBUG_ME 0 - -#ifdef HAVE_UNISTD_H -#include -#endif - -#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) -#include -#endif - -#define BUILDING_CURL_NTLM_MSGS_C - -#include "urldata.h" -#include "non-ascii.h" -#include "sendf.h" -#include "select.h" -#include "rawstr.h" -#include "curl_base64.h" -#include "curl_ntlm_msgs.h" -#include "url.h" -#include "strerror.h" -#include "curl_gethostname.h" -#include "curl_memory.h" +/* + * NTLM details: + * + * http://davenport.sourceforge.net/ntlm.html + * http://www.innovation.ch/java/ntlm.html + */ -#define _MPRINTF_REPLACE /* use our functions only */ -#include +#define DEBUG_ME 0 #ifdef USE_SSLEAY -#include "ssluse.h" -# ifdef USE_OPENSSL -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# else -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# endif - -#ifndef OPENSSL_VERSION_NUMBER -#error "OPENSSL_VERSION_NUMBER not defined" -#endif -#ifdef OPENSSL_NO_MD4 -/* This requires MD4, but OpenSSL was compiled without it */ -#define USE_NTRESPONSES 0 -#define USE_NTLM2SESSION 0 -#endif +# ifdef USE_OPENSSL +# include +# ifndef OPENSSL_NO_MD4 +# include +# endif +# include +# include +# include +# else +# include +# ifndef OPENSSL_NO_MD4 +# include +# endif +# include +# include +# include +# endif +# include "ssluse.h" #elif defined(USE_GNUTLS) -#include "gtls.h" -#include - -#define MD5_DIGEST_LENGTH 16 -#define MD4_DIGEST_LENGTH 16 +# include +# include "gtls.h" +# define MD5_DIGEST_LENGTH 16 +# define MD4_DIGEST_LENGTH 16 #elif defined(USE_NSS) -#include "curl_md4.h" -#include "nssg.h" -#include -#include -#include -#define MD5_DIGEST_LENGTH MD5_LENGTH +# include +# include +# include +# include "nssg.h" +# include "curl_md4.h" +# define MD5_DIGEST_LENGTH MD5_LENGTH #elif defined(USE_WINDOWS_SSPI) - -#include "curl_sspi.h" - +# include "curl_sspi.h" #else -# error "Can't compile NTLM support without a crypto library." +# error "Can't compile NTLM support without a crypto library." #endif -#ifndef USE_NTRESPONSES -/* Define this to make the type-3 message include the NT response message */ -#define USE_NTRESPONSES 1 +#include "urldata.h" +#include "non-ascii.h" +#include "sendf.h" +#include "curl_base64.h" +#include "curl_ntlm_core.h" +#include "curl_gethostname.h" +#include "curl_memory.h" -/* Define this to make the type-3 message include the NTLM2Session response - message, requires USE_NTRESPONSES. */ -#define USE_NTLM2SESSION 1 -#endif +#define BUILDING_CURL_NTLM_MSGS_C +#include "curl_ntlm_msgs.h" -#include "curl_ntlm_core.h" +#define _MPRINTF_REPLACE /* use our functions only */ +#include /* The last #include file should be: */ #include "memdebug.h" -- cgit v1.2.1 From 6b75d2c2df7209919a70a29a4479625b62fb3c28 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 3 Sep 2011 16:06:10 +0200 Subject: fix a bunch of MSVC compiler warnings --- lib/curl_ntlm_msgs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index e27e947dd..0c8d2e961 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -182,7 +182,7 @@ static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) fprintf(stderr, "%02.2x", (unsigned int)*p++); } #else -# define DEBUG_OUT(x) +# define DEBUG_OUT(x) Curl_nop_stmt #endif #ifndef USE_WINDOWS_SSPI -- cgit v1.2.1 From 38b5744266f805f3dd6d9486ba323f99ab420d52 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sun, 25 Sep 2011 23:58:47 +0200 Subject: HOSTNAME_MAX: Moved to curl_gethostname.h Moved HOSTNAME_MAX #define into curl_gethostname.h rather than being locally defined in curl_gethostname.c, curl_ntlm_msgs.c and smtp.c. --- lib/curl_ntlm_msgs.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 0c8d2e961..d2d34a7b3 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -93,9 +93,6 @@ /* The last #include file should be: */ #include "memdebug.h" -/* Hostname buffer size */ -#define HOSTNAME_MAX 1024 - /* "NTLMSSP" signature is always in ASCII regardless of the platform */ #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" -- cgit v1.2.1 From 5801ddb85cc26dea10f73246b364d8cc52557372 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Mon, 19 Sep 2011 20:55:56 +0100 Subject: Curl_ntlm_create_type3_message: Tidied up the use of Curl_gethostname. Removed the code that striped off the domain name when Curl_gethostname returned the fully qualified domain name as the function has been updated to return the un-qualified host name. Replaced the use of HOSTNAME_MAX as the size of the buffer in the call to Curl_gethostname with sizeof(host) as this is safer should the buffer size ever be changed. --- lib/curl_ntlm_msgs.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index d2d34a7b3..c67fdb2cf 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -683,18 +683,13 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, if(user) userlen = strlen(user); - if(Curl_gethostname(host, HOSTNAME_MAX)) { + /* Get the machine's un-qualified host name as NTLM doesn't like the fully + qualified domain name */ + if(Curl_gethostname(host, sizeof(host))) { infof(data, "gethostname() failed, continuing without!"); hostlen = 0; } else { - /* If the workstation if configured with a full DNS name (i.e. - * workstation.somewhere.net) gethostname() returns the fully qualified - * name, which NTLM doesn't like. - */ - char *dot = strchr(host, '.'); - if(dot) - *dot = '\0'; hostlen = strlen(host); } -- cgit v1.2.1 From 185ed3409a883d32f7b6d41e20fddd5b04d98a7d Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Sat, 1 Oct 2011 13:03:40 +0100 Subject: Curl_ntlm_create_typeX_message: Added the outlen parameter Added the output message length as a parameter to both Curl_ntlm_create_type1_message() and Curl_ntlm_create_type3_message() for use by future functions that require it. Updated curl_ntlm.c to cater for the extra parameter on these two functions. --- lib/curl_ntlm_msgs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index c67fdb2cf..23dbb7e18 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -354,13 +354,15 @@ static void unicodecpy(unsigned char *dest, * ntlm [in/out] - The ntlm data struct being used and modified. * outptr [in/out] - The adress where a pointer to newly allocated memory * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. * * Returns CURLE_OK on success. */ CURLcode Curl_ntlm_create_type1_message(const char *userp, const char *passwdp, struct ntlmdata *ntlm, - char **outptr) + char **outptr, + size_t *outlen) { /* NTLM type-1 message structure: @@ -377,7 +379,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, */ unsigned char ntlmbuf[NTLM_BUFSIZE]; - size_t base64_sz = 0; size_t size; #ifdef USE_WINDOWS_SSPI @@ -556,7 +557,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, }); /* Return with binary blob encoded into base64 */ - return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); + return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); } /* @@ -574,6 +575,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, * ntlm [in/out] - The ntlm data struct being used and modified. * outptr [in/out] - The adress where a pointer to newly allocated memory * holding the result will be stored upon completion. + * outlen [out] - The length of the output message. * * Returns CURLE_OK on success. */ @@ -581,7 +583,8 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, const char *userp, const char *passwdp, struct ntlmdata *ntlm, - char **outptr) + char **outptr, + size_t *outlen) { /* NTLM type-3 message structure: @@ -602,7 +605,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, */ unsigned char ntlmbuf[NTLM_BUFSIZE]; - size_t base64_sz = 0; size_t size; #ifdef USE_WINDOWS_SSPI @@ -950,7 +952,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, #endif /* Return with binary blob encoded into base64 */ - return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, &base64_sz); + return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); } #endif /* USE_NTLM */ -- cgit v1.2.1 From 47e4537ac6d7c8b40ba742908efd6ddb1d362ba9 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 13 Oct 2011 21:09:17 +0200 Subject: curl_ntlm_msgs.c: fix variable shadowing declaration introduced in 185ed340 --- lib/curl_ntlm_msgs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 23dbb7e18..bfd3e2814 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -720,7 +720,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM); #elif defined(USE_NSS) PK11Context *MD5pw; - unsigned int outlen; + unsigned int MD5len; Curl_nss_seed(data); /* Initiate the seed if not already done */ PK11_GenerateRandom(entropy, 8); #endif @@ -747,7 +747,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, #elif defined(USE_NSS) MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); PK11_DigestOp(MD5pw, tmp, 16); - PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH); + PK11_DigestFinal(MD5pw, md5sum, &MD5len, MD5_DIGEST_LENGTH); PK11_DestroyContext(MD5pw, PR_TRUE); #endif -- cgit v1.2.1 From 64f328c787ab763cc994eadd6b82f32490d37ebb Mon Sep 17 00:00:00 2001 From: Martin Storsjo Date: Tue, 15 Nov 2011 11:52:32 +0200 Subject: Add support for using nettle instead of gcrypt as gnutls backend --- lib/curl_ntlm_msgs.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index bfd3e2814..712c4b432 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -54,6 +54,13 @@ # endif # include "ssluse.h" +#elif defined(USE_GNUTLS_NETTLE) + +# include +# include +# include +# define MD5_DIGEST_LENGTH 16 + #elif defined(USE_GNUTLS) # include @@ -714,6 +721,9 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, MD5_CTX MD5pw; Curl_ossl_seed(data); /* Initiate the seed if not already done */ RAND_bytes(entropy, 8); +#elif defined(USE_GNUTLS_NETTLE) + struct md5_ctx MD5pw; + gnutls_rnd(GNUTLS_RND_RANDOM, entropy, 8); #elif defined(USE_GNUTLS) gcry_md_hd_t MD5pw; Curl_gtls_seed(data); /* Initiate the seed if not already done */ @@ -739,6 +749,10 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, MD5_Init(&MD5pw); MD5_Update(&MD5pw, tmp, 16); MD5_Final(md5sum, &MD5pw); +#elif defined(USE_GNUTLS_NETTLE) + md5_init(&MD5pw); + md5_update(&MD5pw, 16, tmp); + md5_digest(&MD5pw, 16, md5sum); #elif defined(USE_GNUTLS) gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH); -- cgit v1.2.1 From 0ce2bca741ae596a346b2ab767dfbf5be9bc7dae Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Mon, 16 Jan 2012 21:14:05 +0100 Subject: add LF termination to infof() trace string --- lib/curl_ntlm_msgs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 712c4b432..c88d98b28 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -695,7 +695,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, /* Get the machine's un-qualified host name as NTLM doesn't like the fully qualified domain name */ if(Curl_gethostname(host, sizeof(host))) { - infof(data, "gethostname() failed, continuing without!"); + infof(data, "gethostname() failed, continuing without!\n"); hostlen = 0; } else { -- cgit v1.2.1 From 3c14c524c589632ba0a715f0f9095388b2174d96 Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Wed, 30 May 2012 20:56:37 +0100 Subject: curl_ntlm_msgs.c: Corrected small spelling mistake in comments --- lib/curl_ntlm_msgs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index c88d98b28..e097c40a8 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -359,7 +359,7 @@ static void unicodecpy(unsigned char *dest, * userp [in] - The user name in the format User or Domain\User. * passdwp [in] - The user's password. * ntlm [in/out] - The ntlm data struct being used and modified. - * outptr [in/out] - The adress where a pointer to newly allocated memory + * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. * @@ -580,7 +580,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, * userp [in] - The user name in the format User or Domain\User. * passdwp [in] - The user's password. * ntlm [in/out] - The ntlm data struct being used and modified. - * outptr [in/out] - The adress where a pointer to newly allocated memory + * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. * outlen [out] - The length of the output message. * -- cgit v1.2.1 From 3f9ab7cf5deb892cc7b8cb3f36322e072898b789 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Mon, 11 Jun 2012 02:23:00 +0200 Subject: curl_ntlm_msgs.c: Fixed passwdlen not being used and recalculated --- lib/curl_ntlm_msgs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index e097c40a8..5789a24c7 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -438,7 +438,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) return CURLE_OUT_OF_MEMORY; - ntlm->identity.PasswordLength = (unsigned long)strlen(passwdp); + ntlm->identity.PasswordLength = (unsigned long)passwdlen; if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL) return CURLE_OUT_OF_MEMORY; -- cgit v1.2.1 From 46480bb9a1569eaf156012f33e3e7e8c3de18f87 Mon Sep 17 00:00:00 2001 From: Mark Salisbury Date: Fri, 15 Jun 2012 18:05:11 +0200 Subject: SSPI related code: Unicode support for WinCE SSPI related code now compiles with ANSI and WCHAR versions of security methods (WinCE requires WCHAR versions of methods). Pulled UTF8 to WCHAR conversion methods out of idn_win32.c into their own file. curl_sasl.c - include curl_memory.h to use correct memory functions. getenv.c and telnet.c - WinCE compatibility fix With some committer adjustments --- lib/curl_ntlm_msgs.c | 61 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 26 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 5789a24c7..0fd34cb80 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -89,6 +89,7 @@ #include "curl_base64.h" #include "curl_ntlm_core.h" #include "curl_gethostname.h" +#include "curl_multibyte.h" #include "curl_memory.h" #define BUILDING_CURL_NTLM_MSGS_C @@ -394,7 +395,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, SecBufferDesc desc; SECURITY_STATUS status; ULONG attrs; - const char *dest = ""; const char *user; const char *domain = ""; size_t userlen = 0; @@ -431,12 +431,22 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, */ ntlm->p_identity = &ntlm->identity; memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity)); +#ifdef UNICODE + if((ntlm->identity.User = Curl_convert_UTF8_to_wchar(user)) == NULL) + return CURLE_OUT_OF_MEMORY; +#else if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL) return CURLE_OUT_OF_MEMORY; +#endif ntlm->identity.UserLength = (unsigned long)userlen; +#ifdef UNICODE + if((ntlm->identity.Password = Curl_convert_UTF8_to_wchar(passwdp)) == NULL) + return CURLE_OUT_OF_MEMORY; +#else if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) return CURLE_OUT_OF_MEMORY; +#endif ntlm->identity.PasswordLength = (unsigned long)passwdlen; if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL) @@ -450,10 +460,10 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, else ntlm->p_identity = NULL; - status = s_pSecFn->AcquireCredentialsHandleA(NULL, (void *)"NTLM", - SECPKG_CRED_OUTBOUND, NULL, - ntlm->p_identity, NULL, NULL, - &ntlm->handle, &tsDummy); + status = s_pSecFn->AcquireCredentialsHandle(NULL, TEXT("NTLM"), + SECPKG_CRED_OUTBOUND, NULL, + ntlm->p_identity, NULL, NULL, + &ntlm->handle, &tsDummy); if(status != SEC_E_OK) return CURLE_OUT_OF_MEMORY; @@ -464,15 +474,15 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, buf.BufferType = SECBUFFER_TOKEN; buf.pvBuffer = ntlmbuf; - status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL, - (void *)dest, - ISC_REQ_CONFIDENTIALITY | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONNECTION, - 0, SECURITY_NETWORK_DREP, - NULL, 0, - &ntlm->c_handle, &desc, - &attrs, &tsDummy); + status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL, + TEXT(""), + ISC_REQ_CONFIDENTIALITY | + ISC_REQ_REPLAY_DETECT | + ISC_REQ_CONNECTION, + 0, SECURITY_NETWORK_DREP, + NULL, 0, + &ntlm->c_handle, &desc, + &attrs, &tsDummy); if(status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) @@ -615,7 +625,6 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, size_t size; #ifdef USE_WINDOWS_SSPI - const char *dest = ""; SecBuffer type_2; SecBuffer type_3; SecBufferDesc type_2_desc; @@ -640,17 +649,17 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, type_3.pvBuffer = ntlmbuf; type_3.cbBuffer = NTLM_BUFSIZE; - status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, - &ntlm->c_handle, - (void *)dest, - ISC_REQ_CONFIDENTIALITY | - ISC_REQ_REPLAY_DETECT | - ISC_REQ_CONNECTION, - 0, SECURITY_NETWORK_DREP, - &type_2_desc, - 0, &ntlm->c_handle, - &type_3_desc, - &attrs, &tsDummy); + status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, + &ntlm->c_handle, + TEXT(""), + ISC_REQ_CONFIDENTIALITY | + ISC_REQ_REPLAY_DETECT | + ISC_REQ_CONNECTION, + 0, SECURITY_NETWORK_DREP, + &type_2_desc, + 0, &ntlm->c_handle, + &type_3_desc, + &attrs, &tsDummy); if(status != SEC_E_OK) return CURLE_RECV_ERROR; -- cgit v1.2.1 From ac3e356c95b3867b96070da2f85022b6280921d1 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 15 Jun 2012 21:50:57 +0200 Subject: SSPI related code: Unicode support for WinCE - kill compiler warnings --- lib/curl_ntlm_msgs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 0fd34cb80..b064553c2 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -460,7 +460,8 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, else ntlm->p_identity = NULL; - status = s_pSecFn->AcquireCredentialsHandle(NULL, TEXT("NTLM"), + status = s_pSecFn->AcquireCredentialsHandle(NULL, + (SECURITY_PSTR) TEXT("NTLM"), SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity, NULL, NULL, &ntlm->handle, &tsDummy); @@ -475,7 +476,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, buf.pvBuffer = ntlmbuf; status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL, - TEXT(""), + (SECURITY_PSTR) TEXT(""), ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION, @@ -651,7 +652,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, &ntlm->c_handle, - TEXT(""), + (SECURITY_PSTR) TEXT(""), ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION, -- cgit v1.2.1 From d56e8bcc8aeed07d73a3047c5a5be8bb9df53e0b Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Sat, 16 Jun 2012 19:20:50 +0200 Subject: Win32: downplay MS bazillion type synonyms game Avoid usage of some MS type synonyms to allow compilation with compiler headers that don't define these, using simpler synonyms. --- lib/curl_ntlm_msgs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index b064553c2..4c4dcfde6 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -394,7 +394,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, SecBuffer buf; SecBufferDesc desc; SECURITY_STATUS status; - ULONG attrs; + unsigned long attrs; const char *user; const char *domain = ""; size_t userlen = 0; @@ -461,7 +461,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, ntlm->p_identity = NULL; status = s_pSecFn->AcquireCredentialsHandle(NULL, - (SECURITY_PSTR) TEXT("NTLM"), + (TCHAR *) TEXT("NTLM"), SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity, NULL, NULL, &ntlm->handle, &tsDummy); @@ -476,7 +476,7 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, buf.pvBuffer = ntlmbuf; status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, NULL, - (SECURITY_PSTR) TEXT(""), + (TCHAR *) TEXT(""), ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION, @@ -631,7 +631,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, SecBufferDesc type_2_desc; SecBufferDesc type_3_desc; SECURITY_STATUS status; - ULONG attrs; + unsigned long attrs; TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */ (void)passwdp; @@ -652,7 +652,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, status = s_pSecFn->InitializeSecurityContext(&ntlm->handle, &ntlm->c_handle, - (SECURITY_PSTR) TEXT(""), + (TCHAR *) TEXT(""), ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION, -- cgit v1.2.1 From 849179ba2739ab9a0ad079384b125d9c1745db5f Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 26 Jun 2012 14:52:46 +0200 Subject: SSL cleanup: use crypto functions through the sslgen layer curl_ntlm_msgs.c would previously use an #ifdef maze and direct SSL-library calls instead of using the SSL layer we have for this purpose. --- lib/curl_ntlm_msgs.c | 94 +++++----------------------------------------------- 1 file changed, 8 insertions(+), 86 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 4c4dcfde6..c17880bb4 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -33,56 +33,6 @@ #define DEBUG_ME 0 -#ifdef USE_SSLEAY - -# ifdef USE_OPENSSL -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# else -# include -# ifndef OPENSSL_NO_MD4 -# include -# endif -# include -# include -# include -# endif -# include "ssluse.h" - -#elif defined(USE_GNUTLS_NETTLE) - -# include -# include -# include -# define MD5_DIGEST_LENGTH 16 - -#elif defined(USE_GNUTLS) - -# include -# include "gtls.h" -# define MD5_DIGEST_LENGTH 16 -# define MD4_DIGEST_LENGTH 16 - -#elif defined(USE_NSS) - -# include -# include -# include -# include "nssg.h" -# include "curl_md4.h" -# define MD5_DIGEST_LENGTH MD5_LENGTH - -#elif defined(USE_WINDOWS_SSPI) -# include "curl_sspi.h" -#else -# error "Can't compile NTLM support without a crypto library." -#endif - #include "urldata.h" #include "non-ascii.h" #include "sendf.h" @@ -92,6 +42,12 @@ #include "curl_multibyte.h" #include "curl_memory.h" +#if defined(USE_WINDOWS_SSPI) +# include "curl_sspi.h" +#endif + +#include "sslgen.h" + #define BUILDING_CURL_NTLM_MSGS_C #include "curl_ntlm_msgs.h" @@ -727,23 +683,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, unsigned char entropy[8]; /* Need to create 8 bytes random data */ -#ifdef USE_SSLEAY - MD5_CTX MD5pw; - Curl_ossl_seed(data); /* Initiate the seed if not already done */ - RAND_bytes(entropy, 8); -#elif defined(USE_GNUTLS_NETTLE) - struct md5_ctx MD5pw; - gnutls_rnd(GNUTLS_RND_RANDOM, entropy, 8); -#elif defined(USE_GNUTLS) - gcry_md_hd_t MD5pw; - Curl_gtls_seed(data); /* Initiate the seed if not already done */ - gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM); -#elif defined(USE_NSS) - PK11Context *MD5pw; - unsigned int MD5len; - Curl_nss_seed(data); /* Initiate the seed if not already done */ - PK11_GenerateRandom(entropy, 8); -#endif + Curl_ssl_random(data, entropy, sizeof(entropy)); /* 8 bytes random data as challenge in lmresp */ memcpy(lmresp, entropy, 8); @@ -755,25 +695,7 @@ CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data, memcpy(tmp, &ntlm->nonce[0], 8); memcpy(tmp + 8, entropy, 8); -#ifdef USE_SSLEAY - MD5_Init(&MD5pw); - MD5_Update(&MD5pw, tmp, 16); - MD5_Final(md5sum, &MD5pw); -#elif defined(USE_GNUTLS_NETTLE) - md5_init(&MD5pw); - md5_update(&MD5pw, 16, tmp); - md5_digest(&MD5pw, 16, md5sum); -#elif defined(USE_GNUTLS) - gcry_md_open(&MD5pw, GCRY_MD_MD5, 0); - gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH); - memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH); - gcry_md_close(MD5pw); -#elif defined(USE_NSS) - MD5pw = PK11_CreateDigestContext(SEC_OID_MD5); - PK11_DigestOp(MD5pw, tmp, 16); - PK11_DigestFinal(MD5pw, md5sum, &MD5len, MD5_DIGEST_LENGTH); - PK11_DestroyContext(MD5pw, PR_TRUE); -#endif + Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH); /* We shall only use the first 8 bytes of md5sum, but the des code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */ -- cgit v1.2.1 From dd302206ad3dc98c9dca74086850cc560739f188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20H=C3=A4gele?= Date: Mon, 2 Jul 2012 22:59:54 +0200 Subject: unicode NTLM SSPI: heap corruption fixed When compiling libcurl with UNICODE defined and using unicode characters in username. --- lib/curl_ntlm_msgs.c | 89 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 34 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index c17880bb4..0fcfec69e 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -351,67 +351,88 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, SecBufferDesc desc; SECURITY_STATUS status; unsigned long attrs; - const char *user; - const char *domain = ""; - size_t userlen = 0; + const TCHAR *useranddomain; + const TCHAR *user; + const TCHAR *passwd; + const TCHAR *domain = TEXT(""); size_t domlen = 0; - size_t passwdlen = 0; TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */ Curl_ntlm_sspi_cleanup(ntlm); - user = strchr(userp, '\\'); - if(!user) - user = strchr(userp, '/'); - - if(user) { - domain = userp; - domlen = user - userp; - user++; - } - else { - user = userp; - domain = ""; - domlen = 0; - } - - if(user) - userlen = strlen(user); + if(userp && *userp) { +#ifdef UNICODE + useranddomain = Curl_convert_UTF8_to_wchar(userp); + if(useranddomain == NULL) + return CURLE_OUT_OF_MEMORY; +#else + useranddomain = userp; +#endif - if(passwdp) - passwdlen = strlen(passwdp); + user = _tcschr(useranddomain, TEXT('\\')); + if(!user) + user = _tcschr(useranddomain, TEXT('/')); + + if(user) { + domain = useranddomain; + domlen = user - useranddomain; + user++; + } + else { + user = useranddomain; + domain = TEXT(""); + domlen = 0; + } - if(userlen > 0) { /* note: initialize all of this before doing the mallocs so that * it can be cleaned up later without leaking memory. */ ntlm->p_identity = &ntlm->identity; memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity)); + #ifdef UNICODE - if((ntlm->identity.User = Curl_convert_UTF8_to_wchar(user)) == NULL) + if((ntlm->identity.User = (unsigned short *)_wcsdup(user)) == NULL) { + free((void *)useranddomain); return CURLE_OUT_OF_MEMORY; + } #else if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL) return CURLE_OUT_OF_MEMORY; #endif + ntlm->identity.UserLength = (unsigned long)_tcslen(user); + + ntlm->identity.Domain = malloc(sizeof(TCHAR) * (domlen + 1)); + if(ntlm->identity.Domain == NULL) { +#ifdef UNICODE + free((void *)useranddomain); +#endif + return CURLE_OUT_OF_MEMORY; + } + _tcsncpy((TCHAR *)ntlm->identity.Domain, domain, domlen); + ntlm->identity.Domain[domlen] = TEXT('\0'); + ntlm->identity.DomainLength = (unsigned long)domlen; + +#ifdef UNICODE + free((void *)useranddomain); +#endif - ntlm->identity.UserLength = (unsigned long)userlen; #ifdef UNICODE - if((ntlm->identity.Password = Curl_convert_UTF8_to_wchar(passwdp)) == NULL) + ntlm->identity.Password = (unsigned short *) + Curl_convert_UTF8_to_wchar(passwdp); + if(ntlm->identity.Password == NULL) return CURLE_OUT_OF_MEMORY; #else if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) return CURLE_OUT_OF_MEMORY; #endif + ntlm->identity.PasswordLength = + (unsigned long)_tcslen((TCHAR *)ntlm->identity.Password); - ntlm->identity.PasswordLength = (unsigned long)passwdlen; - if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL) - return CURLE_OUT_OF_MEMORY; - - strncpy((char *)ntlm->identity.Domain, domain, domlen); - ntlm->identity.Domain[domlen] = '\0'; - ntlm->identity.DomainLength = (unsigned long)domlen; +#ifdef UNICODE + ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; +#else ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; +#endif } else ntlm->p_identity = NULL; -- cgit v1.2.1 From e0b9d3b2c9ced971ab927f44304b783416ab9ba6 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Tue, 3 Jul 2012 00:14:14 +0200 Subject: curl_ntlm_msgs.c: include for prototypes --- lib/curl_ntlm_msgs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 0fcfec69e..0fa0c9d2c 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -33,6 +33,10 @@ #define DEBUG_ME 0 +#ifdef USE_WINDOWS_SSPI +# include +#endif + #include "urldata.h" #include "non-ascii.h" #include "sendf.h" @@ -42,7 +46,7 @@ #include "curl_multibyte.h" #include "curl_memory.h" -#if defined(USE_WINDOWS_SSPI) +#ifdef USE_WINDOWS_SSPI # include "curl_sspi.h" #endif -- cgit v1.2.1 From 1a97fd7b6350b13e39b2063d96ae1250473e91c3 Mon Sep 17 00:00:00 2001 From: Marc Hoersken Date: Tue, 3 Jul 2012 09:16:00 +0200 Subject: curl_ntlm_msgs.c: Removed unused variable passwd --- lib/curl_ntlm_msgs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 0fa0c9d2c..02368e0bb 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -357,7 +357,6 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, unsigned long attrs; const TCHAR *useranddomain; const TCHAR *user; - const TCHAR *passwd; const TCHAR *domain = TEXT(""); size_t domlen = 0; TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */ -- cgit v1.2.1 From e77d8670685d38d80c940877a4fdfa3382c4d6cc Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Thu, 5 Jul 2012 22:16:15 +0200 Subject: unicode NTLM SSPI: cleanup Reduce the number of #ifdef UNICODE directives used in source files. --- lib/curl_ntlm_msgs.c | 130 ++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 70 deletions(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 02368e0bb..94f71c836 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -33,10 +33,6 @@ #define DEBUG_ME 0 -#ifdef USE_WINDOWS_SSPI -# include -#endif - #include "urldata.h" #include "non-ascii.h" #include "sendf.h" @@ -44,6 +40,7 @@ #include "curl_ntlm_core.h" #include "curl_gethostname.h" #include "curl_multibyte.h" +#include "warnless.h" #include "curl_memory.h" #ifdef USE_WINDOWS_SSPI @@ -242,7 +239,7 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data, free(buffer); return CURLE_OUT_OF_MEMORY; } - ntlm->n_type_2 = (unsigned long)size; + ntlm->n_type_2 = curlx_uztoul(size); memcpy(ntlm->type_2, buffer, size); #else ntlm->flags = 0; @@ -276,19 +273,16 @@ CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data, #ifdef USE_WINDOWS_SSPI void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm) { - if(ntlm->type_2) { - free(ntlm->type_2); - ntlm->type_2 = NULL; - } + 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) { - if(ntlm->identity.User) free(ntlm->identity.User); - if(ntlm->identity.Password) free(ntlm->identity.Password); - if(ntlm->identity.Domain) free(ntlm->identity.Domain); + Curl_safefree(ntlm->identity.User); + Curl_safefree(ntlm->identity.Password); + Curl_safefree(ntlm->identity.Domain); ntlm->p_identity = NULL; } } @@ -355,87 +349,83 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, SecBufferDesc desc; SECURITY_STATUS status; unsigned long attrs; - const TCHAR *useranddomain; - const TCHAR *user; - const TCHAR *domain = TEXT(""); + 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) { -#ifdef UNICODE - useranddomain = Curl_convert_UTF8_to_wchar(userp); - if(useranddomain == NULL) + + /* 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; -#else - useranddomain = userp; -#endif - user = _tcschr(useranddomain, TEXT('\\')); - if(!user) - user = _tcschr(useranddomain, TEXT('/')); + 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) { - domain = useranddomain; - domlen = user - useranddomain; - user++; + if(user.tchar_ptr) { + domain.tchar_ptr = useranddomain.tchar_ptr; + domlen = user.tchar_ptr - useranddomain.tchar_ptr; + user.tchar_ptr++; } else { - user = useranddomain; - domain = TEXT(""); + user.tchar_ptr = useranddomain.tchar_ptr; + domain.const_tchar_ptr = TEXT(""); domlen = 0; } - /* note: initialize all of this before doing the mallocs so that - * it can be cleaned up later without leaking memory. - */ - ntlm->p_identity = &ntlm->identity; - memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity)); - -#ifdef UNICODE - if((ntlm->identity.User = (unsigned short *)_wcsdup(user)) == NULL) { - free((void *)useranddomain); + /* 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; } -#else - if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL) - return CURLE_OUT_OF_MEMORY; -#endif - ntlm->identity.UserLength = (unsigned long)_tcslen(user); - - ntlm->identity.Domain = malloc(sizeof(TCHAR) * (domlen + 1)); - if(ntlm->identity.Domain == NULL) { -#ifdef UNICODE - free((void *)useranddomain); -#endif + 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((TCHAR *)ntlm->identity.Domain, domain, domlen); - ntlm->identity.Domain[domlen] = TEXT('\0'); - ntlm->identity.DomainLength = (unsigned long)domlen; + _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; -#ifdef UNICODE - free((void *)useranddomain); -#endif + Curl_unicodefree(useranddomain.tchar_ptr); -#ifdef UNICODE - ntlm->identity.Password = (unsigned short *) - Curl_convert_UTF8_to_wchar(passwdp); - if(ntlm->identity.Password == NULL) + /* 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; -#else - if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) + dup_passwd.tchar_ptr = _tcsdup(passwd.tchar_ptr); + if(!dup_passwd.tchar_ptr) { + Curl_unicodefree(passwd.tchar_ptr); return CURLE_OUT_OF_MEMORY; -#endif - ntlm->identity.PasswordLength = - (unsigned long)_tcslen((TCHAR *)ntlm->identity.Password); + } + ntlm->identity.Password = dup_passwd.tbyte_ptr; + ntlm->identity.PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); + dup_passwd.tchar_ptr = NULL; -#ifdef UNICODE - ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; -#else - ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; -#endif + Curl_unicodefree(passwd.tchar_ptr); + + /* setup ntlm identity's flags */ + ntlm->identity.Flags = SECFLAG_WINNT_AUTH_IDENTITY; } else ntlm->p_identity = NULL; -- cgit v1.2.1 From 4ac56b9d9f48080b240ce13f0f350ba418972e80 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 6 Jul 2012 00:19:41 +0200 Subject: code police: narrow source to < 80 columns --- lib/curl_ntlm_msgs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/curl_ntlm_msgs.c') diff --git a/lib/curl_ntlm_msgs.c b/lib/curl_ntlm_msgs.c index 94f71c836..8e788d733 100644 --- a/lib/curl_ntlm_msgs.c +++ b/lib/curl_ntlm_msgs.c @@ -419,7 +419,8 @@ CURLcode Curl_ntlm_create_type1_message(const char *userp, return CURLE_OUT_OF_MEMORY; } ntlm->identity.Password = dup_passwd.tbyte_ptr; - ntlm->identity.PasswordLength = curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); + ntlm->identity.PasswordLength = + curlx_uztoul(_tcslen(dup_passwd.tchar_ptr)); dup_passwd.tchar_ptr = NULL; Curl_unicodefree(passwd.tchar_ptr); -- cgit v1.2.1