1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at http://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 #include "setup.h"
23 
24 /* NTLM details:
25 
26    http://davenport.sourceforge.net/ntlm.html
27    http://www.innovation.ch/java/ntlm.html
28 
29    Another implementation:
30    http://lxr.mozilla.org/mozilla/source/security/manager/ssl/src/nsNTLMAuthModule.cpp
31 
32 */
33 
34 #ifndef CURL_DISABLE_HTTP
35 #ifdef USE_NTLM
36 
37 #define DEBUG_ME 0
38 
39 /* -- WIN32 approved -- */
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdarg.h>
43 #include <stdlib.h>
44 #include <ctype.h>
45 
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49 
50 #if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
51 #include <netdb.h>
52 #endif
53 
54 #include "urldata.h"
55 #include "non-ascii.h"  /* for Curl_convert_... prototypes */
56 #include "sendf.h"
57 #include "rawstr.h"
58 #include "curl_base64.h"
59 #include "http_ntlm.h"
60 #include "url.h"
61 #include "curl_gethostname.h"
62 #include "curl_memory.h"
63 
64 #define _MPRINTF_REPLACE /* use our functions only */
65 #include <curl/mprintf.h>
66 
67 /* "NTLMSSP" signature is always in ASCII regardless of the platform */
68 #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
69 
70 #ifdef USE_SSLEAY
71 #include "ssluse.h"
72 #    ifdef USE_OPENSSL
73 #      include <openssl/des.h>
74 #      ifndef OPENSSL_NO_MD4
75 #        include <openssl/md4.h>
76 #      endif
77 #      include <openssl/md5.h>
78 #      include <openssl/ssl.h>
79 #      include <openssl/rand.h>
80 #    else
81 #      include <des.h>
82 #      ifndef OPENSSL_NO_MD4
83 #        include <md4.h>
84 #      endif
85 #      include <md5.h>
86 #      include <ssl.h>
87 #      include <rand.h>
88 #    endif
89 
90 #if OPENSSL_VERSION_NUMBER < 0x00907001L
91 #define DES_key_schedule des_key_schedule
92 #define DES_cblock des_cblock
93 #define DES_set_odd_parity des_set_odd_parity
94 #define DES_set_key des_set_key
95 #define DES_ecb_encrypt des_ecb_encrypt
96 
97 /* This is how things were done in the old days */
98 #define DESKEY(x) x
99 #define DESKEYARG(x) x
100 #else
101 /* Modern version */
102 #define DESKEYARG(x) *x
103 #define DESKEY(x) &x
104 #endif
105 
106 #ifdef OPENSSL_NO_MD4
107 /* This requires MD4, but OpenSSL was compiled without it */
108 #define USE_NTRESPONSES 0
109 #define USE_NTLM2SESSION 0
110 #endif
111 
112 #elif defined(USE_GNUTLS)
113 
114 #include "gtls.h"
115 #include <gcrypt.h>
116 
117 #define MD5_DIGEST_LENGTH 16
118 #define MD4_DIGEST_LENGTH 16
119 
120 #elif defined(USE_NSS)
121 
122 #include "curl_md4.h"
123 #include "nssg.h"
124 #include <nss.h>
125 #include <pk11pub.h>
126 #include <hasht.h>
127 #define MD5_DIGEST_LENGTH MD5_LENGTH
128 
129 #elif defined(USE_WINDOWS_SSPI)
130 
131 #include "curl_sspi.h"
132 
133 #else
134 #    error "Can't compile NTLM support without a crypto library."
135 #endif
136 
137 /* The last #include file should be: */
138 #include "memdebug.h"
139 
140 #ifndef USE_NTRESPONSES
141 /* Define this to make the type-3 message include the NT response message */
142 #define USE_NTRESPONSES 1
143 
144 /* Define this to make the type-3 message include the NTLM2Session response
145    message, requires USE_NTRESPONSES. */
146 #define USE_NTLM2SESSION 1
147 #endif
148 
149 #ifndef USE_WINDOWS_SSPI
150 /* this function converts from the little endian format used in the incoming
151    package to whatever endian format we're using natively */
readint_le(unsigned char * buf)152 static unsigned int readint_le(unsigned char *buf) /* must point to a
153                                                       4 bytes buffer*/
154 {
155   return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
156     ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
157 }
158 #endif
159 
160 #if DEBUG_ME
161 # define DEBUG_OUT(x) x
print_flags(FILE * handle,unsigned long flags)162 static void print_flags(FILE *handle, unsigned long flags)
163 {
164   if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
165     fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
166   if(flags & NTLMFLAG_NEGOTIATE_OEM)
167     fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
168   if(flags & NTLMFLAG_REQUEST_TARGET)
169     fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
170   if(flags & (1<<3))
171     fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
172   if(flags & NTLMFLAG_NEGOTIATE_SIGN)
173     fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
174   if(flags & NTLMFLAG_NEGOTIATE_SEAL)
175     fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
176   if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
177     fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
178   if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
179     fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
180   if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
181     fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
182   if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
183     fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
184   if(flags & (1<<10))
185     fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
186   if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
187     fprintf(handle, "NTLMFLAG_NEGOTIATE_ANONYMOUS ");
188   if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
189     fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
190   if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
191     fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
192   if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
193     fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
194   if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
195     fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
196   if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
197     fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
198   if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
199     fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
200   if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
201     fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
202   if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
203     fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
204   if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
205     fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
206   if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
207     fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
208   if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
209     fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
210   if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
211     fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
212   if(flags & (1<<24))
213     fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
214   if(flags & (1<<25))
215     fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
216   if(flags & (1<<26))
217     fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
218   if(flags & (1<<27))
219     fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
220   if(flags & (1<<28))
221     fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
222   if(flags & NTLMFLAG_NEGOTIATE_128)
223     fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
224   if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
225     fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
226   if(flags & NTLMFLAG_NEGOTIATE_56)
227     fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
228 }
229 
print_hex(FILE * handle,const char * buf,size_t len)230 static void print_hex(FILE *handle, const char *buf, size_t len)
231 {
232   const char *p = buf;
233   fprintf(stderr, "0x");
234   while(len-- > 0)
235     fprintf(stderr, "%02.2x", (unsigned int)*p++);
236 }
237 #else
238 # define DEBUG_OUT(x)
239 #endif
240 
241 /*
242   (*) = A "security buffer" is a triplet consisting of two shorts and one
243   long:
244 
245   1. a 'short' containing the length of the buffer in bytes
246   2. a 'short' containing the allocated space for the buffer in bytes
247   3. a 'long' containing the offset to the start of the buffer from the
248      beginning of the NTLM message, in bytes.
249 */
250 
251 
Curl_input_ntlm(struct connectdata * conn,bool proxy,const char * header)252 CURLntlm Curl_input_ntlm(struct connectdata *conn,
253                          bool proxy,   /* if proxy or not */
254                          const char *header) /* rest of the www-authenticate:
255                                                 header */
256 {
257   /* point to the correct struct with this */
258   struct ntlmdata *ntlm;
259 #ifndef USE_WINDOWS_SSPI
260   static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
261 #endif
262 
263 #ifdef USE_NSS
264   if(CURLE_OK != Curl_nss_force_init(conn->data))
265     return CURLNTLM_BAD;
266 #endif
267 
268   ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
269 
270   /* skip initial whitespaces */
271   while(*header && ISSPACE(*header))
272     header++;
273 
274   if(checkprefix("NTLM", header)) {
275     header += strlen("NTLM");
276 
277     while(*header && ISSPACE(*header))
278       header++;
279 
280     if(*header) {
281       /* We got a type-2 message here:
282 
283          Index   Description         Content
284          0       NTLMSSP Signature   Null-terminated ASCII "NTLMSSP"
285                                      (0x4e544c4d53535000)
286          8       NTLM Message Type   long (0x02000000)
287          12      Target Name         security buffer(*)
288          20      Flags               long
289          24      Challenge           8 bytes
290          (32)    Context (optional)  8 bytes (two consecutive longs)
291          (40)    Target Information  (optional) security buffer(*)
292          32 (48) start of data block
293       */
294       size_t size;
295       unsigned char *buffer;
296       size = Curl_base64_decode(header, &buffer);
297       if(!buffer)
298         return CURLNTLM_BAD;
299 
300       ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
301 
302 #ifdef USE_WINDOWS_SSPI
303       ntlm->type_2 = malloc(size+1);
304       if(ntlm->type_2 == NULL) {
305         free(buffer);
306         return CURLE_OUT_OF_MEMORY;
307       }
308       ntlm->n_type_2 = size;
309       memcpy(ntlm->type_2, buffer, size);
310 #else
311       ntlm->flags = 0;
312 
313       if((size < 32) ||
314          (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
315          (memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
316         /* This was not a good enough type-2 message */
317         free(buffer);
318         return CURLNTLM_BAD;
319       }
320 
321       ntlm->flags = readint_le(&buffer[20]);
322       memcpy(ntlm->nonce, &buffer[24], 8);
323 
324       DEBUG_OUT({
325         fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
326         print_flags(stderr, ntlm->flags);
327         fprintf(stderr, "\n                  nonce=");
328         print_hex(stderr, (char *)ntlm->nonce, 8);
329         fprintf(stderr, "\n****\n");
330         fprintf(stderr, "**** Header %s\n ", header);
331       });
332 #endif
333       free(buffer);
334     }
335     else {
336       if(ntlm->state >= NTLMSTATE_TYPE1)
337         return CURLNTLM_BAD;
338 
339       ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
340     }
341   }
342   return CURLNTLM_FINE;
343 }
344 
345 #ifndef USE_WINDOWS_SSPI
346 
347 #ifdef USE_SSLEAY
348 /*
349  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
350  * key schedule ks is also set.
351  */
setup_des_key(const unsigned char * key_56,DES_key_schedule DESKEYARG (ks))352 static void setup_des_key(const unsigned char *key_56,
353                           DES_key_schedule DESKEYARG(ks))
354 {
355   DES_cblock key;
356 
357   key[0] = key_56[0];
358   key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
359   key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
360   key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
361   key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
362   key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
363   key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
364   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
365 
366   DES_set_odd_parity(&key);
367   DES_set_key(&key, ks);
368 }
369 
370 #else /* defined(USE_SSLEAY) */
371 
372 /*
373  * Turns a 56 bit key into the 64 bit, odd parity key.  Used by GnuTLS and NSS.
374  */
extend_key_56_to_64(const unsigned char * key_56,char * key)375 static void extend_key_56_to_64(const unsigned char *key_56, char *key)
376 {
377   key[0] = key_56[0];
378   key[1] = (unsigned char)(((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1));
379   key[2] = (unsigned char)(((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2));
380   key[3] = (unsigned char)(((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3));
381   key[4] = (unsigned char)(((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4));
382   key[5] = (unsigned char)(((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5));
383   key[6] = (unsigned char)(((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6));
384   key[7] = (unsigned char) ((key_56[6] << 1) & 0xFF);
385 }
386 
387 #if defined(USE_GNUTLS)
388 
389 /*
390  * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.
391  */
setup_des_key(const unsigned char * key_56,gcry_cipher_hd_t * des)392 static void setup_des_key(const unsigned char *key_56,
393                           gcry_cipher_hd_t *des)
394 {
395   char key[8];
396   extend_key_56_to_64(key_56, key);
397   gcry_cipher_setkey(*des, key, 8);
398 }
399 
400 #elif defined(USE_NSS)
401 
402 /*
403  * Expands a 56 bit key KEY_56 to 64 bit and encrypts 64 bit of data, using
404  * the expanded key.  The caller is responsible for giving 64 bit of valid
405  * data is IN and (at least) 64 bit large buffer as OUT.
406  */
encrypt_des(const unsigned char * in,unsigned char * out,const unsigned char * key_56)407 static bool encrypt_des(const unsigned char *in, unsigned char *out,
408                         const unsigned char *key_56)
409 {
410   const CK_MECHANISM_TYPE mech = CKM_DES_ECB; /* DES cipher in ECB mode */
411   PK11SlotInfo *slot = NULL;
412   char key[8];                                /* expanded 64 bit key */
413   SECItem key_item;
414   PK11SymKey *symkey = NULL;
415   SECItem *param = NULL;
416   PK11Context *ctx = NULL;
417   int out_len;                                /* not used, required by NSS */
418   bool rv = FALSE;
419 
420   /* use internal slot for DES encryption (requires NSS to be initialized) */
421   slot = PK11_GetInternalKeySlot();
422   if(!slot)
423     return FALSE;
424 
425   /* expand the 56 bit key to 64 bit and wrap by NSS */
426   extend_key_56_to_64(key_56, key);
427   key_item.data = (unsigned char *)key;
428   key_item.len = /* hard-wired */ 8;
429   symkey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_ENCRYPT,
430                              &key_item, NULL);
431   if(!symkey)
432     goto fail;
433 
434   /* create DES encryption context */
435   param = PK11_ParamFromIV(mech, /* no IV in ECB mode */ NULL);
436   if(!param)
437     goto fail;
438   ctx = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, symkey, param);
439   if(!ctx)
440     goto fail;
441 
442   /* perform the encryption */
443   if(SECSuccess == PK11_CipherOp(ctx, out, &out_len, /* outbuflen */ 8,
444                                  (unsigned char *)in, /* inbuflen */ 8)
445       && SECSuccess == PK11_Finalize(ctx))
446     rv = /* all OK */ TRUE;
447 
448 fail:
449   /* cleanup */
450   if(ctx)
451     PK11_DestroyContext(ctx, PR_TRUE);
452   if(symkey)
453     PK11_FreeSymKey(symkey);
454   if(param)
455     SECITEM_FreeItem(param, PR_TRUE);
456   PK11_FreeSlot(slot);
457   return rv;
458 }
459 
460 #endif /* defined(USE_NSS) */
461 
462 #endif /* defined(USE_SSLEAY) */
463 
464  /*
465   * takes a 21 byte array and treats it as 3 56-bit DES keys. The
466   * 8 byte plaintext is encrypted with each key and the resulting 24
467   * bytes are stored in the results array.
468   */
lm_resp(const unsigned char * keys,const unsigned char * plaintext,unsigned char * results)469 static void lm_resp(const unsigned char *keys,
470                     const unsigned char *plaintext,
471                     unsigned char *results)
472 {
473 #ifdef USE_SSLEAY
474   DES_key_schedule ks;
475 
476   setup_des_key(keys, DESKEY(ks));
477   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
478                   DESKEY(ks), DES_ENCRYPT);
479 
480   setup_des_key(keys+7, DESKEY(ks));
481   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
482                   DESKEY(ks), DES_ENCRYPT);
483 
484   setup_des_key(keys+14, DESKEY(ks));
485   DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
486                   DESKEY(ks), DES_ENCRYPT);
487 #elif defined(USE_GNUTLS)
488   gcry_cipher_hd_t des;
489 
490   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
491   setup_des_key(keys, &des);
492   gcry_cipher_encrypt(des, results, 8, plaintext, 8);
493   gcry_cipher_close(des);
494 
495   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
496   setup_des_key(keys+7, &des);
497   gcry_cipher_encrypt(des, results+8, 8, plaintext, 8);
498   gcry_cipher_close(des);
499 
500   gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
501   setup_des_key(keys+14, &des);
502   gcry_cipher_encrypt(des, results+16, 8, plaintext, 8);
503   gcry_cipher_close(des);
504 #elif defined(USE_NSS)
505   encrypt_des(plaintext, results,    keys);
506   encrypt_des(plaintext, results+8,  keys+7);
507   encrypt_des(plaintext, results+16, keys+14);
508 #endif
509 }
510 
511 
512 /*
513  * Set up lanmanager hashed password
514  */
mk_lm_hash(struct SessionHandle * data,const char * password,unsigned char * lmbuffer)515 static void mk_lm_hash(struct SessionHandle *data,
516                        const char *password,
517                        unsigned char *lmbuffer /* 21 bytes */)
518 {
519   unsigned char pw[14];
520   static const unsigned char magic[] = {
521     0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
522   };
523   size_t len = CURLMIN(strlen(password), 14);
524 
525   Curl_strntoupper((char *)pw, password, len);
526   memset(&pw[len], 0, 14-len);
527 
528   /*
529    * The LanManager hashed password needs to be created using the
530    * password in the network encoding not the host encoding.
531    */
532   if(Curl_convert_to_network(data, (char *)pw, 14))
533     return;
534 
535   {
536     /* Create LanManager hashed password. */
537 
538 #ifdef USE_SSLEAY
539     DES_key_schedule ks;
540 
541     setup_des_key(pw, DESKEY(ks));
542     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
543                     DESKEY(ks), DES_ENCRYPT);
544 
545     setup_des_key(pw+7, DESKEY(ks));
546     DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
547                     DESKEY(ks), DES_ENCRYPT);
548 #elif defined(USE_GNUTLS)
549     gcry_cipher_hd_t des;
550 
551     gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
552     setup_des_key(pw, &des);
553     gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
554     gcry_cipher_close(des);
555 
556     gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
557     setup_des_key(pw+7, &des);
558     gcry_cipher_encrypt(des, lmbuffer+8, 8, magic, 8);
559     gcry_cipher_close(des);
560 #elif defined(USE_NSS)
561     encrypt_des(magic, lmbuffer,   pw);
562     encrypt_des(magic, lmbuffer+8, pw+7);
563 #endif
564 
565     memset(lmbuffer + 16, 0, 21 - 16);
566   }
567 }
568 
569 #if USE_NTRESPONSES
ascii_to_unicode_le(unsigned char * dest,const char * src,size_t srclen)570 static void ascii_to_unicode_le(unsigned char *dest, const char *src,
571                                size_t srclen)
572 {
573   size_t i;
574   for (i=0; i<srclen; i++) {
575     dest[2*i]   = (unsigned char)src[i];
576     dest[2*i+1] =   '\0';
577   }
578 }
579 
580 /*
581  * Set up nt hashed passwords
582  */
mk_nt_hash(struct SessionHandle * data,const char * password,unsigned char * ntbuffer)583 static CURLcode mk_nt_hash(struct SessionHandle *data,
584                            const char *password,
585                            unsigned char *ntbuffer /* 21 bytes */)
586 {
587   size_t len = strlen(password);
588   unsigned char *pw = malloc(len*2);
589   CURLcode result;
590   if(!pw)
591     return CURLE_OUT_OF_MEMORY;
592 
593   ascii_to_unicode_le(pw, password, len);
594 
595   /*
596    * The NT hashed password needs to be created using the password in the
597    * network encoding not the host encoding.
598    */
599   result = Curl_convert_to_network(data, (char *)pw, len*2);
600   if(result)
601     return result;
602 
603   {
604     /* Create NT hashed password. */
605 #ifdef USE_SSLEAY
606     MD4_CTX MD4pw;
607     MD4_Init(&MD4pw);
608     MD4_Update(&MD4pw, pw, 2*len);
609     MD4_Final(ntbuffer, &MD4pw);
610 #elif defined(USE_GNUTLS)
611     gcry_md_hd_t MD4pw;
612     gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
613     gcry_md_write(MD4pw, pw, 2*len);
614     memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
615     gcry_md_close(MD4pw);
616 #elif defined(USE_NSS)
617     Curl_md4it(ntbuffer, pw, 2*len);
618 #endif
619 
620     memset(ntbuffer + 16, 0, 21 - 16);
621   }
622 
623   free(pw);
624   return CURLE_OK;
625 }
626 #endif
627 
628 
629 #endif
630 
631 #ifdef USE_WINDOWS_SSPI
632 
633 static void
ntlm_sspi_cleanup(struct ntlmdata * ntlm)634 ntlm_sspi_cleanup(struct ntlmdata *ntlm)
635 {
636   if(ntlm->type_2) {
637     free(ntlm->type_2);
638     ntlm->type_2 = NULL;
639   }
640   if(ntlm->has_handles) {
641     s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
642     s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
643     ntlm->has_handles = 0;
644   }
645   if(ntlm->p_identity) {
646     if(ntlm->identity.User) free(ntlm->identity.User);
647     if(ntlm->identity.Password) free(ntlm->identity.Password);
648     if(ntlm->identity.Domain) free(ntlm->identity.Domain);
649     ntlm->p_identity = NULL;
650   }
651 }
652 
653 #endif
654 
655 #define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
656 #define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
657   (((x) >>16)&0xff), (((x)>>24) & 0xff)
658 
659 #define HOSTNAME_MAX 1024
660 
661 /* this is for creating ntlm header output */
Curl_output_ntlm(struct connectdata * conn,bool proxy)662 CURLcode Curl_output_ntlm(struct connectdata *conn,
663                           bool proxy)
664 {
665   const char *domain=""; /* empty */
666   char host [HOSTNAME_MAX+ 1] = ""; /* empty */
667 #ifndef USE_WINDOWS_SSPI
668   size_t domlen = strlen(domain);
669   size_t hostlen = strlen(host);
670   size_t hostoff; /* host name offset */
671   size_t domoff;  /* domain name offset */
672 #endif
673   size_t size;
674   char *base64=NULL;
675   unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
676                                   long */
677 
678   /* point to the address of the pointer that holds the string to sent to the
679      server, which is for a plain host or for a HTTP proxy */
680   char **allocuserpwd;
681 
682   /* point to the name and password for this */
683   const char *userp;
684   const char *passwdp;
685   /* point to the correct struct with this */
686   struct ntlmdata *ntlm;
687   struct auth *authp;
688 
689   DEBUGASSERT(conn);
690   DEBUGASSERT(conn->data);
691 
692 #ifdef USE_NSS
693   if(CURLE_OK != Curl_nss_force_init(conn->data))
694     return CURLE_OUT_OF_MEMORY;
695 #endif
696 
697   if(proxy) {
698     allocuserpwd = &conn->allocptr.proxyuserpwd;
699     userp = conn->proxyuser;
700     passwdp = conn->proxypasswd;
701     ntlm = &conn->proxyntlm;
702     authp = &conn->data->state.authproxy;
703   }
704   else {
705     allocuserpwd = &conn->allocptr.userpwd;
706     userp = conn->user;
707     passwdp = conn->passwd;
708     ntlm = &conn->ntlm;
709     authp = &conn->data->state.authhost;
710   }
711   authp->done = FALSE;
712 
713   /* not set means empty */
714   if(!userp)
715     userp="";
716 
717   if(!passwdp)
718     passwdp="";
719 
720 #ifdef USE_WINDOWS_SSPI
721   if (s_hSecDll == NULL) {
722     /* not thread safe and leaks - use curl_global_init() to avoid */
723     CURLcode err = Curl_sspi_global_init();
724     if (s_hSecDll == NULL)
725       return err;
726   }
727 #endif
728 
729   switch(ntlm->state) {
730   case NTLMSTATE_TYPE1:
731   default: /* for the weird cases we (re)start here */
732 #ifdef USE_WINDOWS_SSPI
733   {
734     SecBuffer buf;
735     SecBufferDesc desc;
736     SECURITY_STATUS status;
737     ULONG attrs;
738     const char *user;
739     int domlen;
740     TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
741 
742     ntlm_sspi_cleanup(ntlm);
743 
744     user = strchr(userp, '\\');
745     if(!user)
746       user = strchr(userp, '/');
747 
748     if(user) {
749       domain = userp;
750       domlen = user - userp;
751       user++;
752     }
753     else {
754       user = userp;
755       domain = "";
756       domlen = 0;
757     }
758 
759     if(user && *user) {
760       /* note: initialize all of this before doing the mallocs so that
761        * it can be cleaned up later without leaking memory.
762        */
763       ntlm->p_identity = &ntlm->identity;
764       memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
765       if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
766         return CURLE_OUT_OF_MEMORY;
767       ntlm->identity.UserLength = strlen(user);
768       if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
769         return CURLE_OUT_OF_MEMORY;
770       ntlm->identity.PasswordLength = strlen(passwdp);
771       if((ntlm->identity.Domain = malloc(domlen+1)) == NULL)
772         return CURLE_OUT_OF_MEMORY;
773       strncpy((char *)ntlm->identity.Domain, domain, domlen);
774       ntlm->identity.Domain[domlen] = '\0';
775       ntlm->identity.DomainLength = domlen;
776       ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
777     }
778     else {
779       ntlm->p_identity = NULL;
780     }
781 
782     if(s_pSecFn->AcquireCredentialsHandleA(
783           NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
784           NULL, NULL, &ntlm->handle, &tsDummy
785           ) != SEC_E_OK) {
786       return CURLE_OUT_OF_MEMORY;
787     }
788 
789     desc.ulVersion = SECBUFFER_VERSION;
790     desc.cBuffers  = 1;
791     desc.pBuffers  = &buf;
792     buf.cbBuffer   = sizeof(ntlmbuf);
793     buf.BufferType = SECBUFFER_TOKEN;
794     buf.pvBuffer   = ntlmbuf;
795 
796     status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
797                                                  (char *) host,
798                                                  ISC_REQ_CONFIDENTIALITY |
799                                                  ISC_REQ_REPLAY_DETECT |
800                                                  ISC_REQ_CONNECTION,
801                                                  0, SECURITY_NETWORK_DREP,
802                                                  NULL, 0,
803                                                  &ntlm->c_handle, &desc,
804                                                  &attrs, &tsDummy);
805 
806     if(status == SEC_I_COMPLETE_AND_CONTINUE ||
807         status == SEC_I_CONTINUE_NEEDED) {
808       s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
809     }
810     else if(status != SEC_E_OK) {
811       s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
812       return CURLE_RECV_ERROR;
813     }
814 
815     ntlm->has_handles = 1;
816     size = buf.cbBuffer;
817   }
818 #else
819     hostoff = 0;
820     domoff = hostoff + hostlen; /* This is 0: remember that host and domain
821                                    are empty */
822 
823     /* Create and send a type-1 message:
824 
825     Index Description          Content
826     0     NTLMSSP Signature    Null-terminated ASCII "NTLMSSP"
827                                (0x4e544c4d53535000)
828     8     NTLM Message Type    long (0x01000000)
829     12    Flags                long
830     16    Supplied Domain      security buffer(*)
831     24    Supplied Workstation security buffer(*)
832     32    start of data block
833 
834     */
835 #if USE_NTLM2SESSION
836 #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
837 #else
838 #define NTLM2FLAG 0
839 #endif
840     snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
841              "\x01%c%c%c" /* 32-bit type = 1 */
842              "%c%c%c%c"   /* 32-bit NTLM flag field */
843              "%c%c"  /* domain length */
844              "%c%c"  /* domain allocated space */
845              "%c%c"  /* domain name offset */
846              "%c%c"  /* 2 zeroes */
847              "%c%c"  /* host length */
848              "%c%c"  /* host allocated space */
849              "%c%c"  /* host name offset */
850              "%c%c"  /* 2 zeroes */
851              "%s"   /* host name */
852              "%s",  /* domain string */
853              0,     /* trailing zero */
854              0,0,0, /* part of type-1 long */
855 
856              LONGQUARTET(
857                NTLMFLAG_NEGOTIATE_OEM|
858                NTLMFLAG_REQUEST_TARGET|
859                NTLMFLAG_NEGOTIATE_NTLM_KEY|
860                NTLM2FLAG|
861                NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
862                ),
863              SHORTPAIR(domlen),
864              SHORTPAIR(domlen),
865              SHORTPAIR(domoff),
866              0,0,
867              SHORTPAIR(hostlen),
868              SHORTPAIR(hostlen),
869              SHORTPAIR(hostoff),
870              0,0,
871              host /* this is empty */, domain /* this is empty */);
872 
873     /* initial packet length */
874     size = 32 + hostlen + domlen;
875 #endif
876 
877     DEBUG_OUT({
878       fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
879               LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
880                           NTLMFLAG_REQUEST_TARGET|
881                           NTLMFLAG_NEGOTIATE_NTLM_KEY|
882                           NTLM2FLAG|
883                           NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
884               NTLMFLAG_NEGOTIATE_OEM|
885               NTLMFLAG_REQUEST_TARGET|
886               NTLMFLAG_NEGOTIATE_NTLM_KEY|
887               NTLM2FLAG|
888               NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
889       print_flags(stderr,
890                   NTLMFLAG_NEGOTIATE_OEM|
891                   NTLMFLAG_REQUEST_TARGET|
892                   NTLMFLAG_NEGOTIATE_NTLM_KEY|
893                   NTLM2FLAG|
894                   NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
895       fprintf(stderr, "\n****\n");
896     });
897 
898     /* now size is the size of the base64 encoded package size */
899     size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
900 
901     if(size >0 ) {
902       Curl_safefree(*allocuserpwd);
903       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
904                               proxy?"Proxy-":"",
905                               base64);
906       DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
907       free(base64);
908     }
909     else
910       return CURLE_OUT_OF_MEMORY; /* FIX TODO */
911 
912     break;
913 
914   case NTLMSTATE_TYPE2:
915     /* We received the type-2 message already, create a type-3 message:
916 
917     Index   Description            Content
918     0       NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
919                                    (0x4e544c4d53535000)
920     8       NTLM Message Type      long (0x03000000)
921     12      LM/LMv2 Response       security buffer(*)
922     20      NTLM/NTLMv2 Response   security buffer(*)
923     28      Domain Name            security buffer(*)
924     36      User Name              security buffer(*)
925     44      Workstation Name       security buffer(*)
926     (52)    Session Key (optional) security buffer(*)
927     (60)    Flags (optional)       long
928     52 (64) start of data block
929 
930     */
931 
932   {
933 #ifdef USE_WINDOWS_SSPI
934     SecBuffer type_2, type_3;
935     SecBufferDesc type_2_desc, type_3_desc;
936     SECURITY_STATUS status;
937     ULONG attrs;
938     TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
939 
940     type_2_desc.ulVersion  = type_3_desc.ulVersion  = SECBUFFER_VERSION;
941     type_2_desc.cBuffers   = type_3_desc.cBuffers   = 1;
942     type_2_desc.pBuffers   = &type_2;
943     type_3_desc.pBuffers   = &type_3;
944 
945     type_2.BufferType = SECBUFFER_TOKEN;
946     type_2.pvBuffer   = ntlm->type_2;
947     type_2.cbBuffer   = ntlm->n_type_2;
948     type_3.BufferType = SECBUFFER_TOKEN;
949     type_3.pvBuffer   = ntlmbuf;
950     type_3.cbBuffer   = sizeof(ntlmbuf);
951 
952     status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, &ntlm->c_handle,
953                                        (char *) host,
954                                        ISC_REQ_CONFIDENTIALITY |
955                                        ISC_REQ_REPLAY_DETECT |
956                                        ISC_REQ_CONNECTION,
957                                        0, SECURITY_NETWORK_DREP, &type_2_desc,
958                                        0, &ntlm->c_handle, &type_3_desc,
959                                        &attrs, &tsDummy);
960 
961     if(status != SEC_E_OK)
962       return CURLE_RECV_ERROR;
963 
964     size = type_3.cbBuffer;
965 
966     ntlm_sspi_cleanup(ntlm);
967 
968 #else
969     int lmrespoff;
970     unsigned char lmresp[24]; /* fixed-size */
971 #if USE_NTRESPONSES
972     int ntrespoff;
973     unsigned char ntresp[24]; /* fixed-size */
974 #endif
975     size_t useroff;
976     const char *user;
977     size_t userlen;
978 
979     user = strchr(userp, '\\');
980     if(!user)
981       user = strchr(userp, '/');
982 
983     if(user) {
984       domain = userp;
985       domlen = (user - domain);
986       user++;
987     }
988     else
989       user = userp;
990     userlen = strlen(user);
991 
992     if(Curl_gethostname(host, HOSTNAME_MAX)) {
993       infof(conn->data, "gethostname() failed, continuing without!");
994       hostlen = 0;
995     }
996     else {
997       /* If the workstation if configured with a full DNS name (i.e.
998        * workstation.somewhere.net) gethostname() returns the fully qualified
999        * name, which NTLM doesn't like.
1000        */
1001       char *dot = strchr(host, '.');
1002       if(dot)
1003         *dot = '\0';
1004       hostlen = strlen(host);
1005     }
1006 
1007 #if USE_NTLM2SESSION
1008     /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
1009     if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
1010       unsigned char ntbuffer[0x18];
1011       unsigned char tmp[0x18];
1012       unsigned char md5sum[MD5_DIGEST_LENGTH];
1013       unsigned char entropy[8];
1014 
1015       /* Need to create 8 bytes random data */
1016 #ifdef USE_SSLEAY
1017       MD5_CTX MD5pw;
1018       Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
1019       RAND_bytes(entropy,8);
1020 #elif defined(USE_GNUTLS)
1021       gcry_md_hd_t MD5pw;
1022       Curl_gtls_seed(conn->data); /* Initiate the seed if not already done */
1023       gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
1024 #elif defined(USE_NSS)
1025       PK11Context *MD5pw;
1026       unsigned int outlen;
1027       Curl_nss_seed(conn->data);  /* Initiate the seed if not already done */
1028       PK11_GenerateRandom(entropy, 8);
1029 #endif
1030 
1031       /* 8 bytes random data as challenge in lmresp */
1032       memcpy(lmresp,entropy,8);
1033       /* Pad with zeros */
1034       memset(lmresp+8,0,0x10);
1035 
1036       /* Fill tmp with challenge(nonce?) + entropy */
1037       memcpy(tmp,&ntlm->nonce[0],8);
1038       memcpy(tmp+8,entropy,8);
1039 
1040 #ifdef USE_SSLEAY
1041       MD5_Init(&MD5pw);
1042       MD5_Update(&MD5pw, tmp, 16);
1043       MD5_Final(md5sum, &MD5pw);
1044 #elif defined(USE_GNUTLS)
1045       gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1046       gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);
1047       memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH);
1048       gcry_md_close(MD5pw);
1049 #elif defined(USE_NSS)
1050       MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
1051       PK11_DigestOp(MD5pw, tmp, 16);
1052       PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH);
1053       PK11_DestroyContext(MD5pw, PR_TRUE);
1054 #endif
1055 
1056       /* We shall only use the first 8 bytes of md5sum,
1057          but the des code in lm_resp only encrypt the first 8 bytes */
1058       if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
1059         return CURLE_OUT_OF_MEMORY;
1060       lm_resp(ntbuffer, md5sum, ntresp);
1061 
1062       /* End of NTLM2 Session code */
1063     }
1064     else
1065 #endif
1066         {
1067 
1068 #if USE_NTRESPONSES
1069       unsigned char ntbuffer[0x18];
1070 #endif
1071       unsigned char lmbuffer[0x18];
1072 
1073 #if USE_NTRESPONSES
1074       if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
1075         return CURLE_OUT_OF_MEMORY;
1076       lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
1077 #endif
1078 
1079       mk_lm_hash(conn->data, passwdp, lmbuffer);
1080       lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
1081       /* A safer but less compatible alternative is:
1082        *   lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
1083        * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
1084     }
1085 
1086     lmrespoff = 64; /* size of the message header */
1087 #if USE_NTRESPONSES
1088     ntrespoff = lmrespoff + 0x18;
1089     domoff = ntrespoff + 0x18;
1090 #else
1091     domoff = lmrespoff + 0x18;
1092 #endif
1093     useroff = domoff + domlen;
1094     hostoff = useroff + userlen;
1095 
1096     /*
1097      * In the case the server sets the flag NTLMFLAG_NEGOTIATE_UNICODE, we
1098      * need to filter it off because libcurl doesn't UNICODE encode the
1099      * strings it packs into the NTLM authenticate packet.
1100      */
1101     ntlm->flags &= ~NTLMFLAG_NEGOTIATE_UNICODE;
1102 
1103     /* Create the big type-3 message binary blob */
1104     size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
1105                     NTLMSSP_SIGNATURE "%c"
1106                     "\x03%c%c%c" /* type-3, 32 bits */
1107 
1108                     "%c%c" /* LanManager length */
1109                     "%c%c" /* LanManager allocated space */
1110                     "%c%c" /* LanManager offset */
1111                     "%c%c" /* 2 zeroes */
1112 
1113                     "%c%c" /* NT-response length */
1114                     "%c%c" /* NT-response allocated space */
1115                     "%c%c" /* NT-response offset */
1116                     "%c%c" /* 2 zeroes */
1117 
1118                     "%c%c"  /* domain length */
1119                     "%c%c"  /* domain allocated space */
1120                     "%c%c"  /* domain name offset */
1121                     "%c%c"  /* 2 zeroes */
1122 
1123                     "%c%c"  /* user length */
1124                     "%c%c"  /* user allocated space */
1125                     "%c%c"  /* user offset */
1126                     "%c%c"  /* 2 zeroes */
1127 
1128                     "%c%c"  /* host length */
1129                     "%c%c"  /* host allocated space */
1130                     "%c%c"  /* host offset */
1131                     "%c%c"  /* 2 zeroes */
1132 
1133                     "%c%c"  /* session key length (unknown purpose) */
1134                     "%c%c"  /* session key allocated space (unknown purpose) */
1135                     "%c%c"  /* session key offset (unknown purpose) */
1136                     "%c%c"  /* 2 zeroes */
1137 
1138                     "%c%c%c%c" /* flags */
1139 
1140                     /* domain string */
1141                     /* user string */
1142                     /* host string */
1143                     /* LanManager response */
1144                     /* NT response */
1145                     ,
1146                     0, /* zero termination */
1147                     0,0,0, /* type-3 long, the 24 upper bits */
1148 
1149                     SHORTPAIR(0x18),  /* LanManager response length, twice */
1150                     SHORTPAIR(0x18),
1151                     SHORTPAIR(lmrespoff),
1152                     0x0, 0x0,
1153 
1154 #if USE_NTRESPONSES
1155                     SHORTPAIR(0x18),  /* NT-response length, twice */
1156                     SHORTPAIR(0x18),
1157                     SHORTPAIR(ntrespoff),
1158                     0x0, 0x0,
1159 #else
1160                     0x0, 0x0,
1161                     0x0, 0x0,
1162                     0x0, 0x0,
1163                     0x0, 0x0,
1164 #endif
1165                     SHORTPAIR(domlen),
1166                     SHORTPAIR(domlen),
1167                     SHORTPAIR(domoff),
1168                     0x0, 0x0,
1169 
1170                     SHORTPAIR(userlen),
1171                     SHORTPAIR(userlen),
1172                     SHORTPAIR(useroff),
1173                     0x0, 0x0,
1174 
1175                     SHORTPAIR(hostlen),
1176                     SHORTPAIR(hostlen),
1177                     SHORTPAIR(hostoff),
1178                     0x0, 0x0,
1179 
1180                     0x0, 0x0,
1181                     0x0, 0x0,
1182                     0x0, 0x0,
1183                     0x0, 0x0,
1184 
1185                     LONGQUARTET(ntlm->flags));
1186     DEBUGASSERT(size==64);
1187 
1188     DEBUGASSERT(size == (size_t)lmrespoff);
1189     /* We append the binary hashes */
1190     if(size < (sizeof(ntlmbuf) - 0x18)) {
1191       memcpy(&ntlmbuf[size], lmresp, 0x18);
1192       size += 0x18;
1193     }
1194 
1195     DEBUG_OUT({
1196         fprintf(stderr, "**** TYPE3 header lmresp=");
1197         print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
1198     });
1199 
1200 #if USE_NTRESPONSES
1201     if(size < (sizeof(ntlmbuf) - 0x18)) {
1202       DEBUGASSERT(size == (size_t)ntrespoff);
1203       memcpy(&ntlmbuf[size], ntresp, 0x18);
1204       size += 0x18;
1205     }
1206 
1207     DEBUG_OUT({
1208         fprintf(stderr, "\n                  ntresp=");
1209         print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
1210     });
1211 
1212 #endif
1213 
1214     DEBUG_OUT({
1215         fprintf(stderr, "\n                  flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
1216                 LONGQUARTET(ntlm->flags), ntlm->flags);
1217         print_flags(stderr, ntlm->flags);
1218         fprintf(stderr, "\n****\n");
1219     });
1220 
1221 
1222     /* Make sure that the domain, user and host strings fit in the target
1223        buffer before we copy them there. */
1224     if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
1225       failf(conn->data, "user + domain + host name too big");
1226       return CURLE_OUT_OF_MEMORY;
1227     }
1228 
1229     DEBUGASSERT(size == domoff);
1230     memcpy(&ntlmbuf[size], domain, domlen);
1231     size += domlen;
1232 
1233     DEBUGASSERT(size == useroff);
1234     memcpy(&ntlmbuf[size], user, userlen);
1235     size += userlen;
1236 
1237     DEBUGASSERT(size == hostoff);
1238     memcpy(&ntlmbuf[size], host, hostlen);
1239     size += hostlen;
1240 
1241     /* convert domain, user, and host to ASCII but leave the rest as-is */
1242     if(Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff],
1243                                size-domoff))
1244       return CURLE_CONV_FAILED;
1245 
1246 #endif
1247 
1248     /* convert the binary blob into base64 */
1249     size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
1250 
1251     if(size >0 ) {
1252       Curl_safefree(*allocuserpwd);
1253       *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
1254                               proxy?"Proxy-":"",
1255                               base64);
1256       DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
1257       free(base64);
1258     }
1259     else
1260       return CURLE_OUT_OF_MEMORY; /* FIX TODO */
1261 
1262     ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
1263     authp->done = TRUE;
1264   }
1265   break;
1266 
1267   case NTLMSTATE_TYPE3:
1268     /* connection is already authenticated,
1269      * don't send a header in future requests */
1270     if(*allocuserpwd) {
1271       free(*allocuserpwd);
1272       *allocuserpwd=NULL;
1273     }
1274     authp->done = TRUE;
1275     break;
1276   }
1277 
1278   return CURLE_OK;
1279 }
1280 
1281 
1282 void
Curl_ntlm_cleanup(struct connectdata * conn)1283 Curl_ntlm_cleanup(struct connectdata *conn)
1284 {
1285 #ifdef USE_WINDOWS_SSPI
1286   ntlm_sspi_cleanup(&conn->ntlm);
1287   ntlm_sspi_cleanup(&conn->proxyntlm);
1288 #else
1289   (void)conn;
1290 #endif
1291 }
1292 
1293 
1294 #endif /* USE_NTLM */
1295 #endif /* !CURL_DISABLE_HTTP */
1296