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
30#ifndef CURL_DISABLE_HTTP
31#ifdef USE_NTLM
32
33#define DEBUG_ME 0
34
35/* -- WIN32 approved -- */
36#include <stdio.h>
37#include <string.h>
38#include <stdarg.h>
39#include <stdlib.h>
40#include <ctype.h>
41
42#ifdef HAVE_UNISTD_H
43#include <unistd.h>
44#endif
45
46#if (defined(NETWARE) && !defined(__NOVELL_LIBC__))
47#include <netdb.h>
48#endif
49
50#include "urldata.h"
51#include "non-ascii.h"  /* for Curl_convert_... prototypes */
52#include "sendf.h"
53#include "rawstr.h"
54#include "curl_base64.h"
55#include "http_ntlm.h"
56#include "url.h"
57#include "curl_gethostname.h"
58#include "curl_memory.h"
59
60#define _MPRINTF_REPLACE /* use our functions only */
61#include <curl/mprintf.h>
62
63/* "NTLMSSP" signature is always in ASCII regardless of the platform */
64#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
65
66#ifdef USE_SSLEAY
67#include "ssluse.h"
68#    ifdef USE_OPENSSL
69#      include <openssl/des.h>
70#      ifndef OPENSSL_NO_MD4
71#        include <openssl/md4.h>
72#      endif
73#      include <openssl/md5.h>
74#      include <openssl/ssl.h>
75#      include <openssl/rand.h>
76#    else
77#      include <des.h>
78#      ifndef OPENSSL_NO_MD4
79#        include <md4.h>
80#      endif
81#      include <md5.h>
82#      include <ssl.h>
83#      include <rand.h>
84#    endif
85
86#ifndef OPENSSL_VERSION_NUMBER
87#error "OPENSSL_VERSION_NUMBER not defined"
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 */
152static 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
162static 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
230static 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
252CURLntlm 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 */
352static 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 */
375static 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 */
392static 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 */
407static 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
448fail:
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  */
469static 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 */
515static void mk_lm_hash(struct SessionHandle *data,
516                       const char *password,
517                       unsigned char *lmbuffer /* 21 bytes */)
518{
519  CURLcode res;
520  unsigned char pw[14];
521  static const unsigned char magic[] = {
522    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
523  };
524  size_t len = CURLMIN(strlen(password), 14);
525
526  Curl_strntoupper((char *)pw, password, len);
527  memset(&pw[len], 0, 14-len);
528
529  /*
530   * The LanManager hashed password needs to be created using the
531   * password in the network encoding not the host encoding.
532   */
533  res = Curl_convert_to_network(data, (char *)pw, 14);
534  if(res)
535    return;
536
537  {
538    /* Create LanManager hashed password. */
539
540#ifdef USE_SSLEAY
541    DES_key_schedule ks;
542
543    setup_des_key(pw, DESKEY(ks));
544    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
545                    DESKEY(ks), DES_ENCRYPT);
546
547    setup_des_key(pw+7, DESKEY(ks));
548    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
549                    DESKEY(ks), DES_ENCRYPT);
550#elif defined(USE_GNUTLS)
551    gcry_cipher_hd_t des;
552
553    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
554    setup_des_key(pw, &des);
555    gcry_cipher_encrypt(des, lmbuffer, 8, magic, 8);
556    gcry_cipher_close(des);
557
558    gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0);
559    setup_des_key(pw+7, &des);
560    gcry_cipher_encrypt(des, lmbuffer+8, 8, magic, 8);
561    gcry_cipher_close(des);
562#elif defined(USE_NSS)
563    encrypt_des(magic, lmbuffer,   pw);
564    encrypt_des(magic, lmbuffer+8, pw+7);
565#endif
566
567    memset(lmbuffer + 16, 0, 21 - 16);
568  }
569}
570
571#if USE_NTRESPONSES
572static void ascii_to_unicode_le(unsigned char *dest, const char *src,
573                               size_t srclen)
574{
575  size_t i;
576  for(i=0; i<srclen; i++) {
577    dest[2*i]   = (unsigned char)src[i];
578    dest[2*i+1] =   '\0';
579  }
580}
581
582/*
583 * Set up nt hashed passwords
584 */
585static CURLcode mk_nt_hash(struct SessionHandle *data,
586                           const char *password,
587                           unsigned char *ntbuffer /* 21 bytes */)
588{
589  size_t len = strlen(password);
590  unsigned char *pw = malloc(len*2);
591  CURLcode result;
592  if(!pw)
593    return CURLE_OUT_OF_MEMORY;
594
595  ascii_to_unicode_le(pw, password, len);
596
597  /*
598   * The NT hashed password needs to be created using the password in the
599   * network encoding not the host encoding.
600   */
601  result = Curl_convert_to_network(data, (char *)pw, len*2);
602  if(result)
603    return result;
604
605  {
606    /* Create NT hashed password. */
607#ifdef USE_SSLEAY
608    MD4_CTX MD4pw;
609    MD4_Init(&MD4pw);
610    MD4_Update(&MD4pw, pw, 2*len);
611    MD4_Final(ntbuffer, &MD4pw);
612#elif defined(USE_GNUTLS)
613    gcry_md_hd_t MD4pw;
614    gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
615    gcry_md_write(MD4pw, pw, 2*len);
616    memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
617    gcry_md_close(MD4pw);
618#elif defined(USE_NSS)
619    Curl_md4it(ntbuffer, pw, 2*len);
620#endif
621
622    memset(ntbuffer + 16, 0, 21 - 16);
623  }
624
625  free(pw);
626  return CURLE_OK;
627}
628#endif
629
630
631#endif
632
633#ifdef USE_WINDOWS_SSPI
634
635static void
636ntlm_sspi_cleanup(struct ntlmdata *ntlm)
637{
638  if(ntlm->type_2) {
639    free(ntlm->type_2);
640    ntlm->type_2 = NULL;
641  }
642  if(ntlm->has_handles) {
643    s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
644    s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
645    ntlm->has_handles = 0;
646  }
647  if(ntlm->p_identity) {
648    if(ntlm->identity.User) free(ntlm->identity.User);
649    if(ntlm->identity.Password) free(ntlm->identity.Password);
650    if(ntlm->identity.Domain) free(ntlm->identity.Domain);
651    ntlm->p_identity = NULL;
652  }
653}
654
655#endif
656
657#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
658#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
659  (((x) >>16)&0xff), (((x)>>24) & 0xff)
660
661#define HOSTNAME_MAX 1024
662
663#ifndef USE_WINDOWS_SSPI
664/* copy the source to the destination and fill in zeroes in every
665   other destination byte! */
666static void unicodecpy(unsigned char *dest,
667                       const char *src, size_t length)
668{
669  size_t i;
670  for(i=0; i<length; i++) {
671    dest[2*i] = (unsigned char)src[i];
672    dest[2*i+1] = '\0';
673  }
674}
675#endif
676
677/* this is for creating ntlm header output */
678CURLcode Curl_output_ntlm(struct connectdata *conn,
679                          bool proxy)
680{
681  const char *domain=""; /* empty */
682  char host [HOSTNAME_MAX+ 1] = ""; /* empty */
683#ifndef USE_WINDOWS_SSPI
684  size_t domlen = strlen(domain);
685  size_t hostlen = strlen(host);
686  size_t hostoff; /* host name offset */
687  size_t domoff;  /* domain name offset */
688#endif
689  size_t size;
690  char *base64=NULL;
691  unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
692                                  long */
693
694  /* point to the address of the pointer that holds the string to sent to the
695     server, which is for a plain host or for a HTTP proxy */
696  char **allocuserpwd;
697
698  /* point to the name and password for this */
699  const char *userp;
700  const char *passwdp;
701  /* point to the correct struct with this */
702  struct ntlmdata *ntlm;
703  struct auth *authp;
704
705  DEBUGASSERT(conn);
706  DEBUGASSERT(conn->data);
707
708#ifdef USE_NSS
709  if(CURLE_OK != Curl_nss_force_init(conn->data))
710    return CURLE_OUT_OF_MEMORY;
711#endif
712
713  if(proxy) {
714    allocuserpwd = &conn->allocptr.proxyuserpwd;
715    userp = conn->proxyuser;
716    passwdp = conn->proxypasswd;
717    ntlm = &conn->proxyntlm;
718    authp = &conn->data->state.authproxy;
719  }
720  else {
721    allocuserpwd = &conn->allocptr.userpwd;
722    userp = conn->user;
723    passwdp = conn->passwd;
724    ntlm = &conn->ntlm;
725    authp = &conn->data->state.authhost;
726  }
727  authp->done = FALSE;
728
729  /* not set means empty */
730  if(!userp)
731    userp="";
732
733  if(!passwdp)
734    passwdp="";
735
736#ifdef USE_WINDOWS_SSPI
737  if(s_hSecDll == NULL) {
738    /* not thread safe and leaks - use curl_global_init() to avoid */
739    CURLcode err = Curl_sspi_global_init();
740    if(s_hSecDll == NULL)
741      return err;
742  }
743#endif
744
745  switch(ntlm->state) {
746  case NTLMSTATE_TYPE1:
747  default: /* for the weird cases we (re)start here */
748#ifdef USE_WINDOWS_SSPI
749  {
750    SecBuffer buf;
751    SecBufferDesc desc;
752    SECURITY_STATUS status;
753    ULONG attrs;
754    const char *user;
755    int domlen;
756    TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
757
758    ntlm_sspi_cleanup(ntlm);
759
760    user = strchr(userp, '\\');
761    if(!user)
762      user = strchr(userp, '/');
763
764    if(user) {
765      domain = userp;
766      domlen = user - userp;
767      user++;
768    }
769    else {
770      user = userp;
771      domain = "";
772      domlen = 0;
773    }
774
775    if(user && *user) {
776      /* note: initialize all of this before doing the mallocs so that
777       * it can be cleaned up later without leaking memory.
778       */
779      ntlm->p_identity = &ntlm->identity;
780      memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
781      if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
782        return CURLE_OUT_OF_MEMORY;
783      ntlm->identity.UserLength = strlen(user);
784      if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
785        return CURLE_OUT_OF_MEMORY;
786      ntlm->identity.PasswordLength = strlen(passwdp);
787      if((ntlm->identity.Domain = malloc(domlen+1)) == NULL)
788        return CURLE_OUT_OF_MEMORY;
789      strncpy((char *)ntlm->identity.Domain, domain, domlen);
790      ntlm->identity.Domain[domlen] = '\0';
791      ntlm->identity.DomainLength = domlen;
792      ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
793    }
794    else {
795      ntlm->p_identity = NULL;
796    }
797
798    if(s_pSecFn->AcquireCredentialsHandleA(
799          NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity,
800          NULL, NULL, &ntlm->handle, &tsDummy
801          ) != SEC_E_OK) {
802      return CURLE_OUT_OF_MEMORY;
803    }
804
805    desc.ulVersion = SECBUFFER_VERSION;
806    desc.cBuffers  = 1;
807    desc.pBuffers  = &buf;
808    buf.cbBuffer   = sizeof(ntlmbuf);
809    buf.BufferType = SECBUFFER_TOKEN;
810    buf.pvBuffer   = ntlmbuf;
811
812    status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
813                                                 (char *) host,
814                                                 ISC_REQ_CONFIDENTIALITY |
815                                                 ISC_REQ_REPLAY_DETECT |
816                                                 ISC_REQ_CONNECTION,
817                                                 0, SECURITY_NETWORK_DREP,
818                                                 NULL, 0,
819                                                 &ntlm->c_handle, &desc,
820                                                 &attrs, &tsDummy);
821
822    if(status == SEC_I_COMPLETE_AND_CONTINUE ||
823        status == SEC_I_CONTINUE_NEEDED) {
824      s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
825    }
826    else if(status != SEC_E_OK) {
827      s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
828      return CURLE_RECV_ERROR;
829    }
830
831    ntlm->has_handles = 1;
832    size = buf.cbBuffer;
833  }
834#else
835    hostoff = 0;
836    domoff = hostoff + hostlen; /* This is 0: remember that host and domain
837                                   are empty */
838
839    /* Create and send a type-1 message:
840
841    Index Description          Content
842    0     NTLMSSP Signature    Null-terminated ASCII "NTLMSSP"
843                               (0x4e544c4d53535000)
844    8     NTLM Message Type    long (0x01000000)
845    12    Flags                long
846    16    Supplied Domain      security buffer(*)
847    24    Supplied Workstation security buffer(*)
848    32    start of data block
849
850    */
851#if USE_NTLM2SESSION
852#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
853#else
854#define NTLM2FLAG 0
855#endif
856    snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
857             "\x01%c%c%c" /* 32-bit type = 1 */
858             "%c%c%c%c"   /* 32-bit NTLM flag field */
859             "%c%c"  /* domain length */
860             "%c%c"  /* domain allocated space */
861             "%c%c"  /* domain name offset */
862             "%c%c"  /* 2 zeroes */
863             "%c%c"  /* host length */
864             "%c%c"  /* host allocated space */
865             "%c%c"  /* host name offset */
866             "%c%c"  /* 2 zeroes */
867             "%s"   /* host name */
868             "%s",  /* domain string */
869             0,     /* trailing zero */
870             0,0,0, /* part of type-1 long */
871
872             LONGQUARTET(
873               NTLMFLAG_NEGOTIATE_OEM|
874               NTLMFLAG_REQUEST_TARGET|
875               NTLMFLAG_NEGOTIATE_NTLM_KEY|
876               NTLM2FLAG|
877               NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
878               ),
879             SHORTPAIR(domlen),
880             SHORTPAIR(domlen),
881             SHORTPAIR(domoff),
882             0,0,
883             SHORTPAIR(hostlen),
884             SHORTPAIR(hostlen),
885             SHORTPAIR(hostoff),
886             0,0,
887             host /* this is empty */, domain /* this is empty */);
888
889    /* initial packet length */
890    size = 32 + hostlen + domlen;
891#endif
892
893    DEBUG_OUT({
894        fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
895                "0x%08.8x ",
896                LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
897                            NTLMFLAG_REQUEST_TARGET|
898                            NTLMFLAG_NEGOTIATE_NTLM_KEY|
899                            NTLM2FLAG|
900                            NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
901                NTLMFLAG_NEGOTIATE_OEM|
902                NTLMFLAG_REQUEST_TARGET|
903                NTLMFLAG_NEGOTIATE_NTLM_KEY|
904                NTLM2FLAG|
905                NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
906        print_flags(stderr,
907                    NTLMFLAG_NEGOTIATE_OEM|
908                    NTLMFLAG_REQUEST_TARGET|
909                    NTLMFLAG_NEGOTIATE_NTLM_KEY|
910                    NTLM2FLAG|
911                    NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
912        fprintf(stderr, "\n****\n");
913      });
914
915    /* now size is the size of the base64 encoded package size */
916    size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
917
918    if(size >0 ) {
919      Curl_safefree(*allocuserpwd);
920      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
921                              proxy?"Proxy-":"",
922                              base64);
923      DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd));
924      free(base64);
925    }
926    else
927      return CURLE_OUT_OF_MEMORY; /* FIX TODO */
928
929    break;
930
931  case NTLMSTATE_TYPE2:
932    /* We received the type-2 message already, create a type-3 message:
933
934    Index   Description            Content
935    0       NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
936                                   (0x4e544c4d53535000)
937    8       NTLM Message Type      long (0x03000000)
938    12      LM/LMv2 Response       security buffer(*)
939    20      NTLM/NTLMv2 Response   security buffer(*)
940    28      Domain Name            security buffer(*)
941    36      User Name              security buffer(*)
942    44      Workstation Name       security buffer(*)
943    (52)    Session Key (optional) security buffer(*)
944    (60)    Flags (optional)       long
945    52 (64) start of data block
946
947    */
948
949  {
950#ifdef USE_WINDOWS_SSPI
951    SecBuffer type_2, type_3;
952    SecBufferDesc type_2_desc, type_3_desc;
953    SECURITY_STATUS status;
954    ULONG attrs;
955    TimeStamp tsDummy; /* For Windows 9x compatibility of SPPI calls */
956
957    type_2_desc.ulVersion  = type_3_desc.ulVersion  = SECBUFFER_VERSION;
958    type_2_desc.cBuffers   = type_3_desc.cBuffers   = 1;
959    type_2_desc.pBuffers   = &type_2;
960    type_3_desc.pBuffers   = &type_3;
961
962    type_2.BufferType = SECBUFFER_TOKEN;
963    type_2.pvBuffer   = ntlm->type_2;
964    type_2.cbBuffer   = ntlm->n_type_2;
965    type_3.BufferType = SECBUFFER_TOKEN;
966    type_3.pvBuffer   = ntlmbuf;
967    type_3.cbBuffer   = sizeof(ntlmbuf);
968
969    status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
970                                                  &ntlm->c_handle,
971                                                  (char *) host,
972                                                  ISC_REQ_CONFIDENTIALITY |
973                                                  ISC_REQ_REPLAY_DETECT |
974                                                  ISC_REQ_CONNECTION,
975                                                  0, SECURITY_NETWORK_DREP,
976                                                  &type_2_desc,
977                                                  0, &ntlm->c_handle,
978                                                  &type_3_desc,
979                                                  &attrs, &tsDummy);
980
981    if(status != SEC_E_OK)
982      return CURLE_RECV_ERROR;
983
984    size = type_3.cbBuffer;
985
986    ntlm_sspi_cleanup(ntlm);
987
988#else
989    int lmrespoff;
990    unsigned char lmresp[24]; /* fixed-size */
991#if USE_NTRESPONSES
992    int ntrespoff;
993    unsigned char ntresp[24]; /* fixed-size */
994#endif
995    bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE)?TRUE:FALSE;
996    size_t useroff;
997    const char *user;
998    size_t userlen;
999    CURLcode res;
1000
1001    user = strchr(userp, '\\');
1002    if(!user)
1003      user = strchr(userp, '/');
1004
1005    if(user) {
1006      domain = userp;
1007      domlen = (user - domain);
1008      user++;
1009    }
1010    else
1011      user = userp;
1012    userlen = strlen(user);
1013
1014    if(Curl_gethostname(host, HOSTNAME_MAX)) {
1015      infof(conn->data, "gethostname() failed, continuing without!");
1016      hostlen = 0;
1017    }
1018    else {
1019      /* If the workstation if configured with a full DNS name (i.e.
1020       * workstation.somewhere.net) gethostname() returns the fully qualified
1021       * name, which NTLM doesn't like.
1022       */
1023      char *dot = strchr(host, '.');
1024      if(dot)
1025        *dot = '\0';
1026      hostlen = strlen(host);
1027    }
1028
1029    if(unicode) {
1030      domlen = domlen * 2;
1031      userlen = userlen * 2;
1032      hostlen = hostlen * 2;
1033    }
1034
1035#if USE_NTLM2SESSION
1036    /* We don't support NTLM2 if we don't have USE_NTRESPONSES */
1037    if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
1038      unsigned char ntbuffer[0x18];
1039      unsigned char tmp[0x18];
1040      unsigned char md5sum[MD5_DIGEST_LENGTH];
1041      unsigned char entropy[8];
1042
1043      /* Need to create 8 bytes random data */
1044#ifdef USE_SSLEAY
1045      MD5_CTX MD5pw;
1046      Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
1047      RAND_bytes(entropy,8);
1048#elif defined(USE_GNUTLS)
1049      gcry_md_hd_t MD5pw;
1050      Curl_gtls_seed(conn->data); /* Initiate the seed if not already done */
1051      gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
1052#elif defined(USE_NSS)
1053      PK11Context *MD5pw;
1054      unsigned int outlen;
1055      Curl_nss_seed(conn->data);  /* Initiate the seed if not already done */
1056      PK11_GenerateRandom(entropy, 8);
1057#endif
1058
1059      /* 8 bytes random data as challenge in lmresp */
1060      memcpy(lmresp,entropy,8);
1061      /* Pad with zeros */
1062      memset(lmresp+8,0,0x10);
1063
1064      /* Fill tmp with challenge(nonce?) + entropy */
1065      memcpy(tmp,&ntlm->nonce[0],8);
1066      memcpy(tmp+8,entropy,8);
1067
1068#ifdef USE_SSLEAY
1069      MD5_Init(&MD5pw);
1070      MD5_Update(&MD5pw, tmp, 16);
1071      MD5_Final(md5sum, &MD5pw);
1072#elif defined(USE_GNUTLS)
1073      gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
1074      gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);
1075      memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH);
1076      gcry_md_close(MD5pw);
1077#elif defined(USE_NSS)
1078      MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
1079      PK11_DigestOp(MD5pw, tmp, 16);
1080      PK11_DigestFinal(MD5pw, md5sum, &outlen, MD5_DIGEST_LENGTH);
1081      PK11_DestroyContext(MD5pw, PR_TRUE);
1082#endif
1083
1084      /* We shall only use the first 8 bytes of md5sum,
1085         but the des code in lm_resp only encrypt the first 8 bytes */
1086      if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
1087        return CURLE_OUT_OF_MEMORY;
1088      lm_resp(ntbuffer, md5sum, ntresp);
1089
1090      /* End of NTLM2 Session code */
1091    }
1092    else
1093#endif
1094        {
1095
1096#if USE_NTRESPONSES
1097      unsigned char ntbuffer[0x18];
1098#endif
1099      unsigned char lmbuffer[0x18];
1100
1101#if USE_NTRESPONSES
1102      if(mk_nt_hash(conn->data, passwdp, ntbuffer) == CURLE_OUT_OF_MEMORY)
1103        return CURLE_OUT_OF_MEMORY;
1104      lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
1105#endif
1106
1107      mk_lm_hash(conn->data, passwdp, lmbuffer);
1108      lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
1109      /* A safer but less compatible alternative is:
1110       *   lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
1111       * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
1112    }
1113
1114    lmrespoff = 64; /* size of the message header */
1115#if USE_NTRESPONSES
1116    ntrespoff = lmrespoff + 0x18;
1117    domoff = ntrespoff + 0x18;
1118#else
1119    domoff = lmrespoff + 0x18;
1120#endif
1121    useroff = domoff + domlen;
1122    hostoff = useroff + userlen;
1123
1124    /* Create the big type-3 message binary blob */
1125    size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
1126                    NTLMSSP_SIGNATURE "%c"
1127                    "\x03%c%c%c" /* type-3, 32 bits */
1128
1129                    "%c%c" /* LanManager length */
1130                    "%c%c" /* LanManager allocated space */
1131                    "%c%c" /* LanManager offset */
1132                    "%c%c" /* 2 zeroes */
1133
1134                    "%c%c" /* NT-response length */
1135                    "%c%c" /* NT-response allocated space */
1136                    "%c%c" /* NT-response offset */
1137                    "%c%c" /* 2 zeroes */
1138
1139                    "%c%c"  /* domain length */
1140                    "%c%c"  /* domain allocated space */
1141                    "%c%c"  /* domain name offset */
1142                    "%c%c"  /* 2 zeroes */
1143
1144                    "%c%c"  /* user length */
1145                    "%c%c"  /* user allocated space */
1146                    "%c%c"  /* user offset */
1147                    "%c%c"  /* 2 zeroes */
1148
1149                    "%c%c"  /* host length */
1150                    "%c%c"  /* host allocated space */
1151                    "%c%c"  /* host offset */
1152                    "%c%c"  /* 2 zeroes */
1153
1154                    "%c%c"  /* session key length (unknown purpose) */
1155                    "%c%c"  /* session key allocated space (unknown purpose) */
1156                    "%c%c"  /* session key offset (unknown purpose) */
1157                    "%c%c"  /* 2 zeroes */
1158
1159                    "%c%c%c%c" /* flags */
1160
1161                    /* domain string */
1162                    /* user string */
1163                    /* host string */
1164                    /* LanManager response */
1165                    /* NT response */
1166                    ,
1167                    0, /* zero termination */
1168                    0,0,0, /* type-3 long, the 24 upper bits */
1169
1170                    SHORTPAIR(0x18),  /* LanManager response length, twice */
1171                    SHORTPAIR(0x18),
1172                    SHORTPAIR(lmrespoff),
1173                    0x0, 0x0,
1174
1175#if USE_NTRESPONSES
1176                    SHORTPAIR(0x18),  /* NT-response length, twice */
1177                    SHORTPAIR(0x18),
1178                    SHORTPAIR(ntrespoff),
1179                    0x0, 0x0,
1180#else
1181                    0x0, 0x0,
1182                    0x0, 0x0,
1183                    0x0, 0x0,
1184                    0x0, 0x0,
1185#endif
1186                    SHORTPAIR(domlen),
1187                    SHORTPAIR(domlen),
1188                    SHORTPAIR(domoff),
1189                    0x0, 0x0,
1190
1191                    SHORTPAIR(userlen),
1192                    SHORTPAIR(userlen),
1193                    SHORTPAIR(useroff),
1194                    0x0, 0x0,
1195
1196                    SHORTPAIR(hostlen),
1197                    SHORTPAIR(hostlen),
1198                    SHORTPAIR(hostoff),
1199                    0x0, 0x0,
1200
1201                    0x0, 0x0,
1202                    0x0, 0x0,
1203                    0x0, 0x0,
1204                    0x0, 0x0,
1205
1206                    LONGQUARTET(ntlm->flags));
1207    DEBUGASSERT(size==64);
1208
1209    DEBUGASSERT(size == (size_t)lmrespoff);
1210    /* We append the binary hashes */
1211    if(size < (sizeof(ntlmbuf) - 0x18)) {
1212      memcpy(&ntlmbuf[size], lmresp, 0x18);
1213      size += 0x18;
1214    }
1215
1216    DEBUG_OUT({
1217        fprintf(stderr, "**** TYPE3 header lmresp=");
1218        print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
1219    });
1220
1221#if USE_NTRESPONSES
1222    if(size < (sizeof(ntlmbuf) - 0x18)) {
1223      DEBUGASSERT(size == (size_t)ntrespoff);
1224      memcpy(&ntlmbuf[size], ntresp, 0x18);
1225      size += 0x18;
1226    }
1227
1228    DEBUG_OUT({
1229        fprintf(stderr, "\n   ntresp=");
1230        print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
1231    });
1232
1233#endif
1234
1235    DEBUG_OUT({
1236        fprintf(stderr, "\n   flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
1237                LONGQUARTET(ntlm->flags), ntlm->flags);
1238        print_flags(stderr, ntlm->flags);
1239        fprintf(stderr, "\n****\n");
1240    });
1241
1242
1243    /* Make sure that the domain, user and host strings fit in the target
1244       buffer before we copy them there. */
1245    if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
1246      failf(conn->data, "user + domain + host name too big");
1247      return CURLE_OUT_OF_MEMORY;
1248    }
1249
1250    DEBUGASSERT(size == domoff);
1251    if(unicode)
1252      unicodecpy(&ntlmbuf[size], domain, domlen/2);
1253    else
1254      memcpy(&ntlmbuf[size], domain, domlen);
1255
1256    size += domlen;
1257
1258    DEBUGASSERT(size == useroff);
1259    if(unicode)
1260      unicodecpy(&ntlmbuf[size], user, userlen/2);
1261    else
1262      memcpy(&ntlmbuf[size], user, userlen);
1263
1264    size += userlen;
1265
1266    DEBUGASSERT(size == hostoff);
1267    if(unicode)
1268      unicodecpy(&ntlmbuf[size], host, hostlen/2);
1269    else
1270      memcpy(&ntlmbuf[size], host, hostlen);
1271
1272    size += hostlen;
1273
1274    /* convert domain, user, and host to ASCII but leave the rest as-is */
1275    res = Curl_convert_to_network(conn->data, (char *)&ntlmbuf[domoff],
1276                                  size-domoff);
1277    if(res)
1278      return CURLE_CONV_FAILED;
1279
1280#endif
1281
1282    /* convert the binary blob into base64 */
1283    size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
1284
1285    if(size >0 ) {
1286      Curl_safefree(*allocuserpwd);
1287      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
1288                              proxy?"Proxy-":"",
1289                              base64);
1290      DEBUG_OUT(fprintf(stderr, "**** %s\n ", *allocuserpwd));
1291      free(base64);
1292    }
1293    else
1294      return CURLE_OUT_OF_MEMORY; /* FIX TODO */
1295
1296    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
1297    authp->done = TRUE;
1298  }
1299  break;
1300
1301  case NTLMSTATE_TYPE3:
1302    /* connection is already authenticated,
1303     * don't send a header in future requests */
1304    if(*allocuserpwd) {
1305      free(*allocuserpwd);
1306      *allocuserpwd=NULL;
1307    }
1308    authp->done = TRUE;
1309    break;
1310  }
1311
1312  return CURLE_OK;
1313}
1314
1315
1316void
1317Curl_ntlm_cleanup(struct connectdata *conn)
1318{
1319#ifdef USE_WINDOWS_SSPI
1320  ntlm_sspi_cleanup(&conn->ntlm);
1321  ntlm_sspi_cleanup(&conn->proxyntlm);
1322#else
1323  (void)conn;
1324#endif
1325}
1326
1327
1328#endif /* USE_NTLM */
1329#endif /* !CURL_DISABLE_HTTP */
1330