~ubuntu-branches/ubuntu/warty/curl/warty

« back to all changes in this revision

Viewing changes to lib/http_ntlm.c

  • Committer: Bazaar Package Importer
  • Author(s): Domenico Andreoli
  • Date: 2004-06-04 19:09:25 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040604190925-wy048bp31320r2z6
Tags: 7.12.0.is.7.11.2-1
* Reverted to version 7.11.2 (closes: #252348).
* Disabled support for libidn (closes: #252367). This is to leave
  curl in unstable as much similar as possible to the one in testing.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *                                  _   _ ____  _     
 
3
 *  Project                     ___| | | |  _ \| |    
 
4
 *                             / __| | | | |_) | |    
 
5
 *                            | (__| |_| |  _ <| |___ 
 
6
 *                             \___|\___/|_| \_\_____|
 
7
 *
 
8
 * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
 
9
 *
 
10
 * This software is licensed as described in the file COPYING, which
 
11
 * you should have received as part of this distribution. The terms
 
12
 * are also available at http://curl.haxx.se/docs/copyright.html.
 
13
 * 
 
14
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 
15
 * copies of the Software, and permit persons to whom the Software is
 
16
 * furnished to do so, under the terms of the COPYING file.
 
17
 *
 
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 
19
 * KIND, either express or implied.
 
20
 *
 
21
 * $Id: http_ntlm.c,v 1.30 2004/03/30 06:39:24 bagder Exp $
 
22
 ***************************************************************************/
 
23
#include "setup.h"
 
24
 
 
25
/* NTLM details:
 
26
   
 
27
   http://davenport.sourceforge.net/ntlm.html
 
28
   http://www.innovation.ch/java/ntlm.html
 
29
 
 
30
*/
 
31
 
 
32
#ifndef CURL_DISABLE_HTTP
 
33
#ifdef USE_SSLEAY
 
34
/* We need OpenSSL for the crypto lib to provide us with MD4 and DES */
 
35
 
 
36
/* -- WIN32 approved -- */
 
37
#include <stdio.h>
 
38
#include <string.h>
 
39
#include <stdarg.h>
 
40
#include <stdlib.h>
 
41
#include <ctype.h>
 
42
 
 
43
#include "urldata.h"
 
44
#include "sendf.h"
 
45
#include "strequal.h"
 
46
#include "base64.h"
 
47
#include "http_ntlm.h"
 
48
#include "url.h"
 
49
#include "http.h" /* for Curl_http_auth_stage() */
 
50
 
 
51
#define _MPRINTF_REPLACE /* use our functions only */
 
52
#include <curl/mprintf.h>
 
53
 
 
54
#include <openssl/des.h>
 
55
#include <openssl/md4.h>
 
56
#include <openssl/ssl.h>
 
57
 
 
58
#if OPENSSL_VERSION_NUMBER < 0x00907001L
 
59
#define DES_key_schedule des_key_schedule
 
60
#define DES_cblock des_cblock
 
61
#define DES_set_odd_parity des_set_odd_parity
 
62
#define DES_set_key des_set_key
 
63
#define DES_ecb_encrypt des_ecb_encrypt
 
64
 
 
65
/* This is how things were done in the old days */
 
66
#define DESKEY(x) x
 
67
#define DESKEYARG(x) x
 
68
#else
 
69
/* Modern version */
 
70
#define DESKEYARG(x) *x
 
71
#define DESKEY(x) &x
 
72
#endif
 
73
 
 
74
/* The last #include file should be: */
 
75
#ifdef CURLDEBUG
 
76
#include "memdebug.h"
 
77
#endif
 
78
 
 
79
/* Define this to make the type-3 message include the NT response message */
 
80
#define USE_NTRESPONSES 1
 
81
 
 
82
/*
 
83
  (*) = A "security buffer" is a triplet consisting of two shorts and one
 
84
  long:
 
85
 
 
86
  1. a 'short' containing the length of the buffer in bytes
 
87
  2. a 'short' containing the allocated space for the buffer in bytes
 
88
  3. a 'long' containing the offset to the start of the buffer from the
 
89
     beginning of the NTLM message, in bytes.
 
90
*/
 
91
 
 
92
 
 
93
CURLntlm Curl_input_ntlm(struct connectdata *conn,
 
94
                         bool proxy,   /* if proxy or not */
 
95
                         char *header) /* rest of the www-authenticate:
 
96
                                          header */
 
97
{
 
98
  /* point to the correct struct with this */
 
99
  struct ntlmdata *ntlm;
 
100
 
 
101
  ntlm = proxy?&conn->proxyntlm:&conn->ntlm;
 
102
 
 
103
  /* skip initial whitespaces */
 
104
  while(*header && isspace((int)*header))
 
105
    header++;
 
106
 
 
107
  if(checkprefix("NTLM", header)) {
 
108
    unsigned char buffer[256];
 
109
    header += strlen("NTLM");
 
110
 
 
111
    while(*header && isspace((int)*header))
 
112
      header++;
 
113
 
 
114
    if(*header) {
 
115
      /* We got a type-2 message here:
 
116
 
 
117
         Index   Description         Content
 
118
         0       NTLMSSP Signature   Null-terminated ASCII "NTLMSSP"
 
119
                                     (0x4e544c4d53535000)
 
120
         8       NTLM Message Type   long (0x02000000)
 
121
         12      Target Name         security buffer(*)
 
122
         20      Flags               long
 
123
         24      Challenge           8 bytes
 
124
         (32)    Context (optional)  8 bytes (two consecutive longs)
 
125
         (40)    Target Information  (optional) security buffer(*)
 
126
         32 (48) start of data block
 
127
      */
 
128
 
 
129
      size_t size = Curl_base64_decode(header, (char *)buffer);
 
130
 
 
131
      ntlm->state = NTLMSTATE_TYPE2; /* we got a type-2 */
 
132
 
 
133
      if(size >= 48)
 
134
        /* the nonce of interest is index [24 .. 31], 8 bytes */
 
135
        memcpy(ntlm->nonce, &buffer[24], 8);
 
136
 
 
137
      /* at index decimal 20, there's a 32bit NTLM flag field */
 
138
      
 
139
    }
 
140
    else {
 
141
      if(ntlm->state >= NTLMSTATE_TYPE1)
 
142
        return CURLNTLM_BAD;
 
143
 
 
144
      ntlm->state = NTLMSTATE_TYPE1; /* we should sent away a type-1 */
 
145
    }
 
146
  }
 
147
  return CURLNTLM_FINE;
 
148
}
 
149
 
 
150
/*
 
151
 * Turns a 56 bit key into the 64 bit, odd parity key and sets the key.  The
 
152
 * key schedule ks is also set.
 
153
 */
 
154
static void setup_des_key(unsigned char *key_56,
 
155
                          DES_key_schedule DESKEYARG(ks))
 
156
{
 
157
  DES_cblock key;
 
158
 
 
159
  key[0] = key_56[0];
 
160
  key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1);
 
161
  key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2);
 
162
  key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3);
 
