2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
4 Contributed by Daniel Stenberg.
6 This file is part of GNU Wget.
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.
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.
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/>.
21 Additional permission under GNU GPL version 3 section 7
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. */
36 http://davenport.sourceforge.net/ntlm.html
37 http://www.innovation.ch/java/ntlm.html
46 #include "http-ntlm.h"
49 # include <nettle/md4.h>
50 # include <nettle/des.h>
52 # include <openssl/des.h>
53 # include <openssl/md4.h>
54 # include <openssl/opensslv.h>
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
63 /* This is how things were done in the old days */
65 # define DESKEYARG(x) x
68 # define DESKEYARG(x) *x
74 /* Define this to make the type-3 message include the NT response message */
75 #define USE_NTRESPONSES 1
78 /* Flag bits definitions available at on
79 http://davenport.sourceforge.net/ntlm.html */
81 #define NTLMFLAG_NEGOTIATE_OEM (1<<1)
82 #define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
85 (*) = A "security buffer" is a triplet consisting of two shorts and one
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.
94 /* return true on success, false otherwise */
96 ntlm_input (struct ntlmdata *ntlm, const char *header)
98 if (0 != strncmp (header, "NTLM", 4))
102 while (*header && c_isspace(*header))
107 /* We got a type-2 message here:
109 Index Description Content
110 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
112 8 NTLM Message Type long (0x02000000)
113 12 Target Name security buffer(*)
116 (32) Context (optional) 8 bytes (two consecutive longs)
117 (40) Target Information (optional) security buffer(*)
118 32 (48) start of data block
121 char *buffer = (char *) alloca (strlen (header));
123 DEBUGP (("Received a type-2 NTLM message.\n"));
125 size = base64_decode (header, buffer);
127 return false; /* malformed base64 from server */
129 ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
132 /* the nonce of interest is index [24 .. 31], 8 bytes */
133 memcpy (ntlm->nonce, &buffer[24], 8);
135 /* at index decimal 20, there's a 32bit NTLM flag field */
139 if (ntlm->state >= NTLMSTATE_TYPE1)
141 DEBUGP (("Unexpected empty NTLM message.\n"));
142 return false; /* this is an error */
145 DEBUGP (("Empty NTLM message, starting transaction.\n"));
146 ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
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.
158 setup_des_key(unsigned char *key_56,
161 unsigned char key[8];
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;
172 nettle_des_set_key(des, key);
176 setup_des_key(unsigned char *key_56,
177 DES_key_schedule DESKEYARG(ks))
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;
190 DES_set_odd_parity(&key);
191 DES_set_key(&key, ks);
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.
201 calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
206 setup_des_key(keys, &des);
207 nettle_des_encrypt(&des, 8, results, plaintext);
209 setup_des_key(keys + 7, &des);
210 nettle_des_encrypt(&des, 8, results + 8, plaintext);
212 setup_des_key(keys + 14, &des);
213 nettle_des_encrypt(&des, 8, results + 16, plaintext);
217 setup_des_key(keys, DESKEY(ks));
218 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
219 DESKEY(ks), DES_ENCRYPT);
221 setup_des_key(keys+7, DESKEY(ks));
222 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
223 DESKEY(ks), DES_ENCRYPT);
225 setup_des_key(keys+14, DESKEY(ks));
226 DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
227 DESKEY(ks), DES_ENCRYPT);
232 * Set up lanmanager and nt hashed passwords
235 mkhash(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 */
243 unsigned char lmbuffer[21];
244 #ifdef USE_NTRESPONSES
245 unsigned char ntbuffer[21];
248 static const unsigned char magic[] = {
249 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
251 size_t i, len = strlen(password);
253 /* make it fit at least 14 bytes */
254 pw = (unsigned char *) alloca (len < 7 ? 14 : len * 2);
259 for (i=0; i<len; i++)
260 pw[i] = (unsigned char) c_toupper (password[i]);
266 /* create LanManager hashed password */
270 setup_des_key(pw, &des);
271 nettle_des_encrypt(&des, 8, lmbuffer, magic);
273 setup_des_key(pw + 7, &des);
274 nettle_des_encrypt(&des, 8, lmbuffer + 8, magic);
278 setup_des_key(pw, DESKEY(ks));
279 DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
280 DESKEY(ks), DES_ENCRYPT);
282 setup_des_key(pw+7, DESKEY(ks));
283 DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
284 DESKEY(ks), DES_ENCRYPT);
287 memset(lmbuffer+16, 0, 5);
289 /* create LM responses */
290 calc_resp(lmbuffer, nonce, lmresp);
292 #ifdef USE_NTRESPONSES
300 len = strlen(password);
302 for (i=0; i<len; i++) {
303 pw[2*i] = (unsigned char) password[i];
308 nettle_md4_init(&MD4);
309 nettle_md4_update(&MD4, (unsigned) (2 * len), pw);
310 nettle_md4_digest(&MD4, MD4_DIGEST_SIZE, ntbuffer);
312 /* create NT hashed password */
314 MD4_Update(&MD4, pw, 2*len);
315 MD4_Final(ntbuffer, &MD4);
318 memset(ntbuffer+16, 0, 5);
321 calc_resp(ntbuffer, nonce, ntresp);
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)
329 /* this is for creating ntlm header output */
331 ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
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 */
342 char ntlmbuf[256]; /* enough, unless the host/domain is very long */
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 */
350 /* not set means empty */
357 switch(ntlm->state) {
358 case NTLMSTATE_TYPE1:
362 domoff = hostoff + hostlen;
364 DEBUGP (("Creating a type-1 NTLM message.\n"));
366 /* Create and send a type-1 message:
368 Index Description Content
369 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
371 8 NTLM Message Type long (0x01000000)
373 16 Supplied Domain security buffer(*)
374 24 Supplied Workstation security buffer(*)
375 32 start of data block
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 */
391 "%s", /* domain string */
392 0, /* trailing zero */
393 0,0,0, /* part of type-1 long */
396 NTLMFLAG_NEGOTIATE_OEM| /* 2 */
397 NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
410 /* initial packet length */
411 size = 32 + hostlen + domlen;
413 base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
414 base64_encode (ntlmbuf, size, base64);
416 output = concat_strings ("NTLM ", base64, (char *) 0);
419 case NTLMSTATE_TYPE2:
420 /* We received the type-2 already, create a type-3 message:
422 Index Description Content
423 0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
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
441 unsigned char lmresp[0x18]; /* fixed-size */
442 #ifdef USE_NTRESPONSES
443 unsigned char ntresp[0x18]; /* fixed-size */
448 DEBUGP (("Creating a type-3 NTLM message.\n"));
450 usr = strchr(user, '\\');
452 usr = strchr(user, '/');
456 domlen = (size_t) (usr - domain);
461 userlen = strlen(usr);
463 mkhash(passwd, &ntlm->nonce[0], lmresp
464 #ifdef USE_NTRESPONSES
469 domoff = 64; /* always */
470 useroff = domoff + domlen;
471 hostoff = useroff + userlen;
472 lmrespoff = hostoff + hostlen;
473 ntrespoff = lmrespoff + 0x18;
475 /* Create the big type-3 message binary blob */
477 size = (size_t) snprintf (ntlmbuf, sizeof(ntlmbuf),
479 "\x03%c%c%c" /* type-3, 32 bits */
481 "%c%c%c%c" /* LanManager length + allocated space */
482 "%c%c" /* LanManager offset */
483 "%c%c" /* 2 zeroes */
485 "%c%c" /* NT-response length */
486 "%c%c" /* NT-response allocated space */
487 "%c%c" /* NT-response offset */
488 "%c%c" /* 2 zeroes */
490 "%c%c" /* domain length */
491 "%c%c" /* domain allocated space */
492 "%c%c" /* domain name offset */
493 "%c%c" /* 2 zeroes */
495 "%c%c" /* user length */
496 "%c%c" /* user allocated space */
497 "%c%c" /* user offset */
498 "%c%c" /* 2 zeroes */
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 */
505 "\xff\xff" /* message length */
506 "%c%c" /* 2 zeroes */
508 "\x01\x82" /* flags */
509 "%c%c" /* 2 zeroes */
514 /* LanManager response */
517 0, /* zero termination */
518 0,0,0, /* type-3 long, the 24 upper bits */
520 SHORTPAIR(0x18), /* LanManager response length, twice */
522 SHORTPAIR(lmrespoff),
525 #ifdef USE_NTRESPONSES
526 SHORTPAIR(0x18), /* NT-response length, twice */
532 SHORTPAIR(ntrespoff),
548 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
556 ntlmbuf[62]=ntlmbuf[63]=0;
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))
563 memcpy(&ntlmbuf[size], domain, domlen);
566 memcpy(&ntlmbuf[size], usr, userlen);
569 /* we append the binary hashes to the end of the blob */
570 if(size < (sizeof(ntlmbuf) - 0x18)) {
571 memcpy(&ntlmbuf[size], lmresp, 0x18);
575 #ifdef USE_NTRESPONSES
576 if(size < (sizeof(ntlmbuf) - 0x18)) {
577 memcpy(&ntlmbuf[size], ntresp, 0x18);
582 ntlmbuf[56] = (char) (size & 0xff);
583 ntlmbuf[57] = (char) (size >> 8);
585 /* convert the binary blob into base64 */
586 base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
587 base64_encode (ntlmbuf, size, base64);
589 output = concat_strings ("NTLM ", base64, (char *) 0);
591 ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
596 case NTLMSTATE_TYPE3:
597 /* connection is already authenticated,
598 * don't send a header in future requests */