#endif
#include "urldata.h"
+#include "easyif.h" /* for Curl_convert_... prototypes */
#include "sendf.h"
#include "strequal.h"
#include "base64.h"
#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>
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);
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);
});
/*
* 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[] = {
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. */
/*
* 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;
#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 */
});
/* 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);
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 */
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
/* 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 */
DEBUG_OUT({
fprintf(stderr, "**** TYPE3 header lmresp=");
- print_hex(stderr, &ntlmbuf[lmrespoff], 0x18);
+ print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18);
});
#if USE_NTRESPONSES
DEBUG_OUT({
fprintf(stderr, "\n ntresp=");
- print_hex(stderr, &ntlmbuf[ntrespoff], 0x18);
+ print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
});
#endif
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);