Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / net / http / http_auth_sspi_win.h
blobdd0b1772b16f00c4fad6bff6e6c24c19cfa42aa8
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/net_export.h"
21 #include "net/http/http_auth.h"
23 namespace net {
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
32 // sensitive code.
33 class SSPILibrary {
34 public:
35 virtual ~SSPILibrary() {}
37 virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
38 LPWSTR pszPackage,
39 unsigned long fCredentialUse,
40 void* pvLogonId,
41 void* pvAuthData,
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 {
71 public:
72 SSPILibraryDefault() {}
73 virtual ~SSPILibraryDefault() {}
75 virtual SECURITY_STATUS AcquireCredentialsHandle(LPWSTR pszPrincipal,
76 LPWSTR pszPackage,
77 unsigned long fCredentialUse,
78 void* pvLogonId,
79 void* pvAuthData,
80 SEC_GET_KEY_FN pGetKeyFn,
81 void* pvGetKeyArgument,
82 PCredHandle phCredential,
83 PTimeStamp ptsExpiry) {
84 return ::AcquireCredentialsHandle(pszPrincipal, pszPackage, fCredentialUse,
85 pvLogonId, pvAuthData, pGetKeyFn,
86 pvGetKeyArgument, phCredential,
87 ptsExpiry);
90 virtual SECURITY_STATUS InitializeSecurityContext(PCredHandle phCredential,
91 PCtxtHandle phContext,
92 SEC_WCHAR* pszTargetName,
93 unsigned long fContextReq,
94 unsigned long Reserved1,
95 unsigned long TargetDataRep,
96 PSecBufferDesc pInput,
97 unsigned long Reserved2,
98 PCtxtHandle phNewContext,
99 PSecBufferDesc pOutput,
100 unsigned long* contextAttr,
101 PTimeStamp ptsExpiry) {
102 return ::InitializeSecurityContext(phCredential, phContext, pszTargetName,
103 fContextReq, Reserved1, TargetDataRep,
104 pInput, Reserved2, phNewContext, pOutput,
105 contextAttr, ptsExpiry);
108 virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName,
109 PSecPkgInfoW *pkgInfo) {
110 return ::QuerySecurityPackageInfo(pszPackageName, pkgInfo);
113 virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) {
114 return ::FreeCredentialsHandle(phCredential);
117 virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) {
118 return ::DeleteSecurityContext(phContext);
121 virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) {
122 return ::FreeContextBuffer(pvContextBuffer);
126 class NET_EXPORT_PRIVATE HttpAuthSSPI {
127 public:
128 HttpAuthSSPI(SSPILibrary* sspi_library,
129 const std::string& scheme,
130 const SEC_WCHAR* security_package,
131 ULONG max_token_length);
132 ~HttpAuthSSPI();
134 bool NeedsIdentity() const;
136 bool AllowsExplicitCredentials() const;
138 HttpAuth::AuthorizationResult ParseChallenge(
139 HttpAuthChallengeTokenizer* tok);
141 // Generates an authentication token for the service specified by the
142 // Service Principal Name |spn| and stores the value in |*auth_token|.
143 // If the return value is not |OK|, then the value of |*auth_token| is
144 // unspecified. ERR_IO_PENDING is not a valid return code.
145 // If this is the first round of a multiple round scheme, credentials are
146 // obtained using |*credentials|. If |credentials| is NULL, the credentials
147 // for the currently logged in user are used instead.
148 int GenerateAuthToken(const AuthCredentials* credentials,
149 const std::string& spn,
150 std::string* auth_token);
152 // Delegation is allowed on the Kerberos ticket. This allows certain servers
153 // to act as the user, such as an IIS server retrieiving 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_