1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This file contains common routines used by NTLM and Negotiate authentication
6 // using the SSPI API on Windows.
8 #ifndef NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
9 #define NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
11 // security.h needs to be included for CredHandle. Unfortunately CredHandle
12 // is a typedef and can't be forward declared.
13 #define SECURITY_WIN32 1
19 #include "base/strings/string16.h"
20 #include "net/base/net_export.h"
21 #include "net/http/http_auth.h"
25 class HttpAuthChallengeTokenizer
;
27 // SSPILibrary is introduced so unit tests can mock the calls to Windows' SSPI
28 // implementation. The default implementation simply passes the arguments on to
29 // the SSPI implementation provided by Secur32.dll.
30 // NOTE(cbentzel): I considered replacing the Secur32.dll with a mock DLL, but
31 // decided that it wasn't worth the effort as this is unlikely to be performance
35 virtual ~SSPILibrary() {}
37 virtual SECURITY_STATUS
AcquireCredentialsHandle(LPWSTR pszPrincipal
,
39 unsigned long fCredentialUse
,
42 SEC_GET_KEY_FN pGetKeyFn
,
43 void* pvGetKeyArgument
,
44 PCredHandle phCredential
,
45 PTimeStamp ptsExpiry
) = 0;
47 virtual SECURITY_STATUS
InitializeSecurityContext(PCredHandle phCredential
,
48 PCtxtHandle phContext
,
49 SEC_WCHAR
* pszTargetName
,
50 unsigned long fContextReq
,
51 unsigned long Reserved1
,
52 unsigned long TargetDataRep
,
53 PSecBufferDesc pInput
,
54 unsigned long Reserved2
,
55 PCtxtHandle phNewContext
,
56 PSecBufferDesc pOutput
,
57 unsigned long* contextAttr
,
58 PTimeStamp ptsExpiry
) = 0;
60 virtual SECURITY_STATUS
QuerySecurityPackageInfo(LPWSTR pszPackageName
,
61 PSecPkgInfoW
*pkgInfo
) = 0;
63 virtual SECURITY_STATUS
FreeCredentialsHandle(PCredHandle phCredential
) = 0;
65 virtual SECURITY_STATUS
DeleteSecurityContext(PCtxtHandle phContext
) = 0;
67 virtual SECURITY_STATUS
FreeContextBuffer(PVOID pvContextBuffer
) = 0;
70 class SSPILibraryDefault
: public SSPILibrary
{
72 SSPILibraryDefault() {}
73 ~SSPILibraryDefault() override
{}
75 SECURITY_STATUS
AcquireCredentialsHandle(LPWSTR pszPrincipal
,
77 unsigned long fCredentialUse
,
80 SEC_GET_KEY_FN pGetKeyFn
,
81 void* pvGetKeyArgument
,
82 PCredHandle phCredential
,
83 PTimeStamp ptsExpiry
) override
;
85 SECURITY_STATUS
InitializeSecurityContext(PCredHandle phCredential
,
86 PCtxtHandle phContext
,
87 SEC_WCHAR
* pszTargetName
,
88 unsigned long fContextReq
,
89 unsigned long Reserved1
,
90 unsigned long TargetDataRep
,
91 PSecBufferDesc pInput
,
92 unsigned long Reserved2
,
93 PCtxtHandle phNewContext
,
94 PSecBufferDesc pOutput
,
95 unsigned long* contextAttr
,
96 PTimeStamp ptsExpiry
) override
;
98 SECURITY_STATUS
QuerySecurityPackageInfo(LPWSTR pszPackageName
,
99 PSecPkgInfoW
* pkgInfo
) override
;
101 SECURITY_STATUS
FreeCredentialsHandle(PCredHandle phCredential
) override
;
103 SECURITY_STATUS
DeleteSecurityContext(PCtxtHandle phContext
) override
;
105 SECURITY_STATUS
FreeContextBuffer(PVOID pvContextBuffer
) override
;
108 class NET_EXPORT_PRIVATE HttpAuthSSPI
{
110 HttpAuthSSPI(SSPILibrary
* sspi_library
,
111 const std::string
& scheme
,
112 const SEC_WCHAR
* security_package
,
113 ULONG max_token_length
);
116 bool NeedsIdentity() const;
118 bool AllowsExplicitCredentials() const;
120 HttpAuth::AuthorizationResult
ParseChallenge(
121 HttpAuthChallengeTokenizer
* tok
);
123 // Generates an authentication token for the service specified by the
124 // Service Principal Name |spn| and stores the value in |*auth_token|.
125 // If the return value is not |OK|, then the value of |*auth_token| is
126 // unspecified. ERR_IO_PENDING is not a valid return code.
127 // If this is the first round of a multiple round scheme, credentials are
128 // obtained using |*credentials|. If |credentials| is NULL, the credentials
129 // for the currently logged in user are used instead.
130 int GenerateAuthToken(const AuthCredentials
* credentials
,
131 const std::string
& spn
,
132 std::string
* auth_token
);
134 // Delegation is allowed on the Kerberos ticket. This allows certain servers
135 // to act as the user, such as an IIS server retrieiving data from a
136 // Kerberized MSSQL server.
140 int OnFirstRound(const AuthCredentials
* credentials
);
142 int GetNextSecurityToken(
143 const std::string
& spn
,
144 const void* in_token
,
149 void ResetSecurityContext();
151 SSPILibrary
* library_
;
153 const SEC_WCHAR
* security_package_
;
154 std::string decoded_server_auth_token_
;
155 ULONG max_token_length_
;
161 // Splits |combined| into domain and username.
162 // If |combined| is of form "FOO\bar", |domain| will contain "FOO" and |user|
163 // will contain "bar".
164 // If |combined| is of form "bar", |domain| will be empty and |user| will
166 // |domain| and |user| must be non-NULL.
167 NET_EXPORT_PRIVATE
void SplitDomainAndUser(const base::string16
& combined
,
168 base::string16
* domain
,
169 base::string16
* user
);
171 // Determines the maximum token length in bytes for a particular SSPI package.
173 // |library| and |max_token_length| must be non-NULL pointers to valid objects.
175 // If the return value is OK, |*max_token_length| contains the maximum token
178 // If the return value is ERR_UNSUPPORTED_AUTH_SCHEME, |package| is not an
179 // known SSPI authentication scheme on this system. |*max_token_length| is not
182 // If the return value is ERR_UNEXPECTED, there was an unanticipated problem
183 // in the underlying SSPI call. The details are logged, and |*max_token_length|
185 NET_EXPORT_PRIVATE
int DetermineMaxTokenLength(SSPILibrary
* library
,
186 const std::wstring
& package
,
187 ULONG
* max_token_length
);
191 #endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_