Index: net/http/http_auth_sspi_win.cc |
diff --git a/net/http/http_auth_sspi_win.cc b/net/http/http_auth_sspi_win.cc |
index f59ce4d9d781d28dc38847f9a88bf3615acafa4d..a2929fbb569441122d6dd51f094a6ba94fa158a1 100644 |
--- a/net/http/http_auth_sspi_win.cc |
+++ b/net/http/http_auth_sspi_win.cc |
@@ -292,6 +292,7 @@ HttpAuth::AuthorizationResult HttpAuthSSPI::ParseChallenge( |
int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials, |
const std::string& spn, |
+ const std::string& channel_bindings, |
std::string* auth_token, |
const CompletionCallback& /*callback*/) { |
// Initial challenge. |
@@ -305,12 +306,9 @@ int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials, |
void* out_buf; |
int out_buf_len; |
int rv = GetNextSecurityToken( |
- spn, |
- static_cast<void *>(const_cast<char *>( |
- decoded_server_auth_token_.c_str())), |
- decoded_server_auth_token_.length(), |
- &out_buf, |
- &out_buf_len); |
+ spn, channel_bindings, |
+ static_cast<void*>(const_cast<char*>(decoded_server_auth_token_.c_str())), |
+ decoded_server_auth_token_.length(), &out_buf, &out_buf_len); |
if (rv != OK) |
return rv; |
@@ -344,27 +342,27 @@ int HttpAuthSSPI::OnFirstRound(const AuthCredentials* credentials) { |
return rv; |
} |
-int HttpAuthSSPI::GetNextSecurityToken( |
- const std::string& spn, |
- const void* in_token, |
- int in_token_len, |
- void** out_token, |
- int* out_token_len) { |
- CtxtHandle* ctxt_ptr; |
+int HttpAuthSSPI::GetNextSecurityToken(const std::string& spn, |
+ const std::string& channel_bindings, |
+ const void* in_token, |
+ int in_token_len, |
+ void** out_token, |
+ int* out_token_len) { |
+ CtxtHandle* ctxt_ptr = nullptr; |
SecBufferDesc in_buffer_desc, out_buffer_desc; |
- SecBufferDesc* in_buffer_desc_ptr; |
- SecBuffer in_buffer, out_buffer; |
+ SecBufferDesc* in_buffer_desc_ptr = nullptr; |
+ SecBuffer in_buffers[2], out_buffer; |
+ in_buffer_desc.ulVersion = SECBUFFER_VERSION; |
+ in_buffer_desc.cBuffers = 0; |
+ in_buffer_desc.pBuffers = in_buffers; |
if (in_token_len > 0) { |
// Prepare input buffer. |
- in_buffer_desc.ulVersion = SECBUFFER_VERSION; |
- in_buffer_desc.cBuffers = 1; |
- in_buffer_desc.pBuffers = &in_buffer; |
- in_buffer.BufferType = SECBUFFER_TOKEN; |
- in_buffer.cbBuffer = in_token_len; |
- in_buffer.pvBuffer = const_cast<void*>(in_token); |
+ SecBuffer& sec_buffer = in_buffers[in_buffer_desc.cBuffers++]; |
+ sec_buffer.BufferType = SECBUFFER_TOKEN; |
+ sec_buffer.cbBuffer = in_token_len; |
+ sec_buffer.pvBuffer = const_cast<void*>(in_token); |
ctxt_ptr = &ctxt_; |
- in_buffer_desc_ptr = &in_buffer_desc; |
} else { |
// If there is no input token, then we are starting a new authentication |
// sequence. If we have already initialized our security context, then |
@@ -373,10 +371,33 @@ int HttpAuthSSPI::GetNextSecurityToken( |
NOTREACHED(); |
return ERR_UNEXPECTED; |
} |
- ctxt_ptr = NULL; |
- in_buffer_desc_ptr = NULL; |
} |
+ std::vector<char> sec_channel_bindings_buffer; |
+ if (!channel_bindings.empty()) { |
+ sec_channel_bindings_buffer.reserve(sizeof(SEC_CHANNEL_BINDINGS) + |
+ channel_bindings.size()); |
+ sec_channel_bindings_buffer.resize(sizeof(SEC_CHANNEL_BINDINGS)); |
+ SEC_CHANNEL_BINDINGS* bindings_desc = |
+ reinterpret_cast<SEC_CHANNEL_BINDINGS*>( |
+ &sec_channel_bindings_buffer.front()); |
+ bindings_desc->cbApplicationDataLength = channel_bindings.size(); |
+ bindings_desc->dwApplicationDataOffset = sizeof(SEC_CHANNEL_BINDINGS); |
+ sec_channel_bindings_buffer.insert(sec_channel_bindings_buffer.end(), |
+ channel_bindings.begin(), |
+ channel_bindings.end()); |
+ DCHECK_EQ(sizeof(SEC_CHANNEL_BINDINGS) + channel_bindings.size(), |
+ sec_channel_bindings_buffer.size()); |
+ |
+ SecBuffer& sec_buffer = in_buffers[in_buffer_desc.cBuffers++]; |
+ sec_buffer.BufferType = SECBUFFER_CHANNEL_BINDINGS; |
+ sec_buffer.cbBuffer = sec_channel_bindings_buffer.size(); |
+ sec_buffer.pvBuffer = &sec_channel_bindings_buffer.front(); |
+ } |
+ |
+ if (in_buffer_desc.cBuffers > 0) |
+ in_buffer_desc_ptr = &in_buffer_desc; |
+ |
// Prepare output buffer. |
out_buffer_desc.ulVersion = SECBUFFER_VERSION; |
out_buffer_desc.cBuffers = 1; |
@@ -397,18 +418,18 @@ int HttpAuthSSPI::GetNextSecurityToken( |
DWORD context_attribute; |
base::string16 spn16 = base::ASCIIToUTF16(spn); |
SECURITY_STATUS status = library_->InitializeSecurityContext( |
- &cred_, // phCredential |
- ctxt_ptr, // phContext |
+ &cred_, // phCredential |
+ ctxt_ptr, // phContext |
const_cast<base::char16*>(spn16.c_str()), // pszTargetName |
- context_flags, // fContextReq |
- 0, // Reserved1 (must be 0) |
- SECURITY_NATIVE_DREP, // TargetDataRep |
- in_buffer_desc_ptr, // pInput |
- 0, // Reserved2 (must be 0) |
- &ctxt_, // phNewContext |
- &out_buffer_desc, // pOutput |
- &context_attribute, // pfContextAttr |
- NULL); // ptsExpiry |
+ context_flags, // fContextReq |
+ 0, // Reserved1 (must be 0) |
+ SECURITY_NATIVE_DREP, // TargetDataRep |
+ in_buffer_desc_ptr, // pInput |
+ 0, // Reserved2 (must be 0) |
+ &ctxt_, // phNewContext |
+ &out_buffer_desc, // pOutput |
+ &context_attribute, // pfContextAttr |
+ nullptr); // ptsExpiry |
int rv = MapInitializeSecurityContextStatusToError(status); |
if (rv != OK) { |
ResetSecurityContext(); |