Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / http / http_auth_sspi_win.h
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.
4
5 // This file contains common routines used by NTLM and Negotiate authentication
6 // using the SSPI API on Windows.
7
8 #ifndef NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
9 #define NET_HTTP_HTTP_AUTH_SSPI_WIN_H_
10
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>
16
17 #include <string>
18
19 #include "base/strings/string16.h"
20 #include "net/base/net_export.h"
21 #include "net/http/http_auth.h"
22
23 namespace net {
24
25 class HttpAuthChallengeTokenizer;
26
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() {}
36
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;
46
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;
59
60   virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName,
61                                                    PSecPkgInfoW *pkgInfo) = 0;
62
63   virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) = 0;
64
65   virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) = 0;
66
67   virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) = 0;
68 };
69
70 class SSPILibraryDefault : public SSPILibrary {
71  public:
72   SSPILibraryDefault() {}
73   virtual ~SSPILibraryDefault() {}
74
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);
88   }
89
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);
106   }
107
108   virtual SECURITY_STATUS QuerySecurityPackageInfo(LPWSTR pszPackageName,
109                                                    PSecPkgInfoW *pkgInfo) {
110     return ::QuerySecurityPackageInfo(pszPackageName, pkgInfo);
111   }
112
113   virtual SECURITY_STATUS FreeCredentialsHandle(PCredHandle phCredential) {
114     return ::FreeCredentialsHandle(phCredential);
115   }
116
117   virtual SECURITY_STATUS DeleteSecurityContext(PCtxtHandle phContext) {
118     return ::DeleteSecurityContext(phContext);
119   }
120
121   virtual SECURITY_STATUS FreeContextBuffer(PVOID pvContextBuffer) {
122     return ::FreeContextBuffer(pvContextBuffer);
123   }
124 };
125
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();
133
134   bool NeedsIdentity() const;
135
136   bool AllowsExplicitCredentials() const;
137
138   HttpAuth::AuthorizationResult ParseChallenge(
139       HttpAuthChallengeTokenizer* tok);
140
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);
151
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();
156
157  private:
158   int OnFirstRound(const AuthCredentials* credentials);
159
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);
166
167   void ResetSecurityContext();
168
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_;
177 };
178
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);
188
189 // Determines the maximum token length in bytes for a particular SSPI package.
190 //
191 // |library| and |max_token_length| must be non-NULL pointers to valid objects.
192 //
193 // If the return value is OK, |*max_token_length| contains the maximum token
194 // length in bytes.
195 //
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.
199 //
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);
206
207 }  // namespace net
208
209 #endif  // NET_HTTP_HTTP_AUTH_SSPI_WIN_H_