163
  key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4);
 
164
  key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5);
 
165
  key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6);
 
166
  key[7] =  (key_56[6] << 1) & 0xFF;
 
167
 
 
168
  DES_set_odd_parity(&key);
 
169
  DES_set_key(&key, ks);
 
170
}
 
171
 
 
172
 /*
 
173
  * takes a 21 byte array and treats it as 3 56-bit DES keys. The
 
174
  * 8 byte plaintext is encrypted with each key and the resulting 24
 
175
  * bytes are stored in the results array.
 
176
  */
 
177
static void calc_resp(unsigned char *keys,
 
178
                      unsigned char *plaintext,
 
179
                      unsigned char *results)
 
180
{
 
181
  DES_key_schedule ks;
 
182
 
 
183
  setup_des_key(keys, DESKEY(ks));
 
184
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) results,
 
185
                  DESKEY(ks), DES_ENCRYPT);
 
186
 
 
187
  setup_des_key(keys+7, DESKEY(ks));
 
188
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+8),
 
189
                  DESKEY(ks), DES_ENCRYPT);
 
190
 
 
191
  setup_des_key(keys+14, DESKEY(ks));
 
192
  DES_ecb_encrypt((DES_cblock*) plaintext, (DES_cblock*) (results+16),
 
193
                  DESKEY(ks), DES_ENCRYPT);
 
