OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // See "SSPI Sample Application" at | 5 // See "SSPI Sample Application" at |
6 // http://msdn.microsoft.com/en-us/library/aa918273.aspx | 6 // http://msdn.microsoft.com/en-us/library/aa918273.aspx |
7 | 7 |
8 #include "net/http/http_auth_sspi_win.h" | 8 #include "net/http/http_auth_sspi_win.h" |
9 | 9 |
10 #include "base/base64.h" | 10 #include "base/base64.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/singleton.h" | 12 #include "base/singleton.h" |
13 #include "base/string_util.h" | 13 #include "base/string_util.h" |
| 14 #include "base/utf_string_conversions.h" |
14 #include "net/base/net_errors.h" | 15 #include "net/base/net_errors.h" |
15 #include "net/http/http_auth.h" | 16 #include "net/http/http_auth.h" |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 int MapAcquireCredentialsStatusToError(SECURITY_STATUS status, | 22 int MapAcquireCredentialsStatusToError(SECURITY_STATUS status, |
22 const SEC_WCHAR* package) { | 23 const SEC_WCHAR* package) { |
23 switch (status) { | 24 switch (status) { |
(...skipping 12 matching lines...) Expand all Loading... |
36 LOG(ERROR) << "Received SEC_E_SECPKG_NOT_FOUND for " << package; | 37 LOG(ERROR) << "Received SEC_E_SECPKG_NOT_FOUND for " << package; |
37 return ERR_UNSUPPORTED_AUTH_SCHEME; | 38 return ERR_UNSUPPORTED_AUTH_SCHEME; |
38 default: | 39 default: |
39 LOG(ERROR) << "Unexpected SECURITY_STATUS " << status; | 40 LOG(ERROR) << "Unexpected SECURITY_STATUS " << status; |
40 return ERR_UNEXPECTED; | 41 return ERR_UNEXPECTED; |
41 } | 42 } |
42 } | 43 } |
43 | 44 |
44 int AcquireExplicitCredentials(SSPILibrary* library, | 45 int AcquireExplicitCredentials(SSPILibrary* library, |
45 const SEC_WCHAR* package, | 46 const SEC_WCHAR* package, |
46 const std::wstring& domain, | 47 const string16& domain, |
47 const std::wstring& user, | 48 const string16& user, |
48 const std::wstring& password, | 49 const string16& password, |
49 CredHandle* cred) { | 50 CredHandle* cred) { |
50 SEC_WINNT_AUTH_IDENTITY identity; | 51 SEC_WINNT_AUTH_IDENTITY identity; |
51 identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; | 52 identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; |
52 identity.User = | 53 identity.User = |
53 reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str())); | 54 reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str())); |
54 identity.UserLength = user.size(); | 55 identity.UserLength = user.size(); |
55 identity.Domain = | 56 identity.Domain = |
56 reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str())); | 57 reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str())); |
57 identity.DomainLength = domain.size(); | 58 identity.DomainLength = domain.size(); |
58 identity.Password = | 59 identity.Password = |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 std::string decoded_auth_token; | 153 std::string decoded_auth_token; |
153 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); | 154 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); |
154 if (!base64_rv) { | 155 if (!base64_rv) { |
155 LOG(ERROR) << "Base64 decoding of auth token failed."; | 156 LOG(ERROR) << "Base64 decoding of auth token failed."; |
156 return false; | 157 return false; |
157 } | 158 } |
158 decoded_server_auth_token_ = decoded_auth_token; | 159 decoded_server_auth_token_ = decoded_auth_token; |
159 return true; | 160 return true; |
160 } | 161 } |
161 | 162 |
162 int HttpAuthSSPI::GenerateAuthToken(const std::wstring* username, | 163 int HttpAuthSSPI::GenerateAuthToken(const string16* username, |
163 const std::wstring* password, | 164 const string16* password, |
164 const std::wstring& spn, | 165 const std::wstring& spn, |
165 std::string* auth_token) { | 166 std::string* auth_token) { |
166 DCHECK((username == NULL) == (password == NULL)); | 167 DCHECK((username == NULL) == (password == NULL)); |
167 | 168 |
168 // Initial challenge. | 169 // Initial challenge. |
169 if (!IsFinalRound()) { | 170 if (!IsFinalRound()) { |
170 int rv = OnFirstRound(username, password); | 171 int rv = OnFirstRound(username, password); |
171 if (rv != OK) | 172 if (rv != OK) |
172 return rv; | 173 return rv; |
173 } | 174 } |
(...skipping 18 matching lines...) Expand all Loading... |
192 // OK, we are done with |out_buf| | 193 // OK, we are done with |out_buf| |
193 free(out_buf); | 194 free(out_buf); |
194 if (!base64_rv) { | 195 if (!base64_rv) { |
195 LOG(ERROR) << "Base64 encoding of auth token failed."; | 196 LOG(ERROR) << "Base64 encoding of auth token failed."; |
196 return ERR_UNEXPECTED; | 197 return ERR_UNEXPECTED; |
197 } | 198 } |
198 *auth_token = scheme_ + " " + encode_output; | 199 *auth_token = scheme_ + " " + encode_output; |
199 return OK; | 200 return OK; |
200 } | 201 } |
201 | 202 |
202 int HttpAuthSSPI::OnFirstRound(const std::wstring* username, | 203 int HttpAuthSSPI::OnFirstRound(const string16* username, |
203 const std::wstring* password) { | 204 const string16* password) { |
204 DCHECK((username == NULL) == (password == NULL)); | 205 DCHECK((username == NULL) == (password == NULL)); |
205 DCHECK(!SecIsValidHandle(&cred_)); | 206 DCHECK(!SecIsValidHandle(&cred_)); |
206 int rv = OK; | 207 int rv = OK; |
207 if (username) { | 208 if (username) { |
208 std::wstring domain; | 209 string16 domain; |
209 std::wstring user; | 210 string16 user; |
210 SplitDomainAndUser(*username, &domain, &user); | 211 SplitDomainAndUser(*username, &domain, &user); |
211 rv = AcquireExplicitCredentials(library_, security_package_, domain, | 212 rv = AcquireExplicitCredentials(library_, security_package_, domain, |
212 user, *password, &cred_); | 213 user, *password, &cred_); |
213 if (rv != OK) | 214 if (rv != OK) |
214 return rv; | 215 return rv; |
215 } else { | 216 } else { |
216 rv = AcquireDefaultCredentials(library_, security_package_, &cred_); | 217 rv = AcquireDefaultCredentials(library_, security_package_, &cred_); |
217 if (rv != OK) | 218 if (rv != OK) |
218 return rv; | 219 return rv; |
219 } | 220 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 } | 294 } |
294 if (!out_buffer.cbBuffer) { | 295 if (!out_buffer.cbBuffer) { |
295 free(out_buffer.pvBuffer); | 296 free(out_buffer.pvBuffer); |
296 out_buffer.pvBuffer = NULL; | 297 out_buffer.pvBuffer = NULL; |
297 } | 298 } |
298 *out_token = out_buffer.pvBuffer; | 299 *out_token = out_buffer.pvBuffer; |
299 *out_token_len = out_buffer.cbBuffer; | 300 *out_token_len = out_buffer.cbBuffer; |
300 return OK; | 301 return OK; |
301 } | 302 } |
302 | 303 |
303 void SplitDomainAndUser(const std::wstring& combined, | 304 void SplitDomainAndUser(const string16& combined, |
304 std::wstring* domain, | 305 string16* domain, |
305 std::wstring* user) { | 306 string16* user) { |
306 // |combined| may be in the form "user" or "DOMAIN\user". | 307 // |combined| may be in the form "user" or "DOMAIN\user". |
307 // Separatethe two parts if they exist. | 308 // Separate the two parts if they exist. |
308 // TODO(cbentzel): I believe user@domain is also a valid form. | 309 // TODO(cbentzel): I believe user@domain is also a valid form. |
309 size_t backslash_idx = combined.find(L'\\'); | 310 size_t backslash_idx = combined.find(L'\\'); |
310 if (backslash_idx == std::wstring::npos) { | 311 if (backslash_idx == string16::npos) { |
311 domain->clear(); | 312 domain->clear(); |
312 *user = combined; | 313 *user = combined; |
313 } else { | 314 } else { |
314 *domain = combined.substr(0, backslash_idx); | 315 *domain = combined.substr(0, backslash_idx); |
315 *user = combined.substr(backslash_idx + 1); | 316 *user = combined.substr(backslash_idx + 1); |
316 } | 317 } |
317 } | 318 } |
318 | 319 |
319 int DetermineMaxTokenLength(SSPILibrary* library, | 320 int DetermineMaxTokenLength(SSPILibrary* library, |
320 const std::wstring& package, | 321 const std::wstring& package, |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 private: | 412 private: |
412 friend struct DefaultSingletonTraits<SSPILibraryDefault>; | 413 friend struct DefaultSingletonTraits<SSPILibraryDefault>; |
413 }; | 414 }; |
414 | 415 |
415 // static | 416 // static |
416 SSPILibrary* SSPILibrary::GetDefault() { | 417 SSPILibrary* SSPILibrary::GetDefault() { |
417 return Singleton<SSPILibraryDefault>::get(); | 418 return Singleton<SSPILibraryDefault>::get(); |
418 } | 419 } |
419 | 420 |
420 } // namespace net | 421 } // namespace net |
OLD | NEW |