aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2006-06-07 14:14:04 +0000
committerDaniel Stenberg <daniel@haxx.se>2006-06-07 14:14:04 +0000
commit2bd3033f681eb3cb204f285bd0b2f0b8aa176c7e (patch)
treea172d19de2e4f69196e233d4f0e0926a6ee43f6d /lib
parentfe105a07e35efa74e77e90222c1614748bd31ce8 (diff)
NTLM2 session response support
Diffstat (limited to 'lib')
-rw-r--r--lib/http_ntlm.c53
-rw-r--r--lib/ssluse.c28
-rw-r--r--lib/ssluse.h4
3 files changed, 70 insertions, 15 deletions
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 <curl/mprintf.h>
@@ -59,7 +60,9 @@
#include <openssl/des.h>
#include <openssl/md4.h>
+#include <openssl/md5.h>
#include <openssl/ssl.h>
+#include <openssl/rand.h>
#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, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2006, Daniel Stenberg, <daniel@haxx.se>, 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