194
}
 
195
 
 
196
/*
 
197
 * Set up lanmanager and nt hashed passwords
 
198
 */
 
199
static void mkhash(char *password,
 
200
                   unsigned char *nonce,  /* 8 bytes */
 
201
                   unsigned char *lmresp  /* must fit 0x18 bytes */
 
202
#ifdef USE_NTRESPONSES
 
203
                   , unsigned char *ntresp  /* must fit 0x18 bytes */
 
204
#endif
 
205
  )
 
206
{
 
207
  unsigned char lmbuffer[21];
 
208
#ifdef USE_NTRESPONSES
 
209
  unsigned char ntbuffer[21];
 
210
#endif
 
211
  unsigned char *pw;
 
212
  static const unsigned char magic[] = {
 
213
    0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
 
214
  };
 
215
  unsigned int i;
 
216
  size_t len = strlen(password);
 
217
 
 
218
  /* make it fit at least 14 bytes */
 
219
  pw = malloc(len<7?14:len*2);
 
220
  if(!pw)
 
221
    return; /* this will lead to a badly generated package */
 
222
 
 
223
  if (len > 14)
 
224
    len = 14;
 
225
  
 
226
  for (i=0; i<len; i++)
 
227
    pw[i] = toupper(password[i]);
 
228
 
 
229
  for (; i<14; i++)
 
230
    pw[i] = 0;
 
231
 
 
232
  {
 
233
    /* create LanManager hashed password */
 
234
    DES_key_schedule ks;
 
235
 
 
236
    setup_des_key(pw, DESKEY(ks));
 
237
    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer,
 
238
                    DESKEY(ks), DES_ENCRYPT);
 
239
  
 
240
    setup_des_key(pw+7, DESKEY(ks));
 
241
    DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8),
 
242
                    DESKEY(ks), DES_ENCRYPT);
 
243
 
 
244
    memset(lmbuffer+16, 0, 5);
 
245
  }
 
246
  /* create LM responses */
 
247
  calc_resp(lmbuffer, nonce, lmresp);
 
248
 
 
249
#ifdef USE_NTRESPONSES
 
250
  {
 
251
    /* create NT hashed password */
 
252
    MD4_CTX MD4;
 
253
 
 
254
    len = strlen(password);
 
255
 
 
256
    for (i=0; i<len; i++) {
 
257
      pw[2*i]   = password[i];
 
258
      pw[2*i+1] = 0;
 
259
    }
 
260
 
 
261
    MD4_Init(&MD4);
 
262
    MD4_Update(&MD4, pw, 2*len);
 
263
    MD4_Final(ntbuffer, &MD4);
 
264
 
 
265
    memset(ntbuffer+16, 0, 8);
 
266
  }
 
267
 
 
268
  calc_resp(ntbuffer, nonce, ntresp);
 
269
#endif
 
270
 
 
271
  free(pw);
 
272
}
 
273
 
 
274
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
 
275
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
 
276
  (((x) >>16)&0xff), ((x)>>24)
 
277
 
 
278
/* this is for creating ntlm header output */
 
279
CURLcode Curl_output_ntlm(struct connectdata *conn,
 
280
                          bool proxy)
 
