Index: net/http/http_auth_handler_ntlm.cc |
diff --git a/net/http/http_auth_handler_ntlm.cc b/net/http/http_auth_handler_ntlm.cc |
index de0fe290a3c53aad3e083373a2548cdaf98c1193..c818b33b1b502f5b18bca4f0b94bd62b7b42d799 100644 |
--- a/net/http/http_auth_handler_ntlm.cc |
+++ b/net/http/http_auth_handler_ntlm.cc |
@@ -38,11 +38,37 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( |
CreateSPN(origin_), |
auth_token); |
#else // !defined(NTLM_SSPI) |
- // TODO(cbentzel): Shouldn't be hitting this case. |
- if (!credentials) { |
- LOG(ERROR) << "Username and password are expected to be non-NULL."; |
- return ERR_MISSING_AUTH_CREDENTIALS; |
+ if (!credentials && try_winbind_) { |
+ token_callback_ = callback; |
+ callback_auth_token_ = auth_token; |
+ if (!auth_data_.empty()) { |
+ std::string tt = std::string("TT ") + auth_data_ + std::string("\n"); |
+ |
+ VLOG(1) << "Feeding challenge to ntlm_auth: %s" << tt; |
+ if (write(ntlm_write_pipe_, tt.data(), tt.length()) != (int)tt.length()) { |
+ VLOG(1) << "Failed to send TT+auth_data_ to ntlm_auth: "; |
+ return ERR_UNEXPECTED; |
+ } |
+ |
+ // Next time round, try real credentials. |
+ try_winbind_ = false; |
+ } else if (!start_ntlm_helper_()) { |
+ // If we don't manage to start winbind's ntlm_auth helper then we can |
+ // fall back immediately to the portable code. |
+ try_winbind_ = false; |
+ goto fallback_to_portable; |
+ } |
+ |
+ if (!base::MessageLoopForIO::current()->WatchFileDescriptor(ntlm_read_pipe_, |
+ false, base::MessageLoopForIO::WATCH_READ, |
+ &ntlm_read_watcher_, this)) { |
+ VLOG(1) << "Failed to setup watcher on ntlm_read_pipe_"; |
+ return ERR_UNEXPECTED; |
+ } |
+ return ERR_IO_PENDING; |
} |
+ |
+ fallback_to_portable: |
// 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. |
@@ -51,22 +77,6 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( |
uint32 in_buf_len, out_buf_len; |
std::string decoded_auth_data; |
- // The username may be in the form "DOMAIN\user". Parse it into the two |
- // components. |
- base::string16 domain; |
- base::string16 user; |
- const base::string16& username = credentials->username(); |
- const base::char16 backslash_character = '\\'; |
- size_t backslash_idx = username.find(backslash_character); |
- if (backslash_idx == base::string16::npos) { |
- user = username; |
- } else { |
- domain = username.substr(0, backslash_idx); |
- user = username.substr(backslash_idx + 1); |
- } |
- domain_ = domain; |
- credentials_.Set(user, credentials->password()); |
- |
// Initial challenge. |
if (auth_data_.empty()) { |
in_buf_len = 0; |
@@ -75,6 +85,28 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( |
if (rv != OK) |
return rv; |
} else { |
+ // TODO(cbentzel): Shouldn't be hitting this case. |
+ if (!credentials) { |
+ LOG(ERROR) << "Username and password are expected to be non-NULL."; |
+ return ERR_MISSING_AUTH_CREDENTIALS; |
+ } |
+ |
+ // The username may be in the form "DOMAIN\user". Parse it into the two |
+ // components. |
+ base::string16 domain; |
+ base::string16 user; |
+ const base::string16& username = credentials->username(); |
+ const base::char16 backslash_character = '\\'; |
+ size_t backslash_idx = username.find(backslash_character); |
+ if (backslash_idx == base::string16::npos) { |
+ user = username; |
+ } else { |
+ domain = username.substr(0, backslash_idx); |
+ user = username.substr(backslash_idx + 1); |
+ } |
+ domain_ = domain; |
+ credentials_.Set(user, credentials->password()); |
+ |
if (!base::Base64Decode(auth_data_, &decoded_auth_data)) { |
LOG(ERROR) << "Unexpected problem Base64 decoding."; |
return ERR_UNEXPECTED; |