Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / net / http / http_auth_sspi_win.h
blob1d524fa12c4f3df45564fbee18841f4cad948dad
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
14 #include <windows.h>
15 #include <security.h>
17 #include <string>
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"
24 namespace net {
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
33 // sensitive code.
34 class SSPILibrary {
35 public:
36 virtual ~SSPILibrary() {}
38 virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
39 LPWSTR pszPackage,
40 unsigned long fCredentialUse,
41 void* pvLogonId,
42 void* pvAuthData,
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 {
72 public:
73 SSPILibraryDefault() {}
74 ~SSPILibraryDefault() override {}
76 SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
77 LPWSTR pszPackage,
78 unsigned long fCredentialUse,
79 void* pvLogonId,
80 void* pvAuthData,
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 {
110 public:
111 HttpAuthSSPI(SSPILibrary* sspi_library,
112 const std::string& scheme,
113 const SEC_WCHAR* security_package,
114 ULONG max_token_length);
115 ~HttpAuthSSPI();
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
133 // call.
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.
155 void Delegate();
157 private:
158 int OnFirstRound(const AuthCredentials* credentials);
160 int GetNextSecurityToken(
161 const std::string& spn,
162 const void* in_token,
163 int in_token_len,
164 void** out_token,
165 int* out_token_len);
167 void ResetSecurityContext();
169 SSPILibrary* library_;
170 std::string scheme_;
171 const SEC_WCHAR* security_package_;
172 std::string decoded_server_auth_token_;
173 ULONG max_token_length_;
174 CredHandle cred_;
175 CtxtHandle ctxt_;
176 bool can_delegate_;
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
183 // contain "bar".
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
194 // length in bytes.
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
198 // changed.
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|
202 // is not changed.
203 NET_EXPORT_PRIVATE int DetermineMaxTokenLength(SSPILibrary* library,
204 const std::wstring& package,
205 ULONG* max_token_length);
207 } // namespace net
209 #endif // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_