281
{
 
282
  const char *domain=""; /* empty */
 
283
  const char *host=""; /* empty */
 
284
  int domlen=(int)strlen(domain);
 
285
  int hostlen = (int)strlen(host);
 
286
  int hostoff; /* host name offset */
 
287
  int domoff;  /* domain name offset */
 
288
  size_t size;
 
289
  char *base64=NULL;
 
290
  unsigned char ntlmbuf[256]; /* enough, unless the host/domain is very long */
 
291
 
 
292
  /* point to the address of the pointer that holds the string to sent to the
 
293
     server, which is for a plain host or for a HTTP proxy */
 
294
  char **allocuserpwd;
 
295
 
 
296
  /* point to the name and password for this */
 
297
  char *userp;
 
298
  char *passwdp;
 
299
  /* point to the correct struct with this */
 
300
  struct ntlmdata *ntlm;
 
301
 
 
302
  curlassert(conn);
 
303
  curlassert(conn->data);
 
304
  conn->data->state.authdone = FALSE;
 
305
 
 
306
  if(proxy) {
 
307
    allocuserpwd = &conn->allocptr.proxyuserpwd;
 
308
    userp = conn->proxyuser;
 
309
    passwdp = conn->proxypasswd;
 
310
    ntlm = &conn->proxyntlm;
 
311
  }
 
312
  else {
 
313
    allocuserpwd = &conn->allocptr.userpwd;
 
314
    userp = conn->user;
 
315
    passwdp = conn->passwd;
 
316
    ntlm = &conn->ntlm;
 
317
  }
 
318
 
 
319
  /* not set means empty */
 
320
  if(!userp)
 
321
    userp=(char *)"";
 
322
 
 
323
  if(!passwdp)
 
324
    passwdp=(char *)"";
 
325
  
 
326
  switch(ntlm->state) {
 
327
  case NTLMSTATE_TYPE1:
 
328
  default: /* for the weird cases we (re)start here */
 
329
    hostoff = 32;
 
330
    domoff = hostoff + hostlen;
 
331
    
 
332
    /* Create and send a type-1 message:
 
333
 
 
334
    Index Description          Content
 
335
    0     NTLMSSP Signature    Null-terminated ASCII "NTLMSSP"
 
336
                               (0x4e544c4d53535000)
 
337
    8     NTLM Message Type    long (0x01000000)
 
338
    12    Flags                long
 
339
    16    Supplied Domain      security buffer(*)
 
340
    24    Supplied Workstation security buffer(*)
 
341
    32    start of data block
 
342
 
 
343
    */
 
344
 
 
345
    snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
 
346
             "\x01%c%c%c" /* 32-bit type = 1 */
 
347
             "%c%c%c%c"   /* 32-bit NTLM flag field */
 
348
             "%c%c"  /* domain length */
 
349
             "%c%c"  /* domain allocated space */
 
350
             "%c%c"  /* domain name offset */
 
351
             "%c%c"  /* 2 zeroes */
 
352
             "%c%c"  /* host length */
 
353
             "%c%c"  /* host allocated space */
 
354
             "%c%c"  /* host name offset */
 
355
             "%c%c"  /* 2 zeroes */
 
356
             "%s"   /* host name */
 
357
             "%s",  /* domain string */
 
358
             0,     /* trailing zero */
 
359
             0,0,0, /* part of type-1 long */
 
360
 
 
361
             LONGQUARTET(
 
362
               NTLMFLAG_NEGOTIATE_OEM|      /*   2 */
 
363
               NTLMFLAG_NEGOTIATE_NTLM_KEY  /* 200 */
 
364
               /* equals 0x0202 */
 
365
               ),
 
366
             SHORTPAIR(domlen),
 
367
             SHORTPAIR(domlen),
 
368
             SHORTPAIR(domoff),
 
369
             0,0,
 
370
             SHORTPAIR(hostlen),
 
371
             SHORTPAIR(hostlen),
 
372
             SHORTPAIR(hostoff),
 
373
             0,0,
 
374
             host, domain);
 
375
 
 
376
    /* initial packet length */
 
377
    size = 32 + hostlen + domlen;
 
378
 
 
379
    /* now keeper of the base64 encoded package size */
 
380
    size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
 
381
 
 
382
    if(size >0 ) {
 
383
      Curl_safefree(*allocuserpwd);
 
384
      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
 
385
                              proxy?"Proxy-":"",
 
386
                              base64);
 
387
      free(base64);
 
388
    }
 
389
    else
 
390
      return CURLE_OUT_OF_MEMORY; /* FIX TODO */
 
391
 
 
392
    break;
 
