113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI) 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci/* 3013498266Sopenharmony_ci * NTLM details: 3113498266Sopenharmony_ci * 3213498266Sopenharmony_ci * https://davenport.sourceforge.net/ntlm.html 3313498266Sopenharmony_ci * https://www.innovation.ch/java/ntlm.html 3413498266Sopenharmony_ci */ 3513498266Sopenharmony_ci 3613498266Sopenharmony_ci#define DEBUG_ME 0 3713498266Sopenharmony_ci 3813498266Sopenharmony_ci#include "urldata.h" 3913498266Sopenharmony_ci#include "sendf.h" 4013498266Sopenharmony_ci#include "curl_ntlm_core.h" 4113498266Sopenharmony_ci#include "curl_gethostname.h" 4213498266Sopenharmony_ci#include "curl_multibyte.h" 4313498266Sopenharmony_ci#include "curl_md5.h" 4413498266Sopenharmony_ci#include "warnless.h" 4513498266Sopenharmony_ci#include "rand.h" 4613498266Sopenharmony_ci#include "vtls/vtls.h" 4713498266Sopenharmony_ci#include "strdup.h" 4813498266Sopenharmony_ci 4913498266Sopenharmony_ci#define BUILDING_CURL_NTLM_MSGS_C 5013498266Sopenharmony_ci#include "vauth/vauth.h" 5113498266Sopenharmony_ci#include "vauth/ntlm.h" 5213498266Sopenharmony_ci#include "curl_endian.h" 5313498266Sopenharmony_ci#include "curl_printf.h" 5413498266Sopenharmony_ci 5513498266Sopenharmony_ci/* The last #include files should be: */ 5613498266Sopenharmony_ci#include "curl_memory.h" 5713498266Sopenharmony_ci#include "memdebug.h" 5813498266Sopenharmony_ci 5913498266Sopenharmony_ci/* "NTLMSSP" signature is always in ASCII regardless of the platform */ 6013498266Sopenharmony_ci#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" 6113498266Sopenharmony_ci 6213498266Sopenharmony_ci/* The fixed host name we provide, in order to not leak our real local host 6313498266Sopenharmony_ci name. Copy the name used by Firefox. */ 6413498266Sopenharmony_ci#define NTLM_HOSTNAME "WORKSTATION" 6513498266Sopenharmony_ci 6613498266Sopenharmony_ci#if DEBUG_ME 6713498266Sopenharmony_ci# define DEBUG_OUT(x) x 6813498266Sopenharmony_cistatic void ntlm_print_flags(FILE *handle, unsigned long flags) 6913498266Sopenharmony_ci{ 7013498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_UNICODE) 7113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); 7213498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_OEM) 7313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM "); 7413498266Sopenharmony_ci if(flags & NTLMFLAG_REQUEST_TARGET) 7513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_REQUEST_TARGET "); 7613498266Sopenharmony_ci if(flags & (1<<3)) 7713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_3 "); 7813498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_SIGN) 7913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN "); 8013498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_SEAL) 8113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL "); 8213498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE) 8313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE "); 8413498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_LM_KEY) 8513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY "); 8613498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY) 8713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY "); 8813498266Sopenharmony_ci if(flags & (1<<10)) 8913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_10 "); 9013498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS) 9113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS "); 9213498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED) 9313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED "); 9413498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED) 9513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED "); 9613498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL) 9713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL "); 9813498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN) 9913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN "); 10013498266Sopenharmony_ci if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN) 10113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN "); 10213498266Sopenharmony_ci if(flags & NTLMFLAG_TARGET_TYPE_SERVER) 10313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER "); 10413498266Sopenharmony_ci if(flags & NTLMFLAG_TARGET_TYPE_SHARE) 10513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE "); 10613498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) 10713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY "); 10813498266Sopenharmony_ci if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE) 10913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE "); 11013498266Sopenharmony_ci if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE) 11113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE "); 11213498266Sopenharmony_ci if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY) 11313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY "); 11413498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) 11513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO "); 11613498266Sopenharmony_ci if(flags & (1<<24)) 11713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_24 "); 11813498266Sopenharmony_ci if(flags & (1<<25)) 11913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_25 "); 12013498266Sopenharmony_ci if(flags & (1<<26)) 12113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_26 "); 12213498266Sopenharmony_ci if(flags & (1<<27)) 12313498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_27 "); 12413498266Sopenharmony_ci if(flags & (1<<28)) 12513498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_UNKNOWN_28 "); 12613498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_128) 12713498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_128 "); 12813498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE) 12913498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE "); 13013498266Sopenharmony_ci if(flags & NTLMFLAG_NEGOTIATE_56) 13113498266Sopenharmony_ci fprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); 13213498266Sopenharmony_ci} 13313498266Sopenharmony_ci 13413498266Sopenharmony_cistatic void ntlm_print_hex(FILE *handle, const char *buf, size_t len) 13513498266Sopenharmony_ci{ 13613498266Sopenharmony_ci const char *p = buf; 13713498266Sopenharmony_ci 13813498266Sopenharmony_ci (void) handle; 13913498266Sopenharmony_ci 14013498266Sopenharmony_ci fprintf(stderr, "0x"); 14113498266Sopenharmony_ci while(len-- > 0) 14213498266Sopenharmony_ci fprintf(stderr, "%02.2x", (unsigned int)*p++); 14313498266Sopenharmony_ci} 14413498266Sopenharmony_ci#else 14513498266Sopenharmony_ci# define DEBUG_OUT(x) Curl_nop_stmt 14613498266Sopenharmony_ci#endif 14713498266Sopenharmony_ci 14813498266Sopenharmony_ci/* 14913498266Sopenharmony_ci * ntlm_decode_type2_target() 15013498266Sopenharmony_ci * 15113498266Sopenharmony_ci * This is used to decode the "target info" in the NTLM type-2 message 15213498266Sopenharmony_ci * received. 15313498266Sopenharmony_ci * 15413498266Sopenharmony_ci * Parameters: 15513498266Sopenharmony_ci * 15613498266Sopenharmony_ci * data [in] - The session handle. 15713498266Sopenharmony_ci * type2ref [in] - The type-2 message. 15813498266Sopenharmony_ci * ntlm [in/out] - The NTLM data struct being used and modified. 15913498266Sopenharmony_ci * 16013498266Sopenharmony_ci * Returns CURLE_OK on success. 16113498266Sopenharmony_ci */ 16213498266Sopenharmony_cistatic CURLcode ntlm_decode_type2_target(struct Curl_easy *data, 16313498266Sopenharmony_ci const struct bufref *type2ref, 16413498266Sopenharmony_ci struct ntlmdata *ntlm) 16513498266Sopenharmony_ci{ 16613498266Sopenharmony_ci unsigned short target_info_len = 0; 16713498266Sopenharmony_ci unsigned int target_info_offset = 0; 16813498266Sopenharmony_ci const unsigned char *type2 = Curl_bufref_ptr(type2ref); 16913498266Sopenharmony_ci size_t type2len = Curl_bufref_len(type2ref); 17013498266Sopenharmony_ci 17113498266Sopenharmony_ci#if defined(CURL_DISABLE_VERBOSE_STRINGS) 17213498266Sopenharmony_ci (void) data; 17313498266Sopenharmony_ci#endif 17413498266Sopenharmony_ci 17513498266Sopenharmony_ci if(type2len >= 48) { 17613498266Sopenharmony_ci target_info_len = Curl_read16_le(&type2[40]); 17713498266Sopenharmony_ci target_info_offset = Curl_read32_le(&type2[44]); 17813498266Sopenharmony_ci if(target_info_len > 0) { 17913498266Sopenharmony_ci if((target_info_offset > type2len) || 18013498266Sopenharmony_ci (target_info_offset + target_info_len) > type2len || 18113498266Sopenharmony_ci target_info_offset < 48) { 18213498266Sopenharmony_ci infof(data, "NTLM handshake failure (bad type-2 message). " 18313498266Sopenharmony_ci "Target Info Offset Len is set incorrect by the peer"); 18413498266Sopenharmony_ci return CURLE_BAD_CONTENT_ENCODING; 18513498266Sopenharmony_ci } 18613498266Sopenharmony_ci 18713498266Sopenharmony_ci free(ntlm->target_info); /* replace any previous data */ 18813498266Sopenharmony_ci ntlm->target_info = Curl_memdup(&type2[target_info_offset], 18913498266Sopenharmony_ci target_info_len); 19013498266Sopenharmony_ci if(!ntlm->target_info) 19113498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 19213498266Sopenharmony_ci } 19313498266Sopenharmony_ci } 19413498266Sopenharmony_ci 19513498266Sopenharmony_ci ntlm->target_info_len = target_info_len; 19613498266Sopenharmony_ci 19713498266Sopenharmony_ci return CURLE_OK; 19813498266Sopenharmony_ci} 19913498266Sopenharmony_ci 20013498266Sopenharmony_ci/* 20113498266Sopenharmony_ci NTLM message structure notes: 20213498266Sopenharmony_ci 20313498266Sopenharmony_ci A 'short' is a 'network short', a little-endian 16-bit unsigned value. 20413498266Sopenharmony_ci 20513498266Sopenharmony_ci A 'long' is a 'network long', a little-endian, 32-bit unsigned value. 20613498266Sopenharmony_ci 20713498266Sopenharmony_ci A 'security buffer' represents a triplet used to point to a buffer, 20813498266Sopenharmony_ci consisting of two shorts and one long: 20913498266Sopenharmony_ci 21013498266Sopenharmony_ci 1. A 'short' containing the length of the buffer content in bytes. 21113498266Sopenharmony_ci 2. A 'short' containing the allocated space for the buffer in bytes. 21213498266Sopenharmony_ci 3. A 'long' containing the offset to the start of the buffer in bytes, 21313498266Sopenharmony_ci from the beginning of the NTLM message. 21413498266Sopenharmony_ci*/ 21513498266Sopenharmony_ci 21613498266Sopenharmony_ci/* 21713498266Sopenharmony_ci * Curl_auth_is_ntlm_supported() 21813498266Sopenharmony_ci * 21913498266Sopenharmony_ci * This is used to evaluate if NTLM is supported. 22013498266Sopenharmony_ci * 22113498266Sopenharmony_ci * Parameters: None 22213498266Sopenharmony_ci * 22313498266Sopenharmony_ci * Returns TRUE as NTLM as handled by libcurl. 22413498266Sopenharmony_ci */ 22513498266Sopenharmony_cibool Curl_auth_is_ntlm_supported(void) 22613498266Sopenharmony_ci{ 22713498266Sopenharmony_ci return TRUE; 22813498266Sopenharmony_ci} 22913498266Sopenharmony_ci 23013498266Sopenharmony_ci/* 23113498266Sopenharmony_ci * Curl_auth_decode_ntlm_type2_message() 23213498266Sopenharmony_ci * 23313498266Sopenharmony_ci * This is used to decode an NTLM type-2 message. The raw NTLM message is 23413498266Sopenharmony_ci * checked * for validity before the appropriate data for creating a type-3 23513498266Sopenharmony_ci * message is * written to the given NTLM data structure. 23613498266Sopenharmony_ci * 23713498266Sopenharmony_ci * Parameters: 23813498266Sopenharmony_ci * 23913498266Sopenharmony_ci * data [in] - The session handle. 24013498266Sopenharmony_ci * type2ref [in] - The type-2 message. 24113498266Sopenharmony_ci * ntlm [in/out] - The NTLM data struct being used and modified. 24213498266Sopenharmony_ci * 24313498266Sopenharmony_ci * Returns CURLE_OK on success. 24413498266Sopenharmony_ci */ 24513498266Sopenharmony_ciCURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data, 24613498266Sopenharmony_ci const struct bufref *type2ref, 24713498266Sopenharmony_ci struct ntlmdata *ntlm) 24813498266Sopenharmony_ci{ 24913498266Sopenharmony_ci static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 }; 25013498266Sopenharmony_ci 25113498266Sopenharmony_ci /* NTLM type-2 message structure: 25213498266Sopenharmony_ci 25313498266Sopenharmony_ci Index Description Content 25413498266Sopenharmony_ci 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" 25513498266Sopenharmony_ci (0x4e544c4d53535000) 25613498266Sopenharmony_ci 8 NTLM Message Type long (0x02000000) 25713498266Sopenharmony_ci 12 Target Name security buffer 25813498266Sopenharmony_ci 20 Flags long 25913498266Sopenharmony_ci 24 Challenge 8 bytes 26013498266Sopenharmony_ci (32) Context 8 bytes (two consecutive longs) (*) 26113498266Sopenharmony_ci (40) Target Information security buffer (*) 26213498266Sopenharmony_ci (48) OS Version Structure 8 bytes (*) 26313498266Sopenharmony_ci 32 (48) (56) Start of data block (*) 26413498266Sopenharmony_ci (*) -> Optional 26513498266Sopenharmony_ci */ 26613498266Sopenharmony_ci 26713498266Sopenharmony_ci CURLcode result = CURLE_OK; 26813498266Sopenharmony_ci const unsigned char *type2 = Curl_bufref_ptr(type2ref); 26913498266Sopenharmony_ci size_t type2len = Curl_bufref_len(type2ref); 27013498266Sopenharmony_ci 27113498266Sopenharmony_ci#if defined(CURL_DISABLE_VERBOSE_STRINGS) 27213498266Sopenharmony_ci (void)data; 27313498266Sopenharmony_ci#endif 27413498266Sopenharmony_ci 27513498266Sopenharmony_ci ntlm->flags = 0; 27613498266Sopenharmony_ci 27713498266Sopenharmony_ci if((type2len < 32) || 27813498266Sopenharmony_ci (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) || 27913498266Sopenharmony_ci (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) { 28013498266Sopenharmony_ci /* This was not a good enough type-2 message */ 28113498266Sopenharmony_ci infof(data, "NTLM handshake failure (bad type-2 message)"); 28213498266Sopenharmony_ci return CURLE_BAD_CONTENT_ENCODING; 28313498266Sopenharmony_ci } 28413498266Sopenharmony_ci 28513498266Sopenharmony_ci ntlm->flags = Curl_read32_le(&type2[20]); 28613498266Sopenharmony_ci memcpy(ntlm->nonce, &type2[24], 8); 28713498266Sopenharmony_ci 28813498266Sopenharmony_ci if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) { 28913498266Sopenharmony_ci result = ntlm_decode_type2_target(data, type2ref, ntlm); 29013498266Sopenharmony_ci if(result) { 29113498266Sopenharmony_ci infof(data, "NTLM handshake failure (bad type-2 message)"); 29213498266Sopenharmony_ci return result; 29313498266Sopenharmony_ci } 29413498266Sopenharmony_ci } 29513498266Sopenharmony_ci 29613498266Sopenharmony_ci DEBUG_OUT({ 29713498266Sopenharmony_ci fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); 29813498266Sopenharmony_ci ntlm_print_flags(stderr, ntlm->flags); 29913498266Sopenharmony_ci fprintf(stderr, "\n nonce="); 30013498266Sopenharmony_ci ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); 30113498266Sopenharmony_ci fprintf(stderr, "\n****\n"); 30213498266Sopenharmony_ci fprintf(stderr, "**** Header %s\n ", header); 30313498266Sopenharmony_ci }); 30413498266Sopenharmony_ci 30513498266Sopenharmony_ci return result; 30613498266Sopenharmony_ci} 30713498266Sopenharmony_ci 30813498266Sopenharmony_ci/* copy the source to the destination and fill in zeroes in every 30913498266Sopenharmony_ci other destination byte! */ 31013498266Sopenharmony_cistatic void unicodecpy(unsigned char *dest, const char *src, size_t length) 31113498266Sopenharmony_ci{ 31213498266Sopenharmony_ci size_t i; 31313498266Sopenharmony_ci for(i = 0; i < length; i++) { 31413498266Sopenharmony_ci dest[2 * i] = (unsigned char)src[i]; 31513498266Sopenharmony_ci dest[2 * i + 1] = '\0'; 31613498266Sopenharmony_ci } 31713498266Sopenharmony_ci} 31813498266Sopenharmony_ci 31913498266Sopenharmony_ci/* 32013498266Sopenharmony_ci * Curl_auth_create_ntlm_type1_message() 32113498266Sopenharmony_ci * 32213498266Sopenharmony_ci * This is used to generate an NTLM type-1 message ready for sending to the 32313498266Sopenharmony_ci * recipient using the appropriate compile time crypto API. 32413498266Sopenharmony_ci * 32513498266Sopenharmony_ci * Parameters: 32613498266Sopenharmony_ci * 32713498266Sopenharmony_ci * data [in] - The session handle. 32813498266Sopenharmony_ci * userp [in] - The user name in the format User or Domain\User. 32913498266Sopenharmony_ci * passwdp [in] - The user's password. 33013498266Sopenharmony_ci * service [in] - The service type such as http, smtp, pop or imap. 33113498266Sopenharmony_ci * host [in] - The host name. 33213498266Sopenharmony_ci * ntlm [in/out] - The NTLM data struct being used and modified. 33313498266Sopenharmony_ci * out [out] - The result storage. 33413498266Sopenharmony_ci * 33513498266Sopenharmony_ci * Returns CURLE_OK on success. 33613498266Sopenharmony_ci */ 33713498266Sopenharmony_ciCURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data, 33813498266Sopenharmony_ci const char *userp, 33913498266Sopenharmony_ci const char *passwdp, 34013498266Sopenharmony_ci const char *service, 34113498266Sopenharmony_ci const char *hostname, 34213498266Sopenharmony_ci struct ntlmdata *ntlm, 34313498266Sopenharmony_ci struct bufref *out) 34413498266Sopenharmony_ci{ 34513498266Sopenharmony_ci /* NTLM type-1 message structure: 34613498266Sopenharmony_ci 34713498266Sopenharmony_ci Index Description Content 34813498266Sopenharmony_ci 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" 34913498266Sopenharmony_ci (0x4e544c4d53535000) 35013498266Sopenharmony_ci 8 NTLM Message Type long (0x01000000) 35113498266Sopenharmony_ci 12 Flags long 35213498266Sopenharmony_ci (16) Supplied Domain security buffer (*) 35313498266Sopenharmony_ci (24) Supplied Workstation security buffer (*) 35413498266Sopenharmony_ci (32) OS Version Structure 8 bytes (*) 35513498266Sopenharmony_ci (32) (40) Start of data block (*) 35613498266Sopenharmony_ci (*) -> Optional 35713498266Sopenharmony_ci */ 35813498266Sopenharmony_ci 35913498266Sopenharmony_ci size_t size; 36013498266Sopenharmony_ci 36113498266Sopenharmony_ci char *ntlmbuf; 36213498266Sopenharmony_ci const char *host = ""; /* empty */ 36313498266Sopenharmony_ci const char *domain = ""; /* empty */ 36413498266Sopenharmony_ci size_t hostlen = 0; 36513498266Sopenharmony_ci size_t domlen = 0; 36613498266Sopenharmony_ci size_t hostoff = 0; 36713498266Sopenharmony_ci size_t domoff = hostoff + hostlen; /* This is 0: remember that host and 36813498266Sopenharmony_ci domain are empty */ 36913498266Sopenharmony_ci (void)data; 37013498266Sopenharmony_ci (void)userp; 37113498266Sopenharmony_ci (void)passwdp; 37213498266Sopenharmony_ci (void)service; 37313498266Sopenharmony_ci (void)hostname; 37413498266Sopenharmony_ci 37513498266Sopenharmony_ci /* Clean up any former leftovers and initialise to defaults */ 37613498266Sopenharmony_ci Curl_auth_cleanup_ntlm(ntlm); 37713498266Sopenharmony_ci 37813498266Sopenharmony_ci ntlmbuf = aprintf(NTLMSSP_SIGNATURE "%c" 37913498266Sopenharmony_ci "\x01%c%c%c" /* 32-bit type = 1 */ 38013498266Sopenharmony_ci "%c%c%c%c" /* 32-bit NTLM flag field */ 38113498266Sopenharmony_ci "%c%c" /* domain length */ 38213498266Sopenharmony_ci "%c%c" /* domain allocated space */ 38313498266Sopenharmony_ci "%c%c" /* domain name offset */ 38413498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 38513498266Sopenharmony_ci "%c%c" /* host length */ 38613498266Sopenharmony_ci "%c%c" /* host allocated space */ 38713498266Sopenharmony_ci "%c%c" /* host name offset */ 38813498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 38913498266Sopenharmony_ci "%s" /* host name */ 39013498266Sopenharmony_ci "%s", /* domain string */ 39113498266Sopenharmony_ci 0, /* trailing zero */ 39213498266Sopenharmony_ci 0, 0, 0, /* part of type-1 long */ 39313498266Sopenharmony_ci 39413498266Sopenharmony_ci LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | 39513498266Sopenharmony_ci NTLMFLAG_REQUEST_TARGET | 39613498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM_KEY | 39713498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM2_KEY | 39813498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), 39913498266Sopenharmony_ci SHORTPAIR(domlen), 40013498266Sopenharmony_ci SHORTPAIR(domlen), 40113498266Sopenharmony_ci SHORTPAIR(domoff), 40213498266Sopenharmony_ci 0, 0, 40313498266Sopenharmony_ci SHORTPAIR(hostlen), 40413498266Sopenharmony_ci SHORTPAIR(hostlen), 40513498266Sopenharmony_ci SHORTPAIR(hostoff), 40613498266Sopenharmony_ci 0, 0, 40713498266Sopenharmony_ci host, /* this is empty */ 40813498266Sopenharmony_ci domain /* this is empty */); 40913498266Sopenharmony_ci 41013498266Sopenharmony_ci if(!ntlmbuf) 41113498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 41213498266Sopenharmony_ci 41313498266Sopenharmony_ci /* Initial packet length */ 41413498266Sopenharmony_ci size = 32 + hostlen + domlen; 41513498266Sopenharmony_ci 41613498266Sopenharmony_ci DEBUG_OUT({ 41713498266Sopenharmony_ci fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " 41813498266Sopenharmony_ci "0x%08.8x ", 41913498266Sopenharmony_ci LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | 42013498266Sopenharmony_ci NTLMFLAG_REQUEST_TARGET | 42113498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM_KEY | 42213498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM2_KEY | 42313498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), 42413498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_OEM | 42513498266Sopenharmony_ci NTLMFLAG_REQUEST_TARGET | 42613498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM_KEY | 42713498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM2_KEY | 42813498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); 42913498266Sopenharmony_ci ntlm_print_flags(stderr, 43013498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_OEM | 43113498266Sopenharmony_ci NTLMFLAG_REQUEST_TARGET | 43213498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM_KEY | 43313498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_NTLM2_KEY | 43413498266Sopenharmony_ci NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); 43513498266Sopenharmony_ci fprintf(stderr, "\n****\n"); 43613498266Sopenharmony_ci }); 43713498266Sopenharmony_ci 43813498266Sopenharmony_ci Curl_bufref_set(out, ntlmbuf, size, curl_free); 43913498266Sopenharmony_ci return CURLE_OK; 44013498266Sopenharmony_ci} 44113498266Sopenharmony_ci 44213498266Sopenharmony_ci/* 44313498266Sopenharmony_ci * Curl_auth_create_ntlm_type3_message() 44413498266Sopenharmony_ci * 44513498266Sopenharmony_ci * This is used to generate an already encoded NTLM type-3 message ready for 44613498266Sopenharmony_ci * sending to the recipient using the appropriate compile time crypto API. 44713498266Sopenharmony_ci * 44813498266Sopenharmony_ci * Parameters: 44913498266Sopenharmony_ci * 45013498266Sopenharmony_ci * data [in] - The session handle. 45113498266Sopenharmony_ci * userp [in] - The user name in the format User or Domain\User. 45213498266Sopenharmony_ci * passwdp [in] - The user's password. 45313498266Sopenharmony_ci * ntlm [in/out] - The NTLM data struct being used and modified. 45413498266Sopenharmony_ci * out [out] - The result storage. 45513498266Sopenharmony_ci * 45613498266Sopenharmony_ci * Returns CURLE_OK on success. 45713498266Sopenharmony_ci */ 45813498266Sopenharmony_ciCURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, 45913498266Sopenharmony_ci const char *userp, 46013498266Sopenharmony_ci const char *passwdp, 46113498266Sopenharmony_ci struct ntlmdata *ntlm, 46213498266Sopenharmony_ci struct bufref *out) 46313498266Sopenharmony_ci{ 46413498266Sopenharmony_ci /* NTLM type-3 message structure: 46513498266Sopenharmony_ci 46613498266Sopenharmony_ci Index Description Content 46713498266Sopenharmony_ci 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP" 46813498266Sopenharmony_ci (0x4e544c4d53535000) 46913498266Sopenharmony_ci 8 NTLM Message Type long (0x03000000) 47013498266Sopenharmony_ci 12 LM/LMv2 Response security buffer 47113498266Sopenharmony_ci 20 NTLM/NTLMv2 Response security buffer 47213498266Sopenharmony_ci 28 Target Name security buffer 47313498266Sopenharmony_ci 36 User Name security buffer 47413498266Sopenharmony_ci 44 Workstation Name security buffer 47513498266Sopenharmony_ci (52) Session Key security buffer (*) 47613498266Sopenharmony_ci (60) Flags long (*) 47713498266Sopenharmony_ci (64) OS Version Structure 8 bytes (*) 47813498266Sopenharmony_ci 52 (64) (72) Start of data block 47913498266Sopenharmony_ci (*) -> Optional 48013498266Sopenharmony_ci */ 48113498266Sopenharmony_ci 48213498266Sopenharmony_ci CURLcode result = CURLE_OK; 48313498266Sopenharmony_ci size_t size; 48413498266Sopenharmony_ci unsigned char ntlmbuf[NTLM_BUFSIZE]; 48513498266Sopenharmony_ci int lmrespoff; 48613498266Sopenharmony_ci unsigned char lmresp[24]; /* fixed-size */ 48713498266Sopenharmony_ci int ntrespoff; 48813498266Sopenharmony_ci unsigned int ntresplen = 24; 48913498266Sopenharmony_ci unsigned char ntresp[24]; /* fixed-size */ 49013498266Sopenharmony_ci unsigned char *ptr_ntresp = &ntresp[0]; 49113498266Sopenharmony_ci unsigned char *ntlmv2resp = NULL; 49213498266Sopenharmony_ci bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; 49313498266Sopenharmony_ci char host[HOSTNAME_MAX + 1] = ""; 49413498266Sopenharmony_ci const char *user; 49513498266Sopenharmony_ci const char *domain = ""; 49613498266Sopenharmony_ci size_t hostoff = 0; 49713498266Sopenharmony_ci size_t useroff = 0; 49813498266Sopenharmony_ci size_t domoff = 0; 49913498266Sopenharmony_ci size_t hostlen = 0; 50013498266Sopenharmony_ci size_t userlen = 0; 50113498266Sopenharmony_ci size_t domlen = 0; 50213498266Sopenharmony_ci 50313498266Sopenharmony_ci memset(lmresp, 0, sizeof(lmresp)); 50413498266Sopenharmony_ci memset(ntresp, 0, sizeof(ntresp)); 50513498266Sopenharmony_ci user = strchr(userp, '\\'); 50613498266Sopenharmony_ci if(!user) 50713498266Sopenharmony_ci user = strchr(userp, '/'); 50813498266Sopenharmony_ci 50913498266Sopenharmony_ci if(user) { 51013498266Sopenharmony_ci domain = userp; 51113498266Sopenharmony_ci domlen = (user - domain); 51213498266Sopenharmony_ci user++; 51313498266Sopenharmony_ci } 51413498266Sopenharmony_ci else 51513498266Sopenharmony_ci user = userp; 51613498266Sopenharmony_ci 51713498266Sopenharmony_ci userlen = strlen(user); 51813498266Sopenharmony_ci 51913498266Sopenharmony_ci#ifndef NTLM_HOSTNAME 52013498266Sopenharmony_ci /* Get the machine's un-qualified host name as NTLM doesn't like the fully 52113498266Sopenharmony_ci qualified domain name */ 52213498266Sopenharmony_ci if(Curl_gethostname(host, sizeof(host))) { 52313498266Sopenharmony_ci infof(data, "gethostname() failed, continuing without"); 52413498266Sopenharmony_ci hostlen = 0; 52513498266Sopenharmony_ci } 52613498266Sopenharmony_ci else { 52713498266Sopenharmony_ci hostlen = strlen(host); 52813498266Sopenharmony_ci } 52913498266Sopenharmony_ci#else 53013498266Sopenharmony_ci (void)msnprintf(host, sizeof(host), "%s", NTLM_HOSTNAME); 53113498266Sopenharmony_ci hostlen = sizeof(NTLM_HOSTNAME)-1; 53213498266Sopenharmony_ci#endif 53313498266Sopenharmony_ci 53413498266Sopenharmony_ci if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { 53513498266Sopenharmony_ci unsigned char ntbuffer[0x18]; 53613498266Sopenharmony_ci unsigned char entropy[8]; 53713498266Sopenharmony_ci unsigned char ntlmv2hash[0x18]; 53813498266Sopenharmony_ci 53913498266Sopenharmony_ci /* Full NTLM version 2 54013498266Sopenharmony_ci Although this cannot be negotiated, it is used here if available, as 54113498266Sopenharmony_ci servers featuring extended security are likely supporting also 54213498266Sopenharmony_ci NTLMv2. */ 54313498266Sopenharmony_ci result = Curl_rand(data, entropy, 8); 54413498266Sopenharmony_ci if(result) 54513498266Sopenharmony_ci return result; 54613498266Sopenharmony_ci 54713498266Sopenharmony_ci result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer); 54813498266Sopenharmony_ci if(result) 54913498266Sopenharmony_ci return result; 55013498266Sopenharmony_ci 55113498266Sopenharmony_ci result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen, 55213498266Sopenharmony_ci ntbuffer, ntlmv2hash); 55313498266Sopenharmony_ci if(result) 55413498266Sopenharmony_ci return result; 55513498266Sopenharmony_ci 55613498266Sopenharmony_ci /* LMv2 response */ 55713498266Sopenharmony_ci result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy, 55813498266Sopenharmony_ci &ntlm->nonce[0], lmresp); 55913498266Sopenharmony_ci if(result) 56013498266Sopenharmony_ci return result; 56113498266Sopenharmony_ci 56213498266Sopenharmony_ci /* NTLMv2 response */ 56313498266Sopenharmony_ci result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy, 56413498266Sopenharmony_ci ntlm, &ntlmv2resp, &ntresplen); 56513498266Sopenharmony_ci if(result) 56613498266Sopenharmony_ci return result; 56713498266Sopenharmony_ci 56813498266Sopenharmony_ci ptr_ntresp = ntlmv2resp; 56913498266Sopenharmony_ci } 57013498266Sopenharmony_ci else { 57113498266Sopenharmony_ci 57213498266Sopenharmony_ci unsigned char ntbuffer[0x18]; 57313498266Sopenharmony_ci unsigned char lmbuffer[0x18]; 57413498266Sopenharmony_ci 57513498266Sopenharmony_ci /* NTLM version 1 */ 57613498266Sopenharmony_ci 57713498266Sopenharmony_ci result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer); 57813498266Sopenharmony_ci if(result) 57913498266Sopenharmony_ci return result; 58013498266Sopenharmony_ci 58113498266Sopenharmony_ci Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp); 58213498266Sopenharmony_ci 58313498266Sopenharmony_ci result = Curl_ntlm_core_mk_lm_hash(passwdp, lmbuffer); 58413498266Sopenharmony_ci if(result) 58513498266Sopenharmony_ci return result; 58613498266Sopenharmony_ci 58713498266Sopenharmony_ci Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp); 58813498266Sopenharmony_ci ntlm->flags &= ~NTLMFLAG_NEGOTIATE_NTLM2_KEY; 58913498266Sopenharmony_ci 59013498266Sopenharmony_ci /* A safer but less compatible alternative is: 59113498266Sopenharmony_ci * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp); 59213498266Sopenharmony_ci * See https://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */ 59313498266Sopenharmony_ci } 59413498266Sopenharmony_ci 59513498266Sopenharmony_ci if(unicode) { 59613498266Sopenharmony_ci domlen = domlen * 2; 59713498266Sopenharmony_ci userlen = userlen * 2; 59813498266Sopenharmony_ci hostlen = hostlen * 2; 59913498266Sopenharmony_ci } 60013498266Sopenharmony_ci 60113498266Sopenharmony_ci lmrespoff = 64; /* size of the message header */ 60213498266Sopenharmony_ci ntrespoff = lmrespoff + 0x18; 60313498266Sopenharmony_ci domoff = ntrespoff + ntresplen; 60413498266Sopenharmony_ci useroff = domoff + domlen; 60513498266Sopenharmony_ci hostoff = useroff + userlen; 60613498266Sopenharmony_ci 60713498266Sopenharmony_ci /* Create the big type-3 message binary blob */ 60813498266Sopenharmony_ci size = msnprintf((char *)ntlmbuf, NTLM_BUFSIZE, 60913498266Sopenharmony_ci NTLMSSP_SIGNATURE "%c" 61013498266Sopenharmony_ci "\x03%c%c%c" /* 32-bit type = 3 */ 61113498266Sopenharmony_ci 61213498266Sopenharmony_ci "%c%c" /* LanManager length */ 61313498266Sopenharmony_ci "%c%c" /* LanManager allocated space */ 61413498266Sopenharmony_ci "%c%c" /* LanManager offset */ 61513498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 61613498266Sopenharmony_ci 61713498266Sopenharmony_ci "%c%c" /* NT-response length */ 61813498266Sopenharmony_ci "%c%c" /* NT-response allocated space */ 61913498266Sopenharmony_ci "%c%c" /* NT-response offset */ 62013498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 62113498266Sopenharmony_ci 62213498266Sopenharmony_ci "%c%c" /* domain length */ 62313498266Sopenharmony_ci "%c%c" /* domain allocated space */ 62413498266Sopenharmony_ci "%c%c" /* domain name offset */ 62513498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 62613498266Sopenharmony_ci 62713498266Sopenharmony_ci "%c%c" /* user length */ 62813498266Sopenharmony_ci "%c%c" /* user allocated space */ 62913498266Sopenharmony_ci "%c%c" /* user offset */ 63013498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 63113498266Sopenharmony_ci 63213498266Sopenharmony_ci "%c%c" /* host length */ 63313498266Sopenharmony_ci "%c%c" /* host allocated space */ 63413498266Sopenharmony_ci "%c%c" /* host offset */ 63513498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 63613498266Sopenharmony_ci 63713498266Sopenharmony_ci "%c%c" /* session key length (unknown purpose) */ 63813498266Sopenharmony_ci "%c%c" /* session key allocated space (unknown purpose) */ 63913498266Sopenharmony_ci "%c%c" /* session key offset (unknown purpose) */ 64013498266Sopenharmony_ci "%c%c" /* 2 zeroes */ 64113498266Sopenharmony_ci 64213498266Sopenharmony_ci "%c%c%c%c", /* flags */ 64313498266Sopenharmony_ci 64413498266Sopenharmony_ci /* domain string */ 64513498266Sopenharmony_ci /* user string */ 64613498266Sopenharmony_ci /* host string */ 64713498266Sopenharmony_ci /* LanManager response */ 64813498266Sopenharmony_ci /* NT response */ 64913498266Sopenharmony_ci 65013498266Sopenharmony_ci 0, /* null-termination */ 65113498266Sopenharmony_ci 0, 0, 0, /* type-3 long, the 24 upper bits */ 65213498266Sopenharmony_ci 65313498266Sopenharmony_ci SHORTPAIR(0x18), /* LanManager response length, twice */ 65413498266Sopenharmony_ci SHORTPAIR(0x18), 65513498266Sopenharmony_ci SHORTPAIR(lmrespoff), 65613498266Sopenharmony_ci 0x0, 0x0, 65713498266Sopenharmony_ci 65813498266Sopenharmony_ci SHORTPAIR(ntresplen), /* NT-response length, twice */ 65913498266Sopenharmony_ci SHORTPAIR(ntresplen), 66013498266Sopenharmony_ci SHORTPAIR(ntrespoff), 66113498266Sopenharmony_ci 0x0, 0x0, 66213498266Sopenharmony_ci 66313498266Sopenharmony_ci SHORTPAIR(domlen), 66413498266Sopenharmony_ci SHORTPAIR(domlen), 66513498266Sopenharmony_ci SHORTPAIR(domoff), 66613498266Sopenharmony_ci 0x0, 0x0, 66713498266Sopenharmony_ci 66813498266Sopenharmony_ci SHORTPAIR(userlen), 66913498266Sopenharmony_ci SHORTPAIR(userlen), 67013498266Sopenharmony_ci SHORTPAIR(useroff), 67113498266Sopenharmony_ci 0x0, 0x0, 67213498266Sopenharmony_ci 67313498266Sopenharmony_ci SHORTPAIR(hostlen), 67413498266Sopenharmony_ci SHORTPAIR(hostlen), 67513498266Sopenharmony_ci SHORTPAIR(hostoff), 67613498266Sopenharmony_ci 0x0, 0x0, 67713498266Sopenharmony_ci 67813498266Sopenharmony_ci 0x0, 0x0, 67913498266Sopenharmony_ci 0x0, 0x0, 68013498266Sopenharmony_ci 0x0, 0x0, 68113498266Sopenharmony_ci 0x0, 0x0, 68213498266Sopenharmony_ci 68313498266Sopenharmony_ci LONGQUARTET(ntlm->flags)); 68413498266Sopenharmony_ci 68513498266Sopenharmony_ci DEBUGASSERT(size == 64); 68613498266Sopenharmony_ci DEBUGASSERT(size == (size_t)lmrespoff); 68713498266Sopenharmony_ci 68813498266Sopenharmony_ci /* We append the binary hashes */ 68913498266Sopenharmony_ci if(size < (NTLM_BUFSIZE - 0x18)) { 69013498266Sopenharmony_ci memcpy(&ntlmbuf[size], lmresp, 0x18); 69113498266Sopenharmony_ci size += 0x18; 69213498266Sopenharmony_ci } 69313498266Sopenharmony_ci 69413498266Sopenharmony_ci DEBUG_OUT({ 69513498266Sopenharmony_ci fprintf(stderr, "**** TYPE3 header lmresp="); 69613498266Sopenharmony_ci ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); 69713498266Sopenharmony_ci }); 69813498266Sopenharmony_ci 69913498266Sopenharmony_ci /* ntresplen + size should not be risking an integer overflow here */ 70013498266Sopenharmony_ci if(ntresplen + size > sizeof(ntlmbuf)) { 70113498266Sopenharmony_ci failf(data, "incoming NTLM message too big"); 70213498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 70313498266Sopenharmony_ci } 70413498266Sopenharmony_ci DEBUGASSERT(size == (size_t)ntrespoff); 70513498266Sopenharmony_ci memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen); 70613498266Sopenharmony_ci size += ntresplen; 70713498266Sopenharmony_ci 70813498266Sopenharmony_ci DEBUG_OUT({ 70913498266Sopenharmony_ci fprintf(stderr, "\n ntresp="); 71013498266Sopenharmony_ci ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen); 71113498266Sopenharmony_ci }); 71213498266Sopenharmony_ci 71313498266Sopenharmony_ci free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */ 71413498266Sopenharmony_ci 71513498266Sopenharmony_ci DEBUG_OUT({ 71613498266Sopenharmony_ci fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", 71713498266Sopenharmony_ci LONGQUARTET(ntlm->flags), ntlm->flags); 71813498266Sopenharmony_ci ntlm_print_flags(stderr, ntlm->flags); 71913498266Sopenharmony_ci fprintf(stderr, "\n****\n"); 72013498266Sopenharmony_ci }); 72113498266Sopenharmony_ci 72213498266Sopenharmony_ci /* Make sure that the domain, user and host strings fit in the 72313498266Sopenharmony_ci buffer before we copy them there. */ 72413498266Sopenharmony_ci if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) { 72513498266Sopenharmony_ci failf(data, "user + domain + host name too big"); 72613498266Sopenharmony_ci return CURLE_OUT_OF_MEMORY; 72713498266Sopenharmony_ci } 72813498266Sopenharmony_ci 72913498266Sopenharmony_ci DEBUGASSERT(size == domoff); 73013498266Sopenharmony_ci if(unicode) 73113498266Sopenharmony_ci unicodecpy(&ntlmbuf[size], domain, domlen / 2); 73213498266Sopenharmony_ci else 73313498266Sopenharmony_ci memcpy(&ntlmbuf[size], domain, domlen); 73413498266Sopenharmony_ci 73513498266Sopenharmony_ci size += domlen; 73613498266Sopenharmony_ci 73713498266Sopenharmony_ci DEBUGASSERT(size == useroff); 73813498266Sopenharmony_ci if(unicode) 73913498266Sopenharmony_ci unicodecpy(&ntlmbuf[size], user, userlen / 2); 74013498266Sopenharmony_ci else 74113498266Sopenharmony_ci memcpy(&ntlmbuf[size], user, userlen); 74213498266Sopenharmony_ci 74313498266Sopenharmony_ci size += userlen; 74413498266Sopenharmony_ci 74513498266Sopenharmony_ci DEBUGASSERT(size == hostoff); 74613498266Sopenharmony_ci if(unicode) 74713498266Sopenharmony_ci unicodecpy(&ntlmbuf[size], host, hostlen / 2); 74813498266Sopenharmony_ci else 74913498266Sopenharmony_ci memcpy(&ntlmbuf[size], host, hostlen); 75013498266Sopenharmony_ci 75113498266Sopenharmony_ci size += hostlen; 75213498266Sopenharmony_ci 75313498266Sopenharmony_ci /* Return the binary blob. */ 75413498266Sopenharmony_ci result = Curl_bufref_memdup(out, ntlmbuf, size); 75513498266Sopenharmony_ci 75613498266Sopenharmony_ci Curl_auth_cleanup_ntlm(ntlm); 75713498266Sopenharmony_ci 75813498266Sopenharmony_ci return result; 75913498266Sopenharmony_ci} 76013498266Sopenharmony_ci 76113498266Sopenharmony_ci/* 76213498266Sopenharmony_ci * Curl_auth_cleanup_ntlm() 76313498266Sopenharmony_ci * 76413498266Sopenharmony_ci * This is used to clean up the NTLM specific data. 76513498266Sopenharmony_ci * 76613498266Sopenharmony_ci * Parameters: 76713498266Sopenharmony_ci * 76813498266Sopenharmony_ci * ntlm [in/out] - The NTLM data struct being cleaned up. 76913498266Sopenharmony_ci * 77013498266Sopenharmony_ci */ 77113498266Sopenharmony_civoid Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm) 77213498266Sopenharmony_ci{ 77313498266Sopenharmony_ci /* Free the target info */ 77413498266Sopenharmony_ci Curl_safefree(ntlm->target_info); 77513498266Sopenharmony_ci 77613498266Sopenharmony_ci /* Reset any variables */ 77713498266Sopenharmony_ci ntlm->target_info_len = 0; 77813498266Sopenharmony_ci} 77913498266Sopenharmony_ci 78013498266Sopenharmony_ci#endif /* USE_NTLM && !USE_WINDOWS_SSPI */ 781