mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
Many fixes, most of them based on comments by Eric Glass
This commit is contained in:
parent
445684c409
commit
3b2b2496d7
280
lib/http_ntlm.c
280
lib/http_ntlm.c
@ -22,7 +22,12 @@
|
||||
***************************************************************************/
|
||||
#include "setup.h"
|
||||
|
||||
/* All NTLM details here: http://www.innovation.ch/java/ntlm.html */
|
||||
/* NTLM details:
|
||||
|
||||
http://davenport.sourceforge.net/ntlm.html
|
||||
http://www.innovation.ch/java/ntlm.html
|
||||
|
||||
*/
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
#ifdef USE_SSLEAY
|
||||
@ -65,23 +70,23 @@
|
||||
#endif
|
||||
|
||||
/* The last #include file should be: */
|
||||
#ifdef MALLOCDEBUG
|
||||
#ifdef CURLDEBUG
|
||||
#include "memdebug.h"
|
||||
#endif
|
||||
|
||||
/* Define this to make the type-3 message include the NT response message */
|
||||
#undef USE_NTRESPONSES
|
||||
|
||||
/*
|
||||
The one and only master resource for NTLM "hacking":
|
||||
(*) = A "security buffer" is a triplet consisting of two shorts and one
|
||||
long:
|
||||
|
||||
====> http://www.innovation.ch/java/ntlm.html <====
|
||||
|
||||
Brought to the world by Ronald Tschalär.
|
||||
1. a 'short' containing the length of the buffer in bytes
|
||||
2. a 'short' containing the allocated space for the buffer in bytes
|
||||
3. a 'long' containing the offset to the start of the buffer from the
|
||||
beginning of the NTLM message, in bytes.
|
||||
*/
|
||||
|
||||
/* Test example header:
|
||||
|
||||
WWW-Authenticate: NTLM
|
||||
|
||||
*/
|
||||
|
||||
CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
||||
char *header) /* rest of the www-authenticate:
|
||||
@ -101,31 +106,18 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
|
||||
header++;
|
||||
|
||||
if(*header) {
|
||||
/* we got a type-2 message here */
|
||||
|
||||
/* My test-IE session reveived this type-2:
|
||||
|
||||
TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgA\
|
||||
yAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4\
|
||||
AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwB\
|
||||
jAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
|
||||
|
||||
which translates to this:
|
||||
|
||||
0x00: 4e 54 4c 4d 53 53 50 00 02 00 00 00 02 00 02 00 | NTLMSSP.........
|
||||
0x10: 30 00 00 00 06 82 81 00 73 9d 40 61 50 e0 c8 d7 | 0.......s.@aP...
|
||||
0x20: 00 00 00 00 00 00 00 00 6e 00 6e 00 32 00 00 00 | ........n.n.2...
|
||||
0x30: 43 43 02 00 04 00 43 00 43 00 01 00 12 00 45 00 | CC....C.C.....E.
|
||||
0x40: 4c 00 49 00 53 00 41 00 42 00 45 00 54 00 48 00 | L.I.S.A.B.E.T.H.
|
||||
0x50: 04 00 18 00 63 00 63 00 2e 00 69 00 63 00 65 00 | ....c.c...i.c.e.
|
||||
0x60: 64 00 65 00 76 00 2e 00 6e 00 75 00 03 00 2c 00 | d.e.v...n.u...,.
|
||||
0x70: 65 00 6c 00 69 00 73 00 61 00 62 00 65 00 74 00 | e.l.i.s.a.b.e.t.
|
||||
0x80: 68 00 2e 00 63 00 63 00 2e 00 69 00 63 00 65 00 | h...c.c...i.c.e.
|
||||
0x90: 64 00 65 00 76 00 2e 00 6e 00 75 00 00 00 00 00 | d.e.v...n.u.....
|
||||
|
||||
This is not the same format as described on the web page, but doing repeated
|
||||
requests show that 0x18-0x1f seems to be the nonce anyway.
|
||||
/* We got a type-2 message here:
|
||||
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x02000000)
|
||||
12 Target Name security buffer(*)
|
||||
20 Flags long
|
||||
24 Challenge 8 bytes
|
||||
(32) Context (optional) 8 bytes (two consecutive longs)
|
||||
(40) Target Information (optional) security buffer(*)
|
||||
32 (48) start of data block
|
||||
*/
|
||||
|
||||
int size = Curl_base64_decode(header, buffer);
|
||||
@ -135,6 +127,9 @@ requests show that 0x18-0x1f seems to be the nonce anyway.
|
||||
if(size >= 48)
|
||||
/* the nonce of interest is index [24 .. 31], 8 bytes */
|
||||
memcpy(data->state.ntlm.nonce, &buffer[24], 8);
|
||||
|
||||
/* at index decimal 20, there's a 32bit NTLM flag field */
|
||||
|
||||
}
|
||||
else {
|
||||
if(data->state.ntlm.state >= NTLMSTATE_TYPE1)
|
||||
@ -198,12 +193,16 @@ static void calc_resp(unsigned char *keys,
|
||||
*/
|
||||
static void mkhash(char *password,
|
||||
unsigned char *nonce, /* 8 bytes */
|
||||
unsigned char *lmresp, /* must fit 0x18 bytes */
|
||||
unsigned char *ntresp) /* must fit 0x18 bytes */
|
||||
unsigned char *lmresp /* must fit 0x18 bytes */
|
||||
#ifdef USE_NTRESPONSES
|
||||
, unsigned char *ntresp /* must fit 0x18 bytes */
|
||||
#endif
|
||||
)
|
||||
{
|
||||
unsigned char lmbuffer[21];
|
||||
#ifdef USE_NTRESPONSES
|
||||
unsigned char ntbuffer[21];
|
||||
|
||||
#endif
|
||||
unsigned char *pw;
|
||||
static const unsigned char magic[] = {
|
||||
0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25
|
||||
@ -239,7 +238,10 @@ static void mkhash(char *password,
|
||||
|
||||
memset(lmbuffer+16, 0, 5);
|
||||
}
|
||||
/* create LM responses */
|
||||
calc_resp(lmbuffer, nonce, lmresp);
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
{
|
||||
/* create NT hashed password */
|
||||
MD4_CTX MD4;
|
||||
@ -258,35 +260,22 @@ static void mkhash(char *password,
|
||||
memset(ntbuffer+16, 0, 8);
|
||||
}
|
||||
|
||||
/* create responses */
|
||||
calc_resp(lmbuffer, nonce, lmresp);
|
||||
calc_resp(ntbuffer, nonce, ntresp);
|
||||
#endif
|
||||
|
||||
free(pw);
|
||||
}
|
||||
|
||||
/* convert an ascii string to upper case unicode, the destination buffer
|
||||
must fit twice the source size */
|
||||
static void ascii_to_unicode(unsigned char *destunicode,
|
||||
unsigned char *sourceascii,
|
||||
bool conv)
|
||||
{
|
||||
while (*sourceascii) {
|
||||
destunicode[0] = conv?toupper(*sourceascii):*sourceascii;
|
||||
destunicode[1] = '\0';
|
||||
destunicode += 2;
|
||||
sourceascii++;
|
||||
}
|
||||
}
|
||||
|
||||
#define SHORTPAIR(x) ((x) & 0xff), ((x) >> 8)
|
||||
#define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8)&0xff), \
|
||||
(((x) >>16)&0xff), ((x)>>24)
|
||||
|
||||
/* this is for creating ntlm header output */
|
||||
CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
const char *domain="CURL";
|
||||
const char *host="HAXX";
|
||||
const char *domain=""; /* empty */
|
||||
const char *host=""; /* empty */
|
||||
int domlen=strlen(domain);
|
||||
int hostlen = strlen(host);
|
||||
int hostoff; /* host name offset */
|
||||
@ -295,49 +284,46 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
char *base64=NULL;
|
||||
|
||||
unsigned char ntlm[256]; /* enough, unless the host/domain is very long */
|
||||
if(NTLMSTATE_TYPE1 == data->state.ntlm.state) {
|
||||
switch(data->state.ntlm.state) {
|
||||
case NTLMSTATE_TYPE1:
|
||||
default: /* for the weird cases we (re)start here */
|
||||
hostoff = 32;
|
||||
domoff = hostoff + hostlen;
|
||||
|
||||
/* IE used this as type-1 maessage:
|
||||
/* Create and send a type-1 message:
|
||||
|
||||
Authorization: NTLM \
|
||||
TlRMTVNTUAABAAAABoIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAA\r\n
|
||||
|
||||
This translates into:
|
||||
|
||||
0x00: 4e 54 4c 4d 53 53 50 00 01 00 00 00 06 82 00 00 | NTLMSSP.........
|
||||
0x10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
|
||||
0x20: 00 00 00 00 30 00 00 00 00 00 00 00 30 00 00 00 | ....0.......0...
|
||||
|
||||
Which isn't following the web spec. This uses 0x8206 instead of 0xb203
|
||||
and sends a longer chunk of data than we do! Interestingly, there's no
|
||||
host or domain either.
|
||||
|
||||
We want to send something like this:
|
||||
|
||||
0x00: 4e 54 4c 4d 53 53 50 00 01 00 00 00 03 b2 00 00 | NTLMSSP.........
|
||||
0x10: 05 00 05 00 2b 00 00 00 0b 00 0b 00 20 00 00 00 | ....+...........
|
||||
0x20: 4c 49 4c 4c 41 53 59 53 54 45 52 48 45 4d 4d 41 | LILLASYSTERHEMMA
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x01000000)
|
||||
12 Flags long
|
||||
16 Supplied Domain security buffer(*)
|
||||
24 Supplied Workstation security buffer(*)
|
||||
32 start of data block
|
||||
|
||||
*/
|
||||
|
||||
snprintf((char *)ntlm, sizeof(ntlm), "NTLMSSP%c"
|
||||
"\x01" /* type 1 */
|
||||
"%c%c%c"
|
||||
"\x03\xb2"
|
||||
"%c%c"
|
||||
"%c%c" /* domain length */
|
||||
"\x01%c%c%c" /* 32-bit type = 1 */
|
||||
"%c%c%c%c" /* 32-bit NTLM flag field */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
"%s" /* host name */
|
||||
"%s", /* domain string */
|
||||
0,0,0,0,0,0,
|
||||
0, /* trailing zero */
|
||||
0,0,0, /* part of type-1 long */
|
||||
|
||||
LONGQUARTET(
|
||||
NTLMFLAG_NEGOTIATE_OEM| /* 2 */
|
||||
NTLMFLAG_NEGOTIATE_NTLM_KEY /* 200 */
|
||||
/* equals 0x0202 */
|
||||
),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domlen),
|
||||
SHORTPAIR(domoff),
|
||||
@ -350,11 +336,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
|
||||
/* initial packet length */
|
||||
size = 32 + hostlen + domlen;
|
||||
#if 0
|
||||
#define CHUNK "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x06\x82\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00\x00\x00\x00\x00\x30\x00\x00\x00"
|
||||
memcpy(ntlm, CHUNK, sizeof(CHUNK)-1);
|
||||
size = sizeof(CHUNK)-1;
|
||||
#endif
|
||||
|
||||
/* now keeper of the base64 encoded package size */
|
||||
size = Curl_base64_encode(ntlm, size, &base64);
|
||||
|
||||
@ -365,55 +347,43 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
}
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY; /* FIX TODO */
|
||||
}
|
||||
else {
|
||||
if(NTLMSTATE_TYPE2 == data->state.ntlm.state) {
|
||||
/* We received the type-2 already, create a type-3 message */
|
||||
|
||||
/*
|
||||
My test-IE session sent this type-3:
|
||||
break;
|
||||
|
||||
TlRMTVNTUAADAAAAGAAYAEoAAAAAAAAAYgAAAAUABQA0AAAABgAGADk\
|
||||
AAAALAAsAPwAAAEhFTU1BZGFuaWVsTElMTEFTWVNURVJPVPJELoebUg\
|
||||
4SvW0ed2QmKu0SjX4qNrI=
|
||||
case NTLMSTATE_TYPE2:
|
||||
/* We received the type-2 already, create a type-3 message:
|
||||
|
||||
Which translates to:
|
||||
|
||||
0x00: 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 | NTLMSSP.........
|
||||
0x10: 4a 00 00 00 00 00 00 00 62 00 00 00 05 00 05 00 | J.......b.......
|
||||
0x20: 34 00 00 00 06 00 06 00 39 00 00 00 0b 00 0b 00 | 4.......9.......
|
||||
0x30: 3f 00 00 00 48 45 4d 4d 41 64 61 6e 69 65 6c 4c | ?...HEMMAdanielL
|
||||
0x40: 49 4c 4c 41 53 59 53 54 45 52 4f 54 f2 44 2e 87 | ILLASYSTEROT.D..
|
||||
0x50: 9b 52 0e 12 bd 6d 1e 77 64 26 2a ed 12 8d 7e 2a | .R...m.wd&*...~*
|
||||
0x60: 36 b2 | 6.
|
||||
|
||||
Note how the domain + username + hostname ARE NOT unicoded in any way.
|
||||
Domain and hostname are uppercase, while username are case sensitive.
|
||||
|
||||
We send something like this:
|
||||
|
||||
0x00: 4e 54 4c 4d 53 53 50 00 03 00 00 00 18 00 18 00 | NTLMSSP.........
|
||||
0x10: 6c 00 00 00 18 00 18 00 84 00 00 00 0a 00 0a 00 | l...............
|
||||
0x20: 40 00 00 00 0c 00 0c 00 4a 00 00 00 16 00 16 00 | @.......J.......
|
||||
0x30: 56 00 00 00 00 00 00 00 9c 00 00 00 01 82 00 00 | V...............
|
||||
0x40: 48 00 45 00 4d 00 4d 00 41 00 64 00 61 00 6e 00 | H.E.M.M.A.d.a.n.
|
||||
0x50: 69 00 65 00 6c 00 4c 00 49 00 4c 00 4c 00 41 00 | i.e.l.L.I.L.L.A.
|
||||
0x60: 53 00 59 00 53 00 54 00 45 00 52 00 bc ed 28 c9 | S.Y.S.T.E.R...(.
|
||||
0x70: 16 c4 1b 16 d7 c9 b4 0e ef ef 02 6d 26 8d c0 ba | ...........m&...
|
||||
0x80: ac b6 5a c1 26 8d c0 ba ac b6 5a c1 26 8d c0 ba | ..Z.&.....Z.&...
|
||||
0x90: ac b6 5a c1 26 8d c0 ba ac b6 5a c1 | ..Z.&.....Z.
|
||||
Index Description Content
|
||||
0 NTLMSSP Signature Null-terminated ASCII "NTLMSSP"
|
||||
(0x4e544c4d53535000)
|
||||
8 NTLM Message Type long (0x03000000)
|
||||
12 LM/LMv2 Response security buffer(*)
|
||||
20 NTLM/NTLMv2 Response security buffer(*)
|
||||
28 Domain Name security buffer(*)
|
||||
36 User Name security buffer(*)
|
||||
44 Workstation Name security buffer(*)
|
||||
(52) Session Key (optional) security buffer(*)
|
||||
(60) Flags (optional) long
|
||||
52 (64) start of data block
|
||||
|
||||
*/
|
||||
|
||||
{
|
||||
int lmrespoff;
|
||||
int ntrespoff;
|
||||
int useroff;
|
||||
unsigned char lmresp[0x18]; /* fixed-size */
|
||||
#ifdef USE_NTRESPONSES
|
||||
unsigned char ntresp[0x18]; /* fixed-size */
|
||||
|
||||
#endif
|
||||
int userlen = strlen(data->state.user);
|
||||
|
||||
mkhash(data->state.passwd, &data->state.ntlm.nonce[0], lmresp, ntresp);
|
||||
mkhash(data->state.passwd, &data->state.ntlm.nonce[0], lmresp
|
||||
#ifdef USE_NTRESPONSES
|
||||
, ntresp
|
||||
#endif
|
||||
|
||||
);
|
||||
|
||||
/* these are going unicode */
|
||||
domlen *= 2;
|
||||
@ -429,29 +399,29 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
/* Create the big type-3 message binary blob */
|
||||
size = snprintf((char *)ntlm, sizeof(ntlm),
|
||||
"NTLMSSP%c"
|
||||
"\x03" /* type 3 */
|
||||
"%c%c%c" /* 3 zeroes */
|
||||
"\x03%c%c%c" /* type-3, 32 bits */
|
||||
|
||||
"%c%c%c%c" /* LanManager length twice */
|
||||
"%c%c%c%c" /* LanManager length + allocated space */
|
||||
"%c%c" /* LanManager offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c%c%c" /* NT-response length twice */
|
||||
"%c%c" /* NT-response length */
|
||||
"%c%c" /* NT-response allocated space */
|
||||
"%c%c" /* NT-response offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain length */
|
||||
"%c%c" /* domain allocated space */
|
||||
"%c%c" /* domain name offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user length */
|
||||
"%c%c" /* user allocated space */
|
||||
"%c%c" /* user offset */
|
||||
"%c%c" /* 2 zeroes */
|
||||
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host length */
|
||||
"%c%c" /* host allocated space */
|
||||
"%c%c" /* host offset */
|
||||
"%c%c%c%c%c%c" /* 6 zeroes */
|
||||
|
||||
@ -467,16 +437,21 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
/* LanManager response */
|
||||
/* NT response */
|
||||
,
|
||||
0,
|
||||
0,0,0,
|
||||
0, /* zero termination */
|
||||
0,0,0, /* type-3 long, the 24 upper bits */
|
||||
|
||||
SHORTPAIR(0x18), /* LanManager response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
SHORTPAIR(lmrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
SHORTPAIR(0x18), /* NT-response length, twice */
|
||||
SHORTPAIR(0x18),
|
||||
#else
|
||||
0x0, 0x0,
|
||||
0x0, 0x0,
|
||||
#endif
|
||||
SHORTPAIR(ntrespoff),
|
||||
0x0, 0x0,
|
||||
|
||||
@ -503,50 +478,25 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
size=64;
|
||||
ntlm[62]=ntlm[63]=0;
|
||||
|
||||
#if 1
|
||||
ascii_to_unicode(&ntlm[size], (unsigned char *)domain, TRUE);
|
||||
size += domlen;
|
||||
|
||||
ascii_to_unicode(&ntlm[size], (unsigned char *)data->state.user, FALSE);
|
||||
memcpy(&ntlm[size], data->state.user, userlen);
|
||||
size += userlen;
|
||||
|
||||
ascii_to_unicode(&ntlm[size], (unsigned char *)host, TRUE);
|
||||
size += hostlen;
|
||||
#else
|
||||
strcpy(&ntlm[size], (unsigned char *)domain);
|
||||
size += domlen;
|
||||
|
||||
strcpy(&ntlm[size], (unsigned char *)data->state.user);
|
||||
size += userlen;
|
||||
|
||||
strcpy(&ntlm[size], (unsigned char *)host);
|
||||
size += hostlen;
|
||||
#endif
|
||||
|
||||
/* we append the binary hashes to the end of the blob */
|
||||
if(size < ((int)sizeof(ntlm) - 0x18)) {
|
||||
memcpy(&ntlm[size], lmresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
|
||||
#ifdef USE_NTRESPONSES
|
||||
if(size < ((int)sizeof(ntlm) - 0x18)) {
|
||||
memcpy(&ntlm[size], ntresp, 0x18);
|
||||
size += 0x18;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ntlm[56] = size & 0xff;
|
||||
ntlm[57] = size >> 8;
|
||||
|
||||
#if 0
|
||||
#undef CHUNK
|
||||
|
||||
#define CHUNK "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00\x4a\x00\x00\x00\x00\x00\x00\x00\x62\x00\x00\x00\x05\x00\x05\x00\x34\x00\x00\x00\x06\x00\x06\x00\x39\x00\x00\x00\x0b\x00\x0b\x00\x3f\x00\x00\x00\x48\x45\x4d\x4d\x41\x64\x61\x6e\x69\x65\x6c\x4c\x49\x4c\x4c\x41\x53\x59\x53\x54\x45\x52\x4f\x54\xf2\x44\x2e\x87\x9b\x52\x0e\x12\xbd\x6d\x1e\x77\x64\x26\x2a\xed\x12\x8d\x7e\x2a\x36\xb2"
|
||||
memcpy(ntlm, CHUNK, sizeof(CHUNK)-1);
|
||||
size = sizeof(CHUNK)-1;
|
||||
#endif
|
||||
|
||||
|
||||
/* convert the binary blob into base64 */
|
||||
size = Curl_base64_encode(ntlm, size, &base64);
|
||||
|
||||
@ -560,15 +510,17 @@ CURLcode Curl_output_ntlm(struct connectdata *conn)
|
||||
|
||||
data->state.ntlm.state = NTLMSTATE_TYPE3; /* we sent a type-3 */
|
||||
|
||||
} else
|
||||
if(NTLMSTATE_TYPE3 == data->state.ntlm.state) {
|
||||
}
|
||||
break;
|
||||
|
||||
case NTLMSTATE_TYPE3:
|
||||
/* connection is already authenticated,
|
||||
* don't send a header in future requests */
|
||||
if(conn->allocptr.userpwd) {
|
||||
free(conn->allocptr.userpwd);
|
||||
conn->allocptr.userpwd=NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user