393
    
 
394
  case NTLMSTATE_TYPE2:
 
395
    /* We received the type-2 already, create a type-3 message:
 
396
 
 
397
    Index   Description            Content
 
398
    0       NTLMSSP Signature      Null-terminated ASCII "NTLMSSP"
 
399
                                   (0x4e544c4d53535000)
 
400
    8       NTLM Message Type      long (0x03000000)
 
401
    12      LM/LMv2 Response       security buffer(*)
 
402
    20      NTLM/NTLMv2 Response   security buffer(*)
 
403
    28      Domain Name            security buffer(*)
 
404
    36      User Name              security buffer(*)
 
405
    44      Workstation Name       security buffer(*)
 
406
    (52)    Session Key (optional) security buffer(*)
 
407
    (60)    Flags (optional)       long
 
408
    52 (64) start of data block
 
409
 
 
410
    */
 
411
  
 
412
  {
 
413
    int lmrespoff;
 
414
    int ntrespoff;
 
415
    int useroff;
 
416
    unsigned char lmresp[0x18]; /* fixed-size */
 
417
#ifdef USE_NTRESPONSES
 
418
    unsigned char ntresp[0x18]; /* fixed-size */
 
419
#endif
 
420
    const char *user;
 
421
    int userlen;
 
422
 
 
423
    user = strchr(userp, '\\');
 
424
    if(!user)
 
425
      user = strchr(userp, '/');
 
426
 
 
427
    if (user) {
 
428
      domain = userp;
 
429
      domlen = user - domain;
 
430
      user++;
 
431
    }
 
432
    else
 
433
      user = userp;
 
434
    userlen = strlen(user);
 
435
 
 
436
    mkhash(passwdp, &ntlm->nonce[0], lmresp
 
437
#ifdef USE_NTRESPONSES
 
438
           , ntresp
 
439
#endif
 
440
      );
 
441
 
 
442
    domoff = 64; /* always */
 
443
    useroff = domoff + domlen;
 
444
    hostoff = useroff + userlen;
 
445
    lmrespoff = hostoff + hostlen;
 
446
    ntrespoff = lmrespoff + 0x18;
 
447
 
 
448
    /* Create the big type-3 message binary blob */
 
449
    size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
 
450
                    "NTLMSSP%c"
 
451
                    "\x03%c%c%c" /* type-3, 32 bits */
 
452
 
 
453
                    "%c%c%c%c" /* LanManager length + allocated space */
 
454
                    "%c%c" /* LanManager offset */
 
455
                    "%c%c" /* 2 zeroes */
 
456
 
 
457
                    "%c%c" /* NT-response length */
 
458
                    "%c%c" /* NT-response allocated space */
 
459
                    "%c%c" /* NT-response offset */
 
460
                    "%c%c" /* 2 zeroes */
 
461
                    
 
462
                    "%c%c"  /* domain length */
 
463
                    "%c%c"  /* domain allocated space */
 
464
                    "%c%c"  /* domain name offset */
 
465
                    "%c%c"  /* 2 zeroes */
 
466
                    
 
467
                    "%c%c"  /* user length */
 
468
                    "%c%c"  /* user allocated space */
 
469
                    "%c%c"  /* user offset */
 
470
                    "%c%c"  /* 2 zeroes */
 
471
                    
 
472
                    "%c%c"  /* host length */
 
473
                    "%c%c"  /* host allocated space */
 
474
                    "%c%c"  /* host offset */
 
475
                    "%c%c%c%c%c%c"  /* 6 zeroes */
 
476
                    
 
477
                    "\xff\xff"  /* message length */
 
478
                    "%c%c"  /* 2 zeroes */
 
479
                    
 
480
                    "\x01\x82" /* flags */
 
481
                    "%c%c"  /* 2 zeroes */
 
482
 
 
483
                    /* domain string */
 
484
                    /* user string */
 
485
                    /* host string */
 
486
                    /* LanManager response */
 
487
                    /* NT response */
 
488
                    ,
 
489
                    0, /* zero termination */
 
490
                    0,0,0, /* type-3 long, the 24 upper bits */
 
491
 
 
492
                    SHORTPAIR(0x18),  /* LanManager response length, twice */
 
493
                    SHORTPAIR(0x18),
 
494
                    SHORTPAIR(lmrespoff),
 
495
                    0x0, 0x0,
 
496
                    
 
497
#ifdef USE_NTRESPONSES
 
498
                    SHORTPAIR(0x18),  /* NT-response length, twice */
 
499
                    SHORTPAIR(0x18),
 
500
#else
 
501
                    0x0, 0x0,
 
502
                    0x0, 0x0,
 
503
#endif
 
504
                    SHORTPAIR(ntrespoff),
 
505
                    0x0, 0x0,
 
506
 
 
507
                    SHORTPAIR(domlen),
 
508
                    SHORTPAIR(domlen),
 
509
                    SHORTPAIR(domoff),
 
510
                    0x0, 0x0,
 
511
 
 
512
                    SHORTPAIR(userlen),
 
513
                    SHORTPAIR(userlen),
 
514
                    SHORTPAIR(useroff),
 
515
                    0x0, 0x0,
 
516
                    
 
517
                    SHORTPAIR(hostlen),
 
518
                    SHORTPAIR(hostlen),
 
519
                    SHORTPAIR(hostoff),
 
520
                    0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 
521
             
 
522
                    0x0, 0x0,
 
523
 
 
524
                    0x0, 0x0);
 
