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/completion_callback.h"
21 #include "net/base/net_export.h"
22 #include "net/http/http_auth.h"
26 class HttpAuthChallengeTokenizer
;
28 // SSPILibrary is introduced so unit tests can mock the calls to Windows' SSPI
29 // implementation. The default implementation simply passes the arguments on to
30 // the SSPI implementation provided by Secur32.dll.
31 // NOTE(cbentzel): I considered replacing the Secur32.dll with a mock DLL, but
32 // decided that it wasn't worth the effort as this is unlikely to be performance
36 virtual ~SSPILibrary() {}
38 virtual SECURITY_STATUS
AcquireCredentialsHandle(LPWSTR pszPrincipal
,
40 unsigned long fCredentialUse
,
43 SEC_GET_KEY_FN pGetKeyFn
,
44 void* pvGetKeyArgument
,
45 PCredHandle phCredential
,
46 PTimeStamp ptsExpiry
) = 0;
48 virtual SECURITY_STATUS
InitializeSecurityContext(PCredHandle phCredential
,
49 PCtxtHandle phContext
,
50 SEC_WCHAR
* pszTargetName
,
51 unsigned long fContextReq
,
52 unsigned long Reserved1
,
53 unsigned long TargetDataRep
,
54 PSecBufferDesc pInput
,
55 unsigned long Reserved2
,
56 PCtxtHandle phNewContext
,
57 PSecBufferDesc pOutput
,
58 unsigned long* contextAttr
,
59 PTimeStamp ptsExpiry
) = 0;
61 virtual SECURITY_STATUS
QuerySecurityPackageInfo(LPWSTR pszPackageName
,
62 PSecPkgInfoW
*pkgInfo
) = 0;
64 virtual SECURITY_STATUS
FreeCredentialsHandle(PCredHandle phCredential
) = 0;
66 virtual SECURITY_STATUS
DeleteSecurityContext(PCtxtHandle phContext
) = 0;
68 virtual SECURITY_STATUS
FreeContextBuffer(PVOID pvContextBuffer
) = 0;
71 class SSPILibraryDefault
: public SSPILibrary
{
73 SSPILibraryDefault() {}
74 ~SSPILibraryDefault() override
{}
76 SECURITY_STATUS
AcquireCredentialsHandle(LPWSTR pszPrincipal
,
78 unsigned long fCredentialUse
,
81 SEC_GET_KEY_FN pGetKeyFn
,
82 void* pvGetKeyArgument
,
83 PCredHandle phCredential
,
84 PTimeStamp ptsExpiry
) override
;
86 SECURITY_STATUS
InitializeSecurityContext(PCredHandle phCredential
,
87 PCtxtHandle phContext
,
88 SEC_WCHAR
* pszTargetName
,
89 unsigned long fContextReq
,
90 unsigned long Reserved1
,
91 unsigned long TargetDataRep
,
92 PSecBufferDesc pInput
,
93 unsigned long Reserved2
,
94 PCtxtHandle phNewContext
,
95 PSecBufferDesc pOutput
,
96 unsigned long* contextAttr
,
97 PTimeStamp ptsExpiry
) override
;
99 SECURITY_STATUS
QuerySecurityPackageInfo(LPWSTR pszPackageName
,
100 PSecPkgInfoW
* pkgInfo
) override
;
102 SECURITY_STATUS
FreeCredentialsHandle(PCredHandle phCredential
) override
;
104 SECURITY_STATUS
DeleteSecurityContext(PCtxtHandle phContext
) override
;
106 SECURITY_STATUS
FreeContextBuffer(PVOID pvContextBuffer
) override
;
109 class NET_EXPORT_PRIVATE HttpAuthSSPI
{
111 HttpAuthSSPI(SSPILibrary
* sspi_library
,
112 const std::string
& scheme
,
113 const SEC_WCHAR
* security_package
,
114 ULONG max_token_length
);
117 bool NeedsIdentity() const;
119 bool AllowsExplicitCredentials() const;
121 HttpAuth::AuthorizationResult
ParseChallenge(
122 HttpAuthChallengeTokenizer
* tok
);
124 // Generates an authentication token.
126 // The return value is an error code. The authentication token will be
127 // returned in |*auth_token|. If the result code is not |OK|, the value of
128 // |*auth_token| is unspecified.
130 // If the operation cannot be completed synchronously, |ERR_IO_PENDING| will
131 // be returned and the real result code will be passed to the completion
132 // callback. Otherwise the result code is returned immediately from this
135 // If the HttpAuthSPPI object is deleted before completion then the callback
136 // will not be called.
138 // If no immediate result is returned then |auth_token| must remain valid
139 // until the callback has been called.
141 // |spn| is the Service Principal Name of the server that the token is
142 // being generated for.
144 // If this is the first round of a multiple round scheme, credentials are
145 // obtained using |*credentials|. If |credentials| is NULL, the default
146 // credentials are used instead.
147 int GenerateAuthToken(const AuthCredentials
* credentials
,
148 const std::string
& spn
,
149 std::string
* auth_token
,
150 const CompletionCallback
& callback
);
152 // Delegation is allowed on the Kerberos ticket. This allows certain servers
153 // to act as the user, such as an IIS server retrieving data from a
154 // Kerberized MSSQL server.
158 int OnFirstRound(const AuthCredentials
* credentials
);
160 int GetNextSecurityToken(
161 const std::string
& spn
,
162 const void* in_token
,
167 void ResetSecurityContext();
169 SSPILibrary
* library_
;
171 const SEC_WCHAR
* security_package_
;
172 std::string decoded_server_auth_token_
;
173 ULONG max_token_length_
;
179 // Splits |combined| into domain and username.
180 // If |combined| is of form "FOO\bar", |domain| will contain "FOO" and |user|
181 // will contain "bar".
182 // If |combined| is of form "bar", |domain| will be empty and |user| will
184 // |domain| and |user| must be non-NULL.
185 NET_EXPORT_PRIVATE
void SplitDomainAndUser(const base::string16
& combined
,
186 base::string16
* domain
,
187 base::string16
* user
);
189 // Determines the maximum token length in bytes for a particular SSPI package.
191 // |library| and |max_token_length| must be non-NULL pointers to valid objects.
193 // If the return value is OK, |*max_token_length| contains the maximum token
196 // If the return value is ERR_UNSUPPORTED_AUTH_SCHEME, |package| is not an
197 // known SSPI authentication scheme on this system. |*max_token_length| is not
200 // If the return value is ERR_UNEXPECTED, there was an unanticipated problem
201 // in the underlying SSPI call. The details are logged, and |*max_token_length|
203 NET_EXPORT_PRIVATE
int DetermineMaxTokenLength(SSPILibrary
* library
,
204 const std::wstring
& package
,
205 ULONG
* max_token_length
);
209 #endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_