Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1673)

Unified Diff: net/http/http_auth_sspi_win.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_auth_sspi_win.h ('k') | net/http/http_auth_sspi_win_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
deleted file mode 100644
index 156a55f7ed87d1df4ff6562558aa7837dccc07e7..0000000000000000000000000000000000000000
--- a/net/http/http_auth_sspi_win.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// See "SSPI Sample Application" at
-// http://msdn.microsoft.com/en-us/library/aa918273.aspx
-
-#include "net/http/http_auth_sspi_win.h"
-
-#include "base/base64.h"
-#include "base/logging.h"
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_auth.h"
-#include "net/http/http_auth_challenge_tokenizer.h"
-
-namespace net {
-
-namespace {
-
-int MapAcquireCredentialsStatusToError(SECURITY_STATUS status,
- const SEC_WCHAR* package) {
- VLOG(1) << "AcquireCredentialsHandle returned 0x" << std::hex << status;
- switch (status) {
- case SEC_E_OK:
- return OK;
- case SEC_E_INSUFFICIENT_MEMORY:
- return ERR_OUT_OF_MEMORY;
- case SEC_E_INTERNAL_ERROR:
- LOG(WARNING)
- << "AcquireCredentialsHandle returned unexpected status 0x"
- << std::hex << status;
- return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_NOT_OWNER:
- case SEC_E_UNKNOWN_CREDENTIALS:
- return ERR_INVALID_AUTH_CREDENTIALS;
- case SEC_E_SECPKG_NOT_FOUND:
- // This indicates that the SSPI configuration does not match expectations
- return ERR_UNSUPPORTED_AUTH_SCHEME;
- default:
- LOG(WARNING)
- << "AcquireCredentialsHandle returned undocumented status 0x"
- << std::hex << status;
- return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
- }
-}
-
-int AcquireExplicitCredentials(SSPILibrary* library,
- const SEC_WCHAR* package,
- const base::string16& domain,
- const base::string16& user,
- const base::string16& password,
- CredHandle* cred) {
- SEC_WINNT_AUTH_IDENTITY identity;
- identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
- identity.User =
- reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(user.c_str()));
- identity.UserLength = user.size();
- identity.Domain =
- reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str()));
- identity.DomainLength = domain.size();
- identity.Password =
- reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(password.c_str()));
- identity.PasswordLength = password.size();
-
- TimeStamp expiry;
-
- // Pass the username/password to get the credentials handle.
- SECURITY_STATUS status = library->AcquireCredentialsHandle(
- NULL, // pszPrincipal
- const_cast<SEC_WCHAR*>(package), // pszPackage
- SECPKG_CRED_OUTBOUND, // fCredentialUse
- NULL, // pvLogonID
- &identity, // pAuthData
- NULL, // pGetKeyFn (not used)
- NULL, // pvGetKeyArgument (not used)
- cred, // phCredential
- &expiry); // ptsExpiry
-
- return MapAcquireCredentialsStatusToError(status, package);
-}
-
-int AcquireDefaultCredentials(SSPILibrary* library, const SEC_WCHAR* package,
- CredHandle* cred) {
- TimeStamp expiry;
-
- // Pass the username/password to get the credentials handle.
- // Note: Since the 5th argument is NULL, it uses the default
- // cached credentials for the logged in user, which can be used
- // for a single sign-on.
- SECURITY_STATUS status = library->AcquireCredentialsHandle(
- NULL, // pszPrincipal
- const_cast<SEC_WCHAR*>(package), // pszPackage
- SECPKG_CRED_OUTBOUND, // fCredentialUse
- NULL, // pvLogonID
- NULL, // pAuthData
- NULL, // pGetKeyFn (not used)
- NULL, // pvGetKeyArgument (not used)
- cred, // phCredential
- &expiry); // ptsExpiry
-
- return MapAcquireCredentialsStatusToError(status, package);
-}
-
-int MapInitializeSecurityContextStatusToError(SECURITY_STATUS status) {
- VLOG(1) << "InitializeSecurityContext returned 0x" << std::hex << status;
- switch (status) {
- case SEC_E_OK:
- case SEC_I_CONTINUE_NEEDED:
- return OK;
- case SEC_I_COMPLETE_AND_CONTINUE:
- case SEC_I_COMPLETE_NEEDED:
- case SEC_I_INCOMPLETE_CREDENTIALS:
- case SEC_E_INCOMPLETE_MESSAGE:
- case SEC_E_INTERNAL_ERROR:
- // These are return codes reported by InitializeSecurityContext
- // but not expected by Chrome (for example, INCOMPLETE_CREDENTIALS
- // and INCOMPLETE_MESSAGE are intended for schannel).
- LOG(WARNING)
- << "InitializeSecurityContext returned unexpected status 0x"
- << std::hex << status;
- return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
- case SEC_E_INSUFFICIENT_MEMORY:
- return ERR_OUT_OF_MEMORY;
- case SEC_E_UNSUPPORTED_FUNCTION:
- NOTREACHED();
- return ERR_UNEXPECTED;
- case SEC_E_INVALID_HANDLE:
- NOTREACHED();
- return ERR_INVALID_HANDLE;
- case SEC_E_INVALID_TOKEN:
- return ERR_INVALID_RESPONSE;
- case SEC_E_LOGON_DENIED:
- return ERR_ACCESS_DENIED;
- case SEC_E_NO_CREDENTIALS:
- case SEC_E_WRONG_PRINCIPAL:
- return ERR_INVALID_AUTH_CREDENTIALS;
- case SEC_E_NO_AUTHENTICATING_AUTHORITY:
- case SEC_E_TARGET_UNKNOWN:
- return ERR_MISCONFIGURED_AUTH_ENVIRONMENT;
- default:
- LOG(WARNING)
- << "InitializeSecurityContext returned undocumented status 0x"
- << std::hex << status;
- return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
- }
-}
-
-int MapQuerySecurityPackageInfoStatusToError(SECURITY_STATUS status) {
- VLOG(1) << "QuerySecurityPackageInfo returned 0x" << std::hex << status;
- switch (status) {
- case SEC_E_OK:
- return OK;
- case SEC_E_SECPKG_NOT_FOUND:
- // This isn't a documented return code, but has been encountered
- // during testing.
- return ERR_UNSUPPORTED_AUTH_SCHEME;
- default:
- LOG(WARNING)
- << "QuerySecurityPackageInfo returned undocumented status 0x"
- << std::hex << status;
- return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
- }
-}
-
-int MapFreeContextBufferStatusToError(SECURITY_STATUS status) {
- VLOG(1) << "FreeContextBuffer returned 0x" << std::hex << status;
- switch (status) {
- case SEC_E_OK:
- return OK;
- default:
- // The documentation at
- // http://msdn.microsoft.com/en-us/library/aa375416(VS.85).aspx
- // only mentions that a non-zero (or non-SEC_E_OK) value is returned
- // if the function fails, and does not indicate what the failure
- // conditions are.
- LOG(WARNING)
- << "FreeContextBuffer returned undocumented status 0x"
- << std::hex << status;
- return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
- }
-}
-
-} // anonymous namespace
-
-HttpAuthSSPI::HttpAuthSSPI(SSPILibrary* library,
- const std::string& scheme,
- const SEC_WCHAR* security_package,
- ULONG max_token_length)
- : library_(library),
- scheme_(scheme),
- security_package_(security_package),
- max_token_length_(max_token_length),
- can_delegate_(false) {
- DCHECK(library_);
- SecInvalidateHandle(&cred_);
- SecInvalidateHandle(&ctxt_);
-}
-
-HttpAuthSSPI::~HttpAuthSSPI() {
- ResetSecurityContext();
- if (SecIsValidHandle(&cred_)) {
- library_->FreeCredentialsHandle(&cred_);
- SecInvalidateHandle(&cred_);
- }
-}
-
-bool HttpAuthSSPI::NeedsIdentity() const {
- return decoded_server_auth_token_.empty();
-}
-
-bool HttpAuthSSPI::AllowsExplicitCredentials() const {
- return true;
-}
-
-void HttpAuthSSPI::Delegate() {
- can_delegate_ = true;
-}
-
-void HttpAuthSSPI::ResetSecurityContext() {
- if (SecIsValidHandle(&ctxt_)) {
- library_->DeleteSecurityContext(&ctxt_);
- SecInvalidateHandle(&ctxt_);
- }
-}
-
-HttpAuth::AuthorizationResult HttpAuthSSPI::ParseChallenge(
- HttpAuthChallengeTokenizer* tok) {
- // Verify the challenge's auth-scheme.
- if (!LowerCaseEqualsASCII(tok->scheme(),
- base::StringToLowerASCII(scheme_).c_str()))
- return HttpAuth::AUTHORIZATION_RESULT_INVALID;
-
- std::string encoded_auth_token = tok->base64_param();
- if (encoded_auth_token.empty()) {
- // If a context has already been established, an empty challenge
- // should be treated as a rejection of the current attempt.
- if (SecIsValidHandle(&ctxt_))
- return HttpAuth::AUTHORIZATION_RESULT_REJECT;
- DCHECK(decoded_server_auth_token_.empty());
- return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
- } else {
- // If a context has not already been established, additional tokens should
- // not be present in the auth challenge.
- if (!SecIsValidHandle(&ctxt_))
- return HttpAuth::AUTHORIZATION_RESULT_INVALID;
- }
-
- std::string decoded_auth_token;
- bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
- if (!base64_rv)
- return HttpAuth::AUTHORIZATION_RESULT_INVALID;
- decoded_server_auth_token_ = decoded_auth_token;
- return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
-}
-
-int HttpAuthSSPI::GenerateAuthToken(const AuthCredentials* credentials,
- const std::string& spn,
- std::string* auth_token) {
- // Initial challenge.
- if (!SecIsValidHandle(&cred_)) {
- int rv = OnFirstRound(credentials);
- if (rv != OK)
- return rv;
- }
-
- DCHECK(SecIsValidHandle(&cred_));
- 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);
- if (rv != OK)
- return rv;
-
- // Base64 encode data in output buffer and prepend the scheme.
- std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
- std::string encode_output;
- base::Base64Encode(encode_input, &encode_output);
- // OK, we are done with |out_buf|
- free(out_buf);
- *auth_token = scheme_ + " " + encode_output;
- return OK;
-}
-
-int HttpAuthSSPI::OnFirstRound(const AuthCredentials* credentials) {
- DCHECK(!SecIsValidHandle(&cred_));
- int rv = OK;
- if (credentials) {
- base::string16 domain;
- base::string16 user;
- SplitDomainAndUser(credentials->username(), &domain, &user);
- rv = AcquireExplicitCredentials(library_, security_package_, domain,
- user, credentials->password(), &cred_);
- if (rv != OK)
- return rv;
- } else {
- rv = AcquireDefaultCredentials(library_, security_package_, &cred_);
- if (rv != OK)
- return rv;
- }
-
- 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;
- SecBufferDesc in_buffer_desc, out_buffer_desc;
- SecBufferDesc* in_buffer_desc_ptr;
- SecBuffer in_buffer, out_buffer;
-
- 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);
- 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
- // we're incorrectly reusing the auth handler for a new sequence.
- if (SecIsValidHandle(&ctxt_)) {
- NOTREACHED();
- return ERR_UNEXPECTED;
- }
- ctxt_ptr = NULL;
- in_buffer_desc_ptr = NULL;
- }
-
- // Prepare output buffer.
- out_buffer_desc.ulVersion = SECBUFFER_VERSION;
- out_buffer_desc.cBuffers = 1;
- out_buffer_desc.pBuffers = &out_buffer;
- out_buffer.BufferType = SECBUFFER_TOKEN;
- out_buffer.cbBuffer = max_token_length_;
- out_buffer.pvBuffer = malloc(out_buffer.cbBuffer);
- if (!out_buffer.pvBuffer)
- return ERR_OUT_OF_MEMORY;
-
- DWORD context_flags = 0;
- // Firefox only sets ISC_REQ_DELEGATE, but MSDN documentation indicates that
- // ISC_REQ_MUTUAL_AUTH must also be set.
- if (can_delegate_)
- context_flags |= (ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH);
-
- // This returns a token that is passed to the remote server.
- DWORD context_attribute;
- base::string16 spn16 = base::ASCIIToUTF16(spn);
- SECURITY_STATUS status = library_->InitializeSecurityContext(
- &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
- int rv = MapInitializeSecurityContextStatusToError(status);
- if (rv != OK) {
- ResetSecurityContext();
- free(out_buffer.pvBuffer);
- return rv;
- }
- if (!out_buffer.cbBuffer) {
- free(out_buffer.pvBuffer);
- out_buffer.pvBuffer = NULL;
- }
- *out_token = out_buffer.pvBuffer;
- *out_token_len = out_buffer.cbBuffer;
- return OK;
-}
-
-void SplitDomainAndUser(const base::string16& combined,
- base::string16* domain,
- base::string16* user) {
- // |combined| may be in the form "user" or "DOMAIN\user".
- // Separate the two parts if they exist.
- // TODO(cbentzel): I believe user@domain is also a valid form.
- size_t backslash_idx = combined.find(L'\\');
- if (backslash_idx == base::string16::npos) {
- domain->clear();
- *user = combined;
- } else {
- *domain = combined.substr(0, backslash_idx);
- *user = combined.substr(backslash_idx + 1);
- }
-}
-
-int DetermineMaxTokenLength(SSPILibrary* library,
- const std::wstring& package,
- ULONG* max_token_length) {
- DCHECK(library);
- DCHECK(max_token_length);
- PSecPkgInfo pkg_info = NULL;
- SECURITY_STATUS status = library->QuerySecurityPackageInfo(
- const_cast<wchar_t *>(package.c_str()), &pkg_info);
- int rv = MapQuerySecurityPackageInfoStatusToError(status);
- if (rv != OK)
- return rv;
- int token_length = pkg_info->cbMaxToken;
- status = library->FreeContextBuffer(pkg_info);
- rv = MapFreeContextBufferStatusToError(status);
- if (rv != OK)
- return rv;
- *max_token_length = token_length;
- return OK;
-}
-
-} // namespace net
« no previous file with comments | « net/http/http_auth_sspi_win.h ('k') | net/http/http_auth_sspi_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698