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