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