1/* NTLM code.
2   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
3   Foundation, Inc.
4   Contributed by Daniel Stenberg.
5
6This file is part of GNU Wget.
7
8GNU Wget is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13GNU Wget is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with Wget.  If not, see <http://www.gnu.org/licenses/>.
20
21Additional permission under GNU GPL version 3 section 7
22
23If you modify this program, or any covered work, by linking or
24combining it with the OpenSSL project's OpenSSL library (or a
25modified version of that library), containing parts covered by the
26terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
27grants you additional permission to convey the resulting work.
28Corresponding Source for a non-source form of such a combination
29shall include the source code for the parts of OpenSSL used as well
30as that of the covered work.  */
31
32#include "wget.h"
33
34/* NTLM details:
35
36   http://davenport.sourceforge.net/ntlm.html
37   http://www.innovation.ch/java/ntlm.html
38
39*/
40
41#include <stdio.h>
42#include <string.h>
43#include <stdlib.h>
44
45#include "utils.h"
46#include "http-ntlm.h"
47
48#ifdef HAVE_NETTLE
49# include <nettle/md4.h>
50# include <nettle/des.h>
51#else
52# include <openssl/des.h>
53# include <openssl/md4.h>
54# include <openssl/opensslv.h>
55
56# if OPENSSL_VERSION_NUMBER < 0x00907001L
57#  define DES_key_schedule des_key_schedule
58#  define DES_cblock des_cblock
59#  define DES_set_odd_parity des_set_odd_parity
60#  define DES_set_key des_set_key
61#  define DES_ecb_encrypt des_ecb_encrypt
62
63/* This is how things were done in the old days */
64#  define DESKEY(x) x
65#  define DESKEYARG(x) x
66# else
67/* Modern version */
68#  define DESKEYARG(x) *x
69#  define DESKEY(x) &x
70# endif
71
72#endif
73
74/* Define this to make the type-3 message include the NT response message */
75#define USE_NTRESPONSES 1
76
77
78/* Flag bits definitions available at on
79   http://davenport.sourceforge.net/ntlm.html */
80
81#define NTLMFLAG_NEGOTIATE_OEM                   (1<<1)
82#define NTLMFLAG_NEGOTIATE_NTLM_KEY              (1<<9)
83
84/*
85  (*) = A "security buffer" is a triplet consisting of two shorts and one
86  long:
87
88  1. a 'short' containing the length of the buffer in bytes
89  2. a 'short' containing the allocated space for the buffer in bytes
90  3. a 'long' containing the offset to the start of the buffer from the
91     beginning of the NTLM message, in bytes.
92*/
93
94/* return true on success, false otherwise */
95bool
96ntlm_input (struct ntlmdata *ntlm, const char *header)
97{
98  if (0 != strncmp (header, "NTLM", 4))
99    return false;
100
101  header += 4;
102  while (*header && c_isspace(*header))
103    header++;
104
105  if (*header)
106    {
107      /* We got a type-2 message here:
108
109         Index   Description         Content
110         0       NTLMSSP Signature   Null-terminated ASCII "NTLMSSP"
111                                     (0x4e544c4d53535000)
112         8       NTLM Message Type   long (0x02000000)
113         12      Target Name         security buffer(*)
114         20      Flags               long
115         24      Challenge           8 bytes
116         (32)    Context (optional)  8 bytes (two consecutive longs)
117         (40)    Target Information  (optional) security buffer(*)
118         32 (48) start of data block
119      */
120      ssize_t size;
121      char *buffer = (char *) alloca (strlen (header));
122
123      DEBUGP (("Received a type-2 NTLM message.\n"));
124
125      size = base64_decode (header, buffer);
126      if (size < 0)
127        return false;           /* malformed base64 from server */
128
129      ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
130
131      if (size >= 48)
132        /* the nonce of interest is index [24 .. 31], 8 bytes */
133        memcpy (ntlm->nonce, &buffer[24], 8);
134
135      /* at index decimal 20, there's a 32bit NTLM flag field */
136    }
137  else
138    {
139      if (ntlm->state >= NTLMSTATE_TYPE1)
140        {
141          DEBUGP (("Unexpected empty NTLM message.\n"));
142          return false; /* this is an error */
143        }
144
145      DEBUGP (("Empty NTLM message, starting transaction.\n"));
146      ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
147    }
148
149  return true;
150}
151
152/*
153 * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
154 * key schedule ks is also set.
155 */
156#ifdef HAVE_NETTLE
157static void
158setup_des_key(unsigned char *key_56,
159              struct des_ctx *des)
160{
161  unsigned char key[8];
162
163  key[0] = key_56[0];
164  key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
165  key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
166  key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
167  key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
168  key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
169  key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
170  key[7] =  (key_56[6] << 1) & 0xFF;
171
172  nettle_des_set_key(des, key);
173}
174#else
175static void
176setup_des_key(unsigned char *key_56,
177              DES_key_schedule DESKEYARG(ks))
178{
179  DES_cblock key;
180
181  key[0] = key_56[0];
182  key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
183  key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
184  key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
185  key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
186  key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
187  key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
188  key[7] =  (key_56[6] << 1) & 0xFF;
189
190  DES_set_odd_parity(&key);
191  DES_set_key(&key, ks);
192}
193#endif
194
195 /*
196  * takes a 21 byte array and treats it as 3 56-bit DES keys. The
197  * 8 byte plaintext is encrypted with each key and the resulting 24
198  * bytes are stored in the results array.
199  */
200static void
201calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
202{
203#ifdef HAVE_NETTLE
204  struct des_ctx des;
205
206  setup_des_key(keys, &des);
207  nettle_des_encrypt(&des, 8, results, plaintext);
208
209  setup_des_key(keys + 7, &des);
210  nettle_des_encrypt(&des, 8, results + 8, plaintext);
211
212  setup_des_key(keys + 14, &des);
213  nettle_des_encrypt(&des, 8, results + 16, plaintext);
214#else
215  DES_key_schedule ks;
216
217  setup_des_key(keys, DESKEY(ks));
218  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
219                  DESKEY(ks), DES_ENCRYPT);
220
221  setup_des_key(keys+7, DESKEY(ks));
222  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
223                  DESKEY(ks), DES_ENCRYPT);
224
225  setup_des_key(keys+14, DESKEY(ks));
226  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
227                  DESKEY(ks), DES_ENCRYPT);
228#endif
229}
230
231/*
232 * Set up lanmanager and nt hashed passwords
233 */
234static void
235mkhash(const char *password,
236       unsigned char *nonce,    /* 8 bytes */
237       unsigned char *lmresp    /* must fit 0x18 bytes */
238#ifdef USE_NTRESPONSES
239       , unsigned char *ntresp  /* must fit 0x18 bytes */
240#endif
241  )
242{
243  unsigned char lmbuffer[21];
244#ifdef USE_NTRESPONSES
245  unsigned char ntbuffer[21];
246#endif
247  unsigned char *pw;
248  static const unsigned char magic[] = {
249    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
250  };
251  size_t i, len = strlen(password);
252
253  /* make it fit at least 14 bytes */
254  pw = (unsigned char *) alloca (len < 7 ? 14 : len * 2);
255
256  if (len > 14)
257    len = 14;
258
259  for (i=0; i<len; i++)
260    pw[i] = (unsigned char) c_toupper (password[i]);
261
262  for (; i<14; i++)
263    pw[i] = 0;
264
265  {
266    /* create LanManager hashed password */
267#ifdef HAVE_NETTLE
268    struct des_ctx des;
269
270    setup_des_key(pw, &des);
271    nettle_des_encrypt(&des, 8, lmbuffer, magic);
272
273    setup_des_key(pw + 7, &des);
274    nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
275#else
276    DES_key_schedule ks;
277
278    setup_des_key(pw, DESKEY(ks));
279    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
280                    DESKEY(ks), DES_ENCRYPT);
281
282    setup_des_key(pw+7, DESKEY(ks));
283    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
284                    DESKEY(ks), DES_ENCRYPT);
285#endif
286
287    memset(lmbuffer+16, 0, 5);
288  }
289  /* create LM responses */
290  calc_resp(lmbuffer, nonce, lmresp);
291
292#ifdef USE_NTRESPONSES
293  {
294#ifdef HAVE_NETTLE
295    struct md4_ctx MD4;
296#else
297    MD4_CTX MD4;
298#endif
299
300    len = strlen(password);
301
302    for (i=0; i<len; i++) {
303      pw[2*i]   = (unsigned char) password[i];
304      pw[2*i+1] = 0;
305    }
306
307#ifdef HAVE_NETTLE
308    nettle_md4_init(&MD4);
309    nettle_md4_update(&MD4, (unsigned) (2 * len), pw);
310    nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
311#else
312    /* create NT hashed password */
313    MD4_Init(&MD4);
314    MD4_Update(&MD4, pw, 2*len);
315    MD4_Final(ntbuffer, &MD4);
316#endif
317
318    memset(ntbuffer+16, 0, 5);
319  }
320
321  calc_resp(ntbuffer, nonce, ntresp);
322#endif
323}
324
325#define SHORTPAIR(x) (char) ((x) & 0xff), (char) ((x) >> 8)
326#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
327  (((x) >>16)&0xff), ((x)>>24)
328
329/* this is for creating ntlm header output */
330char *
331ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
332             bool *ready)
333{
334  const char *domain = ""; /* empty */
335  const char *host = ""; /* empty */
336  size_t domlen = strlen(domain);
337  size_t hostlen = strlen(host);
338  size_t hostoff; /* host name offset */
339  size_t domoff;  /* domain name offset */
340  size_t size;
341  char *base64;
342  char ntlmbuf[256]; /* enough, unless the host/domain is very long */
343
344  /* point to the address of the pointer that holds the string to sent to the
345     server, which is for a plain host or for a HTTP proxy */
346  char *output = NULL;
347
348  *ready = false;
349
350  /* not set means empty */
351  if(!user)
352    user="";
353
354  if(!passwd)
355    passwd="";
356
357  switch(ntlm->state) {
358  case NTLMSTATE_TYPE1:
359  case NTLMSTATE_NONE:
360  case NTLMSTATE_LAST:
361    hostoff = 32;
362    domoff = hostoff + hostlen;
363
364    DEBUGP (("Creating a type-1 NTLM message.\n"));
365
366    /* Create and send a type-1 message:
367
368    Index Description          Content
369    0     NTLMSSP Signature    Null-terminated ASCII "NTLMSSP"
370                               (0x4e544c4d53535000)
371    8     NTLM Message Type    long (0x01000000)
372    12    Flags                long
373    16    Supplied Domain      security buffer(*)
374    24    Supplied Workstation security buffer(*)
375    32    start of data block
376
377    */
378
379    snprintf (ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
380              "\x01%c%c%c" /* 32-bit type = 1 */
381              "%c%c%c%c"   /* 32-bit NTLM flag field */
382              "%c%c"  /* domain length */
383              "%c%c"  /* domain allocated space */
384              "%c%c"  /* domain name offset */
385              "%c%c"  /* 2 zeroes */
386              "%c%c"  /* host length */
387              "%c%c"  /* host allocated space */
388              "%c%c"  /* host name offset */
389              "%c%c"  /* 2 zeroes */
390              "%s"   /* host name */
391              "%s",  /* domain string */
392              0,     /* trailing zero */
393              0,0,0, /* part of type-1 long */
394
395              LONGQUARTET(
396                NTLMFLAG_NEGOTIATE_OEM|      /*   2 */
397                NTLMFLAG_NEGOTIATE_NTLM_KEY  /* 200 */
398                /* equals 0x0202 */
399                ),
400              SHORTPAIR(domlen),
401              SHORTPAIR(domlen),
402              SHORTPAIR(domoff),
403              0,0,
404              SHORTPAIR(hostlen),
405              SHORTPAIR(hostlen),
406              SHORTPAIR(hostoff),
407              0,0,
408              host, domain);
409
410    /* initial packet length */
411    size = 32 + hostlen + domlen;
412
413    base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
414    base64_encode (ntlmbuf, size, base64);
415
416    output = concat_strings ("NTLM ", base64, (char *) 0);
417    break;
418
419  case NTLMSTATE_TYPE2:
420    /* We received the type-2 already, create a type-3 message:
421
422    Index   Description            Content
423    0       NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
424                                   (0x4e544c4d53535000)
425    8       NTLM Message Type      long (0x03000000)
426    12      LM/LMv2 Response       security buffer(*)
427    20      NTLM/NTLMv2 Response   security buffer(*)
428    28      Domain Name            security buffer(*)
429    36      User Name              security buffer(*)
430    44      Workstation Name       security buffer(*)
431    (52)    Session Key (optional) security buffer(*)
432    (60)    Flags (optional)       long
433    52 (64) start of data block
434
435    */
436
437  {
438    size_t lmrespoff;
439    size_t ntrespoff;
440    size_t useroff;
441    unsigned char lmresp[0x18]; /* fixed-size */
442#ifdef USE_NTRESPONSES
443    unsigned char ntresp[0x18]; /* fixed-size */
444#endif
445    const char *usr;
446    size_t userlen;
447
448    DEBUGP (("Creating a type-3 NTLM message.\n"));
449
450    usr = strchr(user, '\\');
451    if(!usr)
452      usr = strchr(user, '/');
453
454    if (usr) {
455      domain = user;
456      domlen = (size_t) (usr - domain);
457      usr++;
458    }
459    else
460      usr = user;
461    userlen = strlen(usr);
462
463    mkhash(passwd, &ntlm->nonce[0], lmresp
464#ifdef USE_NTRESPONSES
465           , ntresp
466#endif
467      );
468
469    domoff = 64; /* always */
470    useroff = domoff + domlen;
471    hostoff = useroff + userlen;
472    lmrespoff = hostoff + hostlen;
473    ntrespoff = lmrespoff + 0x18;
474
475    /* Create the big type-3 message binary blob */
476
477    size = (size_t) snprintf (ntlmbuf, sizeof(ntlmbuf),
478                     "NTLMSSP%c"
479                     "\x03%c%c%c" /* type-3, 32 bits */
480
481                     "%c%c%c%c" /* LanManager length + allocated space */
482                     "%c%c" /* LanManager offset */
483                     "%c%c" /* 2 zeroes */
484
485                     "%c%c" /* NT-response length */
486                     "%c%c" /* NT-response allocated space */
487                     "%c%c" /* NT-response offset */
488                     "%c%c" /* 2 zeroes */
489
490                     "%c%c"  /* domain length */
491                     "%c%c"  /* domain allocated space */
492                     "%c%c"  /* domain name offset */
493                     "%c%c"  /* 2 zeroes */
494
495                     "%c%c"  /* user length */
496                     "%c%c"  /* user allocated space */
497                     "%c%c"  /* user offset */
498                     "%c%c"  /* 2 zeroes */
499
500                     "%c%c"  /* host length */
501                     "%c%c"  /* host allocated space */
502                     "%c%c"  /* host offset */
503                     "%c%c%c%c%c%c"  /* 6 zeroes */
504
505                     "\xff\xff"  /* message length */
506                     "%c%c"  /* 2 zeroes */
507
508                     "\x01\x82" /* flags */
509                     "%c%c"  /* 2 zeroes */
510
511                     /* domain string */
512                     /* user string */
513                     /* host string */
514                     /* LanManager response */
515                     /* NT response */
516                     ,
517                     0, /* zero termination */
518                     0,0,0, /* type-3 long, the 24 upper bits */
519
520                     SHORTPAIR(0x18),  /* LanManager response length, twice */
521                     SHORTPAIR(0x18),
522                     SHORTPAIR(lmrespoff),
523                     0x0, 0x0,
524
525#ifdef USE_NTRESPONSES
526                     SHORTPAIR(0x18),  /* NT-response length, twice */
527                     SHORTPAIR(0x18),
528#else
529                     0x0, 0x0,
530                     0x0, 0x0,
531#endif
532                     SHORTPAIR(ntrespoff),
533                     0x0, 0x0,
534
535                     SHORTPAIR(domlen),
536                     SHORTPAIR(domlen),
537                     SHORTPAIR(domoff),
538                     0x0, 0x0,
539
540                     SHORTPAIR(userlen),
541                     SHORTPAIR(userlen),
542                     SHORTPAIR(useroff),
543                     0x0, 0x0,
544
545                     SHORTPAIR(hostlen),
546                     SHORTPAIR(hostlen),
547                     SHORTPAIR(hostoff),
548                     0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
549
550                     0x0, 0x0,
551
552                     0x0, 0x0);
553
554    /* size is now 64 */
555    size=64;
556    ntlmbuf[62]=ntlmbuf[63]=0;
557
558    /* Make sure that the user and domain strings fit in the target buffer
559       before we copy them there. */
560    if((size + userlen + domlen) >= sizeof(ntlmbuf))
561      return NULL;
562
563    memcpy(&ntlmbuf[size], domain, domlen);
564    size += domlen;
565
566    memcpy(&ntlmbuf[size], usr, userlen);
567    size += userlen;
568
569    /* we append the binary hashes to the end of the blob */
570    if(size < (sizeof(ntlmbuf) - 0x18)) {
571      memcpy(&ntlmbuf[size], lmresp, 0x18);
572      size += 0x18;
573    }
574
575#ifdef USE_NTRESPONSES
576    if(size < (sizeof(ntlmbuf) - 0x18)) {
577      memcpy(&ntlmbuf[size], ntresp, 0x18);
578      size += 0x18;
579    }
580#endif
581
582    ntlmbuf[56] = (char) (size & 0xff);
583    ntlmbuf[57] = (char) (size >> 8);
584
585    /* convert the binary blob into base64 */
586    base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
587    base64_encode (ntlmbuf, size, base64);
588
589    output = concat_strings ("NTLM ", base64, (char *) 0);
590
591    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
592    *ready = true;
593  }
594  break;
595
596  case NTLMSTATE_TYPE3:
597    /* connection is already authenticated,
598     * don't send a header in future requests */
599    *ready = true;
600    output = NULL;
601    break;
602  }
603
604  return output;
605}
606