diff options
Diffstat (limited to 'Utilities/cmcurl/lib/vauth/ntlm.c')
-rw-r--r-- | Utilities/cmcurl/lib/vauth/ntlm.c | 295 |
1 files changed, 155 insertions, 140 deletions
diff --git a/Utilities/cmcurl/lib/vauth/ntlm.c b/Utilities/cmcurl/lib/vauth/ntlm.c index 42196455f..047c2b5a3 100644 --- a/Utilities/cmcurl/lib/vauth/ntlm.c +++ b/Utilities/cmcurl/lib/vauth/ntlm.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, 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 * you should have received as part of this distribution. The terms @@ -44,7 +44,9 @@ #include "rand.h" #include "vtls/vtls.h" -#ifdef USE_NSS +/* SSL backend-specific #if branches in this file must be kept in the order + documented in curl_ntlm_core. */ +#if defined(NTLM_NEEDS_NSS_INIT) #include "vtls/nssg.h" /* for Curl_nss_force_init() */ #endif @@ -61,9 +63,9 @@ /* "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) +#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)) +#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \ + ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff)) #if DEBUG_ME # define DEBUG_OUT(x) x @@ -180,10 +182,11 @@ static CURLcode ntlm_decode_type2_target(struct Curl_easy *data, target_info_len = Curl_read16_le(&buffer[40]); target_info_offset = Curl_read32_le(&buffer[44]); if(target_info_len > 0) { - if(((target_info_offset + target_info_len) > size) || + if((target_info_offset >= size) || + ((target_info_offset + target_info_len) > size) || (target_info_offset < 48)) { infof(data, "NTLM handshake failure (bad type-2 message). " - "Target Info Offset Len is set incorrect by the peer\n"); + "Target Info Offset Len is set incorrect by the peer\n"); return CURLE_BAD_CONTENT_ENCODING; } @@ -272,7 +275,7 @@ CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, unsigned char *type2 = NULL; size_t type2_len = 0; -#if defined(USE_NSS) +#if defined(NTLM_NEEDS_NSS_INIT) /* Make sure the crypto backend is initialized */ result = Curl_nss_force_init(data); if(result) @@ -350,8 +353,11 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) * * Parameters: * + * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. + * service [in] - The service type such as http, smtp, pop or imap. + * host [in] - The host name. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -359,8 +365,11 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) * * Returns CURLE_OK on success. */ -CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, +CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, + const char *userp, const char *passwdp, + const char *service, + const char *hostname, struct ntlmdata *ntlm, char **outptr, size_t *outlen) { @@ -390,47 +399,49 @@ CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, domain are empty */ (void)userp; (void)passwdp; + (void)service, + (void)hostname, /* Clean up any former leftovers and initialise to defaults */ - Curl_auth_ntlm_cleanup(ntlm); + Curl_auth_cleanup_ntlm(ntlm); #if defined(USE_NTRESPONSES) && defined(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 */); + msnprintf((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; @@ -458,7 +469,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, }); /* Return with binary blob encoded into base64 */ - return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); + return Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); } /* @@ -471,7 +482,7 @@ CURLcode Curl_auth_create_ntlm_type1_message(const char *userp, * * data [in] - The session handle. * userp [in] - The user name in the format User or Domain\User. - * passdwp [in] - The user's password. + * passwdp [in] - The user's password. * ntlm [in/out] - The NTLM data struct being used and modified. * outptr [in/out] - The address where a pointer to newly allocated memory * holding the result will be stored upon completion. @@ -539,8 +550,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, else user = userp; - if(user) - userlen = strlen(user); + userlen = strlen(user); /* Get the machine's un-qualified host name as NTLM doesn't like the fully qualified domain name */ @@ -553,7 +563,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, } #if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2) - if(ntlm->target_info_len) { + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { unsigned char ntbuffer[0x18]; unsigned char entropy[8]; unsigned char ntlmv2hash[0x18]; @@ -590,7 +600,7 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, #if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ - if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { + if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) { unsigned char ntbuffer[0x18]; unsigned char tmp[0x18]; unsigned char md5sum[MD5_DIGEST_LENGTH]; @@ -622,7 +632,9 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp); /* End of NTLM2 Session code */ - + /* NTLM v2 session security is a misnomer because it is not NTLM v2. + It is NTLM v1 using the extended session security that is also + in NTLM v2 */ } else #endif @@ -669,88 +681,88 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, 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, + size = msnprintf((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, #ifdef USE_NTRESPONSES - SHORTPAIR(ntresplen), /* NT-response length, twice */ - SHORTPAIR(ntresplen), - SHORTPAIR(ntrespoff), - 0x0, 0x0, + SHORTPAIR(ntresplen), /* NT-response length, twice */ + SHORTPAIR(ntresplen), + SHORTPAIR(ntrespoff), + 0x0, 0x0, #else - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, #endif - SHORTPAIR(domlen), - SHORTPAIR(domlen), - SHORTPAIR(domoff), - 0x0, 0x0, + SHORTPAIR(domlen), + SHORTPAIR(domlen), + SHORTPAIR(domoff), + 0x0, 0x0, - SHORTPAIR(userlen), - SHORTPAIR(userlen), - SHORTPAIR(useroff), - 0x0, 0x0, + SHORTPAIR(userlen), + SHORTPAIR(userlen), + SHORTPAIR(useroff), + 0x0, 0x0, - SHORTPAIR(hostlen), - SHORTPAIR(hostlen), - SHORTPAIR(hostoff), - 0x0, 0x0, + SHORTPAIR(hostlen), + SHORTPAIR(hostlen), + SHORTPAIR(hostoff), + 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, - 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, + 0x0, 0x0, - LONGQUARTET(ntlm->flags)); + LONGQUARTET(ntlm->flags)); DEBUGASSERT(size == 64); DEBUGASSERT(size == (size_t)lmrespoff); @@ -767,11 +779,14 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, }); #ifdef USE_NTRESPONSES - if(size < (NTLM_BUFSIZE - ntresplen)) { - DEBUGASSERT(size == (size_t)ntrespoff); - memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); - size += ntresplen; + /* ntresplen + size should not be risking an integer overflow here */ + if(ntresplen + size > sizeof(ntlmbuf)) { + failf(data, "incoming NTLM message too big"); + return CURLE_OUT_OF_MEMORY; } + DEBUGASSERT(size == (size_t)ntrespoff); + memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); + size += ntresplen; DEBUG_OUT({ fprintf(stderr, "\n ntresp="); @@ -827,24 +842,24 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, return CURLE_CONV_FAILED; /* Return with binary blob encoded into base64 */ - result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen); + result = Curl_base64_encode(data, (char *)ntlmbuf, size, outptr, outlen); - Curl_auth_ntlm_cleanup(ntlm); + Curl_auth_cleanup_ntlm(ntlm); return result; } /* -* Curl_auth_ntlm_cleanup() -* -* This is used to clean up the NTLM specific data. -* -* Parameters: -* -* ntlm [in/out] - The NTLM data struct being cleaned up. -* -*/ -void Curl_auth_ntlm_cleanup(struct ntlmdata *ntlm) + * Curl_auth_cleanup_ntlm() + * + * This is used to clean up the NTLM specific data. + * + * Parameters: + * + * ntlm [in/out] - The NTLM data struct being cleaned up. + * + */ +void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) { /* Free the target info */ Curl_safefree(ntlm->target_info); |