89
97
/* Define this to make the type-3 message include the NT response message */
90
98
#define USE_NTRESPONSES 1
100
/* Define this to make the type-3 message include the NTLM2Session response
101
message, requires USE_NTRESPONSES. */
102
#define USE_NTLM2SESSION 1
104
#ifndef USE_WINDOWS_SSPI
105
/* this function converts from the little endian format used in the incoming
106
package to whatever endian format we're using natively */
107
static unsigned int readint_le(unsigned char *buf) /* must point to a
110
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
111
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
116
# define DEBUG_OUT(x) x
117
static void print_flags(FILE *handle, unsigned long flags)
119
if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
120
fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE ");
121
if(flags & NTLMFLAG_NEGOTIATE_OEM)
122
fprintf(handle, "NTLMFLAG_NEGOTIATE_OEM ");
123
if(flags & NTLMFLAG_REQUEST_TARGET)
124
fprintf(handle, "NTLMFLAG_REQUEST_TARGET ");
126
fprintf(handle, "NTLMFLAG_UNKNOWN_3 ");
127
if(flags & NTLMFLAG_NEGOTIATE_SIGN)
128
fprintf(handle, "NTLMFLAG_NEGOTIATE_SIGN ");
129
if(flags & NTLMFLAG_NEGOTIATE_SEAL)
130
fprintf(handle, "NTLMFLAG_NEGOTIATE_SEAL ");
131
if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
132
fprintf(handle, "NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
133
if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
134
fprintf(handle, "NTLMFLAG_NEGOTIATE_LM_KEY ");
135
if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
136
fprintf(handle, "NTLMFLAG_NEGOTIATE_NETWARE ");
137
if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
138
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM_KEY ");
140
fprintf(handle, "NTLMFLAG_UNKNOWN_10 ");
142
fprintf(handle, "NTLMFLAG_UNKNOWN_11 ");
143
if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
144
fprintf(handle, "NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
145
if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
146
fprintf(handle, "NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
147
if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
148
fprintf(handle, "NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
149
if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
150
fprintf(handle, "NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
151
if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
152
fprintf(handle, "NTLMFLAG_TARGET_TYPE_DOMAIN ");
153
if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
154
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SERVER ");
155
if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
156
fprintf(handle, "NTLMFLAG_TARGET_TYPE_SHARE ");
157
if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
158
fprintf(handle, "NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
159
if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
160
fprintf(handle, "NTLMFLAG_REQUEST_INIT_RESPONSE ");
161
if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
162
fprintf(handle, "NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
163
if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
164
fprintf(handle, "NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
165
if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
166
fprintf(handle, "NTLMFLAG_NEGOTIATE_TARGET_INFO ");
168
fprintf(handle, "NTLMFLAG_UNKNOWN_24 ");
170
fprintf(handle, "NTLMFLAG_UNKNOWN_25 ");
172
fprintf(handle, "NTLMFLAG_UNKNOWN_26 ");
174
fprintf(handle, "NTLMFLAG_UNKNOWN_27 ");
176
fprintf(handle, "NTLMFLAG_UNKNOWN_28 ");
177
if(flags & NTLMFLAG_NEGOTIATE_128)
178
fprintf(handle, "NTLMFLAG_NEGOTIATE_128 ");
179
if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
180
fprintf(handle, "NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
181
if(flags & NTLMFLAG_NEGOTIATE_56)
182
fprintf(handle, "NTLMFLAG_NEGOTIATE_56 ");
185
static void print_hex(FILE *handle, const char *buf, size_t len)
188
fprintf(stderr, "0x");
190
fprintf(stderr, "%02.2x", (unsigned int)*p++);
193
# define DEBUG_OUT(x)
93
197
(*) = A "security buffer" is a triplet consisting of two shorts and one
143
250
ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
145
252
#ifdef USE_WINDOWS_SSPI
146
if ((ntlm->type_2 = malloc(size+1)) == NULL) {
253
ntlm->type_2 = malloc(size+1);
254
if (ntlm->type_2 == NULL) {
148
256
return CURLE_OUT_OF_MEMORY;
150
258
ntlm->n_type_2 = size;
151
259
memcpy(ntlm->type_2, buffer, size);
154
/* the nonce of interest is index [24 .. 31], 8 bytes */
155
memcpy(ntlm->nonce, &buffer[24], 8);
156
/* FIX: add an else here! */
158
/* at index decimal 20, there's a 32bit NTLM flag field */
264
(memcmp(buffer, "NTLMSSP", 8) != 0) ||
265
(memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
266
/* This was not a good enough type-2 message */
271
ntlm->flags = readint_le(&buffer[20]);
272
memcpy(ntlm->nonce, &buffer[24], 8);
275
fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
276
print_flags(stderr, ntlm->flags);
277
fprintf(stderr, "\n nonce=");
278
print_hex(stderr, ntlm->nonce, 8);
279
fprintf(stderr, "\n****\n");
218
340
DESKEY(ks), DES_ENCRYPT);
222
* Set up lanmanager and nt hashed passwords
345
* Set up lanmanager hashed password
224
static void mkhash(char *password,
225
unsigned char *nonce, /* 8 bytes */
226
unsigned char *lmresp /* must fit 0x18 bytes */
227
#ifdef USE_NTRESPONSES
228
, unsigned char *ntresp /* must fit 0x18 bytes */
347
static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
232
/* 21 bytes fits 3 7-bytes chunks, as we use 56 bit (7 bytes) as DES input,
233
and we add three different ones, see the calc_resp() function */
234
unsigned char lmbuffer[21];
235
#ifdef USE_NTRESPONSES
236
unsigned char ntbuffer[21];
349
unsigned char pw[14];
239
350
static const unsigned char magic[] = {
240
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
351
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 /* i.e. KGS!@#$% */
243
354
size_t len = strlen(password);
245
/* make it fit at least 14 bytes */
246
pw = malloc(len<7?14:len*2);
248
return; /* this will lead to a badly generated package */
268
375
DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
269
376
DESKEY(ks), DES_ENCRYPT);
271
memset(lmbuffer+16, 0, sizeof(lmbuffer)-16);
273
/* create LM responses */
274
calc_resp(lmbuffer, nonce, lmresp);
276
#ifdef USE_NTRESPONSES
378
memset(lmbuffer + 16, 0, 21 - 16);
383
static void utf8_to_unicode_le(unsigned char *dest, const char *src,
387
for (i=0; i<srclen; i++) {
388
dest[2*i] = (unsigned char)src[i];
394
* Set up nt hashed passwords
396
static void mk_nt_hash(char *password, unsigned char *ntbuffer /* 21 bytes */)
398
size_t len = strlen(password);
399
unsigned char *pw = malloc(len*2);
401
utf8_to_unicode_le(pw, password, len);
278
/* create NT hashed password */
404
/* Create NT hashed password. */
281
len = strlen(password);
283
for (i=0; i<len; i++) {
284
pw[2*i] = password[i];
289
408
MD4_Update(&MD4, pw, 2*len);
290
409
MD4_Final(ntbuffer, &MD4);
292
memset(ntbuffer+16, 0, sizeof(ntbuffer)-16);
411
memset(ntbuffer + 16, 0, 21 - 16);
295
calc_resp(ntbuffer, nonce, ntresp);
327
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
445
#define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff)
328
446
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
329
(((x) >>16)&0xff), ((x)>>24)
447
(((x) >>16)&0xff), (((x)>>24) & 0xff)
449
#define HOSTNAME_MAX 1024
331
451
/* this is for creating ntlm header output */
332
452
CURLcode Curl_output_ntlm(struct connectdata *conn,
335
455
const char *domain=""; /* empty */
336
const char *host=""; /* empty */
456
char host [HOSTNAME_MAX+ 1] = ""; /* empty */
337
457
#ifndef USE_WINDOWS_SSPI
338
int domlen=(int)strlen(domain);
339
int hostlen = (int)strlen(host);
340
int hostoff; /* host name offset */
341
int domoff; /* domain name offset */
458
size_t domlen = strlen(domain);
459
size_t hostlen = strlen(host);
460
size_t hostoff; /* host name offset */
461
size_t domoff; /* domain name offset */
344
464
char *base64=NULL;
345
unsigned char ntlmbuf[512]; /* enough, unless the host/domain is very long */
465
unsigned char ntlmbuf[1024]; /* enough, unless the user+host+domain is very
347
468
/* point to the address of the pointer that holds the string to sent to the
348
469
server, which is for a plain host or for a HTTP proxy */
545
673
SHORTPAIR(hostlen),
546
674
SHORTPAIR(hostoff),
676
host /* this is empty */, domain /* this is empty */);
550
678
/* initial packet length */
551
679
size = 32 + hostlen + domlen;
554
/* now keeper of the base64 encoded package size */
683
fprintf(stderr, "**** TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
684
LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM|
685
NTLMFLAG_REQUEST_TARGET|
686
NTLMFLAG_NEGOTIATE_NTLM_KEY|
688
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
689
NTLMFLAG_NEGOTIATE_OEM|
690
NTLMFLAG_REQUEST_TARGET|
691
NTLMFLAG_NEGOTIATE_NTLM_KEY|
693
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
695
NTLMFLAG_NEGOTIATE_OEM|
696
NTLMFLAG_REQUEST_TARGET|
697
NTLMFLAG_NEGOTIATE_NTLM_KEY|
699
NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
700
fprintf(stderr, "\n****\n");
703
/* now size is the size of the base64 encoded package size */
555
704
size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
640
domlen = (int)(user - domain);
789
domlen = (user - domain);
645
userlen = (int)strlen(user);
647
mkhash(passwdp, &ntlm->nonce[0], lmresp
648
#ifdef USE_NTRESPONSES
653
domoff = 64; /* always */
794
userlen = strlen(user);
796
if (gethostname(host, HOSTNAME_MAX)) {
797
infof(conn->data, "gethostname() failed, continuing without!");
801
hostlen = strlen(host);
805
/* We don't support NTLM2 if we don't have USE_NTRESPONSES */
806
if (ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
807
unsigned char ntbuffer[0x18];
808
unsigned char tmp[0x18];
809
unsigned char md5sum[MD5_DIGEST_LENGTH];
811
unsigned char random[8];
813
/* Need to create 8 bytes random data */
814
Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */
815
RAND_bytes(random,8);
817
/* 8 bytes random data as challenge in lmresp */
818
memcpy(lmresp,random,8);
820
memset(lmresp+8,0,0x10);
822
/* Fill tmp with challenge(nonce?) + random */
823
memcpy(tmp,&ntlm->nonce[0],8);
824
memcpy(tmp+8,random,8);
827
MD5_Update(&MD5, tmp, 16);
828
MD5_Final(md5sum, &MD5);
829
/* We shall only use the first 8 bytes of md5sum,
830
but the des code in lm_resp only encrypt the first 8 bytes */
831
mk_nt_hash(passwdp, ntbuffer);
832
lm_resp(ntbuffer, md5sum, ntresp);
834
/* End of NTLM2 Session code */
840
unsigned char ntbuffer[0x18];
842
unsigned char lmbuffer[0x18];
845
mk_nt_hash(passwdp, ntbuffer);
846
lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
849
mk_lm_hash(passwdp, lmbuffer);
850
lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
851
/* A safer but less compatible alternative is:
852
* lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
853
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
856
lmrespoff = 64; /* size of the message header */
858
ntrespoff = lmrespoff + 0x18;
859
domoff = ntrespoff + 0x18;
861
domoff = lmrespoff + 0x18;
654
863
useroff = domoff + domlen;
655
864
hostoff = useroff + userlen;
656
lmrespoff = hostoff + hostlen;
657
ntrespoff = lmrespoff + 0x18;
659
866
/* Create the big type-3 message binary blob */
660
867
size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
662
869
"\x03%c%c%c" /* type-3, 32 bits */
664
"%c%c%c%c" /* LanManager length + allocated space */
871
"%c%c" /* LanManager length */
872
"%c%c" /* LanManager allocated space */
665
873
"%c%c" /* LanManager offset */
666
874
"%c%c" /* 2 zeroes */
728
938
SHORTPAIR(hostlen),
729
939
SHORTPAIR(hostlen),
730
940
SHORTPAIR(hostoff),
731
0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
739
ntlmbuf[62]=ntlmbuf[63]=0;
741
/* Make sure that the user and domain strings fit in the target buffer
742
before we copy them there. */
743
if(size + userlen + domlen >= sizeof(ntlmbuf)) {
744
failf(conn->data, "user + domain name too big");
948
LONGQUARTET(ntlm->flags));
949
DEBUG_OUT(assert(size==64));
951
DEBUG_OUT(assert(size == lmrespoff));
952
/* We append the binary hashes */
953
if(size < (sizeof(ntlmbuf) - 0x18)) {
954
memcpy(&ntlmbuf[size], lmresp, 0x18);
959
fprintf(stderr, "**** TYPE3 header lmresp=");
960
print_hex(stderr, &ntlmbuf[lmrespoff], 0x18);
964
if(size < (sizeof(ntlmbuf) - 0x18)) {
965
DEBUG_OUT(assert(size == ntrespoff));
966
memcpy(&ntlmbuf[size], ntresp, 0x18);
971
fprintf(stderr, "\n ntresp=");
972
print_hex(stderr, &ntlmbuf[ntrespoff], 0x18);
978
fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
979
LONGQUARTET(ntlm->flags), ntlm->flags);
980
print_flags(stderr, ntlm->flags);
981
fprintf(stderr, "\n****\n");
985
/* Make sure that the domain, user and host strings fit in the target
986
buffer before we copy them there. */
987
if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) {
988
failf(conn->data, "user + domain + host name too big");
745
989
return CURLE_OUT_OF_MEMORY;
992
curlassert(size == domoff);
748
993
memcpy(&ntlmbuf[size], domain, domlen);
996
curlassert(size == useroff);
751
997
memcpy(&ntlmbuf[size], user, userlen);
754
/* we append the binary hashes to the end of the blob */
755
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
756
memcpy(&ntlmbuf[size], lmresp, 0x18);
760
#ifdef USE_NTRESPONSES
761
if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
762
memcpy(&ntlmbuf[size], ntresp, 0x18);
767
ntlmbuf[56] = (unsigned char)(size & 0xff);
768
ntlmbuf[57] = (unsigned char)(size >> 8);
1000
curlassert(size == hostoff);
1001
memcpy(&ntlmbuf[size], host, hostlen);