xref: /aosp_15_r20/external/curl/lib/vauth/ntlm.c (revision 6236dae45794135f37c4eb022389c904c8b0090d)
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