2
Copyright (C) 2005 Free Software Foundation, Inc.
3
Donated by Daniel Stenberg.
5
This file is part of GNU Wget.
7
GNU Wget is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
12
GNU Wget is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with Wget; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
In addition, as a special exception, the Free Software Foundation
22
gives permission to link the code of its release of Wget with the
23
OpenSSL project's "OpenSSL" library (or with modified versions of it
24
that use the same license as the "OpenSSL" library), and distribute
25
the linked executables. You must obey the GNU General Public License
26
in all respects for all of the code used other than "OpenSSL". If you
27
modify this file, you may extend this exception to your version of the
28
file, but you are not obligated to do so. If you do not wish to do
29
so, delete this exception statement from your version. */
35
http://davenport.sourceforge.net/ntlm.html
36
http://www.innovation.ch/java/ntlm.html
40
/* -- WIN32 approved -- */
49
#include <openssl/des.h>
50
#include <openssl/md4.h>
54
#include "http-ntlm.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
72
/* Define this to make the type-3 message include the NT response message */
73
#define USE_NTRESPONSES 1
75
/* Flag bits definitions available at on
76
http://davenport.sourceforge.net/ntlm.html */
78
#define NTLMFLAG_NEGOTIATE_UNICODE (1<<0)
79
#define NTLMFLAG_NEGOTIATE_OEM (1<<1)
80
#define NTLMFLAG_REQUEST_TARGET (1<<2)
82
#define NTLMFLAG_NEGOTIATE_SIGN (1<<4)
83
#define NTLMFLAG_NEGOTIATE_SEAL (1<<5)
84
#define NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE (1<<6)
85
#define NTLMFLAG_NEGOTIATE_LM_KEY (1<<7)
86
#define NTLMFLAG_NEGOTIATE_NETWARE (1<<8)
87
#define NTLMFLAG_NEGOTIATE_NTLM_KEY (1<<9)
90
#define NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED (1<<12)
91
#define NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED (1<<13)
92
#define NTLMFLAG_NEGOTIATE_LOCAL_CALL (1<<14)
93
#define NTLMFLAG_NEGOTIATE_ALWAYS_SIGN (1<<15)
94
#define NTLMFLAG_TARGET_TYPE_DOMAIN (1<<16)
95
#define NTLMFLAG_TARGET_TYPE_SERVER (1<<17)
96
#define NTLMFLAG_TARGET_TYPE_SHARE (1<<18)
97
#define NTLMFLAG_NEGOTIATE_NTLM2_KEY (1<<19)
98
#define NTLMFLAG_REQUEST_INIT_RESPONSE (1<<20)
99
#define NTLMFLAG_REQUEST_ACCEPT_RESPONSE (1<<21)
100
#define NTLMFLAG_REQUEST_NONNT_SESSION_KEY (1<<22)
101
#define NTLMFLAG_NEGOTIATE_TARGET_INFO (1<<23)
107
#define NTLMFLAG_NEGOTIATE_128 (1<<29)
108
#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE (1<<30)
109
#define NTLMFLAG_NEGOTIATE_56 (1<<31)
112
(*) = A "security buffer" is a triplet consisting of two shorts and one
115
1. a 'short' containing the length of the buffer in bytes
116
2. a 'short' containing the allocated space for the buffer in bytes
117
3. a 'long' containing the offset to the start of the buffer from the
118
beginning of the NTLM message, in bytes.
121
/* return 1 on success, 0 otherwise */
123
ntlm_input (struct ntlmdata *ntlm, const char *header)
125
if (0 != strncmp (header, "NTLM", 4))
129
while (*header && ISSPACE(*header))
134
/* We got a type-2 message here:
136
Index Description Content
137
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
139
8 NTLM Message Type long (0x02000000)
140
12 Target Name security buffer(*)
143
(32) Context (optional) 8 bytes (two consecutive longs)
144
(40) Target Information (optional) security buffer(*)
145
32 (48) start of data block
148
char *buffer = (char *) alloca (strlen (header));
150
DEBUGP (("Received a type-2 NTLM message.\n"));
152
size = base64_decode (header, buffer);
154
return 0; /* malformed base64 from server */
156
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
159
/* the nonce of interest is index [24 .. 31], 8 bytes */
160
memcpy (ntlm->nonce, &buffer[24], 8);
162
/* at index decimal 20, there's a 32bit NTLM flag field */
166
if (ntlm->state >= NTLMSTATE_TYPE1)
168
DEBUGP (("Unexpected empty NTLM message.\n"));
169
return 0; /* this is an error */
172
DEBUGP (("Empty NTLM message, starting transaction.\n"));
173
ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
180
* Turns a 56 bit key into the 64 bit, odd parity key and sets the key. The
181
* key schedule ks is also set.
184
setup_des_key(unsigned char *key_56,
185
DES_key_schedule DESKEYARG(ks))
190
key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
191
key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
192
key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
193
key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
194
key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
195
key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
196
key[7] = (key_56[6] << 1) & 0xFF;
198
DES_set_odd_parity(&key);
199
DES_set_key(&key, ks);
203
* takes a 21 byte array and treats it as 3 56-bit DES keys. The
204
* 8 byte plaintext is encrypted with each key and the resulting 24
205
* bytes are stored in the results array.
208
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
212
setup_des_key(keys, DESKEY(ks));
213
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
214
DESKEY(ks), DES_ENCRYPT);
216
setup_des_key(keys+7, DESKEY(ks));
217
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
218
DESKEY(ks), DES_ENCRYPT);
220
setup_des_key(keys+14, DESKEY(ks));
221
DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
222
DESKEY(ks), DES_ENCRYPT);
226
* Set up lanmanager and nt hashed passwords
229
mkhash(const char *password,
230
unsigned char *nonce, /* 8 bytes */
231
unsigned char *lmresp /* must fit 0x18 bytes */
232
#ifdef USE_NTRESPONSES
233
, unsigned char *ntresp /* must fit 0x18 bytes */
237
unsigned char lmbuffer[21];
238
#ifdef USE_NTRESPONSES
239
unsigned char ntbuffer[21];
242
static const unsigned char magic[] = {
243
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
246
int len = strlen(password);
248
/* make it fit at least 14 bytes */
249
pw = (unsigned char *) alloca (len < 7 ? 14 : len * 2);
254
for (i=0; i<len; i++)
255
pw[i] = TOUPPER (password[i]);
261
/* create LanManager hashed password */
264
setup_des_key(pw, DESKEY(ks));
265
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
266
DESKEY(ks), DES_ENCRYPT);
268
setup_des_key(pw+7, DESKEY(ks));
269
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
270
DESKEY(ks), DES_ENCRYPT);
272
memset(lmbuffer+16, 0, 5);
274
/* create LM responses */
275
calc_resp(lmbuffer, nonce, lmresp);
277
#ifdef USE_NTRESPONSES
279
/* create NT hashed password */
282
len = strlen(password);
284
for (i=0; i<len; i++) {
285
pw[2*i] = password[i];
290
MD4_Update(&MD4, pw, 2*len);
291
MD4_Final(ntbuffer, &MD4);
293
memset(ntbuffer+16, 0, 5);
296
calc_resp(ntbuffer, nonce, ntresp);
300
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
301
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
302
(((x) >>16)&0xff), ((x)>>24)
304
/* this is for creating ntlm header output */
306
ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
309
const char *domain=""; /* empty */
310
const char *host=""; /* empty */
311
int domlen=strlen(domain);
312
int hostlen = strlen(host);
313
int hostoff; /* host name offset */
314
int domoff; /* domain name offset */
317
char ntlmbuf[256]; /* enough, unless the host/domain is very long */
319
/* point to the address of the pointer that holds the string to sent to the
320
server, which is for a plain host or for a HTTP proxy */
325
/* not set means empty */
332
switch(ntlm->state) {
333
case NTLMSTATE_TYPE1:
334
default: /* for the weird cases we (re)start here */
336
domoff = hostoff + hostlen;
338
DEBUGP (("Creating a type-1 NTLM message.\n"));
340
/* Create and send a type-1 message:
342
Index Description Content
343
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
345
8 NTLM Message Type long (0x01000000)
347
16 Supplied Domain security buffer(*)
348
24 Supplied Workstation security buffer(*)
349
32 start of data block
351
Format string (merged for pre-ANSI compilers):
353
"\x01%c%c%c" 32-bit type = 1
354
"%c%c%c%c" 32-bit NTLM flag field
356
"%c%c" domain allocated space
357
"%c%c" domain name offset
360
"%c%c" host allocated space
361
"%c%c" host name offset
367
snprintf(ntlmbuf, sizeof(ntlmbuf),
368
"NTLMSSP%c\001%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%s%s",
369
0, /* trailing zero */
370
0,0,0, /* part of type-1 long */
373
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
374
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
387
/* initial packet length */
388
size = 32 + hostlen + domlen;
390
base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
391
base64_encode (ntlmbuf, size, base64);
393
output = concat_strings ("NTLM ", base64, (char *) 0);
396
case NTLMSTATE_TYPE2:
397
/* We received the type-2 already, create a type-3 message:
399
Index Description Content
400
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
402
8 NTLM Message Type long (0x03000000)
403
12 LM/LMv2 Response security buffer(*)
404
20 NTLM/NTLMv2 Response security buffer(*)
405
28 Domain Name security buffer(*)
406
36 User Name security buffer(*)
407
44 Workstation Name security buffer(*)
408
(52) Session Key (optional) security buffer(*)
409
(60) Flags (optional) long
410
52 (64) start of data block
418
unsigned char lmresp[0x18]; /* fixed-size */
419
#ifdef USE_NTRESPONSES
420
unsigned char ntresp[0x18]; /* fixed-size */
425
DEBUGP (("Creating a type-3 NTLM message.\n"));
427
usr = strchr(user, '\\');
429
usr = strchr(user, '/');
433
domlen = usr - domain;
438
userlen = strlen(usr);
440
mkhash(passwd, &ntlm->nonce[0], lmresp
441
#ifdef USE_NTRESPONSES
446
domoff = 64; /* always */
447
useroff = domoff + domlen;
448
hostoff = useroff + userlen;
449
lmrespoff = hostoff + hostlen;
450
ntrespoff = lmrespoff + 0x18;
452
/* Create the big type-3 message binary blob:
454
"\x03%c%c%c" type-3, 32 bits
456
"%c%c%c%c" LanManager length + allocated space
457
"%c%c" LanManager offset
460
"%c%c" NT-response length
461
"%c%c" NT-response allocated space
462
"%c%c" NT-response offset
466
"%c%c" domain allocated space
467
"%c%c" domain name offset
471
"%c%c" user allocated space
476
"%c%c" host allocated space
478
"%c%c%c%c%c%c" 6 zeroes
480
"\xff\xff" message length
486
size = snprintf(ntlmbuf, sizeof(ntlmbuf),
487
"NTLMSSP%c\003%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\377\377%c%c\001\202%c%c",
488
0, /* zero termination */
489
0,0,0, /* type-3 long, the 24 upper bits */
491
SHORTPAIR(0x18), /* LanManager response length, twice */
493
SHORTPAIR(lmrespoff),
496
#ifdef USE_NTRESPONSES
497
SHORTPAIR(0x18), /* NT-response length, twice */
503
SHORTPAIR(ntrespoff),
519
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
527
ntlmbuf[62]=ntlmbuf[63]=0;
529
memcpy(&ntlmbuf[size], domain, domlen);
532
memcpy(&ntlmbuf[size], usr, userlen);
535
/* we append the binary hashes to the end of the blob */
536
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
537
memcpy(&ntlmbuf[size], lmresp, 0x18);
541
#ifdef USE_NTRESPONSES
542
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
543
memcpy(&ntlmbuf[size], ntresp, 0x18);
548
ntlmbuf[56] = size & 0xff;
549
ntlmbuf[57] = size >> 8;
551
/* convert the binary blob into base64 */
552
base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
553
base64_encode (ntlmbuf, size, base64);
555
output = concat_strings ("NTLM ", base64, (char *) 0);
557
ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
562
case NTLMSTATE_TYPE3:
563
/* connection is already authenticated,
564
* don't send a header in future requests */