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