From 5ed17de326765d4e18b7886b046b0c2f9ab363cb Mon Sep 17 00:00:00 2001 From: Steve Holme Date: Tue, 9 Aug 2011 22:53:48 +0200 Subject: [PATCH] http NTLM: Tidied up http_ntlm prior to splitting the ntlm specific code --- lib/http_ntlm.c | 280 +++++++++++++++++++++++++----------------------- lib/http_ntlm.h | 5 +- lib/url.c | 4 +- 3 files changed, 149 insertions(+), 140 deletions(-) diff --git a/lib/http_ntlm.c b/lib/http_ntlm.c index b4fc2da44..3e6378506 100644 --- a/lib/http_ntlm.c +++ b/lib/http_ntlm.c @@ -164,7 +164,7 @@ static unsigned int readint_le(unsigned char *buf) /* must point to a #if DEBUG_ME # define DEBUG_OUT(x) x -static void print_flags(FILE *handle, unsigned long flags) +static void ntlm_print_flags(FILE *handle, unsigned long flags) { if(flags & NTLMFLAG_NEGOTIATE_UNICODE) fprintf(handle, "NTLMFLAG_NEGOTIATE_UNICODE "); @@ -232,7 +232,7 @@ static void print_flags(FILE *handle, unsigned long flags) fprintf(handle, "NTLMFLAG_NEGOTIATE_56 "); } -static void print_hex(FILE *handle, const char *buf, size_t len) +static void ntlm_print_hex(FILE *handle, const char *buf, size_t len) { const char *p = buf; fprintf(stderr, "0x"); @@ -270,7 +270,7 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn, return CURLNTLM_BAD; #endif - ntlm = proxy?&conn->proxyntlm:&conn->ntlm; + ntlm = proxy ? &conn->proxyntlm : &conn->ntlm; /* skip initial whitespaces */ while(*header && ISSPACE(*header)) @@ -328,9 +328,9 @@ CURLntlm Curl_input_ntlm(struct connectdata *conn, DEBUG_OUT({ fprintf(stderr, "**** TYPE2 header flags=0x%08.8lx ", ntlm->flags); - print_flags(stderr, ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); fprintf(stderr, "\n nonce="); - print_hex(stderr, (char *)ntlm->nonce, 8); + ntlm_print_hex(stderr, (char *)ntlm->nonce, 8); fprintf(stderr, "\n****\n"); fprintf(stderr, "**** Header %s\n ", header); }); @@ -549,8 +549,8 @@ static void mk_lm_hash(struct SessionHandle *data, DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)lmbuffer, DESKEY(ks), DES_ENCRYPT); - setup_des_key(pw+7, DESKEY(ks)); - DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer+8), + setup_des_key(pw + 7, DESKEY(ks)); + DES_ecb_encrypt((DES_cblock *)magic, (DES_cblock *)(lmbuffer + 8), DESKEY(ks), DES_ENCRYPT); #elif defined(USE_GNUTLS) gcry_cipher_hd_t des; @@ -561,12 +561,12 @@ static void mk_lm_hash(struct SessionHandle *data, gcry_cipher_close(des); gcry_cipher_open(&des, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB, 0); - setup_des_key(pw+7, &des); - gcry_cipher_encrypt(des, lmbuffer+8, 8, magic, 8); + setup_des_key(pw + 7, &des); + gcry_cipher_encrypt(des, lmbuffer + 8, 8, magic, 8); gcry_cipher_close(des); #elif defined(USE_NSS) encrypt_des(magic, lmbuffer, pw); - encrypt_des(magic, lmbuffer+8, pw+7); + encrypt_des(magic, lmbuffer + 8, pw + 7); #endif memset(lmbuffer + 16, 0, 21 - 16); @@ -578,7 +578,7 @@ static void ascii_to_unicode_le(unsigned char *dest, const char *src, size_t srclen) { size_t i; - for(i=0; itype_2) { free(ntlm->type_2); @@ -672,9 +670,9 @@ static void unicodecpy(unsigned char *dest, const char *src, size_t length) { size_t i; - for(i=0; i 0) { /* note: initialize all of this before doing the mallocs so that * it can be cleaned up later without leaking memory. */ @@ -1106,12 +1113,15 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, 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 = strlen(user); + + ntlm->identity.UserLength = userlen; if((ntlm->identity.Password = (unsigned char *)strdup(passwdp)) == NULL) return CURLE_OUT_OF_MEMORY; + ntlm->identity.PasswordLength = strlen(passwdp); - if((ntlm->identity.Domain = malloc(domlen+1)) == NULL) + 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 = domlen; @@ -1121,10 +1131,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, ntlm->p_identity = NULL; } - if(s_pSecFn->AcquireCredentialsHandleA( - NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, NULL, ntlm->p_identity, - NULL, NULL, &ntlm->handle, &tsDummy - ) != SEC_E_OK) { + if(s_pSecFn->AcquireCredentialsHandleA(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND, + NULL, ntlm->p_identity, NULL, NULL, + &ntlm->handle, &tsDummy) != SEC_E_OK) { return CURLE_OUT_OF_MEMORY; } @@ -1145,8 +1154,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, &ntlm->c_handle, &desc, &attrs, &tsDummy); - if(status == SEC_I_COMPLETE_AND_CONTINUE || - status == SEC_I_CONTINUE_NEEDED) { + 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) { @@ -1179,72 +1187,72 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, #else #define NTLM2FLAG 0 #endif - snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%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 */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host name offset */ - "%c%c" /* 2 zeroes */ - "%s" /* host name */ - "%s", /* domain string */ - 0, /* trailing zero */ - 0,0,0, /* part of type-1 long */ + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host name offset */ + "%c%c" /* 2 zeroes */ + "%s" /* host name */ + "%s", /* domain string */ + 0, /* trailing zero */ + 0, 0, 0, /* part of type-1 long */ - LONGQUARTET( - NTLMFLAG_NEGOTIATE_OEM| - NTLMFLAG_REQUEST_TARGET| - NTLMFLAG_NEGOTIATE_NTLM_KEY| - NTLM2FLAG| - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN - ), + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), SHORTPAIR(domlen), SHORTPAIR(domlen), SHORTPAIR(domoff), - 0,0, + 0, 0, SHORTPAIR(hostlen), SHORTPAIR(hostlen), SHORTPAIR(hostoff), - 0,0, - host /* this is empty */, domain /* this is empty */); + 0, 0, + host, /* this is empty */ + domain /* this is empty */); /* 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 ", - LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM| - NTLMFLAG_REQUEST_TARGET| - NTLMFLAG_NEGOTIATE_NTLM_KEY| - NTLM2FLAG| - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), - NTLMFLAG_NEGOTIATE_OEM| - NTLMFLAG_REQUEST_TARGET| - NTLMFLAG_NEGOTIATE_NTLM_KEY| - NTLM2FLAG| - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - print_flags(stderr, - NTLMFLAG_NEGOTIATE_OEM| - NTLMFLAG_REQUEST_TARGET| - NTLMFLAG_NEGOTIATE_NTLM_KEY| - NTLM2FLAG| - NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); - fprintf(stderr, "\n****\n"); - }); + fprintf(stderr, "* TYPE1 header flags=0x%02.2x%02.2x%02.2x%02.2x " + "0x%08.8x ", + LONGQUARTET(NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN), + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + ntlm_print_flags(stderr, + NTLMFLAG_NEGOTIATE_OEM | + NTLMFLAG_REQUEST_TARGET | + NTLMFLAG_NEGOTIATE_NTLM_KEY | + NTLM2FLAG | + NTLMFLAG_NEGOTIATE_ALWAYS_SIGN); + fprintf(stderr, "\n****\n"); + }); /* now size is the size of the base64 encoded package size */ size = Curl_base64_encode(NULL, (char *)ntlmbuf, size, &base64); - if(size >0 ) { + if(size > 0) { Curl_safefree(*allocuserpwd); *allocuserpwd = aprintf("%sAuthorization: NTLM %s\r\n", - proxy?"Proxy-":"", + proxy ? "Proxy-" : "", base64); DEBUG_OUT(fprintf(stderr, "**** Header %s\n ", *allocuserpwd)); free(base64); @@ -1274,16 +1282,18 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, { #ifdef USE_WINDOWS_SSPI - SecBuffer type_2, type_3; - SecBufferDesc type_2_desc, type_3_desc; + 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 SPPI calls */ - 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_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; @@ -1318,10 +1328,10 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, int ntrespoff; unsigned char ntresp[24]; /* fixed-size */ #endif - bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE)?TRUE:FALSE; + bool unicode = (ntlm->flags & NTLMFLAG_NEGOTIATE_UNICODE) ? TRUE : FALSE; size_t useroff; const char *user; - size_t userlen; + size_t userlen = 0; CURLcode res; user = strchr(userp, '\\'); @@ -1335,7 +1345,9 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, } else user = userp; - userlen = strlen(user); + + if(user) + userlen = strlen(user); if(Curl_gethostname(host, HOSTNAME_MAX)) { infof(conn->data, "gethostname() failed, continuing without!"); @@ -1383,13 +1395,14 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, #endif /* 8 bytes random data as challenge in lmresp */ - memcpy(lmresp,entropy,8); - /* Pad with zeros */ - memset(lmresp+8,0,0x10); + memcpy(lmresp, entropy, 8); + + /* Pad with zeros */ + memset(lmresp + 8, 0, 0x10); /* Fill tmp with challenge(nonce?) + entropy */ - memcpy(tmp,&ntlm->nonce[0],8); - memcpy(tmp+8,entropy,8); + memcpy(tmp, &ntlm->nonce[0], 8); + memcpy(tmp + 8, entropy, 8); #ifdef USE_SSLEAY MD5_Init(&MD5pw); @@ -1417,7 +1430,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, } else #endif - { + { #if USE_NTRESPONSES unsigned char ntbuffer[0x18]; @@ -1450,48 +1463,48 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, /* Create the big type-3 message binary blob */ size = snprintf((char *)ntlmbuf, sizeof(ntlmbuf), NTLMSSP_SIGNATURE "%c" - "\x03%c%c%c" /* type-3, 32 bits */ + "\x03%c%c%c" /* 32-bit type = 3 */ - "%c%c" /* LanManager length */ - "%c%c" /* LanManager allocated space */ - "%c%c" /* LanManager offset */ - "%c%c" /* 2 zeroes */ + "%c%c" /* LanManager length */ + "%c%c" /* LanManager allocated space */ + "%c%c" /* LanManager offset */ + "%c%c" /* 2 zeroes */ - "%c%c" /* NT-response length */ - "%c%c" /* NT-response allocated space */ - "%c%c" /* NT-response offset */ - "%c%c" /* 2 zeroes */ + "%c%c" /* NT-response length */ + "%c%c" /* NT-response allocated space */ + "%c%c" /* NT-response offset */ + "%c%c" /* 2 zeroes */ - "%c%c" /* domain length */ - "%c%c" /* domain allocated space */ - "%c%c" /* domain name offset */ - "%c%c" /* 2 zeroes */ + "%c%c" /* domain length */ + "%c%c" /* domain allocated space */ + "%c%c" /* domain name offset */ + "%c%c" /* 2 zeroes */ - "%c%c" /* user length */ - "%c%c" /* user allocated space */ - "%c%c" /* user offset */ - "%c%c" /* 2 zeroes */ + "%c%c" /* user length */ + "%c%c" /* user allocated space */ + "%c%c" /* user offset */ + "%c%c" /* 2 zeroes */ - "%c%c" /* host length */ - "%c%c" /* host allocated space */ - "%c%c" /* host offset */ - "%c%c" /* 2 zeroes */ + "%c%c" /* host length */ + "%c%c" /* host allocated space */ + "%c%c" /* host offset */ + "%c%c" /* 2 zeroes */ - "%c%c" /* session key length (unknown purpose) */ - "%c%c" /* session key allocated space (unknown purpose) */ - "%c%c" /* session key offset (unknown purpose) */ - "%c%c" /* 2 zeroes */ + "%c%c" /* session key length (unknown purpose) */ + "%c%c" /* session key allocated space (unknown purpose) */ + "%c%c" /* session key offset (unknown purpose) */ + "%c%c" /* 2 zeroes */ - "%c%c%c%c" /* flags */ + "%c%c%c%c", /* flags */ /* domain string */ /* user string */ /* host string */ /* LanManager response */ /* NT response */ - , - 0, /* zero termination */ - 0,0,0, /* type-3 long, the 24 upper bits */ + + 0, /* zero termination */ + 0, 0, 0, /* type-3 long, the 24 upper bits */ SHORTPAIR(0x18), /* LanManager response length, twice */ SHORTPAIR(0x18), @@ -1533,7 +1546,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, DEBUGASSERT(size==64); DEBUGASSERT(size == (size_t)lmrespoff); - /* We append the binary hashes */ + + /* We append the binary hashes */ if(size < (sizeof(ntlmbuf) - 0x18)) { memcpy(&ntlmbuf[size], lmresp, 0x18); size += 0x18; @@ -1541,7 +1555,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, DEBUG_OUT({ fprintf(stderr, "**** TYPE3 header lmresp="); - print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); + ntlm_print_hex(stderr, (char *)&ntlmbuf[lmrespoff], 0x18); }); #if USE_NTRESPONSES @@ -1553,7 +1567,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, DEBUG_OUT({ fprintf(stderr, "\n ntresp="); - print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18); + ntlm_print_hex(stderr, (char *)&ntlmbuf[ntrespoff], 0x18); }); #endif @@ -1561,11 +1575,10 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, DEBUG_OUT({ fprintf(stderr, "\n flags=0x%02.2x%02.2x%02.2x%02.2x 0x%08.8x ", LONGQUARTET(ntlm->flags), ntlm->flags); - print_flags(stderr, ntlm->flags); + ntlm_print_flags(stderr, ntlm->flags); fprintf(stderr, "\n****\n"); }); - /* Make sure that the domain, user and host strings fit in the target buffer before we copy them there. */ if(size + userlen + domlen + hostlen >= sizeof(ntlmbuf)) { @@ -1638,9 +1651,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, return CURLE_OK; } - -void -Curl_ntlm_cleanup(struct connectdata *conn) +void Curl_http_ntlm_cleanup(struct connectdata *conn) { #ifdef USE_WINDOWS_SSPI ntlm_sspi_cleanup(&conn->ntlm); @@ -1653,6 +1664,5 @@ Curl_ntlm_cleanup(struct connectdata *conn) #endif } - #endif /* USE_NTLM */ #endif /* !CURL_DISABLE_HTTP */ diff --git a/lib/http_ntlm.h b/lib/http_ntlm.h index 5275e46ef..1cc751e34 100644 --- a/lib/http_ntlm.h +++ b/lib/http_ntlm.h @@ -44,10 +44,7 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy); CURLcode Curl_output_ntlm_sso(struct connectdata *conn, bool proxy); #endif -void Curl_ntlm_cleanup(struct connectdata *conn); -#ifndef USE_NTLM -#define Curl_ntlm_cleanup(x) -#endif +void Curl_http_ntlm_cleanup(struct connectdata *conn); /* Flag bits definitions based on http://davenport.sourceforge.net/ntlm.html */ diff --git a/lib/url.c b/lib/url.c index 400ceffde..5f0be160c 100644 --- a/lib/url.c +++ b/lib/url.c @@ -2617,7 +2617,9 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection) if(has_host_ntlm || has_proxy_ntlm) { data->state.authproblem = FALSE; - Curl_ntlm_cleanup(conn); +#ifdef USE_NTLM + Curl_http_ntlm_cleanup(conn); +#endif } }