Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(145)

Side by Side Diff: net/http/http_auth_handler_ntlm.cc

Issue 388063005: Add NTLM single-sign-on support via Samba's ntlm_auth helper Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review feedback Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_auth_handler_ntlm.h ('k') | net/http/http_auth_handler_ntlm_portable.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_auth_handler_ntlm.h" 5 #include "net/http/http_auth_handler_ntlm.h"
6 6
7 #if !defined(NTLM_SSPI) 7 #if !defined(NTLM_SSPI)
8 #include "base/base64.h" 8 #include "base/base64.h"
9 #endif 9 #endif
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 20 matching lines...) Expand all
31 31
32 int HttpAuthHandlerNTLM::GenerateAuthTokenImpl( 32 int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
33 const AuthCredentials* credentials, const HttpRequestInfo* request, 33 const AuthCredentials* credentials, const HttpRequestInfo* request,
34 const CompletionCallback& callback, std::string* auth_token) { 34 const CompletionCallback& callback, std::string* auth_token) {
35 #if defined(NTLM_SSPI) 35 #if defined(NTLM_SSPI)
36 return auth_sspi_.GenerateAuthToken( 36 return auth_sspi_.GenerateAuthToken(
37 credentials, 37 credentials,
38 CreateSPN(origin_), 38 CreateSPN(origin_),
39 auth_token); 39 auth_token);
40 #else // !defined(NTLM_SSPI) 40 #else // !defined(NTLM_SSPI)
41 // TODO(cbentzel): Shouldn't be hitting this case. 41 if (!credentials && try_winbind_) {
42 if (!credentials) { 42 token_callback_ = callback;
43 LOG(ERROR) << "Username and password are expected to be non-NULL."; 43 callback_auth_token_ = auth_token;
44 return ERR_MISSING_AUTH_CREDENTIALS; 44 if (!auth_data_.empty()) {
45 std::string tt = std::string("TT ") + auth_data_ + std::string("\n");
46
47 VLOG(1) << "Feeding challenge to ntlm_auth: %s" << tt;
48 if (write(ntlm_write_pipe_, tt.data(), tt.length()) != (int)tt.length()) {
49 VLOG(1) << "Failed to send TT+auth_data_ to ntlm_auth: ";
50 return ERR_UNEXPECTED;
51 }
52
53 // Next time round, try real credentials.
54 try_winbind_ = false;
55 } else if (!start_ntlm_helper_()) {
56 // If we don't manage to start winbind's ntlm_auth helper then we can
57 // fall back immediately to the portable code.
58 try_winbind_ = false;
59 goto fallback_to_portable;
60 }
61
62 if (!base::MessageLoopForIO::current()->WatchFileDescriptor(ntlm_read_pipe_,
63 false, base::MessageLoopForIO::WATCH_READ,
64 &ntlm_read_watcher_, this)) {
65 VLOG(1) << "Failed to setup watcher on ntlm_read_pipe_";
66 return ERR_UNEXPECTED;
67 }
68 return ERR_IO_PENDING;
45 } 69 }
70
71 fallback_to_portable:
46 // TODO(wtc): See if we can use char* instead of void* for in_buf and 72 // TODO(wtc): See if we can use char* instead of void* for in_buf and
47 // out_buf. This change will need to propagate to GetNextToken, 73 // out_buf. This change will need to propagate to GetNextToken,
48 // GenerateType1Msg, and GenerateType3Msg, and perhaps further. 74 // GenerateType1Msg, and GenerateType3Msg, and perhaps further.
49 const void* in_buf; 75 const void* in_buf;
50 void* out_buf; 76 void* out_buf;
51 uint32 in_buf_len, out_buf_len; 77 uint32 in_buf_len, out_buf_len;
52 std::string decoded_auth_data; 78 std::string decoded_auth_data;
53 79
54 // The username may be in the form "DOMAIN\user". Parse it into the two
55 // components.
56 base::string16 domain;
57 base::string16 user;
58 const base::string16& username = credentials->username();
59 const base::char16 backslash_character = '\\';
60 size_t backslash_idx = username.find(backslash_character);
61 if (backslash_idx == base::string16::npos) {
62 user = username;
63 } else {
64 domain = username.substr(0, backslash_idx);
65 user = username.substr(backslash_idx + 1);
66 }
67 domain_ = domain;
68 credentials_.Set(user, credentials->password());
69
70 // Initial challenge. 80 // Initial challenge.
71 if (auth_data_.empty()) { 81 if (auth_data_.empty()) {
72 in_buf_len = 0; 82 in_buf_len = 0;
73 in_buf = NULL; 83 in_buf = NULL;
74 int rv = InitializeBeforeFirstChallenge(); 84 int rv = InitializeBeforeFirstChallenge();
75 if (rv != OK) 85 if (rv != OK)
76 return rv; 86 return rv;
77 } else { 87 } else {
88 // TODO(cbentzel): Shouldn't be hitting this case.
89 if (!credentials) {
90 LOG(ERROR) << "Username and password are expected to be non-NULL.";
91 return ERR_MISSING_AUTH_CREDENTIALS;
92 }
93
94 // The username may be in the form "DOMAIN\user". Parse it into the two
95 // components.
96 base::string16 domain;
97 base::string16 user;
98 const base::string16& username = credentials->username();
99 const base::char16 backslash_character = '\\';
100 size_t backslash_idx = username.find(backslash_character);
101 if (backslash_idx == base::string16::npos) {
102 user = username;
103 } else {
104 domain = username.substr(0, backslash_idx);
105 user = username.substr(backslash_idx + 1);
106 }
107 domain_ = domain;
108 credentials_.Set(user, credentials->password());
109
78 if (!base::Base64Decode(auth_data_, &decoded_auth_data)) { 110 if (!base::Base64Decode(auth_data_, &decoded_auth_data)) {
79 LOG(ERROR) << "Unexpected problem Base64 decoding."; 111 LOG(ERROR) << "Unexpected problem Base64 decoding.";
80 return ERR_UNEXPECTED; 112 return ERR_UNEXPECTED;
81 } 113 }
82 in_buf_len = decoded_auth_data.length(); 114 in_buf_len = decoded_auth_data.length();
83 in_buf = decoded_auth_data.data(); 115 in_buf = decoded_auth_data.data();
84 } 116 }
85 117
86 int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len); 118 int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len);
87 if (rv != OK) 119 if (rv != OK)
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // static 167 // static
136 std::string HttpAuthHandlerNTLM::CreateSPN(const GURL& origin) { 168 std::string HttpAuthHandlerNTLM::CreateSPN(const GURL& origin) {
137 // The service principal name of the destination server. See 169 // The service principal name of the destination server. See
138 // http://msdn.microsoft.com/en-us/library/ms677949%28VS.85%29.aspx 170 // http://msdn.microsoft.com/en-us/library/ms677949%28VS.85%29.aspx
139 std::string target("HTTP/"); 171 std::string target("HTTP/");
140 target.append(GetHostAndPort(origin)); 172 target.append(GetHostAndPort(origin));
141 return target; 173 return target;
142 } 174 }
143 175
144 } // namespace net 176 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_ntlm.h ('k') | net/http/http_auth_handler_ntlm_portable.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698