~ubuntu-branches/ubuntu/precise/wget/precise-proposed

« back to all changes in this revision

Viewing changes to src/http-ntlm.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2005-06-26 16:46:25 UTC
  • mfrom: (1.1.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050626164625-jjcde8hyztx7xq7o
Tags: 1.10-2
* wget-fix_error--save-headers patch from upstream
  (closes: Bug#314728)
* don't pattern-match server redirects patch from upstream
  (closes: Bug#163243)
* correct de.po typos
  (closes: Bug#313883)
* wget-E_html_behind_file_counting fix problem with adding the
  numbers after the html extension
* updated Standards-Version: to 3.6.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* NTLM code.
 
2
   Copyright (C) 2005 Free Software Foundation, Inc.
 
3
   Donated by Daniel Stenberg.
 
4
 
 
5
This file is part of GNU Wget.
 
6
 
 
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.
 
11
 
 
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.
 
16
 
 
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.
 
20
 
 
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.  */
 
30
 
 
31
#include <config.h>
 
32
 
 
33
/* NTLM details:
 
34
   
 
35
   http://davenport.sourceforge.net/ntlm.html
 
36
   http://www.innovation.ch/java/ntlm.html
 
37
 
 
38
*/
 
39
 
 
40
/* -- WIN32 approved -- */
 
41
#include <stdio.h>
 
42
#ifdef HAVE_STRING_H
 
43
# include <string.h>
 
44
#else
 
45
# include <strings.h>
 
46
#endif
 
47
#include <stdlib.h>
 
48
 
 
49
#include <openssl/des.h>
 
50
#include <openssl/md4.h>
 
51
 
 
52
#include "wget.h"
 
53
#include "utils.h"
 
54
#include "http-ntlm.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
/* Define this to make the type-3 message include the NT response message */
 
73
#define USE_NTRESPONSES 1
 
74
 
 
75
/* Flag bits definitions available at on
 
76
   http://davenport.sourceforge.net/ntlm.html */
 
77
 
 
78
#define NTLMFLAG_NEGOTIATE_UNICODE               (1<<0)
 
79
#define NTLMFLAG_NEGOTIATE_OEM                   (1<<1)
 
80
#define NTLMFLAG_REQUEST_TARGET                  (1<<2)
 
81
/* unknown (1<<3) */
 
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)
 
88
/* unknown (1<<10) */
 
89
/* unknown (1<<11) */
 
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)
 
102
/* unknown (1<24) */
 
103
/* unknown (1<25) */
 
104
/* unknown (1<26) */
 
105
/* unknown (1<27) */
 
106
/* unknown (1<28) */
 
107
#define NTLMFLAG_NEGOTIATE_128                   (1<<29)
 
108
#define NTLMFLAG_NEGOTIATE_KEY_EXCHANGE          (1<<30)
 
109
#define NTLMFLAG_NEGOTIATE_56                    (1<<31)
 
110
 
 
111
/*
 
112
  (*) = A "security buffer" is a triplet consisting of two shorts and one
 
113
  long:
 
114
 
 
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.
 
119
*/
 
120
 
 
121
/* return 1 on success, 0 otherwise */
 
122
int
 
123
ntlm_input (struct ntlmdata *ntlm, const char *header)
 
124
{
 
125
  if (0 != strncmp (header, "NTLM", 4))
 
126
    return 0;
 
127
 
 
128
  header += 4;
 
129
  while (*header && ISSPACE(*header))
 
130
    header++;
 
131
 
 
132
  if (*header)
 
133
    {
 
134
      /* We got a type-2 message here:
 
135
 
 
136
         Index   Description         Content
 
137
         0       NTLMSSP Signature   Null-terminated ASCII "NTLMSSP"
 
138
                                     (0x4e544c4d53535000)
 
139
         8       NTLM Message Type   long (0x02000000)
 
140
         12      Target Name         security buffer(*)
 
141
         20      Flags               long
 
142
         24      Challenge           8 bytes
 
143
         (32)    Context (optional)  8 bytes (two consecutive longs)
 
144
         (40)    Target Information  (optional) security buffer(*)
 
145
         32 (48) start of data block
 
146
      */
 
147
      int size;
 
148
      char *buffer = (char *) alloca (strlen (header));
 
149
 
 
150
      DEBUGP (("Received a type-2 NTLM message.\n"));
 
151
 
 
152
      size = base64_decode (header, buffer);
 
153
      if (size < 0)
 
154
        return 0;               /* malformed base64 from server */
 
155
 
 
156
      ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
 
157
 
 
158
      if (size >= 48)
 
159
        /* the nonce of interest is index [24 .. 31], 8 bytes */
 
160
        memcpy (ntlm->nonce, &buffer[24], 8);
 
161
 
 
162
      /* at index decimal 20, there's a 32bit NTLM flag field */
 
163
    }
 
164
  else
 
165
    {
 
166
      if (ntlm->state >= NTLMSTATE_TYPE1)
 
167
        {
 
168
          DEBUGP (("Unexpected empty NTLM message.\n"));
 
169
          return 0; /* this is an error */
 
170
        }
 
171
 
 
172
      DEBUGP (("Empty NTLM message, starting transaction.\n"));
 
173
      ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
 
174
    }
 
175
 
 
176
  return 1;
 
177
}
 
178
 
 
179
/*
 
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.
 
182
 */
 
183
static void
 
184
setup_des_key(unsigned char *key_56,
 
185
              DES_key_schedule DESKEYARG(ks))
 
186
{
 
187
  DES_cblock key;
 
188
 
 
189
  key[0] = key_56[0];
 
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;
 
197
 
 
198
  DES_set_odd_parity(&key);
 
199
  DES_set_key(&key, ks);
 
200
}
 
201
 
 
202
 /*
 
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.
 
206
  */
 
207
static void
 
208
calc_resp(unsigned char *keys, unsigned char *plaintext, unsigned char *results)
 
209
{
 
210
  DES_key_schedule ks;
 
211
 
 
212
  setup_des_key(keys, DESKEY(ks));
 
213
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
 
214
                  DESKEY(ks), DES_ENCRYPT);
 
215
 
 
216
  setup_des_key(keys+7, DESKEY(ks));
 
217
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
 
218
                  DESKEY(ks), DES_ENCRYPT);
 
219
 
 
220
  setup_des_key(keys+14, DESKEY(ks));
 
221
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
 
222
                  DESKEY(ks), DES_ENCRYPT);
 
