Index: net/http/http_auth_handler_ntlm.cc |
=================================================================== |
--- net/http/http_auth_handler_ntlm.cc (revision 12289) |
+++ net/http/http_auth_handler_ntlm.cc (working copy) |
@@ -18,6 +18,7 @@ |
#include "base/sys_string_conversions.h" |
#include "net/base/base64.h" |
#include "net/base/net_errors.h" |
+#include "net/base/net_util.h" |
#include "net/http/des.h" |
#include "net/http/md4.h" |
@@ -439,28 +440,16 @@ |
output[i] = base::RandInt(0, 255); |
} |
-static void GetHostName(char* name, size_t namelen) { |
- if (gethostname(name, namelen) != 0) |
- name[0] = '\0'; |
-} |
- |
-// TODO(wtc): these two function pointers should become static members of |
-// HttpAuthHandlerNTLM. They are file-scope static variables now so that |
-// GenerateType3Msg can use them without being a friend function. We should |
-// have HttpAuthHandlerNTLM absorb NTLMAuthModule and pass the host name and |
-// random bytes as input arguments to GenerateType3Msg. |
-static HttpAuthHandlerNTLM::GenerateRandomProc generate_random_proc_ = |
- GenerateRandom; |
-static HttpAuthHandlerNTLM::HostNameProc get_host_name_proc_ = GetHostName; |
- |
// Returns OK or a network error code. |
static int GenerateType3Msg(const string16& domain, |
const string16& username, |
const string16& password, |
- const void* in_buf, |
- uint32 in_len, |
- void** out_buf, |
- uint32* out_len) { |
+ const std::string& hostname, |
+ const void* rand_8_bytes, |
+ const void* in_buf, |
+ uint32 in_len, |
+ void** out_buf, |
+ uint32* out_len) { |
// in_buf contains Type-2 msg (the challenge) from server. |
int rv; |
@@ -478,7 +467,7 @@ |
#endif |
string16 ucs_host_buf; |
// Temporary buffers for oem strings |
- std::string oem_domain_buf, oem_user_buf, oem_host_buf; |
+ std::string oem_domain_buf, oem_user_buf; |
// Pointers and lengths for the string buffers; encoding is unicode if |
// the "negotiate unicode" flag was set in the Type-2 message. |
const void* domain_ptr; |
@@ -529,14 +518,9 @@ |
// |
// Get workstation name (use local machine's hostname). |
// |
- char host_buf[256]; // Host names are limited to 255 bytes. |
- get_host_name_proc_(host_buf, sizeof(host_buf)); |
- host_len = strlen(host_buf); |
- if (host_len == 0) |
- return ERR_UNEXPECTED; |
if (unicode) { |
// hostname is ASCII, so we can do a simple zero-pad expansion: |
- ucs_host_buf.assign(host_buf, host_buf + host_len); |
+ ucs_host_buf.assign(hostname.begin(), hostname.end()); |
host_ptr = ucs_host_buf.data(); |
host_len = ucs_host_buf.length() * 2; |
#ifdef IS_BIG_ENDIAN |
@@ -544,7 +528,8 @@ |
ucs_host_buf.length()); |
#endif |
} else { |
- host_ptr = host_buf; |
+ host_ptr = hostname.data(); |
+ host_len = hostname.length(); |
} |
// |
@@ -567,7 +552,7 @@ |
MD5Digest session_hash; |
uint8 temp[16]; |
- generate_random_proc_(lm_resp, 8); |
+ memcpy(lm_resp, rand_8_bytes, 8); |
memset(lm_resp + 8, 0, LM_RESP_LEN - 8); |
memcpy(temp, msg.challenge, 8); |
@@ -638,71 +623,24 @@ |
return OK; |
} |
-//----------------------------------------------------------------------------- |
+// NTLM authentication is specified in "NTLM Over HTTP Protocol Specification" |
+// [MS-NTHT]. |
-class NTLMAuthModule { |
- public: |
- NTLMAuthModule() {} |
+// static |
+HttpAuthHandlerNTLM::GenerateRandomProc |
+HttpAuthHandlerNTLM::generate_random_proc_ = GenerateRandom; |
- ~NTLMAuthModule(); |
+// static |
+HttpAuthHandlerNTLM::HostNameProc |
+HttpAuthHandlerNTLM::get_host_name_proc_ = GetMyHostName; |
- int Init(const string16& domain, |
- const string16& username, |
- const string16& password); |
- |
- int GetNextToken(const void* in_token, |
- uint32 in_token_len, |
- void** out_token, |
- uint32* out_token_len); |
- |
- private: |
- string16 domain_; |
- string16 username_; |
- string16 password_; |
-}; |
- |
-NTLMAuthModule::~NTLMAuthModule() { |
- ZapString(&password_); |
+HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() { |
} |
-int NTLMAuthModule::Init(const string16& domain, |
- const string16& username, |
- const string16& password) { |
- domain_ = domain; |
- username_ = username; |
- password_ = password; |
- return OK; |
-} |
- |
-int NTLMAuthModule::GetNextToken(const void* in_token, |
- uint32 in_token_len, |
- void** out_token, |
- uint32* out_token_len) { |
- int rv; |
- |
- // If in_token is non-null, then assume it contains a type 2 message... |
- if (in_token) { |
- LogToken("in-token", in_token, in_token_len); |
- rv = GenerateType3Msg(domain_, username_, password_, in_token, |
- in_token_len, out_token, out_token_len); |
- } else { |
- rv = GenerateType1Msg(out_token, out_token_len); |
- } |
- |
- if (rv == OK) |
- LogToken("out-token", *out_token, *out_token_len); |
- |
- return rv; |
-} |
- |
-// NTLM authentication is specified in "NTLM Over HTTP Protocol Specification" |
-// [MS-NTHT]. |
- |
-HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() |
- : ntlm_module_(new NTLMAuthModule) { |
-} |
- |
HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() { |
+ // Wipe our copy of the password from memory, to reduce the chance of being |
+ // written to the paging file on disk. |
+ ZapString(&password_); |
} |
bool HttpAuthHandlerNTLM::NeedsIdentity() { |
@@ -714,7 +652,6 @@ |
const std::wstring& password, |
const HttpRequestInfo* request, |
const ProxyInfo* proxy) { |
- int rv; |
// TODO(wtc): See if we can use char* instead of void* for in_buf and |
// out_buf. This change will need to propagate to GetNextToken, |
// GenerateType1Msg, and GenerateType3Msg, and perhaps further. |
@@ -734,8 +671,9 @@ |
domain = username.substr(0, backslash_idx); |
user = username.substr(backslash_idx + 1); |
} |
- rv = ntlm_module_->Init(WideToUTF16(domain), WideToUTF16(user), |
- WideToUTF16(password)); |
+ domain_ = WideToUTF16(domain); |
+ username_ = WideToUTF16(user); |
+ password_ = WideToUTF16(password); |
// Initial challenge. |
if (auth_data_.empty()) { |
@@ -759,7 +697,7 @@ |
in_buf = decoded_auth_data.data(); |
} |
- rv = ntlm_module_->GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len); |
+ int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len); |
if (rv != OK) |
return std::string(); |
@@ -775,13 +713,20 @@ |
} |
// static |
-void HttpAuthHandlerNTLM::SetGenerateRandomProc(GenerateRandomProc proc) { |
+HttpAuthHandlerNTLM::GenerateRandomProc |
+HttpAuthHandlerNTLM::SetGenerateRandomProc( |
+ GenerateRandomProc proc) { |
+ GenerateRandomProc old_proc = generate_random_proc_; |
generate_random_proc_ = proc; |
+ return old_proc; |
} |
// static |
-void HttpAuthHandlerNTLM::SetHostNameProc(HostNameProc proc) { |
+HttpAuthHandlerNTLM::HostNameProc HttpAuthHandlerNTLM::SetHostNameProc( |
+ HostNameProc proc) { |
+ HostNameProc old_proc = get_host_name_proc_; |
get_host_name_proc_ = proc; |
+ return old_proc; |
} |
// The NTLM challenge header looks like: |
@@ -811,4 +756,30 @@ |
return true; |
} |
+int HttpAuthHandlerNTLM::GetNextToken(const void* in_token, |
+ uint32 in_token_len, |
+ void** out_token, |
+ uint32* out_token_len) { |
+ int rv; |
+ |
+ // If in_token is non-null, then assume it contains a type 2 message... |
+ if (in_token) { |
+ LogToken("in-token", in_token, in_token_len); |
+ std::string hostname = get_host_name_proc_(); |
+ if (hostname.empty()) |
+ return ERR_UNEXPECTED; |
+ uint8 rand_buf[8]; |
+ generate_random_proc_(rand_buf, 8); |
+ rv = GenerateType3Msg(domain_, username_, password_, hostname, rand_buf, |
+ in_token, in_token_len, out_token, out_token_len); |
+ } else { |
+ rv = GenerateType1Msg(out_token, out_token_len); |
+ } |
+ |
+ if (rv == OK) |
+ LogToken("out-token", *out_token, *out_token_len); |
+ |
+ return rv; |
+} |
+ |
} // namespace net |