25 #if defined(USE_NTLM) && !defined(USE_WINDOWS_SSPI) 49 #if defined(NTLM_NEEDS_NSS_INIT) 53 #define BUILDING_CURL_NTLM_MSGS_C 64 #define NTLMSSP_SIGNATURE "\x4e\x54\x4c\x4d\x53\x53\x50" 66 #define SHORTPAIR(x) ((x) & 0xff), (((x) >> 8) & 0xff) 67 #define LONGQUARTET(x) ((x) & 0xff), (((x) >> 8) & 0xff), \ 68 (((x) >> 16) & 0xff), (((x) >> 24) & 0xff) 71 # define DEBUG_OUT(x) x 72 static void ntlm_print_flags(FILE *handle,
unsigned long flags)
74 if(flags & NTLMFLAG_NEGOTIATE_UNICODE)
75 fprintf(handle,
"NTLMFLAG_NEGOTIATE_UNICODE ");
76 if(flags & NTLMFLAG_NEGOTIATE_OEM)
77 fprintf(handle,
"NTLMFLAG_NEGOTIATE_OEM ");
78 if(flags & NTLMFLAG_REQUEST_TARGET)
79 fprintf(handle,
"NTLMFLAG_REQUEST_TARGET ");
81 fprintf(handle,
"NTLMFLAG_UNKNOWN_3 ");
82 if(flags & NTLMFLAG_NEGOTIATE_SIGN)
83 fprintf(handle,
"NTLMFLAG_NEGOTIATE_SIGN ");
84 if(flags & NTLMFLAG_NEGOTIATE_SEAL)
85 fprintf(handle,
"NTLMFLAG_NEGOTIATE_SEAL ");
86 if(flags & NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE)
87 fprintf(handle,
"NTLMFLAG_NEGOTIATE_DATAGRAM_STYLE ");
88 if(flags & NTLMFLAG_NEGOTIATE_LM_KEY)
89 fprintf(handle,
"NTLMFLAG_NEGOTIATE_LM_KEY ");
90 if(flags & NTLMFLAG_NEGOTIATE_NETWARE)
91 fprintf(handle,
"NTLMFLAG_NEGOTIATE_NETWARE ");
92 if(flags & NTLMFLAG_NEGOTIATE_NTLM_KEY)
93 fprintf(handle,
"NTLMFLAG_NEGOTIATE_NTLM_KEY ");
95 fprintf(handle,
"NTLMFLAG_UNKNOWN_10 ");
96 if(flags & NTLMFLAG_NEGOTIATE_ANONYMOUS)
97 fprintf(handle,
"NTLMFLAG_NEGOTIATE_ANONYMOUS ");
98 if(flags & NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED)
99 fprintf(handle,
"NTLMFLAG_NEGOTIATE_DOMAIN_SUPPLIED ");
100 if(flags & NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED)
101 fprintf(handle,
"NTLMFLAG_NEGOTIATE_WORKSTATION_SUPPLIED ");
102 if(flags & NTLMFLAG_NEGOTIATE_LOCAL_CALL)
103 fprintf(handle,
"NTLMFLAG_NEGOTIATE_LOCAL_CALL ");
104 if(flags & NTLMFLAG_NEGOTIATE_ALWAYS_SIGN)
105 fprintf(handle,
"NTLMFLAG_NEGOTIATE_ALWAYS_SIGN ");
106 if(flags & NTLMFLAG_TARGET_TYPE_DOMAIN)
107 fprintf(handle,
"NTLMFLAG_TARGET_TYPE_DOMAIN ");
108 if(flags & NTLMFLAG_TARGET_TYPE_SERVER)
109 fprintf(handle,
"NTLMFLAG_TARGET_TYPE_SERVER ");
110 if(flags & NTLMFLAG_TARGET_TYPE_SHARE)
111 fprintf(handle,
"NTLMFLAG_TARGET_TYPE_SHARE ");
112 if(flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY)
113 fprintf(handle,
"NTLMFLAG_NEGOTIATE_NTLM2_KEY ");
114 if(flags & NTLMFLAG_REQUEST_INIT_RESPONSE)
115 fprintf(handle,
"NTLMFLAG_REQUEST_INIT_RESPONSE ");
116 if(flags & NTLMFLAG_REQUEST_ACCEPT_RESPONSE)
117 fprintf(handle,
"NTLMFLAG_REQUEST_ACCEPT_RESPONSE ");
118 if(flags & NTLMFLAG_REQUEST_NONNT_SESSION_KEY)
119 fprintf(handle,
"NTLMFLAG_REQUEST_NONNT_SESSION_KEY ");
120 if(flags & NTLMFLAG_NEGOTIATE_TARGET_INFO)
121 fprintf(handle,
"NTLMFLAG_NEGOTIATE_TARGET_INFO ");
123 fprintf(handle,
"NTLMFLAG_UNKNOWN_24 ");
125 fprintf(handle,
"NTLMFLAG_UNKNOWN_25 ");
127 fprintf(handle,
"NTLMFLAG_UNKNOWN_26 ");
129 fprintf(handle,
"NTLMFLAG_UNKNOWN_27 ");
131 fprintf(handle,
"NTLMFLAG_UNKNOWN_28 ");
132 if(flags & NTLMFLAG_NEGOTIATE_128)
133 fprintf(handle,
"NTLMFLAG_NEGOTIATE_128 ");
134 if(flags & NTLMFLAG_NEGOTIATE_KEY_EXCHANGE)
135 fprintf(handle,
"NTLMFLAG_NEGOTIATE_KEY_EXCHANGE ");
136 if(flags & NTLMFLAG_NEGOTIATE_56)
137 fprintf(handle,
"NTLMFLAG_NEGOTIATE_56 ");
140 static void ntlm_print_hex(FILE *handle,
const char *
buf,
size_t len)
148 fprintf(stderr,
"%02.2x", (
unsigned int)*p++);
151 # define DEBUG_OUT(x) Curl_nop_stmt 172 struct ntlmdata *ntlm)
174 unsigned short target_info_len = 0;
175 unsigned int target_info_offset = 0;
177 #if defined(CURL_DISABLE_VERBOSE_STRINGS) 184 if(target_info_len > 0) {
185 if(((target_info_offset + target_info_len) > size) ||
186 (target_info_offset < 48)) {
187 infof(data,
"NTLM handshake failure (bad type-2 message). " 188 "Target Info Offset Len is set incorrect by the peer\n");
192 ntlm->target_info =
malloc(target_info_len);
193 if(!ntlm->target_info)
196 memcpy(ntlm->target_info, &buffer[target_info_offset], target_info_len);
200 ntlm->target_info_len = target_info_len;
230 bool Curl_auth_is_ntlm_supported(
void)
252 const char *type2msg,
253 struct ntlmdata *ntlm)
255 static const char type2_marker[] = { 0x02, 0x00, 0x00, 0x00 };
274 unsigned char *type2 = NULL;
275 size_t type2_len = 0;
277 #if defined(NTLM_NEEDS_NSS_INIT) 279 result = Curl_nss_force_init(data);
282 #elif defined(CURL_DISABLE_VERBOSE_STRINGS) 287 if(strlen(type2msg) && *type2msg !=
'=') {
295 infof(data,
"NTLM handshake failure (empty type-2 message)\n");
301 if((type2_len < 32) ||
302 (memcmp(type2, NTLMSSP_SIGNATURE, 8) != 0) ||
303 (memcmp(type2 + 8, type2_marker,
sizeof(type2_marker)) != 0)) {
306 infof(data,
"NTLM handshake failure (bad type-2 message)\n");
311 memcpy(ntlm->nonce, &type2[24], 8);
313 if(ntlm->flags & NTLMFLAG_NEGOTIATE_TARGET_INFO) {
314 result = ntlm_decode_type2_target(data, type2, type2_len, ntlm);
317 infof(data,
"NTLM handshake failure (bad type-2 message)\n");
323 fprintf(stderr,
"**** TYPE2 header flags=0x%08.8lx ", ntlm->flags);
324 ntlm_print_flags(stderr, ntlm->flags);
326 ntlm_print_hex(stderr, (
char *)ntlm->nonce, 8);
328 fprintf(stderr,
"**** Header %s\n ", header);
338 static void unicodecpy(
unsigned char *dest,
const char *src,
size_t length)
341 for(i = 0; i < length; i++) {
342 dest[2 *
i] = (
unsigned char)src[i];
343 dest[2 * i + 1] =
'\0';
368 struct ntlmdata *ntlm,
369 char **outptr,
size_t *outlen)
387 unsigned char ntlmbuf[NTLM_BUFSIZE];
388 const char *host =
"";
389 const char *domain =
"";
393 size_t domoff = hostoff + hostlen;
399 Curl_auth_ntlm_cleanup(ntlm);
401 #if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) 402 #define NTLM2FLAG NTLMFLAG_NEGOTIATE_NTLM2_KEY 406 snprintf((
char *)ntlmbuf, NTLM_BUFSIZE,
407 NTLMSSP_SIGNATURE
"%c" 423 LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
424 NTLMFLAG_REQUEST_TARGET |
425 NTLMFLAG_NEGOTIATE_NTLM_KEY |
427 NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
440 size = 32 + hostlen + domlen;
443 fprintf(stderr,
"* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " 445 LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM |
446 NTLMFLAG_REQUEST_TARGET |
447 NTLMFLAG_NEGOTIATE_NTLM_KEY |
449 NTLMFLAG_NEGOTIATE_ALWAYS_SIGN),
450 NTLMFLAG_NEGOTIATE_OEM |
451 NTLMFLAG_REQUEST_TARGET |
452 NTLMFLAG_NEGOTIATE_NTLM_KEY |
454 NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
455 ntlm_print_flags(stderr,
456 NTLMFLAG_NEGOTIATE_OEM |
457 NTLMFLAG_REQUEST_TARGET |
458 NTLMFLAG_NEGOTIATE_NTLM_KEY |
460 NTLMFLAG_NEGOTIATE_ALWAYS_SIGN);
489 struct ntlmdata *ntlm,
490 char **outptr,
size_t *outlen)
513 unsigned char ntlmbuf[NTLM_BUFSIZE];
515 unsigned char lmresp[24];
516 #ifdef USE_NTRESPONSES 518 unsigned int ntresplen = 24;
519 unsigned char ntresp[24];
520 unsigned char *ptr_ntresp = &ntresp[0];
521 unsigned char *ntlmv2resp = NULL;
523 bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ?
TRUE :
FALSE;
526 const char *domain =
"";
534 user = strchr(userp,
'\\');
536 user = strchr(userp,
'/');
540 domlen = (user - domain);
547 userlen = strlen(user);
552 infof(data,
"gethostname() failed, continuing without!\n");
556 hostlen = strlen(host);
559 #if defined(USE_NTRESPONSES) && defined(USE_NTLM_V2) 560 if(ntlm->target_info_len) {
561 unsigned char ntbuffer[0x18];
562 unsigned char entropy[8];
563 unsigned char ntlmv2hash[0x18];
569 result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
573 result = Curl_ntlm_core_mk_ntlmv2_hash(user, userlen, domain, domlen,
574 ntbuffer, ntlmv2hash);
579 result = Curl_ntlm_core_mk_lmv2_resp(ntlmv2hash, entropy,
580 &ntlm->nonce[0], lmresp);
585 result = Curl_ntlm_core_mk_ntlmv2_resp(ntlmv2hash, entropy,
586 ntlm, &ntlmv2resp, &ntresplen);
590 ptr_ntresp = ntlmv2resp;
595 #if defined(USE_NTRESPONSES) && defined(USE_NTLM2SESSION) 597 if(ntlm->flags & NTLMFLAG_NEGOTIATE_NTLM2_KEY) {
598 unsigned char ntbuffer[0x18];
599 unsigned char tmp[0x18];
601 unsigned char entropy[8];
609 memcpy(lmresp, entropy, 8);
612 memset(lmresp + 8, 0, 0x10);
615 memcpy(tmp, &ntlm->nonce[0], 8);
616 memcpy(tmp + 8, entropy, 8);
622 result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
626 Curl_ntlm_core_lm_resp(ntbuffer, md5sum, ntresp);
635 #ifdef USE_NTRESPONSES 636 unsigned char ntbuffer[0x18];
638 unsigned char lmbuffer[0x18];
640 #ifdef USE_NTRESPONSES 641 result = Curl_ntlm_core_mk_nt_hash(data, passwdp, ntbuffer);
645 Curl_ntlm_core_lm_resp(ntbuffer, &ntlm->nonce[0], ntresp);
648 result = Curl_ntlm_core_mk_lm_hash(data, passwdp, lmbuffer);
652 Curl_ntlm_core_lm_resp(lmbuffer, &ntlm->nonce[0], lmresp);
661 userlen = userlen * 2;
662 hostlen = hostlen * 2;
666 #ifdef USE_NTRESPONSES 667 ntrespoff = lmrespoff + 0x18;
668 domoff = ntrespoff + ntresplen;
670 domoff = lmrespoff + 0x18;
672 useroff = domoff + domlen;
673 hostoff = useroff + userlen;
676 size =
snprintf((
char *)ntlmbuf, NTLM_BUFSIZE,
677 NTLMSSP_SIGNATURE
"%c" 723 SHORTPAIR(lmrespoff),
726 #ifdef USE_NTRESPONSES
727 SHORTPAIR(ntresplen),
728 SHORTPAIR(ntresplen),
729 SHORTPAIR(ntrespoff),
757 LONGQUARTET(ntlm->flags));
763 if(size < (NTLM_BUFSIZE - 0x18)) {
764 memcpy(&ntlmbuf[size], lmresp, 0x18);
769 fprintf(stderr,
"**** TYPE3 header lmresp=");
770 ntlm_print_hex(stderr, (
char *)&ntlmbuf[lmrespoff], 0x18);
773 #ifdef USE_NTRESPONSES 774 if(size < (NTLM_BUFSIZE - ntresplen)) {
776 memcpy(&ntlmbuf[size], ptr_ntresp, ntresplen);
782 ntlm_print_hex(stderr, (
char *)&ntlmbuf[ntrespoff], ntresplen);
790 fprintf(stderr,
"\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ",
791 LONGQUARTET(ntlm->flags), ntlm->flags);
792 ntlm_print_flags(stderr, ntlm->flags);
798 if(size + userlen + domlen + hostlen >= NTLM_BUFSIZE) {
799 failf(data,
"user + domain + host name too big");
805 unicodecpy(&ntlmbuf[size], domain, domlen / 2);
807 memcpy(&ntlmbuf[size], domain, domlen);
813 unicodecpy(&ntlmbuf[size], user, userlen / 2);
815 memcpy(&ntlmbuf[size], user, userlen);
821 unicodecpy(&ntlmbuf[size], host, hostlen / 2);
823 memcpy(&ntlmbuf[size], host, hostlen);
836 Curl_auth_ntlm_cleanup(ntlm);
851 void Curl_auth_ntlm_cleanup(
struct ntlmdata *ntlm)
857 ntlm->target_info_len = 0;
unsigned int Curl_read32_le(const unsigned char *buf)
CURLcode Curl_base64_decode(const char *src, unsigned char **outptr, size_t *outlen)
CURLcode Curl_base64_encode(struct Curl_easy *data, const char *inputbuff, size_t insize, char **outptr, size_t *outlen)
UNITTEST_START int result
memcpy(filename, filename1, strlen(filename1))
#define Curl_convert_to_network(a, b, c)
CURLcode(* md5sum)(unsigned char *input, size_t inputlen, unsigned char *md5sum, size_t md5sumlen)
unsigned short Curl_read16_le(const unsigned char *buf)
#define Curl_safefree(ptr)
#define MD5_DIGEST_LENGTH
CURLcode Curl_rand(struct Curl_easy *data, unsigned char *rnd, size_t num)
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)