123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- // 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.
- // This file contains common routines used by NTLM and Negotiate authentication
- // using the SSPI API on Windows.
- #ifndef NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
- #define NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
- #include "base/memory/raw_ptr.h"
- // security.h needs to be included for CredHandle. Unfortunately CredHandle
- // is a typedef and can't be forward declared.
- #define SECURITY_WIN32 1
- #include <windows.h>
- #include <security.h>
- #include <string>
- #include "net/base/completion_once_callback.h"
- #include "net/base/net_errors.h"
- #include "net/base/net_export.h"
- #include "net/http/http_auth.h"
- #include "net/http/http_auth_mechanism.h"
- namespace net {
- class HttpAuthChallengeTokenizer;
- // SSPILibrary is introduced so unit tests can mock the calls to Windows' SSPI
- // implementation. The default implementation simply passes the arguments on to
- // the SSPI implementation provided by Secur32.dll.
- //
- // A single SSPILibrary can only be used with a single security package. Hence
- // the package is bound at construction time. Overridable SSPI methods exclude
- // the security package parameter since it is implicit.
- class NET_EXPORT_PRIVATE SSPILibrary {
- public:
- explicit SSPILibrary(const wchar_t* package) : package_name_(package) {}
- virtual ~SSPILibrary() {}
- // Determines the maximum token length in bytes for a particular SSPI package.
- //
- // |library| and |max_token_length| must be non-nullptr pointers to valid
- // objects.
- //
- // If the return value is OK, |*max_token_length| contains the maximum token
- // length in bytes.
- //
- // If the return value is ERR_UNSUPPORTED_AUTH_SCHEME, |package| is not an
- // known SSPI authentication scheme on this system. |*max_token_length| is not
- // changed.
- //
- // If the return value is ERR_UNEXPECTED, there was an unanticipated problem
- // in the underlying SSPI call. The details are logged, and
- // |*max_token_length| is not changed.
- Error DetermineMaxTokenLength(ULONG* max_token_length);
- virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
- unsigned long fCredentialUse,
- void* pvLogonId,
- void* pvAuthData,
- SEC_GET_KEY_FN pGetKeyFn,
- void* pvGetKeyArgument,
- PCredHandle phCredential,
- PTimeStamp ptsExpiry) = 0;
- virtual SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential,
- PCtxtHandle phContext,
- SEC_WCHAR* pszTargetName,
- unsigned long fContextReq,
- unsigned long Reserved1,
- unsigned long TargetDataRep,
- PSecBufferDesc pInput,
- unsigned long Reserved2,
- PCtxtHandle phNewContext,
- PSecBufferDesc pOutput,
- unsigned long* contextAttr,
- PTimeStamp ptsExpiry) = 0;
- virtual SECURITY_STATUS QueryContextAttributesEx(PCtxtHandle phContext,
- ULONG ulAttribute,
- PVOID pBuffer,
- ULONG cbBuffer) = 0;
- virtual SECURITY_STATUS QuerySecurityPackageInfo(PSecPkgInfoW* pkgInfo) = 0;
- virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) = 0;
- virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) = 0;
- virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) = 0;
- protected:
- // Security package used with DetermineMaxTokenLength(),
- // QuerySecurityPackageInfo(), AcquireCredentialsHandle(). All of these must
- // be consistent.
- const std::wstring package_name_;
- ULONG max_token_length_ = 0;
- bool is_supported_ = true;
- };
- class SSPILibraryDefault : public SSPILibrary {
- public:
- explicit SSPILibraryDefault(const wchar_t* package) : SSPILibrary(package) {}
- ~SSPILibraryDefault() override {}
- SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
- unsigned long fCredentialUse,
- void* pvLogonId,
- void* pvAuthData,
- SEC_GET_KEY_FN pGetKeyFn,
- void* pvGetKeyArgument,
- PCredHandle phCredential,
- PTimeStamp ptsExpiry) override;
- SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential,
- PCtxtHandle phContext,
- SEC_WCHAR* pszTargetName,
- unsigned long fContextReq,
- unsigned long Reserved1,
- unsigned long TargetDataRep,
- PSecBufferDesc pInput,
- unsigned long Reserved2,
- PCtxtHandle phNewContext,
- PSecBufferDesc pOutput,
- unsigned long* contextAttr,
- PTimeStamp ptsExpiry) override;
- SECURITY_STATUS QueryContextAttributesEx(PCtxtHandle phContext,
- ULONG ulAttribute,
- PVOID pBuffer,
- ULONG cbBuffer) override;
- SECURITY_STATUS QuerySecurityPackageInfo(PSecPkgInfoW* pkgInfo) override;
- SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) override;
- SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) override;
- SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) override;
- };
- class NET_EXPORT_PRIVATE HttpAuthSSPI : public HttpAuthMechanism {
- public:
- HttpAuthSSPI(SSPILibrary* sspi_library, HttpAuth::Scheme scheme);
- ~HttpAuthSSPI() override;
- // HttpAuthMechanism implementation:
- bool Init(const NetLogWithSource& net_log) override;
- bool NeedsIdentity() const override;
- bool AllowsExplicitCredentials() const override;
- HttpAuth::AuthorizationResult ParseChallenge(
- HttpAuthChallengeTokenizer* tok) override;
- int GenerateAuthToken(const AuthCredentials* credentials,
- const std::string& spn,
- const std::string& channel_bindings,
- std::string* auth_token,
- const NetLogWithSource& net_log,
- CompletionOnceCallback callback) override;
- void SetDelegation(HttpAuth::DelegationType delegation_type) override;
- private:
- int OnFirstRound(const AuthCredentials* credentials,
- const NetLogWithSource& net_log);
- int GetNextSecurityToken(const std::string& spn,
- const std::string& channing_bindings,
- const void* in_token,
- int in_token_len,
- const NetLogWithSource& net_log,
- void** out_token,
- int* out_token_len);
- void ResetSecurityContext();
- raw_ptr<SSPILibrary> library_;
- HttpAuth::Scheme scheme_;
- std::string decoded_server_auth_token_;
- CredHandle cred_;
- CtxtHandle ctxt_;
- HttpAuth::DelegationType delegation_type_;
- };
- // Splits |combined| into domain and username.
- // If |combined| is of form "FOO\bar", |domain| will contain "FOO" and |user|
- // will contain "bar".
- // If |combined| is of form "bar", |domain| will be empty and |user| will
- // contain "bar".
- // |domain| and |user| must be non-nullptr.
- NET_EXPORT_PRIVATE void SplitDomainAndUser(const std::u16string& combined,
- std::u16string* domain,
- std::u16string* user);
- } // namespace net
- #endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
|