* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2014, 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
*
***************************************************************************/
-#include "setup.h"
+#include "curl_setup.h"
-#ifdef USE_NTLM
+#if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI)
/*
* NTLM details:
#define DEBUG_ME 0
-#ifdef USE_SSLEAY
-
-# ifdef USE_OPENSSL
-# include <openssl/des.h>
-# ifndef OPENSSL_NO_MD4
-# include <openssl/md4.h>
-# endif
-# include <openssl/md5.h>
-# include <openssl/ssl.h>
-# include <openssl/rand.h>
-# else
-# include <des.h>
-# ifndef OPENSSL_NO_MD4
-# include <md4.h>
-# endif
-# include <md5.h>
-# include <ssl.h>
-# include <rand.h>
-# endif
-# include "ssluse.h"
-
-#elif defined(USE_GNUTLS_NETTLE)
-
-# include <nettle/md5.h>
-# include <gnutls/gnutls.h>
-# include <gnutls/crypto.h>
-# define MD5_DIGEST_LENGTH 16
-
-#elif defined(USE_GNUTLS)
-
-# include <gcrypt.h>
-# include "gtls.h"
-# define MD5_DIGEST_LENGTH 16
-# define MD4_DIGEST_LENGTH 16
-
-#elif defined(USE_NSS)
-
-# include <nss.h>
-# include <pk11pub.h>
-# include <hasht.h>
-# include "nssg.h"
-# include "curl_md4.h"
-# define MD5_DIGEST_LENGTH MD5_LENGTH
-
-#elif defined(USE_WINDOWS_SSPI)
-# include "curl_sspi.h"
-#else
-# error "Can't compile NTLM support without a crypto library."
-#endif
-
#include "urldata.h"
#include "non-ascii.h"
#include "sendf.h"
#include "curl_base64.h"
#include "curl_ntlm_core.h"
#include "curl_gethostname.h"
+#include "curl_multibyte.h"
+#include "warnless.h"
#include "curl_memory.h"
+#include "vtls/vtls.h"
+
+#ifdef USE_NSS
+#include "vtls/nssg.h" /* for Curl_nss_force_init() */
+#endif
+
#define BUILDING_CURL_NTLM_MSGS_C
#include "curl_ntlm_msgs.h"
+#include "curl_sasl.h"
+#include "curl_endian.h"
#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>
# define DEBUG_OUT(x) Curl_nop_stmt
#endif
-#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.
- * Argument is a pointer to a 4 byte buffer.
+ * ntlm_decode_type2_target()
+ *
+ * This is used to decode the "target info" in the ntlm type-2 message
+ * received.
+ *
+ * Parameters:
+ *
+ * data [in] - The session handle.
+ * buffer [in] - The decoded type-2 message.
+ * size [in] - The input buffer size, at least 32 bytes.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
+ *
+ * Returns CURLE_OK on success.
*/
-static unsigned int readint_le(unsigned char *buf)
+static CURLcode ntlm_decode_type2_target(struct SessionHandle *data,
+ unsigned char *buffer,
+ size_t size,
+ struct ntlmdata *ntlm)
{
- return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
- ((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
+ unsigned short target_info_len = 0;
+ unsigned int target_info_offset = 0;
+
+ if(size >= 48) {
+ target_info_len = Curl_read16_le(&buffer[40]);
+ target_info_offset = Curl_read32_le(&buffer[44]);
+ if(target_info_len > 0) {
+ if(((target_info_offset + target_info_len) > size) ||
+ (target_info_offset < 48)) {
+ infof(data, "NTLM handshake failure (bad type-2 message). "
+ "Target Info Offset Len is set incorrect by the peer\n");
+ return CURLE_BAD_CONTENT_ENCODING;
+ }
+
+ ntlm->target_info = malloc(target_info_len);
+ if(!ntlm->target_info)
+ return CURLE_OUT_OF_MEMORY;
+
+ memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
+ }
+ }
+
+ ntlm->target_info_len = target_info_len;
+
+ return CURLE_OK;
}
-#endif
/*
NTLM message structure notes:
*/
/*
- * Curl_ntlm_decode_type2_message()
+ * Curl_sasl_decode_ntlm_type2_message()
*
- * This is used to decode a ntlm type-2 message received from a: HTTP, SMTP
- * or POP3 server. The message is first decoded from a base64 string into a
- * raw ntlm message and checked for validity before the appropriate data for
- * creating a type-3 message is written to the given ntlm data structure.
+ * This is used to decode an already encoded NTLM type-2 message. The message
+ * is first decoded from a base64 string into a raw NTLM message and checked
+ * for validity before the appropriate data for creating a type-3 message is
+ * written to the given NTLM data structure.
*
* Parameters:
*
- * data [in] - Pointer to session handle.
- * header [in] - Pointer to the input buffer.
- * ntlm [in] - Pointer to ntlm data struct being used and modified.
+ * data [in] - The session handle.
+ * type2msg [in] - The base64 encoded type-2 message.
+ * ntlm [in/out] - The ntlm data struct being used and modified.
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_ntlm_decode_type2_message(struct SessionHandle *data,
- const char* header,
- struct ntlmdata* ntlm)
+CURLcode Curl_sasl_decode_ntlm_type2_message(struct SessionHandle *data,
+ const char *type2msg,
+ struct ntlmdata *ntlm)
{
-#ifndef USE_WINDOWS_SSPI
static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
-#endif
/* NTLM type-2 message structure:
(*) -> Optional
*/
- size_t size = 0;
- unsigned char *buffer = NULL;
- CURLcode error;
+ CURLcode result = CURLE_OK;
+ unsigned char *type2 = NULL;
+ size_t type2_len = 0;
-#if defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_WINDOWS_SSPI)
+#if defined(USE_NSS)
+ /* Make sure the crypto backend is initialized */
+ result = Curl_nss_force_init(data);
+ if(result)
+ return result;
+#elif defined(CURL_DISABLE_VERBOSE_STRINGS)
(void)data;
#endif
- error = Curl_base64_decode(header, &buffer, &size);
- if(error)
- return error;
-
- if(!buffer) {
- infof(data, "NTLM handshake failure (unhandled condition)\n");
- return CURLE_REMOTE_ACCESS_DENIED;
+ /* Decode the base-64 encoded type-2 message */
+ if(strlen(type2msg) && *type2msg != '=') {
+ result = Curl_base64_decode(type2msg, &type2, &type2_len);
+ if(result)
+ return result;
}
-#ifdef USE_WINDOWS_SSPI
- ntlm->type_2 = malloc(size + 1);
- if(ntlm->type_2 == NULL) {
- free(buffer);
- return CURLE_OUT_OF_MEMORY;
+ /* Ensure we have a valid type-2 message */
+ if(!type2) {
+ infof(data, "NTLM handshake failure (empty type-2 message)\n");
+ return CURLE_BAD_CONTENT_ENCODING;
}
- ntlm->n_type_2 = (unsigned long)size;
- memcpy(ntlm->type_2, buffer, size);
-#else
+
ntlm->flags = 0;
- if((size < 32) ||
- (memcmp(buffer, NTLMSSP_SIGNATURE, 8) != 0) ||
- (memcmp(buffer + 8, type2_marker, sizeof(type2_marker)) != 0)) {
+ if((type2_len < 32) ||
+ (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
+ (memcmp(type2 + 8, type2_marker, sizeof(type2_marker)) != 0)) {
/* This was not a good enough type-2 message */
- free(buffer);
+ free(type2);
infof(data, "NTLM handshake failure (bad type-2 message)\n");
- return CURLE_REMOTE_ACCESS_DENIED;
+ return CURLE_BAD_CONTENT_ENCODING;
}
- ntlm->flags = readint_le(&buffer[20]);
- memcpy(ntlm->nonce, &buffer[24], 8);
+ ntlm->flags = Curl_read32_le(&type2[20]);
+ memcpy(ntlm->nonce, &type2[24], 8);
+
+ if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
+ result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
+ if(result) {
+ free(type2);
+ infof(data, "NTLM handshake failure (bad type-2 message)\n");
+ return result;
+ }
+ }
DEBUG_OUT({
fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
fprintf(stderr, "\n****\n");
fprintf(stderr, "**** Header %s\n ", header);
});
-#endif
- free(buffer);
- return CURLE_OK;
-}
+ free(type2);
-#ifdef USE_WINDOWS_SSPI
-void Curl_ntlm_sspi_cleanup(struct ntlmdata *ntlm)
-{
- if(ntlm->type_2) {
- free(ntlm->type_2);
- ntlm->type_2 = NULL;
- }
- if(ntlm->has_handles) {
- s_pSecFn->DeleteSecurityContext(&ntlm->c_handle);
- s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
- ntlm->has_handles = 0;
- }
- if(ntlm->p_identity) {
- if(ntlm->identity.User) free(ntlm->identity.User);
- if(ntlm->identity.Password) free(ntlm->identity.Password);
- if(ntlm->identity.Domain) free(ntlm->identity.Domain);
- ntlm->p_identity = NULL;
- }
+ return result;
}
-#endif
-#ifndef USE_WINDOWS_SSPI
/* copy the source to the destination and fill in zeroes in every
other destination byte! */
-static void unicodecpy(unsigned char *dest,
- const char *src, size_t length)
+static void unicodecpy(unsigned char *dest, const char *src, size_t length)
{
size_t i;
for(i = 0; i < length; i++) {
dest[2 * i + 1] = '\0';
}
}
-#endif
/*
- * Curl_ntlm_create_type1_message()
+ * Curl_sasl_create_ntlm_type1_message()
*
- * This is used to generate an already encoded NTLM type-1 message ready
- * for sending to the recipient, be it a: HTTP, SMTP or POP3 server,
- * using the appropriate compile time crypo API.
+ * This is used to generate an already encoded NTLM type-1 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
*
* Parameters:
*
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_ntlm_create_type1_message(const char *userp,
- const char *passwdp,
- struct ntlmdata *ntlm,
- char **outptr,
- size_t *outlen)
+CURLcode Curl_sasl_create_ntlm_type1_message(const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
{
/* NTLM type-1 message structure:
(*) -> Optional
*/
- unsigned char ntlmbuf[NTLM_BUFSIZE];
size_t size;
-#ifdef USE_WINDOWS_SSPI
-
- SecBuffer buf;
- SecBufferDesc desc;
- SECURITY_STATUS status;
- ULONG attrs;
- const char *dest = "";
- const char *user;
- const char *domain = "";
- size_t userlen = 0;
- size_t domlen = 0;
- size_t passwdlen = 0;
- TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
-
- Curl_ntlm_sspi_cleanup(ntlm);
-
- user = strchr(userp, '\\');
- if(!user)
- user = strchr(userp, '/');
-
- if(user) {
- domain = userp;
- domlen = user - userp;
- user++;
- }
- else {
- user = userp;
- domain = "";
- domlen = 0;
- }
-
- if(user)
- userlen = strlen(user);
-
- if(passwdp)
- passwdlen = strlen(passwdp);
-
- if(userlen > 0) {
- /* note: initialize all of this before doing the mallocs so that
- * it can be cleaned up later without leaking memory.
- */
- ntlm->p_identity = &ntlm->identity;
- memset(ntlm->p_identity, 0, sizeof(*ntlm->p_identity));
- if((ntlm->identity.User = (unsigned char *)strdup(user)) == NULL)
- return CURLE_OUT_OF_MEMORY;
-
- ntlm->identity.UserLength = (unsigned long)userlen;
- if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL)
- return CURLE_OUT_OF_MEMORY;
-
- ntlm->identity.PasswordLength = (unsigned long)passwdlen;
- if((ntlm->identity.Domain = malloc(domlen + 1)) == NULL)
- return CURLE_OUT_OF_MEMORY;
-
- strncpy((char *)ntlm->identity.Domain, domain, domlen);
- ntlm->identity.Domain[domlen] = '\0';
- ntlm->identity.DomainLength = (unsigned long)domlen;
- ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
- }
- else
- ntlm->p_identity = NULL;
-
- status = s_pSecFn->AcquireCredentialsHandleA(NULL, (void *)"NTLM",
- SECPKG_CRED_OUTBOUND, NULL,
- ntlm->p_identity, NULL, NULL,
- &ntlm->handle, &tsDummy);
- if(status != SEC_E_OK)
- return CURLE_OUT_OF_MEMORY;
-
- desc.ulVersion = SECBUFFER_VERSION;
- desc.cBuffers = 1;
- desc.pBuffers = &buf;
- buf.cbBuffer = NTLM_BUFSIZE;
- buf.BufferType = SECBUFFER_TOKEN;
- buf.pvBuffer = ntlmbuf;
-
- status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle, NULL,
- (void *)dest,
- ISC_REQ_CONFIDENTIALITY |
- ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONNECTION,
- 0, SECURITY_NETWORK_DREP,
- NULL, 0,
- &ntlm->c_handle, &desc,
- &attrs, &tsDummy);
-
- if(status == SEC_I_COMPLETE_AND_CONTINUE ||
- status == SEC_I_CONTINUE_NEEDED)
- s_pSecFn->CompleteAuthToken(&ntlm->c_handle, &desc);
- else if(status != SEC_E_OK) {
- s_pSecFn->FreeCredentialsHandle(&ntlm->handle);
- return CURLE_RECV_ERROR;
- }
-
- ntlm->has_handles = 1;
- size = buf.cbBuffer;
-
-#else
-
+ unsigned char ntlmbuf[NTLM_BUFSIZE];
const char *host = ""; /* empty */
const char *domain = ""; /* empty */
size_t hostlen = 0;
domain are empty */
(void)userp;
(void)passwdp;
- (void)ntlm;
-#if USE_NTLM2SESSION
+ /* Clean up any former leftovers and initialise to defaults */
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+#if USE_NTRESPONSES && USE_NTLM2SESSION
#define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY
#else
#define NTLM2FLAG 0
/* Initial packet length */
size = 32 + hostlen + domlen;
-#endif
-
DEBUG_OUT({
fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x "
"0x%08.8x ",
}
/*
- * Curl_ntlm_create_type3_message()
+ * Curl_sasl_create_ntlm_type3_message()
*
- * This is used to generate an already encoded NTLM type-3 message ready
- * for sending to the recipient, be it a: HTTP, SMTP or POP3 server,
- * using the appropriate compile time crypo API.
+ * This is used to generate an already encoded NTLM type-3 message ready for
+ * sending to the recipient using the appropriate compile time crypto API.
*
* Parameters:
*
*
* Returns CURLE_OK on success.
*/
-CURLcode Curl_ntlm_create_type3_message(struct SessionHandle *data,
- const char *userp,
- const char *passwdp,
- struct ntlmdata *ntlm,
- char **outptr,
- size_t *outlen)
+CURLcode Curl_sasl_create_ntlm_type3_message(struct SessionHandle *data,
+ const char *userp,
+ const char *passwdp,
+ struct ntlmdata *ntlm,
+ char **outptr, size_t *outlen)
+
{
/* NTLM type-3 message structure:
(*) -> Optional
*/
- unsigned char ntlmbuf[NTLM_BUFSIZE];
+ CURLcode result = CURLE_OK;
size_t size;
-
-#ifdef USE_WINDOWS_SSPI
- const char *dest = "";
- SecBuffer type_2;
- SecBuffer type_3;
- SecBufferDesc type_2_desc;
- SecBufferDesc type_3_desc;
- SECURITY_STATUS status;
- ULONG attrs;
- TimeStamp tsDummy; /* For Windows 9x compatibility of SSPI calls */
-
- (void)passwdp;
- (void)userp;
- (void)data;
-
- type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
- type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
- type_2_desc.pBuffers = &type_2;
- type_3_desc.pBuffers = &type_3;
-
- type_2.BufferType = SECBUFFER_TOKEN;
- type_2.pvBuffer = ntlm->type_2;
- type_2.cbBuffer = ntlm->n_type_2;
- type_3.BufferType = SECBUFFER_TOKEN;
- type_3.pvBuffer = ntlmbuf;
- type_3.cbBuffer = NTLM_BUFSIZE;
-
- status = s_pSecFn->InitializeSecurityContextA(&ntlm->handle,
- &ntlm->c_handle,
- (void *)dest,
- ISC_REQ_CONFIDENTIALITY |
- ISC_REQ_REPLAY_DETECT |
- ISC_REQ_CONNECTION,
- 0, SECURITY_NETWORK_DREP,
- &type_2_desc,
- 0, &ntlm->c_handle,
- &type_3_desc,
- &attrs, &tsDummy);
- if(status != SEC_E_OK)
- return CURLE_RECV_ERROR;
-
- size = type_3.cbBuffer;
-
- Curl_ntlm_sspi_cleanup(ntlm);
-
-#else
+ unsigned char ntlmbuf[NTLM_BUFSIZE];
int lmrespoff;
unsigned char lmresp[24]; /* fixed-size */
#if USE_NTRESPONSES
int ntrespoff;
+ unsigned int ntresplen = 24;
unsigned char ntresp[24]; /* fixed-size */
+ unsigned char *ptr_ntresp = &ntresp[0];
+ unsigned char *ntlmv2resp = NULL;
#endif
bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE;
char host[HOSTNAME_MAX + 1] = "";
size_t hostlen = 0;
size_t userlen = 0;
size_t domlen = 0;
- CURLcode res;
user = strchr(userp, '\\');
if(!user)
hostlen = strlen(host);
}
- if(unicode) {
- domlen = domlen * 2;
- userlen = userlen * 2;
- hostlen = hostlen * 2;
+#if USE_NTRESPONSES && USE_NTLM_V2
+ if(ntlm->target_info_len) {
+ unsigned char ntbuffer[0x18];
+ unsigned int entropy[2];
+ unsigned char ntlmv2hash[0x18];
+
+ entropy[0] = Curl_rand(data);
+ entropy[1] = Curl_rand(data);
+
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
+ result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
+ ntbuffer, ntlmv2hash);
+ if(result)
+ return result;
+
+ /* LMv2 response */
+ result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash,
+ (unsigned char *)&entropy[0],
+ &ntlm->nonce[0], lmresp);
+ if(result)
+ return result;
+
+ /* NTLMv2 response */
+ result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash,
+ (unsigned char *)&entropy[0],
+ ntlm, &ntlmv2resp, &ntresplen);
+ if(result)
+ return result;
+
+ ptr_ntresp = ntlmv2resp;
}
+ else
+#endif
-#if USE_NTLM2SESSION
+#if USE_NTRESPONSES && 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];
- unsigned char entropy[8];
+ unsigned int entropy[2];
/* Need to create 8 bytes random data */
-#ifdef USE_SSLEAY
- MD5_CTX MD5pw;
- Curl_ossl_seed(data); /* Initiate the seed if not already done */
- RAND_bytes(entropy, 8);
-#elif defined(USE_GNUTLS_NETTLE)
- struct md5_ctx MD5pw;
- gnutls_rnd(GNUTLS_RND_RANDOM, entropy, 8);
-#elif defined(USE_GNUTLS)
- gcry_md_hd_t MD5pw;
- Curl_gtls_seed(data); /* Initiate the seed if not already done */
- gcry_randomize(entropy, 8, GCRY_STRONG_RANDOM);
-#elif defined(USE_NSS)
- PK11Context *MD5pw;
- unsigned int MD5len;
- Curl_nss_seed(data); /* Initiate the seed if not already done */
- PK11_GenerateRandom(entropy, 8);
-#endif
+ entropy[0] = Curl_rand(data);
+ entropy[1] = Curl_rand(data);
/* 8 bytes random data as challenge in lmresp */
memcpy(lmresp, entropy, 8);
memcpy(tmp, &ntlm->nonce[0], 8);
memcpy(tmp + 8, entropy, 8);
-#ifdef USE_SSLEAY
- MD5_Init(&MD5pw);
- MD5_Update(&MD5pw, tmp, 16);
- MD5_Final(md5sum, &MD5pw);
-#elif defined(USE_GNUTLS_NETTLE)
- md5_init(&MD5pw);
- md5_update(&MD5pw, 16, tmp);
- md5_digest(&MD5pw, 16, md5sum);
-#elif defined(USE_GNUTLS)
- gcry_md_open(&MD5pw, GCRY_MD_MD5, 0);
- gcry_md_write(MD5pw, tmp, MD5_DIGEST_LENGTH);
- memcpy(md5sum, gcry_md_read (MD5pw, 0), MD5_DIGEST_LENGTH);
- gcry_md_close(MD5pw);
-#elif defined(USE_NSS)
- MD5pw = PK11_CreateDigestContext(SEC_OID_MD5);
- PK11_DigestOp(MD5pw, tmp, 16);
- PK11_DigestFinal(MD5pw, md5sum, &MD5len, MD5_DIGEST_LENGTH);
- PK11_DestroyContext(MD5pw, PR_TRUE);
-#endif
+ Curl_ssl_md5sum(tmp, 16, md5sum, MD5_DIGEST_LENGTH);
/* We shall only use the first 8 bytes of md5sum, but the des
code in Curl_ntlm_core_lm_resp only encrypt the first 8 bytes */
- if(CURLE_OUT_OF_MEMORY ==
- Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
- return CURLE_OUT_OF_MEMORY;
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
/* End of NTLM2 Session code */
+
}
else
#endif
unsigned char lmbuffer[0x18];
#if USE_NTRESPONSES
- if(CURLE_OUT_OF_MEMORY ==
- Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer))
- return CURLE_OUT_OF_MEMORY;
+ result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
+ if(result)
+ return result;
+
Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
#endif
- Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+ result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
+ if(result)
+ return result;
+
Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
+
/* A safer but less compatible alternative is:
* Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], lmresp);
* See http://davenport.sourceforge.net/ntlm.html#ntlmVersion2 */
}
+ if(unicode) {
+ domlen = domlen * 2;
+ userlen = userlen * 2;
+ hostlen = hostlen * 2;
+ }
+
lmrespoff = 64; /* size of the message header */
#if USE_NTRESPONSES
ntrespoff = lmrespoff + 0x18;
- domoff = ntrespoff + 0x18;
+ domoff = ntrespoff + ntresplen;
#else
domoff = lmrespoff + 0x18;
#endif
0x0, 0x0,
#if USE_NTRESPONSES
- SHORTPAIR(0x18), /* NT-response length, twice */
- SHORTPAIR(0x18),
+ SHORTPAIR(ntresplen), /* NT-response length, twice */
+ SHORTPAIR(ntresplen),
SHORTPAIR(ntrespoff),
0x0, 0x0,
#else
});
#if USE_NTRESPONSES
- if(size < (NTLM_BUFSIZE - 0x18)) {
+ if(size < (NTLM_BUFSIZE - ntresplen)) {
DEBUGASSERT(size == (size_t)ntrespoff);
- memcpy(&ntlmbuf[size], ntresp, 0x18);
- size += 0x18;
+ memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
+ size += ntresplen;
}
DEBUG_OUT({
fprintf(stderr, "\n ntresp=");
- ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18);
+ ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], ntresplen);
});
+ Curl_safefree(ntlmv2resp);/* Free the dynamic buffer allocated for NTLMv2 */
+
#endif
DEBUG_OUT({
size += hostlen;
/* Convert domain, user, and host to ASCII but leave the rest as-is */
- res = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
- size - domoff);
- if(res)
+ result = Curl_convert_to_network(data, (char *)&ntlmbuf[domoff],
+ size - domoff);
+ if(result)
return CURLE_CONV_FAILED;
-#endif
-
/* Return with binary blob encoded into base64 */
- return Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+ result = Curl_base64_encode(NULL, (char *)ntlmbuf, size, outptr, outlen);
+
+ Curl_sasl_ntlm_cleanup(ntlm);
+
+ return result;
}
-#endif /* USE_NTLM */
+#endif /* USE_NTLM && !USE_WINDOWS_SSPI */