223
}
 
224
 
 
225
/*
 
226
 * Set up lanmanager and nt hashed passwords
 
227
 */
 
228
static void
 
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 */
 
234
#endif
 
235
  )
 
236
{
 
237
  unsigned char lmbuffer[21];
 
238
#ifdef USE_NTRESPONSES
 
239
  unsigned char ntbuffer[21];
 
240
#endif
 
241
  unsigned char *pw;
 
242
  static const unsigned char magic[] = {
 
243
    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
 
244
  };
 
245
  int i;
 
246
  int len = strlen(password);
 
247
 
 
248
  /* make it fit at least 14 bytes */
 
249
  pw = (unsigned char *) alloca (len < 7 ? 14 : len * 2);
 
250
 
 
251
  if (len > 14)
 
252
    len = 14;
 
253
  
 
254
  for (i=0; i<len; i++)
 
255
    pw[i] = TOUPPER (password[i]);
 
256
 
 
257
  for (; i<14; i++)
 
258
    pw[i] = 0;
 
259
 
 
260
  {
 
261
    /* create LanManager hashed password */
 
262
    DES_key_schedule ks;
 
263
 
 
264
    setup_des_key(pw, DESKEY(ks));
 
265
    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
 
266
                    DESKEY(ks), DES_ENCRYPT);
 
267
  
 
268
    setup_des_key(pw+7, DESKEY(ks));
 
269
    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
 
270
                    DESKEY(ks), DES_ENCRYPT);
 
271
 
 
272
    memset(lmbuffer+16, 0, 5);
 
273
  }
 
274
  /* create LM responses */
 
275
  calc_resp(lmbuffer, nonce, lmresp);
 
276
 
 
277
#ifdef USE_NTRESPONSES
 
278
  {
 
279
    /* create NT hashed password */
 
280
    MD4_CTX MD4;
 
281
 
 
282
    len = strlen(password);
 
283
 
 
284
    for (i=0; i<len; i++) {
 
285
      pw[2*i]   = password[i];
 
286
      pw[2*i+1] = 0;
 
287
    }
 
288
 
 
289
    MD4_Init(&MD4);
 
290
    MD4_Update(&MD4, pw, 2*len);
 
291
    MD4_Final(ntbuffer, &MD4);
 
292
 
 
293
    memset(ntbuffer+16, 0, 5);
 
294
  }
 
295
 
 
296
  calc_resp(ntbuffer, nonce, ntresp);
 
297
#endif
 
298
}
 
299
 
 
300
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
 
301
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
 
302
  (((x) >>16)&0xff), ((x)>>24)
 
303
 
 
304
/* this is for creating ntlm header output */
 
305
char *
 
306
ntlm_output (struct ntlmdata *ntlm, const char *user, const char *passwd,
 
307
             int *ready)
 
