1*6236dae4SAndroid Build Coastguard Worker /***************************************************************************
2*6236dae4SAndroid Build Coastguard Worker * _ _ ____ _
3*6236dae4SAndroid Build Coastguard Worker * Project ___| | | | _ \| |
4*6236dae4SAndroid Build Coastguard Worker * / __| | | | |_) | |
5*6236dae4SAndroid Build Coastguard Worker * | (__| |_| | _ <| |___
6*6236dae4SAndroid Build Coastguard Worker * \___|\___/|_| \_\_____|
7*6236dae4SAndroid Build Coastguard Worker *
8*6236dae4SAndroid Build Coastguard Worker * Copyright (C) Daniel Stenberg, <[email protected]>, et al.
9*6236dae4SAndroid Build Coastguard Worker *
10*6236dae4SAndroid Build Coastguard Worker * This software is licensed as described in the file COPYING, which
11*6236dae4SAndroid Build Coastguard Worker * you should have received as part of this distribution. The terms
12*6236dae4SAndroid Build Coastguard Worker * are also available at https://curl.se/docs/copyright.html.
13*6236dae4SAndroid Build Coastguard Worker *
14*6236dae4SAndroid Build Coastguard Worker * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15*6236dae4SAndroid Build Coastguard Worker * copies of the Software, and permit persons to whom the Software is
16*6236dae4SAndroid Build Coastguard Worker * furnished to do so, under the terms of the COPYING file.
17*6236dae4SAndroid Build Coastguard Worker *
18*6236dae4SAndroid Build Coastguard Worker * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19*6236dae4SAndroid Build Coastguard Worker * KIND, either express or implied.
20*6236dae4SAndroid Build Coastguard Worker *
21*6236dae4SAndroid Build Coastguard Worker * SPDX-License-Identifier: curl
22*6236dae4SAndroid Build Coastguard Worker *
23*6236dae4SAndroid Build Coastguard Worker ***************************************************************************/
24*6236dae4SAndroid Build Coastguard Worker
25*6236dae4SAndroid Build Coastguard Worker #include "curl_setup.h"
26*6236dae4SAndroid Build Coastguard Worker
27*6236dae4SAndroid Build Coastguard Worker #if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
28*6236dae4SAndroid Build Coastguard Worker
29*6236dae4SAndroid Build Coastguard Worker /*
30*6236dae4SAndroid Build Coastguard Worker * NTLM details:
31*6236dae4SAndroid Build Coastguard Worker *
32*6236dae4SAndroid Build Coastguard Worker * https://davenport.sourceforge.net/ntlm.html
33*6236dae4SAndroid Build Coastguard Worker * https://www.innovation.ch/java/ntlm.html
34*6236dae4SAndroid Build Coastguard Worker */
35*6236dae4SAndroid Build Coastguard Worker
36*6236dae4SAndroid Build Coastguard Worker #define DEBUG_ME 0
37*6236dae4SAndroid Build Coastguard Worker
38*6236dae4SAndroid Build Coastguard Worker #include "urldata.h"
39*6236dae4SAndroid Build Coastguard Worker #include "sendf.h"
40*6236dae4SAndroid Build Coastguard Worker #include "curl_ntlm_core.h"
41*6236dae4SAndroid Build Coastguard Worker #include "curl_gethostname.h"
42*6236dae4SAndroid Build Coastguard Worker #include "curl_multibyte.h"
43*6236dae4SAndroid Build Coastguard Worker #include "curl_md5.h"
44*6236dae4SAndroid Build Coastguard Worker #include "warnless.h"
45*6236dae4SAndroid Build Coastguard Worker #include "rand.h"
46*6236dae4SAndroid Build Coastguard Worker #include "vtls/vtls.h"
47*6236dae4SAndroid Build Coastguard Worker #include "strdup.h"
48*6236dae4SAndroid Build Coastguard Worker
49*6236dae4SAndroid Build Coastguard Worker #define BUILDING_CURL_NTLM_MSGS_C
50*6236dae4SAndroid Build Coastguard Worker #include "vauth/vauth.h"
51*6236dae4SAndroid Build Coastguard Worker #include "vauth/ntlm.h"
52*6236dae4SAndroid Build Coastguard Worker #include "curl_endian.h"
53*6236dae4SAndroid Build Coastguard Worker #include "curl_printf.h"
54*6236dae4SAndroid Build Coastguard Worker
55*6236dae4SAndroid Build Coastguard Worker /* The last #include files should be: */
56*6236dae4SAndroid Build Coastguard Worker #include "curl_memory.h"
57*6236dae4SAndroid Build Coastguard Worker #include "memdebug.h"
58*6236dae4SAndroid Build Coastguard Worker
59*6236dae4SAndroid Build Coastguard Worker /* "NTLMSSP" signature is always in ASCII regardless of the platform */
60*6236dae4SAndroid Build Coastguard Worker #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
61*6236dae4SAndroid Build Coastguard Worker
62*6236dae4SAndroid Build Coastguard Worker #if DEBUG_ME
63*6236dae4SAndroid Build Coastguard Worker # define DEBUG_OUT(x) x
ntlm_print_flags(FILE * handle,unsigned long flags)64*6236dae4SAndroid Build Coastguard Worker static void ntlm_print_flags(FILE *handle, unsigned long flags)
65*6236dae4SAndroid Build Coastguard Worker {
66*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
67*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
68*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_OEM)
69*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
70*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_REQUEST_TARGET)
71*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
72*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 3))
73*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
74*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_SIGN)
75*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
76*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_SEAL)
77*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
78*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
79*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
80*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
81*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
82*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
83*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
84*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 10))
85*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
86*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
87*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
88*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
89*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
90*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
91*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
92*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
93*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
94*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
95*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
96*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
97*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
98*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
99*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
100*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
101*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
102*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
103*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
104*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
105*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
106*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
107*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
108*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
109*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
110*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
111*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
112*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 24))
113*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
114*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 25))
115*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
116*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 26))
117*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
118*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 27))
119*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
120*6236dae4SAndroid Build Coastguard Worker if(flags & (1 << 28))
121*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
122*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_128)
123*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
124*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
125*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
126*6236dae4SAndroid Build Coastguard Worker if(flags & NTLMFLAG_NEGOTIATE_56)
127*6236dae4SAndroid Build Coastguard Worker fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
128*6236dae4SAndroid Build Coastguard Worker }
129*6236dae4SAndroid Build Coastguard Worker
ntlm_print_hex(FILE * handle,const char * buf,size_t len)130*6236dae4SAndroid Build Coastguard Worker static void ntlm_print_hex(FILE *handle, const char *buf, size_t len)
131*6236dae4SAndroid Build Coastguard Worker {
132*6236dae4SAndroid Build Coastguard Worker const char *p = buf;
133*6236dae4SAndroid Build Coastguard Worker
134*6236dae4SAndroid Build Coastguard Worker (void) handle;
135*6236dae4SAndroid Build Coastguard Worker
136*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "0x");
137*6236dae4SAndroid Build Coastguard Worker while(len-- > 0)
138*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "%02.2x", (unsigned int)*p++);
139*6236dae4SAndroid Build Coastguard Worker }
140*6236dae4SAndroid Build Coastguard Worker #else
141*6236dae4SAndroid Build Coastguard Worker # define DEBUG_OUT(x) Curl_nop_stmt
142*6236dae4SAndroid Build Coastguard Worker #endif
143*6236dae4SAndroid Build Coastguard Worker
144*6236dae4SAndroid Build Coastguard Worker /*
145*6236dae4SAndroid Build Coastguard Worker * ntlm_decode_type2_target()
146*6236dae4SAndroid Build Coastguard Worker *
147*6236dae4SAndroid Build Coastguard Worker * This is used to decode the "target info" in the NTLM type-2 message
148*6236dae4SAndroid Build Coastguard Worker * received.
149*6236dae4SAndroid Build Coastguard Worker *
150*6236dae4SAndroid Build Coastguard Worker * Parameters:
151*6236dae4SAndroid Build Coastguard Worker *
152*6236dae4SAndroid Build Coastguard Worker * data [in] - The session handle.
153*6236dae4SAndroid Build Coastguard Worker * type2ref [in] - The type-2 message.
154*6236dae4SAndroid Build Coastguard Worker * ntlm [in/out] - The NTLM data struct being used and modified.
155*6236dae4SAndroid Build Coastguard Worker *
156*6236dae4SAndroid Build Coastguard Worker * Returns CURLE_OK on success.
157*6236dae4SAndroid Build Coastguard Worker */
ntlm_decode_type2_target(struct Curl_easy * data,const struct bufref * type2ref,struct ntlmdata * ntlm)158*6236dae4SAndroid Build Coastguard Worker static CURLcode ntlm_decode_type2_target(struct Curl_easy *data,
159*6236dae4SAndroid Build Coastguard Worker const struct bufref *type2ref,
160*6236dae4SAndroid Build Coastguard Worker struct ntlmdata *ntlm)
161*6236dae4SAndroid Build Coastguard Worker {
162*6236dae4SAndroid Build Coastguard Worker unsigned short target_info_len = 0;
163*6236dae4SAndroid Build Coastguard Worker unsigned int target_info_offset = 0;
164*6236dae4SAndroid Build Coastguard Worker const unsigned char *type2 = Curl_bufref_ptr(type2ref);
165*6236dae4SAndroid Build Coastguard Worker size_t type2len = Curl_bufref_len(type2ref);
166*6236dae4SAndroid Build Coastguard Worker
167*6236dae4SAndroid Build Coastguard Worker #if defined(CURL_DISABLE_VERBOSE_STRINGS)
168*6236dae4SAndroid Build Coastguard Worker (void) data;
169*6236dae4SAndroid Build Coastguard Worker #endif
170*6236dae4SAndroid Build Coastguard Worker
171*6236dae4SAndroid Build Coastguard Worker if(type2len >= 48) {
172*6236dae4SAndroid Build Coastguard Worker target_info_len = Curl_read16_le(&type2[40]);
173*6236dae4SAndroid Build Coastguard Worker target_info_offset = Curl_read32_le(&type2[44]);
174*6236dae4SAndroid Build Coastguard Worker if(target_info_len > 0) {
175*6236dae4SAndroid Build Coastguard Worker if((target_info_offset > type2len) ||
176*6236dae4SAndroid Build Coastguard Worker (target_info_offset + target_info_len) > type2len ||
177*6236dae4SAndroid Build Coastguard Worker target_info_offset < 48) {
178*6236dae4SAndroid Build Coastguard Worker infof(data, "NTLM handshake failure (bad type-2 message). "
179*6236dae4SAndroid Build Coastguard Worker "Target Info Offset Len is set incorrect by the peer");
180*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_CONTENT_ENCODING;
181*6236dae4SAndroid Build Coastguard Worker }
182*6236dae4SAndroid Build Coastguard Worker
183*6236dae4SAndroid Build Coastguard Worker free(ntlm->target_info); /* replace any previous data */
184*6236dae4SAndroid Build Coastguard Worker ntlm->target_info = Curl_memdup(&type2[target_info_offset],
185*6236dae4SAndroid Build Coastguard Worker target_info_len);
186*6236dae4SAndroid Build Coastguard Worker if(!ntlm->target_info)
187*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
188*6236dae4SAndroid Build Coastguard Worker }
189*6236dae4SAndroid Build Coastguard Worker }
190*6236dae4SAndroid Build Coastguard Worker
191*6236dae4SAndroid Build Coastguard Worker ntlm->target_info_len = target_info_len;
192*6236dae4SAndroid Build Coastguard Worker
193*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
194*6236dae4SAndroid Build Coastguard Worker }
195*6236dae4SAndroid Build Coastguard Worker
196*6236dae4SAndroid Build Coastguard Worker /*
197*6236dae4SAndroid Build Coastguard Worker NTLM message structure notes:
198*6236dae4SAndroid Build Coastguard Worker
199*6236dae4SAndroid Build Coastguard Worker A 'short' is a 'network short', a little-endian 16-bit unsigned value.
200*6236dae4SAndroid Build Coastguard Worker
201*6236dae4SAndroid Build Coastguard Worker A 'long' is a 'network long', a little-endian, 32-bit unsigned value.
202*6236dae4SAndroid Build Coastguard Worker
203*6236dae4SAndroid Build Coastguard Worker A 'security buffer' represents a triplet used to point to a buffer,
204*6236dae4SAndroid Build Coastguard Worker consisting of two shorts and one long:
205*6236dae4SAndroid Build Coastguard Worker
206*6236dae4SAndroid Build Coastguard Worker 1. A 'short' containing the length of the buffer content in bytes.
207*6236dae4SAndroid Build Coastguard Worker 2. A 'short' containing the allocated space for the buffer in bytes.
208*6236dae4SAndroid Build Coastguard Worker 3. A 'long' containing the offset to the start of the buffer in bytes,
209*6236dae4SAndroid Build Coastguard Worker from the beginning of the NTLM message.
210*6236dae4SAndroid Build Coastguard Worker */
211*6236dae4SAndroid Build Coastguard Worker
212*6236dae4SAndroid Build Coastguard Worker /*
213*6236dae4SAndroid Build Coastguard Worker * Curl_auth_is_ntlm_supported()
214*6236dae4SAndroid Build Coastguard Worker *
215*6236dae4SAndroid Build Coastguard Worker * This is used to evaluate if NTLM is supported.
216*6236dae4SAndroid Build Coastguard Worker *
217*6236dae4SAndroid Build Coastguard Worker * Parameters: None
218*6236dae4SAndroid Build Coastguard Worker *
219*6236dae4SAndroid Build Coastguard Worker * Returns TRUE as NTLM as handled by libcurl.
220*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_is_ntlm_supported(void)221*6236dae4SAndroid Build Coastguard Worker bool Curl_auth_is_ntlm_supported(void)
222*6236dae4SAndroid Build Coastguard Worker {
223*6236dae4SAndroid Build Coastguard Worker return TRUE;
224*6236dae4SAndroid Build Coastguard Worker }
225*6236dae4SAndroid Build Coastguard Worker
226*6236dae4SAndroid Build Coastguard Worker /*
227*6236dae4SAndroid Build Coastguard Worker * Curl_auth_decode_ntlm_type2_message()
228*6236dae4SAndroid Build Coastguard Worker *
229*6236dae4SAndroid Build Coastguard Worker * This is used to decode an NTLM type-2 message. The raw NTLM message is
230*6236dae4SAndroid Build Coastguard Worker * checked * for validity before the appropriate data for creating a type-3
231*6236dae4SAndroid Build Coastguard Worker * message is * written to the given NTLM data structure.
232*6236dae4SAndroid Build Coastguard Worker *
233*6236dae4SAndroid Build Coastguard Worker * Parameters:
234*6236dae4SAndroid Build Coastguard Worker *
235*6236dae4SAndroid Build Coastguard Worker * data [in] - The session handle.
236*6236dae4SAndroid Build Coastguard Worker * type2ref [in] - The type-2 message.
237*6236dae4SAndroid Build Coastguard Worker * ntlm [in/out] - The NTLM data struct being used and modified.
238*6236dae4SAndroid Build Coastguard Worker *
239*6236dae4SAndroid Build Coastguard Worker * Returns CURLE_OK on success.
240*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_decode_ntlm_type2_message(struct Curl_easy * data,const struct bufref * type2ref,struct ntlmdata * ntlm)241*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_auth_decode_ntlm_type2_message(struct Curl_easy *data,
242*6236dae4SAndroid Build Coastguard Worker const struct bufref *type2ref,
243*6236dae4SAndroid Build Coastguard Worker struct ntlmdata *ntlm)
244*6236dae4SAndroid Build Coastguard Worker {
245*6236dae4SAndroid Build Coastguard Worker static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
246*6236dae4SAndroid Build Coastguard Worker
247*6236dae4SAndroid Build Coastguard Worker /* NTLM type-2 message structure:
248*6236dae4SAndroid Build Coastguard Worker
249*6236dae4SAndroid Build Coastguard Worker Index Description Content
250*6236dae4SAndroid Build Coastguard Worker 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
251*6236dae4SAndroid Build Coastguard Worker (0x4e544c4d53535000)
252*6236dae4SAndroid Build Coastguard Worker 8 NTLM Message Type long (0x02000000)
253*6236dae4SAndroid Build Coastguard Worker 12 Target Name security buffer
254*6236dae4SAndroid Build Coastguard Worker 20 Flags long
255*6236dae4SAndroid Build Coastguard Worker 24 Challenge 8 bytes
256*6236dae4SAndroid Build Coastguard Worker (32) Context 8 bytes (two consecutive longs) (*)
257*6236dae4SAndroid Build Coastguard Worker (40) Target Information security buffer (*)
258*6236dae4SAndroid Build Coastguard Worker (48) OS Version Structure 8 bytes (*)
259*6236dae4SAndroid Build Coastguard Worker 32 (48) (56) Start of data block (*)
260*6236dae4SAndroid Build Coastguard Worker (*) -> Optional
261*6236dae4SAndroid Build Coastguard Worker */
262*6236dae4SAndroid Build Coastguard Worker
263*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
264*6236dae4SAndroid Build Coastguard Worker const unsigned char *type2 = Curl_bufref_ptr(type2ref);
265*6236dae4SAndroid Build Coastguard Worker size_t type2len = Curl_bufref_len(type2ref);
266*6236dae4SAndroid Build Coastguard Worker
267*6236dae4SAndroid Build Coastguard Worker #if defined(CURL_DISABLE_VERBOSE_STRINGS)
268*6236dae4SAndroid Build Coastguard Worker (void)data;
269*6236dae4SAndroid Build Coastguard Worker #endif
270*6236dae4SAndroid Build Coastguard Worker
271*6236dae4SAndroid Build Coastguard Worker ntlm->flags = 0;
272*6236dae4SAndroid Build Coastguard Worker
273*6236dae4SAndroid Build Coastguard Worker if((type2len < 32) ||
274*6236dae4SAndroid Build Coastguard Worker (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
275*6236dae4SAndroid Build Coastguard Worker (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
276*6236dae4SAndroid Build Coastguard Worker /* This was not a good enough type-2 message */
277*6236dae4SAndroid Build Coastguard Worker infof(data, "NTLM handshake failure (bad type-2 message)");
278*6236dae4SAndroid Build Coastguard Worker return CURLE_BAD_CONTENT_ENCODING;
279*6236dae4SAndroid Build Coastguard Worker }
280*6236dae4SAndroid Build Coastguard Worker
281*6236dae4SAndroid Build Coastguard Worker ntlm->flags = Curl_read32_le(&type2[20]);
282*6236dae4SAndroid Build Coastguard Worker memcpy(ntlm->nonce, &type2[24], 8);
283*6236dae4SAndroid Build Coastguard Worker
284*6236dae4SAndroid Build Coastguard Worker if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
285*6236dae4SAndroid Build Coastguard Worker result = ntlm_decode_type2_target(data, type2ref, ntlm);
286*6236dae4SAndroid Build Coastguard Worker if(result) {
287*6236dae4SAndroid Build Coastguard Worker infof(data, "NTLM handshake failure (bad type-2 message)");
288*6236dae4SAndroid Build Coastguard Worker return result;
289*6236dae4SAndroid Build Coastguard Worker }
290*6236dae4SAndroid Build Coastguard Worker }
291*6236dae4SAndroid Build Coastguard Worker
292*6236dae4SAndroid Build Coastguard Worker DEBUG_OUT({
293*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
294*6236dae4SAndroid Build Coastguard Worker ntlm_print_flags(stderr, ntlm->flags);
295*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n nonce=");
296*6236dae4SAndroid Build Coastguard Worker ntlm_print_hex(stderr, (char *)ntlm->nonce, 8);
297*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n****\n");
298*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "**** Header %s\n ", header);
299*6236dae4SAndroid Build Coastguard Worker });
300*6236dae4SAndroid Build Coastguard Worker
301*6236dae4SAndroid Build Coastguard Worker return result;
302*6236dae4SAndroid Build Coastguard Worker }
303*6236dae4SAndroid Build Coastguard Worker
304*6236dae4SAndroid Build Coastguard Worker /* copy the source to the destination and fill in zeroes in every
305*6236dae4SAndroid Build Coastguard Worker other destination byte! */
unicodecpy(unsigned char * dest,const char * src,size_t length)306*6236dae4SAndroid Build Coastguard Worker static void unicodecpy(unsigned char *dest, const char *src, size_t length)
307*6236dae4SAndroid Build Coastguard Worker {
308*6236dae4SAndroid Build Coastguard Worker size_t i;
309*6236dae4SAndroid Build Coastguard Worker for(i = 0; i < length; i++) {
310*6236dae4SAndroid Build Coastguard Worker dest[2 * i] = (unsigned char)src[i];
311*6236dae4SAndroid Build Coastguard Worker dest[2 * i + 1] = '\0';
312*6236dae4SAndroid Build Coastguard Worker }
313*6236dae4SAndroid Build Coastguard Worker }
314*6236dae4SAndroid Build Coastguard Worker
315*6236dae4SAndroid Build Coastguard Worker /*
316*6236dae4SAndroid Build Coastguard Worker * Curl_auth_create_ntlm_type1_message()
317*6236dae4SAndroid Build Coastguard Worker *
318*6236dae4SAndroid Build Coastguard Worker * This is used to generate an NTLM type-1 message ready for sending to the
319*6236dae4SAndroid Build Coastguard Worker * recipient using the appropriate compile time crypto API.
320*6236dae4SAndroid Build Coastguard Worker *
321*6236dae4SAndroid Build Coastguard Worker * Parameters:
322*6236dae4SAndroid Build Coastguard Worker *
323*6236dae4SAndroid Build Coastguard Worker * data [in] - The session handle.
324*6236dae4SAndroid Build Coastguard Worker * userp [in] - The username in the format User or Domain\User.
325*6236dae4SAndroid Build Coastguard Worker * passwdp [in] - The user's password.
326*6236dae4SAndroid Build Coastguard Worker * service [in] - The service type such as http, smtp, pop or imap.
327*6236dae4SAndroid Build Coastguard Worker * host [in] - The hostname.
328*6236dae4SAndroid Build Coastguard Worker * ntlm [in/out] - The NTLM data struct being used and modified.
329*6236dae4SAndroid Build Coastguard Worker * out [out] - The result storage.
330*6236dae4SAndroid Build Coastguard Worker *
331*6236dae4SAndroid Build Coastguard Worker * Returns CURLE_OK on success.
332*6236dae4SAndroid Build Coastguard Worker */
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,struct bufref * out)333*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_auth_create_ntlm_type1_message(struct Curl_easy *data,
334*6236dae4SAndroid Build Coastguard Worker const char *userp,
335*6236dae4SAndroid Build Coastguard Worker const char *passwdp,
336*6236dae4SAndroid Build Coastguard Worker const char *service,
337*6236dae4SAndroid Build Coastguard Worker const char *hostname,
338*6236dae4SAndroid Build Coastguard Worker struct ntlmdata *ntlm,
339*6236dae4SAndroid Build Coastguard Worker struct bufref *out)
340*6236dae4SAndroid Build Coastguard Worker {
341*6236dae4SAndroid Build Coastguard Worker /* NTLM type-1 message structure:
342*6236dae4SAndroid Build Coastguard Worker
343*6236dae4SAndroid Build Coastguard Worker Index Description Content
344*6236dae4SAndroid Build Coastguard Worker 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
345*6236dae4SAndroid Build Coastguard Worker (0x4e544c4d53535000)
346*6236dae4SAndroid Build Coastguard Worker 8 NTLM Message Type long (0x01000000)
347*6236dae4SAndroid Build Coastguard Worker 12 Flags long
348*6236dae4SAndroid Build Coastguard Worker (16) Supplied Domain security buffer (*)
349*6236dae4SAndroid Build Coastguard Worker (24) Supplied Workstation security buffer (*)
350*6236dae4SAndroid Build Coastguard Worker (32) OS Version Structure 8 bytes (*)
351*6236dae4SAndroid Build Coastguard Worker (32) (40) Start of data block (*)
352*6236dae4SAndroid Build Coastguard Worker (*) -> Optional
353*6236dae4SAndroid Build Coastguard Worker */
354*6236dae4SAndroid Build Coastguard Worker
355*6236dae4SAndroid Build Coastguard Worker size_t size;
356*6236dae4SAndroid Build Coastguard Worker
357*6236dae4SAndroid Build Coastguard Worker char *ntlmbuf;
358*6236dae4SAndroid Build Coastguard Worker const char *host = ""; /* empty */
359*6236dae4SAndroid Build Coastguard Worker const char *domain = ""; /* empty */
360*6236dae4SAndroid Build Coastguard Worker size_t hostlen = 0;
361*6236dae4SAndroid Build Coastguard Worker size_t domlen = 0;
362*6236dae4SAndroid Build Coastguard Worker size_t hostoff = 0;
363*6236dae4SAndroid Build Coastguard Worker size_t domoff = hostoff + hostlen; /* This is 0: remember that host and
364*6236dae4SAndroid Build Coastguard Worker domain are empty */
365*6236dae4SAndroid Build Coastguard Worker (void)data;
366*6236dae4SAndroid Build Coastguard Worker (void)userp;
367*6236dae4SAndroid Build Coastguard Worker (void)passwdp;
368*6236dae4SAndroid Build Coastguard Worker (void)service;
369*6236dae4SAndroid Build Coastguard Worker (void)hostname;
370*6236dae4SAndroid Build Coastguard Worker
371*6236dae4SAndroid Build Coastguard Worker /* Clean up any former leftovers and initialise to defaults */
372*6236dae4SAndroid Build Coastguard Worker Curl_auth_cleanup_ntlm(ntlm);
373*6236dae4SAndroid Build Coastguard Worker
374*6236dae4SAndroid Build Coastguard Worker ntlmbuf = aprintf(NTLMSSP_SIGNATURE "%c"
375*6236dae4SAndroid Build Coastguard Worker "\x01%c%c%c" /* 32-bit type = 1 */
376*6236dae4SAndroid Build Coastguard Worker "%c%c%c%c" /* 32-bit NTLM flag field */
377*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain length */
378*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain allocated space */
379*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain name offset */
380*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
381*6236dae4SAndroid Build Coastguard Worker "%c%c" /* host length */
382*6236dae4SAndroid Build Coastguard Worker "%c%c" /* host allocated space */
383*6236dae4SAndroid Build Coastguard Worker "%c%c" /* hostname offset */
384*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
385*6236dae4SAndroid Build Coastguard Worker "%s" /* hostname */
386*6236dae4SAndroid Build Coastguard Worker "%s", /* domain string */
387*6236dae4SAndroid Build Coastguard Worker 0, /* trailing zero */
388*6236dae4SAndroid Build Coastguard Worker 0, 0, 0, /* part of type-1 long */
389*6236dae4SAndroid Build Coastguard Worker
390*6236dae4SAndroid Build Coastguard Worker LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
391*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_REQUEST_TARGET |
392*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM_KEY |
393*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM2_KEY |
394*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
395*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domlen),
396*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domlen),
397*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domoff),
398*6236dae4SAndroid Build Coastguard Worker 0, 0,
399*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostlen),
400*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostlen),
401*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostoff),
402*6236dae4SAndroid Build Coastguard Worker 0, 0,
403*6236dae4SAndroid Build Coastguard Worker host, /* this is empty */
404*6236dae4SAndroid Build Coastguard Worker domain /* this is empty */);
405*6236dae4SAndroid Build Coastguard Worker
406*6236dae4SAndroid Build Coastguard Worker if(!ntlmbuf)
407*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
408*6236dae4SAndroid Build Coastguard Worker
409*6236dae4SAndroid Build Coastguard Worker /* Initial packet length */
410*6236dae4SAndroid Build Coastguard Worker size = 32 + hostlen + domlen;
411*6236dae4SAndroid Build Coastguard Worker
412*6236dae4SAndroid Build Coastguard Worker DEBUG_OUT({
413*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
414*6236dae4SAndroid Build Coastguard Worker "0x%08.8x ",
415*6236dae4SAndroid Build Coastguard Worker LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
416*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_REQUEST_TARGET |
417*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM_KEY |
418*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM2_KEY |
419*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
420*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_OEM |
421*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_REQUEST_TARGET |
422*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM_KEY |
423*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM2_KEY |
424*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
425*6236dae4SAndroid Build Coastguard Worker ntlm_print_flags(stderr,
426*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_OEM |
427*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_REQUEST_TARGET |
428*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM_KEY |
429*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_NTLM2_KEY |
430*6236dae4SAndroid Build Coastguard Worker NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
431*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n****\n");
432*6236dae4SAndroid Build Coastguard Worker });
433*6236dae4SAndroid Build Coastguard Worker
434*6236dae4SAndroid Build Coastguard Worker Curl_bufref_set(out, ntlmbuf, size, curl_free);
435*6236dae4SAndroid Build Coastguard Worker return CURLE_OK;
436*6236dae4SAndroid Build Coastguard Worker }
437*6236dae4SAndroid Build Coastguard Worker
438*6236dae4SAndroid Build Coastguard Worker /*
439*6236dae4SAndroid Build Coastguard Worker * Curl_auth_create_ntlm_type3_message()
440*6236dae4SAndroid Build Coastguard Worker *
441*6236dae4SAndroid Build Coastguard Worker * This is used to generate an already encoded NTLM type-3 message ready for
442*6236dae4SAndroid Build Coastguard Worker * sending to the recipient using the appropriate compile time crypto API.
443*6236dae4SAndroid Build Coastguard Worker *
444*6236dae4SAndroid Build Coastguard Worker * Parameters:
445*6236dae4SAndroid Build Coastguard Worker *
446*6236dae4SAndroid Build Coastguard Worker * data [in] - The session handle.
447*6236dae4SAndroid Build Coastguard Worker * userp [in] - The username in the format User or Domain\User.
448*6236dae4SAndroid Build Coastguard Worker * passwdp [in] - The user's password.
449*6236dae4SAndroid Build Coastguard Worker * ntlm [in/out] - The NTLM data struct being used and modified.
450*6236dae4SAndroid Build Coastguard Worker * out [out] - The result storage.
451*6236dae4SAndroid Build Coastguard Worker *
452*6236dae4SAndroid Build Coastguard Worker * Returns CURLE_OK on success.
453*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_create_ntlm_type3_message(struct Curl_easy * data,const char * userp,const char * passwdp,struct ntlmdata * ntlm,struct bufref * out)454*6236dae4SAndroid Build Coastguard Worker CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data,
455*6236dae4SAndroid Build Coastguard Worker const char *userp,
456*6236dae4SAndroid Build Coastguard Worker const char *passwdp,
457*6236dae4SAndroid Build Coastguard Worker struct ntlmdata *ntlm,
458*6236dae4SAndroid Build Coastguard Worker struct bufref *out)
459*6236dae4SAndroid Build Coastguard Worker {
460*6236dae4SAndroid Build Coastguard Worker /* NTLM type-3 message structure:
461*6236dae4SAndroid Build Coastguard Worker
462*6236dae4SAndroid Build Coastguard Worker Index Description Content
463*6236dae4SAndroid Build Coastguard Worker 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
464*6236dae4SAndroid Build Coastguard Worker (0x4e544c4d53535000)
465*6236dae4SAndroid Build Coastguard Worker 8 NTLM Message Type long (0x03000000)
466*6236dae4SAndroid Build Coastguard Worker 12 LM/LMv2 Response security buffer
467*6236dae4SAndroid Build Coastguard Worker 20 NTLM/NTLMv2 Response security buffer
468*6236dae4SAndroid Build Coastguard Worker 28 Target Name security buffer
469*6236dae4SAndroid Build Coastguard Worker 36 username security buffer
470*6236dae4SAndroid Build Coastguard Worker 44 Workstation Name security buffer
471*6236dae4SAndroid Build Coastguard Worker (52) Session Key security buffer (*)
472*6236dae4SAndroid Build Coastguard Worker (60) Flags long (*)
473*6236dae4SAndroid Build Coastguard Worker (64) OS Version Structure 8 bytes (*)
474*6236dae4SAndroid Build Coastguard Worker 52 (64) (72) Start of data block
475*6236dae4SAndroid Build Coastguard Worker (*) -> Optional
476*6236dae4SAndroid Build Coastguard Worker */
477*6236dae4SAndroid Build Coastguard Worker
478*6236dae4SAndroid Build Coastguard Worker CURLcode result = CURLE_OK;
479*6236dae4SAndroid Build Coastguard Worker size_t size;
480*6236dae4SAndroid Build Coastguard Worker unsigned char ntlmbuf[NTLM_BUFSIZE];
481*6236dae4SAndroid Build Coastguard Worker unsigned int lmrespoff;
482*6236dae4SAndroid Build Coastguard Worker unsigned char lmresp[24]; /* fixed-size */
483*6236dae4SAndroid Build Coastguard Worker unsigned int ntrespoff;
484*6236dae4SAndroid Build Coastguard Worker unsigned int ntresplen = 24;
485*6236dae4SAndroid Build Coastguard Worker unsigned char ntresp[24]; /* fixed-size */
486*6236dae4SAndroid Build Coastguard Worker unsigned char *ptr_ntresp = &ntresp[0];
487*6236dae4SAndroid Build Coastguard Worker unsigned char *ntlmv2resp = NULL;
488*6236dae4SAndroid Build Coastguard Worker bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE);
489*6236dae4SAndroid Build Coastguard Worker /* The fixed hostname we provide, in order to not leak our real local host
490*6236dae4SAndroid Build Coastguard Worker name. Copy the name used by Firefox. */
491*6236dae4SAndroid Build Coastguard Worker static const char host[] = "WORKSTATION";
492*6236dae4SAndroid Build Coastguard Worker const char *user;
493*6236dae4SAndroid Build Coastguard Worker const char *domain = "";
494*6236dae4SAndroid Build Coastguard Worker size_t hostoff = 0;
495*6236dae4SAndroid Build Coastguard Worker size_t useroff = 0;
496*6236dae4SAndroid Build Coastguard Worker size_t domoff = 0;
497*6236dae4SAndroid Build Coastguard Worker size_t hostlen = 0;
498*6236dae4SAndroid Build Coastguard Worker size_t userlen = 0;
499*6236dae4SAndroid Build Coastguard Worker size_t domlen = 0;
500*6236dae4SAndroid Build Coastguard Worker
501*6236dae4SAndroid Build Coastguard Worker memset(lmresp, 0, sizeof(lmresp));
502*6236dae4SAndroid Build Coastguard Worker memset(ntresp, 0, sizeof(ntresp));
503*6236dae4SAndroid Build Coastguard Worker user = strchr(userp, '\\');
504*6236dae4SAndroid Build Coastguard Worker if(!user)
505*6236dae4SAndroid Build Coastguard Worker user = strchr(userp, '/');
506*6236dae4SAndroid Build Coastguard Worker
507*6236dae4SAndroid Build Coastguard Worker if(user) {
508*6236dae4SAndroid Build Coastguard Worker domain = userp;
509*6236dae4SAndroid Build Coastguard Worker domlen = (user - domain);
510*6236dae4SAndroid Build Coastguard Worker user++;
511*6236dae4SAndroid Build Coastguard Worker }
512*6236dae4SAndroid Build Coastguard Worker else
513*6236dae4SAndroid Build Coastguard Worker user = userp;
514*6236dae4SAndroid Build Coastguard Worker
515*6236dae4SAndroid Build Coastguard Worker userlen = strlen(user);
516*6236dae4SAndroid Build Coastguard Worker hostlen = sizeof(host) - 1;
517*6236dae4SAndroid Build Coastguard Worker
518*6236dae4SAndroid Build Coastguard Worker if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
519*6236dae4SAndroid Build Coastguard Worker unsigned char ntbuffer[0x18];
520*6236dae4SAndroid Build Coastguard Worker unsigned char entropy[8];
521*6236dae4SAndroid Build Coastguard Worker unsigned char ntlmv2hash[0x18];
522*6236dae4SAndroid Build Coastguard Worker
523*6236dae4SAndroid Build Coastguard Worker /* Full NTLM version 2
524*6236dae4SAndroid Build Coastguard Worker Although this cannot be negotiated, it is used here if available, as
525*6236dae4SAndroid Build Coastguard Worker servers featuring extended security are likely supporting also
526*6236dae4SAndroid Build Coastguard Worker NTLMv2. */
527*6236dae4SAndroid Build Coastguard Worker result = Curl_rand(data, entropy, 8);
528*6236dae4SAndroid Build Coastguard Worker if(result)
529*6236dae4SAndroid Build Coastguard Worker return result;
530*6236dae4SAndroid Build Coastguard Worker
531*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer);
532*6236dae4SAndroid Build Coastguard Worker if(result)
533*6236dae4SAndroid Build Coastguard Worker return result;
534*6236dae4SAndroid Build Coastguard Worker
535*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
536*6236dae4SAndroid Build Coastguard Worker ntbuffer, ntlmv2hash);
537*6236dae4SAndroid Build Coastguard Worker if(result)
538*6236dae4SAndroid Build Coastguard Worker return result;
539*6236dae4SAndroid Build Coastguard Worker
540*6236dae4SAndroid Build Coastguard Worker /* LMv2 response */
541*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy,
542*6236dae4SAndroid Build Coastguard Worker &ntlm->nonce[0], lmresp);
543*6236dae4SAndroid Build Coastguard Worker if(result)
544*6236dae4SAndroid Build Coastguard Worker return result;
545*6236dae4SAndroid Build Coastguard Worker
546*6236dae4SAndroid Build Coastguard Worker /* NTLMv2 response */
547*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy,
548*6236dae4SAndroid Build Coastguard Worker ntlm, &ntlmv2resp, &ntresplen);
549*6236dae4SAndroid Build Coastguard Worker if(result)
550*6236dae4SAndroid Build Coastguard Worker return result;
551*6236dae4SAndroid Build Coastguard Worker
552*6236dae4SAndroid Build Coastguard Worker ptr_ntresp = ntlmv2resp;
553*6236dae4SAndroid Build Coastguard Worker }
554*6236dae4SAndroid Build Coastguard Worker else {
555*6236dae4SAndroid Build Coastguard Worker
556*6236dae4SAndroid Build Coastguard Worker unsigned char ntbuffer[0x18];
557*6236dae4SAndroid Build Coastguard Worker unsigned char lmbuffer[0x18];
558*6236dae4SAndroid Build Coastguard Worker
559*6236dae4SAndroid Build Coastguard Worker /* NTLM version 1 */
560*6236dae4SAndroid Build Coastguard Worker
561*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_nt_hash(passwdp, ntbuffer);
562*6236dae4SAndroid Build Coastguard Worker if(result)
563*6236dae4SAndroid Build Coastguard Worker return result;
564*6236dae4SAndroid Build Coastguard Worker
565*6236dae4SAndroid Build Coastguard Worker Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
566*6236dae4SAndroid Build Coastguard Worker
567*6236dae4SAndroid Build Coastguard Worker result = Curl_ntlm_core_mk_lm_hash(passwdp, lmbuffer);
568*6236dae4SAndroid Build Coastguard Worker if(result)
569*6236dae4SAndroid Build Coastguard Worker return result;
570*6236dae4SAndroid Build Coastguard Worker
571*6236dae4SAndroid Build Coastguard Worker Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
572*6236dae4SAndroid Build Coastguard Worker ntlm->flags &= ~(unsigned int)NTLMFLAG_NEGOTIATE_NTLM2_KEY;
573*6236dae4SAndroid Build Coastguard Worker
574*6236dae4SAndroid Build Coastguard Worker /* A safer but less compatible alternative is:
575*6236dae4SAndroid Build Coastguard Worker * Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
576*6236dae4SAndroid Build Coastguard Worker * See https://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
577*6236dae4SAndroid Build Coastguard Worker }
578*6236dae4SAndroid Build Coastguard Worker
579*6236dae4SAndroid Build Coastguard Worker if(unicode) {
580*6236dae4SAndroid Build Coastguard Worker domlen = domlen * 2;
581*6236dae4SAndroid Build Coastguard Worker userlen = userlen * 2;
582*6236dae4SAndroid Build Coastguard Worker hostlen = hostlen * 2;
583*6236dae4SAndroid Build Coastguard Worker }
584*6236dae4SAndroid Build Coastguard Worker
585*6236dae4SAndroid Build Coastguard Worker lmrespoff = 64; /* size of the message header */
586*6236dae4SAndroid Build Coastguard Worker ntrespoff = lmrespoff + 0x18;
587*6236dae4SAndroid Build Coastguard Worker domoff = ntrespoff + ntresplen;
588*6236dae4SAndroid Build Coastguard Worker useroff = domoff + domlen;
589*6236dae4SAndroid Build Coastguard Worker hostoff = useroff + userlen;
590*6236dae4SAndroid Build Coastguard Worker
591*6236dae4SAndroid Build Coastguard Worker /* Create the big type-3 message binary blob */
592*6236dae4SAndroid Build Coastguard Worker size = msnprintf((char *)ntlmbuf, NTLM_BUFSIZE,
593*6236dae4SAndroid Build Coastguard Worker NTLMSSP_SIGNATURE "%c"
594*6236dae4SAndroid Build Coastguard Worker "\x03%c%c%c" /* 32-bit type = 3 */
595*6236dae4SAndroid Build Coastguard Worker
596*6236dae4SAndroid Build Coastguard Worker "%c%c" /* LanManager length */
597*6236dae4SAndroid Build Coastguard Worker "%c%c" /* LanManager allocated space */
598*6236dae4SAndroid Build Coastguard Worker "%c%c" /* LanManager offset */
599*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
600*6236dae4SAndroid Build Coastguard Worker
601*6236dae4SAndroid Build Coastguard Worker "%c%c" /* NT-response length */
602*6236dae4SAndroid Build Coastguard Worker "%c%c" /* NT-response allocated space */
603*6236dae4SAndroid Build Coastguard Worker "%c%c" /* NT-response offset */
604*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
605*6236dae4SAndroid Build Coastguard Worker
606*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain length */
607*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain allocated space */
608*6236dae4SAndroid Build Coastguard Worker "%c%c" /* domain name offset */
609*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
610*6236dae4SAndroid Build Coastguard Worker
611*6236dae4SAndroid Build Coastguard Worker "%c%c" /* user length */
612*6236dae4SAndroid Build Coastguard Worker "%c%c" /* user allocated space */
613*6236dae4SAndroid Build Coastguard Worker "%c%c" /* user offset */
614*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
615*6236dae4SAndroid Build Coastguard Worker
616*6236dae4SAndroid Build Coastguard Worker "%c%c" /* host length */
617*6236dae4SAndroid Build Coastguard Worker "%c%c" /* host allocated space */
618*6236dae4SAndroid Build Coastguard Worker "%c%c" /* host offset */
619*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
620*6236dae4SAndroid Build Coastguard Worker
621*6236dae4SAndroid Build Coastguard Worker "%c%c" /* session key length (unknown purpose) */
622*6236dae4SAndroid Build Coastguard Worker "%c%c" /* session key allocated space (unknown purpose) */
623*6236dae4SAndroid Build Coastguard Worker "%c%c" /* session key offset (unknown purpose) */
624*6236dae4SAndroid Build Coastguard Worker "%c%c" /* 2 zeroes */
625*6236dae4SAndroid Build Coastguard Worker
626*6236dae4SAndroid Build Coastguard Worker "%c%c%c%c", /* flags */
627*6236dae4SAndroid Build Coastguard Worker
628*6236dae4SAndroid Build Coastguard Worker /* domain string */
629*6236dae4SAndroid Build Coastguard Worker /* user string */
630*6236dae4SAndroid Build Coastguard Worker /* host string */
631*6236dae4SAndroid Build Coastguard Worker /* LanManager response */
632*6236dae4SAndroid Build Coastguard Worker /* NT response */
633*6236dae4SAndroid Build Coastguard Worker
634*6236dae4SAndroid Build Coastguard Worker 0, /* null-termination */
635*6236dae4SAndroid Build Coastguard Worker 0, 0, 0, /* type-3 long, the 24 upper bits */
636*6236dae4SAndroid Build Coastguard Worker
637*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(0x18), /* LanManager response length, twice */
638*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(0x18),
639*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(lmrespoff),
640*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
641*6236dae4SAndroid Build Coastguard Worker
642*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(ntresplen), /* NT-response length, twice */
643*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(ntresplen),
644*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(ntrespoff),
645*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
646*6236dae4SAndroid Build Coastguard Worker
647*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domlen),
648*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domlen),
649*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(domoff),
650*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
651*6236dae4SAndroid Build Coastguard Worker
652*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(userlen),
653*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(userlen),
654*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(useroff),
655*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
656*6236dae4SAndroid Build Coastguard Worker
657*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostlen),
658*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostlen),
659*6236dae4SAndroid Build Coastguard Worker SHORTPAIR(hostoff),
660*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
661*6236dae4SAndroid Build Coastguard Worker
662*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
663*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
664*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
665*6236dae4SAndroid Build Coastguard Worker 0x0, 0x0,
666*6236dae4SAndroid Build Coastguard Worker
667*6236dae4SAndroid Build Coastguard Worker LONGQUARTET(ntlm->flags));
668*6236dae4SAndroid Build Coastguard Worker
669*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == 64);
670*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == (size_t)lmrespoff);
671*6236dae4SAndroid Build Coastguard Worker
672*6236dae4SAndroid Build Coastguard Worker /* We append the binary hashes */
673*6236dae4SAndroid Build Coastguard Worker if(size < (NTLM_BUFSIZE - 0x18)) {
674*6236dae4SAndroid Build Coastguard Worker memcpy(&ntlmbuf[size], lmresp, 0x18);
675*6236dae4SAndroid Build Coastguard Worker size += 0x18;
676*6236dae4SAndroid Build Coastguard Worker }
677*6236dae4SAndroid Build Coastguard Worker
678*6236dae4SAndroid Build Coastguard Worker DEBUG_OUT({
679*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "**** TYPE3 header lmresp=");
680*6236dae4SAndroid Build Coastguard Worker ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
681*6236dae4SAndroid Build Coastguard Worker });
682*6236dae4SAndroid Build Coastguard Worker
683*6236dae4SAndroid Build Coastguard Worker /* ntresplen + size should not be risking an integer overflow here */
684*6236dae4SAndroid Build Coastguard Worker if(ntresplen + size > sizeof(ntlmbuf)) {
685*6236dae4SAndroid Build Coastguard Worker failf(data, "incoming NTLM message too big");
686*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
687*6236dae4SAndroid Build Coastguard Worker }
688*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == (size_t)ntrespoff);
689*6236dae4SAndroid Build Coastguard Worker memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
690*6236dae4SAndroid Build Coastguard Worker size += ntresplen;
691*6236dae4SAndroid Build Coastguard Worker
692*6236dae4SAndroid Build Coastguard Worker DEBUG_OUT({
693*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n ntresp=");
694*6236dae4SAndroid Build Coastguard Worker ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
695*6236dae4SAndroid Build Coastguard Worker });
696*6236dae4SAndroid Build Coastguard Worker
697*6236dae4SAndroid Build Coastguard Worker free(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
698*6236dae4SAndroid Build Coastguard Worker
699*6236dae4SAndroid Build Coastguard Worker DEBUG_OUT({
700*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
701*6236dae4SAndroid Build Coastguard Worker LONGQUARTET(ntlm->flags), ntlm->flags);
702*6236dae4SAndroid Build Coastguard Worker ntlm_print_flags(stderr, ntlm->flags);
703*6236dae4SAndroid Build Coastguard Worker fprintf(stderr, "\n****\n");
704*6236dae4SAndroid Build Coastguard Worker });
705*6236dae4SAndroid Build Coastguard Worker
706*6236dae4SAndroid Build Coastguard Worker /* Make sure that the domain, user and host strings fit in the
707*6236dae4SAndroid Build Coastguard Worker buffer before we copy them there. */
708*6236dae4SAndroid Build Coastguard Worker if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
709*6236dae4SAndroid Build Coastguard Worker failf(data, "user + domain + hostname too big");
710*6236dae4SAndroid Build Coastguard Worker return CURLE_OUT_OF_MEMORY;
711*6236dae4SAndroid Build Coastguard Worker }
712*6236dae4SAndroid Build Coastguard Worker
713*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == domoff);
714*6236dae4SAndroid Build Coastguard Worker if(unicode)
715*6236dae4SAndroid Build Coastguard Worker unicodecpy(&ntlmbuf[size], domain, domlen / 2);
716*6236dae4SAndroid Build Coastguard Worker else
717*6236dae4SAndroid Build Coastguard Worker memcpy(&ntlmbuf[size], domain, domlen);
718*6236dae4SAndroid Build Coastguard Worker
719*6236dae4SAndroid Build Coastguard Worker size += domlen;
720*6236dae4SAndroid Build Coastguard Worker
721*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == useroff);
722*6236dae4SAndroid Build Coastguard Worker if(unicode)
723*6236dae4SAndroid Build Coastguard Worker unicodecpy(&ntlmbuf[size], user, userlen / 2);
724*6236dae4SAndroid Build Coastguard Worker else
725*6236dae4SAndroid Build Coastguard Worker memcpy(&ntlmbuf[size], user, userlen);
726*6236dae4SAndroid Build Coastguard Worker
727*6236dae4SAndroid Build Coastguard Worker size += userlen;
728*6236dae4SAndroid Build Coastguard Worker
729*6236dae4SAndroid Build Coastguard Worker DEBUGASSERT(size == hostoff);
730*6236dae4SAndroid Build Coastguard Worker if(unicode)
731*6236dae4SAndroid Build Coastguard Worker unicodecpy(&ntlmbuf[size], host, hostlen / 2);
732*6236dae4SAndroid Build Coastguard Worker else
733*6236dae4SAndroid Build Coastguard Worker memcpy(&ntlmbuf[size], host, hostlen);
734*6236dae4SAndroid Build Coastguard Worker
735*6236dae4SAndroid Build Coastguard Worker size += hostlen;
736*6236dae4SAndroid Build Coastguard Worker
737*6236dae4SAndroid Build Coastguard Worker /* Return the binary blob. */
738*6236dae4SAndroid Build Coastguard Worker result = Curl_bufref_memdup(out, ntlmbuf, size);
739*6236dae4SAndroid Build Coastguard Worker
740*6236dae4SAndroid Build Coastguard Worker Curl_auth_cleanup_ntlm(ntlm);
741*6236dae4SAndroid Build Coastguard Worker
742*6236dae4SAndroid Build Coastguard Worker return result;
743*6236dae4SAndroid Build Coastguard Worker }
744*6236dae4SAndroid Build Coastguard Worker
745*6236dae4SAndroid Build Coastguard Worker /*
746*6236dae4SAndroid Build Coastguard Worker * Curl_auth_cleanup_ntlm()
747*6236dae4SAndroid Build Coastguard Worker *
748*6236dae4SAndroid Build Coastguard Worker * This is used to clean up the NTLM specific data.
749*6236dae4SAndroid Build Coastguard Worker *
750*6236dae4SAndroid Build Coastguard Worker * Parameters:
751*6236dae4SAndroid Build Coastguard Worker *
752*6236dae4SAndroid Build Coastguard Worker * ntlm [in/out] - The NTLM data struct being cleaned up.
753*6236dae4SAndroid Build Coastguard Worker *
754*6236dae4SAndroid Build Coastguard Worker */
Curl_auth_cleanup_ntlm(struct ntlmdata * ntlm)755*6236dae4SAndroid Build Coastguard Worker void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm)
756*6236dae4SAndroid Build Coastguard Worker {
757*6236dae4SAndroid Build Coastguard Worker /* Free the target info */
758*6236dae4SAndroid Build Coastguard Worker Curl_safefree(ntlm->target_info);
759*6236dae4SAndroid Build Coastguard Worker
760*6236dae4SAndroid Build Coastguard Worker /* Reset any variables */
761*6236dae4SAndroid Build Coastguard Worker ntlm->target_info_len = 0;
762*6236dae4SAndroid Build Coastguard Worker }
763*6236dae4SAndroid Build Coastguard Worker
764*6236dae4SAndroid Build Coastguard Worker #endif /* USE_NTLM && !USE_WINDOWS_SSPI */
765