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