525
 
 
526
    /* size is now 64 */
 
527
    size=64;
 
528
    ntlmbuf[62]=ntlmbuf[63]=0;
 
529
 
 
530
    memcpy(&ntlmbuf[size], domain, domlen);
 
531
    size += domlen;
 
532
 
 
533
    memcpy(&ntlmbuf[size], user, userlen);
 
534
    size += userlen;
 
535
 
 
536
    /* we append the binary hashes to the end of the blob */
 
537
    if(size < ((int)sizeof(ntlmbuf) - 0x18)) {
 
538
      memcpy(&ntlmbuf[size], lmresp, 0x18);
 
539
      size += 0x18;
 
540
    }
 
541
 
 
542
#ifdef USE_NTRESPONSES
 
543
    if(size < ((int)sizeof(ntlmbuf) - 0x18)) {      
 
544
      memcpy(&ntlmbuf[size], ntresp, 0x18);
 
545
      size += 0x18;
 
546
    }
 
547
#endif
 
548
 
 
549
    ntlmbuf[56] = size & 0xff;
 
550
    ntlmbuf[57] = size >> 8;
 
551
 
 
552
    /* convert the binary blob into base64 */
 
553
    size = Curl_base64_encode((char *)ntlmbuf, size, &base64);
 
554
 
 
555
    if(size >0 ) {
 
556
      Curl_safefree(*allocuserpwd);
 
557
      *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n",
 
558
                              proxy?"Proxy-":"",
 
559
                              base64);
 
560
      free(base64);
 
561
    }
 
562
    else
 
563
      return CURLE_OUT_OF_MEMORY; /* FIX TODO */
 
564
 
 
565
    ntlm->state = NTLMSTATE_TYPE3; /* we sent a type-3 */
 
566
    conn->data->state.authdone = TRUE;
 
567
 
 
568
    /* Switch to web authentication after proxy authentication is done */
 
569
    if (proxy)
 
570
      Curl_http_auth_stage(conn->data, 401);
 
571
  }
 
572
  break;
 
573
 
 
574
  case NTLMSTATE_TYPE3:
 
575
    /* connection is already authenticated,
 
576
     * don't send a header in future requests */
 
577
    if(*allocuserpwd) {
 
578
      free(*allocuserpwd);
 
579
      *allocuserpwd=NULL;
 
580
    }
 
581
    conn->data->state.authdone = TRUE;
 
582
    break;
 
583
  }
 
584
 
 
585
  return CURLE_OK;
 
586
}
 
587
#endif /* USE_SSLEAY */
 
588
#endif /* !CURL_DISABLE_HTTP */