diff --git a/CHANGES b/CHANGES index 07e0bcb27..8d529da00 100644 --- 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 diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index ee6f6eb9b..aff1bb1b6 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -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 +/* "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 @@ -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);