| 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" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 if (SecIsValidHandle(&cred_)) { | 122 if (SecIsValidHandle(&cred_)) { |
| 123 library_->FreeCredentialsHandle(&cred_); | 123 library_->FreeCredentialsHandle(&cred_); |
| 124 SecInvalidateHandle(&cred_); | 124 SecInvalidateHandle(&cred_); |
| 125 } | 125 } |
| 126 } | 126 } |
| 127 | 127 |
| 128 bool HttpAuthSSPI::NeedsIdentity() const { | 128 bool HttpAuthSSPI::NeedsIdentity() const { |
| 129 return decoded_server_auth_token_.empty(); | 129 return decoded_server_auth_token_.empty(); |
| 130 } | 130 } |
| 131 | 131 |
| 132 bool HttpAuthSSPI::IsFinalRound() const { | |
| 133 return !decoded_server_auth_token_.empty(); | |
| 134 } | |
| 135 | |
| 136 void HttpAuthSSPI::Delegate() { | 132 void HttpAuthSSPI::Delegate() { |
| 137 can_delegate_ = true; | 133 can_delegate_ = true; |
| 138 } | 134 } |
| 139 | 135 |
| 140 void HttpAuthSSPI::ResetSecurityContext() { | 136 void HttpAuthSSPI::ResetSecurityContext() { |
| 141 if (SecIsValidHandle(&ctxt_)) { | 137 if (SecIsValidHandle(&ctxt_)) { |
| 142 library_->DeleteSecurityContext(&ctxt_); | 138 library_->DeleteSecurityContext(&ctxt_); |
| 143 SecInvalidateHandle(&ctxt_); | 139 SecInvalidateHandle(&ctxt_); |
| 144 } | 140 } |
| 145 } | 141 } |
| 146 | 142 |
| 147 bool HttpAuthSSPI::ParseChallenge(HttpAuth::ChallengeTokenizer* tok) { | 143 HttpAuth::AuthorizationResult HttpAuthSSPI::ParseChallenge( |
| 144 HttpAuth::ChallengeTokenizer* tok) { |
| 148 // Verify the challenge's auth-scheme. | 145 // Verify the challenge's auth-scheme. |
| 149 if (!tok->valid() || | 146 if (!tok->valid() || |
| 150 !LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str())) | 147 !LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str())) |
| 151 return false; | 148 return HttpAuth::AUTHORIZATION_RESULT_INVALID; |
| 152 | 149 |
| 153 tok->set_expect_base64_token(true); | 150 tok->set_expect_base64_token(true); |
| 154 if (!tok->GetNext()) { | 151 if (!tok->GetNext()) { |
| 155 decoded_server_auth_token_.clear(); | 152 // If a context has already been established, an empty challenge |
| 156 return true; | 153 // should be treated as a rejection of the current attempt. |
| 154 if (SecIsValidHandle(&ctxt_)) |
| 155 return HttpAuth::AUTHORIZATION_RESULT_REJECT; |
| 156 DCHECK(decoded_server_auth_token_.empty()); |
| 157 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; |
| 158 } else { |
| 159 // If a context has not already been established, additional tokens should |
| 160 // not be present in the auth challenge. |
| 161 if (!SecIsValidHandle(&ctxt_)) |
| 162 return HttpAuth::AUTHORIZATION_RESULT_INVALID; |
| 157 } | 163 } |
| 158 | 164 |
| 159 std::string encoded_auth_token = tok->value(); | 165 std::string encoded_auth_token = tok->value(); |
| 160 std::string decoded_auth_token; | 166 std::string decoded_auth_token; |
| 161 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); | 167 bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token); |
| 162 if (!base64_rv) { | 168 if (!base64_rv) |
| 163 LOG(ERROR) << "Base64 decoding of auth token failed."; | 169 return HttpAuth::AUTHORIZATION_RESULT_INVALID; |
| 164 return false; | |
| 165 } | |
| 166 decoded_server_auth_token_ = decoded_auth_token; | 170 decoded_server_auth_token_ = decoded_auth_token; |
| 167 return true; | 171 return HttpAuth::AUTHORIZATION_RESULT_ACCEPT; |
| 168 } | 172 } |
| 169 | 173 |
| 170 int HttpAuthSSPI::GenerateAuthToken(const string16* username, | 174 int HttpAuthSSPI::GenerateAuthToken(const string16* username, |
| 171 const string16* password, | 175 const string16* password, |
| 172 const std::wstring& spn, | 176 const std::wstring& spn, |
| 173 std::string* auth_token) { | 177 std::string* auth_token) { |
| 174 DCHECK((username == NULL) == (password == NULL)); | 178 DCHECK((username == NULL) == (password == NULL)); |
| 175 | 179 |
| 176 // Initial challenge. | 180 // Initial challenge. |
| 177 if (!IsFinalRound()) { | 181 if (!SecIsValidHandle(&cred_)) { |
| 178 int rv = OnFirstRound(username, password); | 182 int rv = OnFirstRound(username, password); |
| 179 if (rv != OK) | 183 if (rv != OK) |
| 180 return rv; | 184 return rv; |
| 181 } | 185 } |
| 182 | 186 |
| 183 DCHECK(SecIsValidHandle(&cred_)); | 187 DCHECK(SecIsValidHandle(&cred_)); |
| 184 void* out_buf; | 188 void* out_buf; |
| 185 int out_buf_len; | 189 int out_buf_len; |
| 186 int rv = GetNextSecurityToken( | 190 int rv = GetNextSecurityToken( |
| 187 spn, | 191 spn, |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 private: | 467 private: |
| 464 friend struct DefaultSingletonTraits<SSPILibraryDefault>; | 468 friend struct DefaultSingletonTraits<SSPILibraryDefault>; |
| 465 }; | 469 }; |
| 466 | 470 |
| 467 // static | 471 // static |
| 468 SSPILibrary* SSPILibrary::GetDefault() { | 472 SSPILibrary* SSPILibrary::GetDefault() { |
| 469 return Singleton<SSPILibraryDefault>::get(); | 473 return Singleton<SSPILibraryDefault>::get(); |
| 470 } | 474 } |
| 471 | 475 |
| 472 } // namespace net | 476 } // namespace net |
| OLD | NEW |