]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
- David McCreedy did NTLM changes mainly for non-ASCII platforms:
authorDaniel Stenberg <daniel@haxx.se>
Tue, 23 Jan 2007 22:57:42 +0000 (22:57 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 23 Jan 2007 22:57:42 +0000 (22:57 +0000)
  #1
  There's a compilation error in http_ntlm.c if USE_NTLM2SESSION is NOT
  defined.  I noticed this while testing various configurations.  Line 867 of
  the current http_ntlm.c is a closing bracket for an if/else pair that only
  gets compiled in if USE_NTLM2SESSION is defined.  But this closing bracket
  wasn't in an #ifdef so the code fails to compile unless USE_NTLM2SESSION was
  defined.  Lines 198 and 140 of my patch wraps that closing bracket in an
  #ifdef USE_NTLM2SESSION.

  #2
  I noticed several picky compiler warnings when DEBUG_ME is defined.  I've
  fixed them with casting.  By the way, DEBUG_ME was a huge help in
  understanding this code.

  #3
  Hopefully the last non-ASCII conversion patch for libcurl in a while.  I
  changed the "NTLMSSP" literal to hex since this signature must always be in
  ASCII.

  Conversion code was strategically added where necessary.  And the
  Curl_base64_encode calls were changed so the binary "blobs" http_ntlm.c
  creates are NOT translated on non-ASCII platforms.

CHANGES
lib/http_ntlm.c

diff --git a/CHANGES b/CHANGES
index 07e0bcb271a5dc843fe3fa23570317e8b8752b35..8d529da006e8d86571ffa14951cbc814f0db1f85 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,32 @@
 
                                   Changelog
 
+Daniel (23 January 2007)
+- David McCreedy did NTLM changes mainly for non-ASCII platforms:
+
+  #1
+  There's a compilation error in http_ntlm.c if USE_NTLM2SESSION is NOT
+  defined.  I noticed this while testing various configurations.  Line 867 of
+  the current http_ntlm.c is a closing bracket for an if/else pair that only
+  gets compiled in if USE_NTLM2SESSION is defined.  But this closing bracket
+  wasn't in an #ifdef so the code fails to compile unless USE_NTLM2SESSION was
+  defined.  Lines 198 and 140 of my patch wraps that closing bracket in an
+  #ifdef USE_NTLM2SESSION.
+
+  #2
+  I noticed several picky compiler warnings when DEBUG_ME is defined.  I've
+  fixed them with casting.  By the way, DEBUG_ME was a huge help in
+  understanding this code.
+
+  #3
+  Hopefully the last non-ASCII conversion patch for libcurl in a while.  I
+  changed the "NTLMSSP" literal to hex since this signature must always be in
+  ASCII.
+
+  Conversion code was strategically added where necessary.  And the
+  Curl_base64_encode calls were changed so the binary "blobs" http_ntlm.c
+  creates are NOT translated on non-ASCII platforms.
+
 Dan F (22 January 2007)
 - Converted (most of) the test data files into genuine XML.  A handful still
   are not, due mainly to the lack of support for XML character entities
index ee6f6eb9b842309e33c0cc482225a8962412c161..aff1bb1b632a0146fe979f0ae58d59c88bdf6c7f 100644 (file)
@@ -49,6 +49,7 @@
 #endif
 
 #include "urldata.h"
+#include "easyif.h"  /* for Curl_convert_... prototypes */
 #include "sendf.h"
 #include "strequal.h"
 #include "base64.h"
@@ -60,6 +61,9 @@
 #define _MPRINTF_REPLACE /* use our functions only */
 #include <curl/mprintf.h>
 
+/* "NTLMSSP" signature is always in ASCII regardless of the platform */
+#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
+
 #ifndef USE_WINDOWS_SSPI
 
 #include <openssl/des.h>
@@ -265,7 +269,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
       ntlm->flags = 0;
 
       if((size < 32) ||
-         (memcmp(buffer, "NTLMSSP", 8) != 0) ||
+         (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
          (memcmp(buffer+8, type2_marker, sizeof(type2_marker)) != 0)) {
         /* This was not a good enough type-2 message */
         free(buffer);
@@ -279,7 +283,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn,
         fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
         print_flags(stderr, ntlm->flags);
         fprintf(stderr, "\n                  nonce=");
-        print_hex(stderr, ntlm->nonce, 8);
+        print_hex(stderr, (char *)ntlm->nonce, 8);
         fprintf(stderr, "\n****\n");
         fprintf(stderr, "**** Header %s\n ", header);
       });
@@ -349,7 +353,9 @@ static void lm_resp(unsigned char *keys,
 /*
  * Set up lanmanager hashed password
  */
-static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
+static void mk_lm_hash(struct SessionHandle *data,
+                       char *password, 
+                       unsigned char *lmbuffer /* 21 bytes */)
 {
   unsigned char pw[14];
   static const unsigned char magic[] = {
@@ -367,6 +373,17 @@ static void mk_lm_hash(char *password, unsigned char *lmbuffer /* 21 bytes */)
   for (; i<14; i++)
     pw[i] = 0;
 
+#ifdef CURL_DOES_CONVERSIONS
+  /*
+   * The LanManager hashed password needs to be created using the
+   * password in the network encoding not the host encoding.
+   */
+  if(data)
+    Curl_convert_to_network(data, (char *)pw, 14);
+#else
+  (void)data;
+#endif
+
   {
     /* Create LanManager hashed password. */
 
@@ -398,13 +415,26 @@ static void utf8_to_unicode_le(unsigned char *dest, const char *src,
 /*
  * Set up nt hashed passwords
  */
-static void mk_nt_hash(char *password, unsigned char *ntbuffer /* 21 bytes */)
+static void mk_nt_hash(struct SessionHandle *data,
+                       char *password,
+                       unsigned char *ntbuffer /* 21 bytes */)
 {
   size_t len = strlen(password);
   unsigned char *pw = malloc(len*2);
 
   utf8_to_unicode_le(pw, password, len);
 
+#ifdef CURL_DOES_CONVERSIONS
+  /*
+   * The NT hashed password needs to be created using the
+   * password in the network encoding not the host encoding.
+   */
+  if(data)
+    Curl_convert_to_network(data, (char *)pw, len*2);
+#else
+  (void)data;
+#endif
+
   {
     /* Create NT hashed password. */
     MD4_CTX MD4;
@@ -647,7 +677,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
 #else
 #define NTLM2FLAG 0
 #endif
-    snprintf((char *)ntlmbuf, sizeof(ntlmbuf), "NTLMSSP%c"
+    snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c"
              "\x01%c%c%c" /* 32-bit type = 1 */
              "%c%c%c%c"   /* 32-bit NTLM flag field */
              "%c%c"  /* domain length */
@@ -706,7 +736,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
     });
 
     /* now size is the size of the base64 encoded package size */
-    size = Curl_base64_encode(conn->data, (char *)ntlmbuf, size, &base64);
+    size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
 
     if(size >0 ) {
       Curl_safefree(*allocuserpwd);
@@ -841,7 +871,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
       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);
+      mk_nt_hash(conn->data, passwdp, ntbuffer);
       lm_resp(ntbuffer, md5sum, ntresp);
 
       /* End of NTLM2 Session code */
@@ -855,16 +885,18 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
       unsigned char lmbuffer[0x18];
 
 #if USE_NTRESPONSES
-      mk_nt_hash(passwdp, ntbuffer);
+      mk_nt_hash(conn->data, passwdp, ntbuffer);
       lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
 #endif
 
-      mk_lm_hash(passwdp, lmbuffer);
+      mk_lm_hash(conn->data, passwdp, lmbuffer);
       lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
       /* A safer but less compatible alternative is:
        *   lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
        * See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
+#if USE_NTLM2SESSION
     }
+#endif
 
     lmrespoff = 64; /* size of the message header */
 #if USE_NTRESPONSES
@@ -878,7 +910,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
 
     /* Create the big type-3 message binary blob */
     size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf),
-                    "NTLMSSP%c"
+                    NTLMSSP_SIGNATURE "%c"
                     "\x03%c%c%c" /* type-3, 32 bits */
 
                     "%c%c" /* LanManager length */
@@ -970,7 +1002,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
 
     DEBUG_OUT({
         fprintf(stderr, "**** TYPE3 header lmresp=");
-        print_hex(stderr, &ntlmbuf[lmrespoff], 0x18);
+        print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
     });
 
 #if USE_NTRESPONSES
@@ -982,7 +1014,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
 
     DEBUG_OUT({
         fprintf(stderr, "\n                  ntresp=");
-        print_hex(stderr, &ntlmbuf[ntrespoff], 0x18);
+        print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
     });
 
 #endif
@@ -1014,10 +1046,19 @@ CURLcode Curl_output_ntlm(struct connectdata *conn,
     memcpy(&ntlmbuf[size], host, hostlen);
     size += hostlen;
 
+#ifdef CURL_DOES_CONVERSIONS
+    /* convert domain, user, and host to ASCII but leave the rest as-is */
+    if(CURLE_OK != Curl_convert_to_network(conn->data, 
+                                           (char *)&ntlmbuf[domoff],
+                                           size-domoff)) {
+      return CURLE_CONV_FAILED;
+    }
+#endif /* CURL_DOES_CONVERSIONS */
+
 #endif
 
     /* convert the binary blob into base64 */
-    size = Curl_base64_encode(conn->data, (char *)ntlmbuf, size, &base64);
+    size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64);
 
     if(size >0 ) {
       Curl_safefree(*allocuserpwd);