| 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
|
|
|