308
{
 
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 */
 
315
  int size;
 
316
  char *base64;
 
317
  char ntlmbuf[256]; /* enough, unless the host/domain is very long */
 
318
 
 
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 */
 
321
  char *output;
 
322
 
 
323
  *ready = 0;
 
324
 
 
325
  /* not set means empty */
 
326
  if(!user)
 
327
    user="";
 
328
 
 
329
  if(!passwd)
 
330
    passwd="";
 
331
  
 
332
  switch(ntlm->state) {
 
333
  case NTLMSTATE_TYPE1:
 
334
  default: /* for the weird cases we (re)start here */
 
335
    hostoff = 32;
 
336
    domoff = hostoff + hostlen;
 
337
 
 
338
    DEBUGP (("Creating a type-1 NTLM message.\n"));
 
339
    
 
340
    /* Create and send a type-1 message:
 
341
 
 
342
    Index Description          Content
 
343
    0     NTLMSSP Signature    Null-terminated ASCII "NTLMSSP"
 
344
                               (0x4e544c4d53535000)
 
345
    8     NTLM Message Type    long (0x01000000)
 
346
    12    Flags                long
 
347
    16    Supplied Domain      security buffer(*)
 
348
    24    Supplied Workstation security buffer(*)
 
349
    32    start of data block
 
350
 
 
351
    Format string (merged for pre-ANSI compilers):
 
352
      "NTLMSSP%c"
 
353
      "\x01%c%c%c" 32-bit type = 1
 
354
      "%c%c%c%c"   32-bit NTLM flag field
 
355
      "%c%c"  domain length
 
356
      "%c%c"  domain allocated space
 
357
      "%c%c"  domain name offset
 
358
      "%c%c"  2 zeroes
 
359
      "%c%c"  host length
 
360
      "%c%c"  host allocated space
 
361
      "%c%c"  host name offset
 
362
      "%c%c"  2 zeroes
 
363
      "%s"    host name
 
364
      "%s"   domain string
 
365
    */
 
366
 
 
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 */
 
371
 
 
372
             LONGQUARTET(
 
373
               NTLMFLAG_NEGOTIATE_OEM|      /*   2 */
 
374
               NTLMFLAG_NEGOTIATE_NTLM_KEY  /* 200 */
 
375
               /* equals 0x0202 */
 
376
               ),
 
377
             SHORTPAIR(domlen),
 
378
             SHORTPAIR(domlen),
 
379
             SHORTPAIR(domoff),
 
380
             0,0,
 
381
             SHORTPAIR(hostlen),
 
382
             SHORTPAIR(hostlen),
 
383
             SHORTPAIR(hostoff),
 
384
             0,0,
 
385
             host, domain);
 
386
 
 
387
    /* initial packet length */
 
388
    size = 32 + hostlen + domlen;
 
389
 
 
390
    base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
 
391
    base64_encode (ntlmbuf, size, base64);
 
392
 
 
393
    output = concat_strings ("NTLM ", base64, (char *) 0);
 
394
    break;
 
395
    
 
396
  case NTLMSTATE_TYPE2:
 
397
    /* We received the type-2 already, create a type-3 message:
 
398
 
 
399
    Index   Description            Content
 
400
    0       NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
 
401
                                   (0x4e544c4d53535000)
 
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
 
411
 
 
412
    */
 
413
  
 
414
  {
 
415
    int lmrespoff;
 
416
    int ntrespoff;
 
417
    int useroff;
 
418
    unsigned char lmresp[0x18]; /* fixed-size */
 
419
#ifdef USE_NTRESPONSES
 
420
    unsigned char ntresp[0x18]; /* fixed-size */
 
421
#endif
 
422
    const char *usr;
 
423
    int userlen;
 
424
 
 
425
    DEBUGP (("Creating a type-3 NTLM message.\n"));
 
426
 
 
427
    usr = strchr(user, '\\');
 
428
    if(!usr)
 
429
      usr = strchr(user, '/');
 
430
 
 
431
    if (usr) {
 
432
      domain = user;
 
433
      domlen = usr - domain;
 
434
      usr++;
 
435
    }
 
436
    else
 
437
      usr = user;
 
438
    userlen = strlen(usr);
 
439
 
 
440
    mkhash(passwd, &ntlm->nonce[0], lmresp
 
441
#ifdef USE_NTRESPONSES
 
442
           , ntresp
 
443
#endif
 
444
      );
 
445
 
 
446
    domoff = 64; /* always */
 
447
    useroff = domoff + domlen;
 
448
    hostoff = useroff + userlen;
 
449
    lmrespoff = hostoff + hostlen;
 
450
    ntrespoff = lmrespoff + 0x18;
 
451
 
 
452
    /* Create the big type-3 message binary blob:
 
453
         "NTLMSSP%c"
 
454
         "\x03%c%c%c"  type-3, 32 bits 
 
455
 
 
456
         "%c%c%c%c"  LanManager length + allocated space 
 
457
         "%c%c"      LanManager offset 
 
458
         "%c%c"      2 zeroes 
 
459
 
 
460
         "%c%c"  NT-response length 
 
461
         "%c%c"  NT-response allocated space 
 
462
         "%c%c"  NT-response offset 
 
463
         "%c%c"  2 zeroes 
 
464
 
 
465
         "%c%c"  domain length 
 
466
         "%c%c"  domain allocated space 
 
467
         "%c%c"  domain name offset 
 
468
         "%c%c"  2 zeroes 
 
469
 
 
470
         "%c%c"  user length 
 
471
         "%c%c"  user allocated space 
 
472
         "%c%c"  user offset 
 
473
         "%c%c"  2 zeroes 
 
474
 
 
475
         "%c%c"  host length 
 
476
         "%c%c"  host allocated space 
 
477
         "%c%c"  host offset 
 
478
         "%c%c%c%c%c%c" 6 zeroes 
 
479
 
 
480
         "\xff\xff"   message length 
 
481
         "%c%c"   2 zeroes 
 
482
 
 
483
         "\x01\x82"  flags 
 
484
         "%c%c"   2 zeroes */
 
485
 
 
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 */
 
490
 
 
491
                    SHORTPAIR(0x18),  /* LanManager response length, twice */
 
492
                    SHORTPAIR(0x18),
 
493
                    SHORTPAIR(lmrespoff),
 
494
                    0x0, 0x0,
 
495
                    
 
496
#ifdef USE_NTRESPONSES
 
497
                    SHORTPAIR(0x18),  /* NT-response length, twice */
 
498
                    SHORTPAIR(0x18),
 
499
#else
 
500
                    0x0, 0x0,
 
501
                    0x0, 0x0,
 
502
#endif
 
503
                    SHORTPAIR(ntrespoff),
 
504
                    0x0, 0x0,
 
505
 
 
506
                    SHORTPAIR(domlen),
 
507
                    SHORTPAIR(domlen),
 
508
                    SHORTPAIR(domoff),
 
509
                    0x0, 0x0,
 
510
 
 
511
                    SHORTPAIR(userlen),
 
512
                    SHORTPAIR(userlen),
 
513
                    SHORTPAIR(useroff),
 
514
                    0x0, 0x0,
 
515
                    
 
516
                    SHORTPAIR(hostlen),
 
517
                    SHORTPAIR(hostlen),
 
518
                    SHORTPAIR(hostoff),
 
519
                    0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 
520
             
 
521
                    0x0, 0x0,
 
522
 
 
523
                    0x0, 0x0);
 
524
 
 
525
    /* size is now 64 */
 
526
    size=64;
 
527
    ntlmbuf[62]=ntlmbuf[63]=0;
 
528
 
 
529
    memcpy(&ntlmbuf[size], domain, domlen);
 
530
    size += domlen;
 
531
 
 
532
    memcpy(&ntlmbuf[size], usr, userlen);
 
533
    size += userlen;
 
534
 
 
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);
 
538
      size += 0x18;
 
539
    }
 
540
 
 
541
#ifdef USE_NTRESPONSES
 
542
    if(size < ((int)sizeof(ntlmbuf) - 0x18)) {      
 
543
      memcpy(&ntlmbuf[size], ntresp, 0x18);
 
544
      size += 0x18;
 
545
    }
 
546
#endif
 
547
 
 
548
    ntlmbuf[56] = size & 0xff;
 
549
    ntlmbuf[57] = size >> 8;
 
550
 
 
551
    /* convert the binary blob into base64 */
 
552
    base64 = (char *) alloca (BASE64_LENGTH (size) + 1);
 
553
    base64_encode (ntlmbuf, size, base64);
 
554
 
 
555
    output = concat_strings ("NTLM ", base64, (char *) 0);
 
556
 
 
557
    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
 
558
    *ready = 1;
 
559
  }
 
560
  break;
 
561
 
 
562
  case NTLMSTATE_TYPE3:
 
563
    /* connection is already authenticated,
 
564
     * don't send a header in future requests */
 
565
    *ready = 1;
 
566
    output = NULL;
 
567
    break;
 
568
  }
 
569
 
 
570
  return output;
 
571
}