summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Monnerat <patrick@monnerat.net>2021-04-06 19:31:03 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-04-09 09:40:49 +0200
commitcca455a36b7c3472fa64b148ded9a11deef93017 (patch)
tree8bb318031c140519100c026a43ee0eba8dfde452
parent10514d0076ef4db1d6d77bb61d54a3a2baa67baf (diff)
downloadcurl-cca455a36b7c3472fa64b148ded9a11deef93017.tar.gz
ntlm: support version 2 on 32-bit platforms
Closes #6849
-rw-r--r--lib/curl_ntlm_core.c69
-rw-r--r--lib/curl_ntlm_core.h10
-rw-r--r--lib/vauth/ntlm.c6
3 files changed, 66 insertions, 19 deletions
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 66146a881..89d4ec872 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -513,6 +513,56 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
#if defined(USE_NTLM_V2) && !defined(USE_WINDOWS_SSPI)
+/* Timestamp in tenths of a microsecond since January 1, 1601 00:00:00 UTC. */
+struct ms_filetime {
+ unsigned int dwLowDateTime;
+ unsigned int dwHighDateTime;
+};
+
+/* Convert a time_t to an MS FILETIME (MS-DTYP section 2.3.3). */
+static void time2filetime(struct ms_filetime *ft, time_t t)
+{
+#if SIZEOF_TIME_T > 4
+ t = (t + CURL_OFF_T_C(11644473600)) * 10000000;
+ ft->dwLowDateTime = (unsigned int) (t & 0xFFFFFFFF);
+ ft->dwHighDateTime = (unsigned int) (t >> 32);
+#else
+ unsigned int r, s;
+ unsigned int i;
+
+ ft->dwLowDateTime = t & 0xFFFFFFFF;
+ ft->dwHighDateTime = 0;
+
+# ifndef HAVE_TIME_T_UNSIGNED
+ /* Extend sign if needed. */
+ if(ft->dwLowDateTime & 0x80000000)
+ ft->dwHighDateTime = ~0;
+# endif
+
+ /* Bias seconds to Jan 1, 1601.
+ 134774 days = 11644473600 seconds = 0x2B6109100 */
+ r = ft->dwLowDateTime;
+ ft->dwLowDateTime = (ft->dwLowDateTime + 0xB6109100U) & 0xFFFFFFFF;
+ ft->dwHighDateTime += ft->dwLowDateTime < r? 0x03: 0x02;
+
+ /* Convert to tenths of microseconds. */
+ ft->dwHighDateTime *= 10000000;
+ i = 32;
+ do {
+ i -= 8;
+ s = ((ft->dwLowDateTime >> i) & 0xFF) * (10000000 - 1);
+ r = (s << i) & 0xFFFFFFFF;
+ s >>= 1; /* Split shift to avoid width overflow. */
+ s >>= 31 - i;
+ ft->dwLowDateTime = (ft->dwLowDateTime + r) & 0xFFFFFFFF;
+ if(ft->dwLowDateTime < r)
+ s++;
+ ft->dwHighDateTime += s;
+ } while(i);
+ ft->dwHighDateTime &= 0xFFFFFFFF;
+#endif
+}
+
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
*/
@@ -586,22 +636,18 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
unsigned int len = 0;
unsigned char *ptr = NULL;
unsigned char hmac_output[HMAC_MD5_LENGTH];
- curl_off_t tw;
+ struct ms_filetime tw;
CURLcode result = CURLE_OK;
-#if SIZEOF_CURL_OFF_T < 8
-#error "this section needs 64bit support to work"
-#endif
-
/* Calculate the timestamp */
#ifdef DEBUGBUILD
char *force_timestamp = getenv("CURL_FORCETIME");
if(force_timestamp)
- tw = CURL_OFF_T_C(11644473600) * 10000000;
+ time2filetime(&tw, (time_t) 0);
else
#endif
- tw = ((curl_off_t)time(NULL) + CURL_OFF_T_C(11644473600)) * 10000000;
+ time2filetime(&tw, time(NULL));
/* Calculate the response len */
len = HMAC_MD5_LENGTH + NTLMv2_BLOB_LEN;
@@ -613,13 +659,14 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_resp(unsigned char *ntlmv2hash,
/* Create the BLOB structure */
msnprintf((char *)ptr + HMAC_MD5_LENGTH, NTLMv2_BLOB_LEN,
- "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
- "%c%c%c%c", /* Reserved = 0 */
+ "%c%c%c%c" /* NTLMv2_BLOB_SIGNATURE */
+ "%c%c%c%c" /* Reserved = 0 */
+ "%c%c%c%c%c%c%c%c", /* Timestamp */
NTLMv2_BLOB_SIGNATURE[0], NTLMv2_BLOB_SIGNATURE[1],
NTLMv2_BLOB_SIGNATURE[2], NTLMv2_BLOB_SIGNATURE[3],
- 0, 0, 0, 0);
+ 0, 0, 0, 0,
+ LONGQUARTET(tw.dwLowDateTime), LONGQUARTET(tw.dwHighDateTime));
- Curl_write64_le(tw, ptr + 24);
memcpy(ptr + 32, challenge_client, 8);
memcpy(ptr + 44, ntlm->target_info, ntlm->target_info_len);
diff --git a/lib/curl_ntlm_core.h b/lib/curl_ntlm_core.h
index a5e02b7f8..02b39d485 100644
--- a/lib/curl_ntlm_core.h
+++ b/lib/curl_ntlm_core.h
@@ -53,12 +53,16 @@
#endif
/* Define USE_NTLM_V2 in order to allow the type-3 message to include the
- LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1
- and support for 64-bit integers. */
-#if defined(USE_NTRESPONSES) && (SIZEOF_CURL_OFF_T > 4)
+ LMv2 and NTLMv2 response messages, requires USE_NTRESPONSES defined to 1 */
+#if defined(USE_NTRESPONSES)
#define USE_NTLM_V2
#endif
+/* Helpers to generate function byte arguments in little endian order */
+#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff))
+#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \
+ ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff))
+
void Curl_ntlm_core_lm_resp(const unsigned char *keys,
const unsigned char *plaintext,
unsigned char *results);
diff --git a/lib/vauth/ntlm.c b/lib/vauth/ntlm.c
index a3117f3fe..5831c5662 100644
--- a/lib/vauth/ntlm.c
+++ b/lib/vauth/ntlm.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -64,10 +64,6 @@
/* "NTLMSSP" signature is always in ASCII regardless of the platform */
#define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50"
-#define SHORTPAIR(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff))
-#define LONGQUARTET(x) ((int)((x) & 0xff)), ((int)(((x) >> 8) & 0xff)), \
- ((int)(((x) >> 16) & 0xff)), ((int)(((x) >> 24) & 0xff))
-
#if DEBUG_ME
# define DEBUG_OUT(x) x
static void ntlm_print_flags(FILE *handle, unsigned long flags)