From 2bd3033f681eb3cb204f285bd0b2f0b8aa176c7e Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 7 Jun 2006 14:14:04 +0000 Subject: NTLM2 session response support --- lib/http_ntlm.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/ssluse.c | 28 +++++++++++++++++----------- lib/ssluse.h | 4 ++-- 3 files changed, 70 insertions(+), 15 deletions(-) (limited to 'lib') diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index 2dc293d9b..01f049f24 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -51,6 +51,7 @@ #include "http_ntlm.h" #include "url.h" #include "memory.h" +#include "ssluse.h" #define _MPRINTF_REPLACE /* use our functions only */ #include @@ -59,7 +60,9 @@ #include #include +#include #include +#include #if OPENSSL_VERSION_NUMBER < 0x00907001L #define DES_key_schedule des_key_schedule @@ -94,6 +97,10 @@ static PSecurityFunctionTable s_pSecFn = NULL; /* Define this to make the type-3 message include the NT response message */ #define USE_NTRESPONSES 1 +/* Define this to make the type-3 message include the NTLM2Session response + message, requires USE_NTRESPONSES. */ +#define USE_NTLM2SESSION 1 + #ifndef USE_WINDOWS_SSPI /* this function converts from the little endian format used in the incoming package to whatever endian format we're using natively */ @@ -630,7 +637,11 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, 32 start of data block */ - +#if USE_NTLM2SESSION +#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY +#else +#define NTLM2FLAG 0 +#endif snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c" "\x01%c%c%c" /* 32-bit type = 1 */ "%c%c%c%c" /* 32-bit NTLM flag field */ @@ -651,6 +662,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, NTLMFLAG_NEGOTIATE_OEM| NTLMFLAG_REQUEST_TARGET| NTLMFLAG_NEGOTIATE_NTLM_KEY| + NTLM2FLAG| NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ), SHORTPAIR(domlen), @@ -672,15 +684,18 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM| NTLMFLAG_REQUEST_TARGET| NTLMFLAG_NEGOTIATE_NTLM_KEY| + NTLM2FLAG| NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), NTLMFLAG_NEGOTIATE_OEM| NTLMFLAG_REQUEST_TARGET| NTLMFLAG_NEGOTIATE_NTLM_KEY| + NTLM2FLAG| NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); print_flags(stderr, NTLMFLAG_NEGOTIATE_OEM| NTLMFLAG_REQUEST_TARGET| NTLMFLAG_NEGOTIATE_NTLM_KEY| + NTLM2FLAG| NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); fprintf(stderr, "\n****\n"); }); @@ -786,7 +801,41 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, hostlen = strlen(host); } - { +#if USE_NTLM2SESSION + /* We don't support NTLM2 if we don't have USE_NTRESPONSES */ + if (ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) { + unsigned char ntbuffer[0x18]; + unsigned char tmp[0x18]; + unsigned char md5sum[MD5_DIGEST_LENGTH]; + MD5_CTX MD5; + unsigned char random[8]; + + /* Need to create 8 bytes random data */ + Curl_ossl_seed(conn->data); /* Initiate the seed if not already done */ + RAND_bytes(random,8); + + /* 8 bytes random data as challenge in lmresp */ + memcpy(lmresp,random,8); + /* Pad with zeros */ + memset(lmresp+8,0,0x10); + + /* Fill tmp with challenge(nonce?) + random */ + memcpy(tmp,&ntlm->nonce[0],8); + memcpy(tmp+8,random,8); + + MD5_Init(&MD5); + MD5_Update(&MD5, tmp, 16); + MD5_Final(md5sum, &MD5); + /* We shall only use the first 8 bytes of md5sum, + but the des code in lm_resp only encrypt the first 8 bytes */ + mk_nt_hash(passwdp, ntbuffer); + lm_resp(ntbuffer, md5sum, ntresp); + + /* End of NTLM2 Session code */ + } + else { +#endif + #if USE_NTRESPONSES unsigned char ntbuffer[0x18]; #endif diff --git a/lib/ssluse.c b/lib/ssluse.c index ab177009a..0bbb57886 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -169,8 +169,7 @@ static bool rand_enough(int nread) } #endif -static -int random_the_seed(struct SessionHandle *data) +static int ossl_seed(struct SessionHandle *data) { char *buf = data->state.buffer; /* point to the big buffer */ int nread=0; @@ -259,6 +258,20 @@ int random_the_seed(struct SessionHandle *data) return nread; } +int Curl_ossl_seed(struct SessionHandle *data) +{ + /* we have the "SSL is seeded" boolean static to prevent multiple + time-consuming seedings in vain */ + static bool ssl_seeded = FALSE; + + if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) { + ossl_seed(data); + ssl_seeded = TRUE; + } + return 0; +} + + #ifndef SSL_FILETYPE_ENGINE #define SSL_FILETYPE_ENGINE 42 #endif @@ -531,9 +544,6 @@ static char *SSL_strerror(unsigned long error, char *buf, size_t size) return (buf); } -/* we have the "SSL is seeded" boolean global for the application to - prevent multiple time-consuming seedings in vain */ -static bool ssl_seeded = FALSE; #endif /* USE_SSLEAY */ #ifdef USE_SSLEAY @@ -1166,12 +1176,8 @@ Curl_ossl_connect_step1(struct connectdata *conn, curlassert(ssl_connect_1 == connssl->connecting_state); - if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) { - /* Make funny stuff to get random input */ - random_the_seed(data); - - ssl_seeded = TRUE; - } + /* Make funny stuff to get random input */ + Curl_ossl_seed(data); /* check to see if we've been told to use an explicit SSL/TLS version */ switch(data->set.ssl.version) { diff --git a/lib/ssluse.h b/lib/ssluse.h index 5cc2f700e..d33ac3878 100644 --- a/lib/ssluse.h +++ b/lib/ssluse.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -63,7 +63,7 @@ ssize_t Curl_ossl_recv(struct connectdata *conn, /* connection data */ bool *wouldblock); size_t Curl_ossl_version(char *buffer, size_t size); - int Curl_ossl_check_cxn(struct connectdata *cxn); +int Curl_ossl_seed(struct SessionHandle *data); #endif -- cgit v1.2.3