Index: lib/http_ntlm.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/http_ntlm.c,v
retrieving revision 1.51
diff -u -r1.51 http_ntlm.c
--- lib/http_ntlm.c	8 Apr 2006 11:04:53 -0000	1.51
+++ lib/http_ntlm.c	2 Jun 2006 08:01:35 -0000
@@ -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 @@
 /* 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 @@
     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 @@
                NTLMFLAG_NEGOTIATE_OEM|
                NTLMFLAG_REQUEST_TARGET|
                NTLMFLAG_NEGOTIATE_NTLM_KEY|
+               NTLM2FLAG|
                NTLMFLAG_NEGOTIATE_ALWAYS_SIGN
                ),
              SHORTPAIR(domlen),
@@ -672,15 +684,18 @@
               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 @@
       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
Index: lib/ssluse.c
===================================================================
RCS file: /cvsroot/curl/curl/lib/ssluse.c,v
retrieving revision 1.150
diff -u -r1.150 ssluse.c
--- lib/ssluse.c	10 May 2006 22:17:42 -0000	1.150
+++ lib/ssluse.c	2 Jun 2006 08:01:35 -0000
@@ -169,8 +169,7 @@
 }
 #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 @@
   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 @@
   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 @@
 
   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) {
Index: lib/ssluse.h
===================================================================
RCS file: /cvsroot/curl/curl/lib/ssluse.h,v
retrieving revision 1.25
diff -u -r1.25 ssluse.h
--- lib/ssluse.h	10 May 2006 22:17:42 -0000	1.25
+++ lib/ssluse.h	2 Jun 2006 08:01:36 -0000
@@ -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 @@
                        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
