| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 101 |
| 102 } // anonymous namespace | 102 } // anonymous namespace |
| 103 | 103 |
| 104 HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, | 104 HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library, |
| 105 const std::string& scheme, | 105 const std::string& scheme, |
| 106 SEC_WCHAR* security_package, | 106 SEC_WCHAR* security_package, |
| 107 ULONG max_token_length) | 107 ULONG max_token_length) |
| 108 : library_(library), | 108 : library_(library), |
| 109 scheme_(scheme), | 109 scheme_(scheme), |
| 110 security_package_(security_package), | 110 security_package_(security_package), |
| 111 max_token_length_(max_token_length) { | 111 max_token_length_(max_token_length), |
| 112 can_delegate_(false) { |
| 112 DCHECK(library_); | 113 DCHECK(library_); |
| 113 SecInvalidateHandle(&cred_); | 114 SecInvalidateHandle(&cred_); |
| 114 SecInvalidateHandle(&ctxt_); | 115 SecInvalidateHandle(&ctxt_); |
| 115 } | 116 } |
| 116 | 117 |
| 117 HttpAuthSSPI::~HttpAuthSSPI() { | 118 HttpAuthSSPI::~HttpAuthSSPI() { |
| 118 ResetSecurityContext(); | 119 ResetSecurityContext(); |
| 119 if (SecIsValidHandle(&cred_)) { | 120 if (SecIsValidHandle(&cred_)) { |
| 120 library_->FreeCredentialsHandle(&cred_); | 121 library_->FreeCredentialsHandle(&cred_); |
| 121 SecInvalidateHandle(&cred_); | 122 SecInvalidateHandle(&cred_); |
| 122 } | 123 } |
| 123 } | 124 } |
| 124 | 125 |
| 125 bool HttpAuthSSPI::NeedsIdentity() const { | 126 bool HttpAuthSSPI::NeedsIdentity() const { |
| 126 return decoded_server_auth_token_.empty(); | 127 return decoded_server_auth_token_.empty(); |
| 127 } | 128 } |
| 128 | 129 |
| 129 bool HttpAuthSSPI::IsFinalRound() const { | 130 bool HttpAuthSSPI::IsFinalRound() const { |
| 130 return !decoded_server_auth_token_.empty(); | 131 return !decoded_server_auth_token_.empty(); |
| 131 } | 132 } |
| 132 | 133 |
| 134 void HttpAuthSSPI::Delegate() { |
| 135 can_delegate_ = true; |
| 136 } |
| 137 |
| 133 void HttpAuthSSPI::ResetSecurityContext() { | 138 void HttpAuthSSPI::ResetSecurityContext() { |
| 134 if (SecIsValidHandle(&ctxt_)) { | 139 if (SecIsValidHandle(&ctxt_)) { |
| 135 library_->DeleteSecurityContext(&ctxt_); | 140 library_->DeleteSecurityContext(&ctxt_); |
| 136 SecInvalidateHandle(&ctxt_); | 141 SecInvalidateHandle(&ctxt_); |
| 137 } | 142 } |
| 138 } | 143 } |
| 139 | 144 |
| 140 bool HttpAuthSSPI::ParseChallenge(HttpAuth::ChallengeTokenizer* tok) { | 145 bool HttpAuthSSPI::ParseChallenge(HttpAuth::ChallengeTokenizer* tok) { |
| 141 // Verify the challenge's auth-scheme. | 146 // Verify the challenge's auth-scheme. |
| 142 if (!tok->valid() || | 147 if (!tok->valid() || |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 rv = AcquireDefaultCredentials(library_, security_package_, &cred_); | 222 rv = AcquireDefaultCredentials(library_, security_package_, &cred_); |
| 218 if (rv != OK) | 223 if (rv != OK) |
| 219 return rv; | 224 return rv; |
| 220 } | 225 } |
| 221 | 226 |
| 222 return rv; | 227 return rv; |
| 223 } | 228 } |
| 224 | 229 |
| 225 int HttpAuthSSPI::GetNextSecurityToken( | 230 int HttpAuthSSPI::GetNextSecurityToken( |
| 226 const std::wstring& spn, | 231 const std::wstring& spn, |
| 227 const void * in_token, | 232 const void* in_token, |
| 228 int in_token_len, | 233 int in_token_len, |
| 229 void** out_token, | 234 void** out_token, |
| 230 int* out_token_len) { | 235 int* out_token_len) { |
| 231 SECURITY_STATUS status; | |
| 232 TimeStamp expiry; | |
| 233 | |
| 234 DWORD ctxt_attr; | |
| 235 CtxtHandle* ctxt_ptr; | 236 CtxtHandle* ctxt_ptr; |
| 236 SecBufferDesc in_buffer_desc, out_buffer_desc; | 237 SecBufferDesc in_buffer_desc, out_buffer_desc; |
| 237 SecBufferDesc* in_buffer_desc_ptr; | 238 SecBufferDesc* in_buffer_desc_ptr; |
| 238 SecBuffer in_buffer, out_buffer; | 239 SecBuffer in_buffer, out_buffer; |
| 239 | 240 |
| 240 if (in_token_len > 0) { | 241 if (in_token_len > 0) { |
| 241 // Prepare input buffer. | 242 // Prepare input buffer. |
| 242 in_buffer_desc.ulVersion = SECBUFFER_VERSION; | 243 in_buffer_desc.ulVersion = SECBUFFER_VERSION; |
| 243 in_buffer_desc.cBuffers = 1; | 244 in_buffer_desc.cBuffers = 1; |
| 244 in_buffer_desc.pBuffers = &in_buffer; | 245 in_buffer_desc.pBuffers = &in_buffer; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 262 // Prepare output buffer. | 263 // Prepare output buffer. |
| 263 out_buffer_desc.ulVersion = SECBUFFER_VERSION; | 264 out_buffer_desc.ulVersion = SECBUFFER_VERSION; |
| 264 out_buffer_desc.cBuffers = 1; | 265 out_buffer_desc.cBuffers = 1; |
| 265 out_buffer_desc.pBuffers = &out_buffer; | 266 out_buffer_desc.pBuffers = &out_buffer; |
| 266 out_buffer.BufferType = SECBUFFER_TOKEN; | 267 out_buffer.BufferType = SECBUFFER_TOKEN; |
| 267 out_buffer.cbBuffer = max_token_length_; | 268 out_buffer.cbBuffer = max_token_length_; |
| 268 out_buffer.pvBuffer = malloc(out_buffer.cbBuffer); | 269 out_buffer.pvBuffer = malloc(out_buffer.cbBuffer); |
| 269 if (!out_buffer.pvBuffer) | 270 if (!out_buffer.pvBuffer) |
| 270 return ERR_OUT_OF_MEMORY; | 271 return ERR_OUT_OF_MEMORY; |
| 271 | 272 |
| 273 DWORD context_flags = 0; |
| 274 // Firefox only sets ISC_REQ_DELEGATE, but MSDN documentation indicates that |
| 275 // ISC_REQ_MUTUAL_AUTH must also be set. |
| 276 if (can_delegate_) |
| 277 context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH); |
| 278 |
| 272 // This returns a token that is passed to the remote server. | 279 // This returns a token that is passed to the remote server. |
| 273 status = library_->InitializeSecurityContext( | 280 DWORD context_attribute; |
| 281 SECURITY_STATUS status = library_->InitializeSecurityContext( |
| 274 &cred_, // phCredential | 282 &cred_, // phCredential |
| 275 ctxt_ptr, // phContext | 283 ctxt_ptr, // phContext |
| 276 const_cast<wchar_t *>(spn.c_str()), // pszTargetName | 284 const_cast<wchar_t *>(spn.c_str()), // pszTargetName |
| 277 0, // fContextReq | 285 context_flags, // fContextReq |
| 278 0, // Reserved1 (must be 0) | 286 0, // Reserved1 (must be 0) |
| 279 SECURITY_NATIVE_DREP, // TargetDataRep | 287 SECURITY_NATIVE_DREP, // TargetDataRep |
| 280 in_buffer_desc_ptr, // pInput | 288 in_buffer_desc_ptr, // pInput |
| 281 0, // Reserved2 (must be 0) | 289 0, // Reserved2 (must be 0) |
| 282 &ctxt_, // phNewContext | 290 &ctxt_, // phNewContext |
| 283 &out_buffer_desc, // pOutput | 291 &out_buffer_desc, // pOutput |
| 284 &ctxt_attr, // pfContextAttr | 292 &context_attribute, // pfContextAttr |
| 285 &expiry); // ptsExpiry | 293 NULL); // ptsExpiry |
| 286 // On success, the function returns SEC_I_CONTINUE_NEEDED on the first call | 294 // On success, the function returns SEC_I_CONTINUE_NEEDED on the first call |
| 287 // and SEC_E_OK on the second call. On failure, the function returns an | 295 // and SEC_E_OK on the second call. On failure, the function returns an |
| 288 // error code. | 296 // error code. |
| 289 if (status != SEC_I_CONTINUE_NEEDED && status != SEC_E_OK) { | 297 if (status != SEC_I_CONTINUE_NEEDED && status != SEC_E_OK) { |
| 290 LOG(ERROR) << "InitializeSecurityContext failed " << status; | 298 LOG(ERROR) << "InitializeSecurityContext failed " << status; |
| 291 ResetSecurityContext(); | 299 ResetSecurityContext(); |
| 292 free(out_buffer.pvBuffer); | 300 free(out_buffer.pvBuffer); |
| 293 return ERR_UNEXPECTED; // TODO(wtc): map error code. | 301 return ERR_UNEXPECTED; // TODO(wtc): map error code. |
| 294 } | 302 } |
| 295 if (!out_buffer.cbBuffer) { | 303 if (!out_buffer.cbBuffer) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 private: | 420 private: |
| 413 friend struct DefaultSingletonTraits<SSPILibraryDefault>; | 421 friend struct DefaultSingletonTraits<SSPILibraryDefault>; |
| 414 }; | 422 }; |
| 415 | 423 |
| 416 // static | 424 // static |
| 417 SSPILibrary* SSPILibrary::GetDefault() { | 425 SSPILibrary* SSPILibrary::GetDefault() { |
| 418 return Singleton<SSPILibraryDefault>::get(); | 426 return Singleton<SSPILibraryDefault>::get(); |
| 419 } | 427 } |
| 420 | 428 |
| 421 } // namespace net | 429 } // namespace net |
| OLD | NEW |