crypt32: Implement file stores.
[wine] / dlls / secur32 / schannel.c
1 /* Copyright (C) 2005 Juan Lang
2  *
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2.1 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  *
17  * This file implements the schannel provider, or, the SSL/TLS implementations.
18  * FIXME: It should be rather obvious that this file is empty of any
19  * implementation.
20  */
21 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "sspi.h"
25 #include "schannel.h"
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
30
31 static SECURITY_STATUS schan_QueryCredentialsAttributes(
32  PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
33 {
34     SECURITY_STATUS ret;
35
36     switch (ulAttribute)
37     {
38     case SECPKG_ATTR_SUPPORTED_ALGS:
39         if (pBuffer)
40         {
41             /* FIXME: get from CryptoAPI */
42             FIXME("%ld: stub\n", ulAttribute);
43             ret = SEC_E_UNSUPPORTED_FUNCTION;
44         }
45         else
46             ret = SEC_E_INTERNAL_ERROR;
47         break;
48     case SECPKG_ATTR_CIPHER_STRENGTHS:
49         if (pBuffer)
50         {
51             /* FIXME: get from CryptoAPI */
52             FIXME("%ld: stub\n", ulAttribute);
53             ret = SEC_E_UNSUPPORTED_FUNCTION;
54         }
55         else
56             ret = SEC_E_INTERNAL_ERROR;
57         break;
58     case SECPKG_ATTR_SUPPORTED_PROTOCOLS:
59         if (pBuffer)
60         {
61             /* FIXME: get from OpenSSL? */
62             FIXME("%ld: stub\n", ulAttribute);
63             ret = SEC_E_UNSUPPORTED_FUNCTION;
64         }
65         else
66             ret = SEC_E_INTERNAL_ERROR;
67         break;
68     default:
69         ret = SEC_E_UNSUPPORTED_FUNCTION;
70     }
71     return ret;
72 }
73
74 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesA(
75  PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
76 {
77     SECURITY_STATUS ret;
78
79     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
80
81     switch (ulAttribute)
82     {
83     case SECPKG_CRED_ATTR_NAMES:
84         FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
85         ret = SEC_E_UNSUPPORTED_FUNCTION;
86         break;
87     default:
88         ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
89          pBuffer);
90     }
91     return ret;
92 }
93
94 static SECURITY_STATUS SEC_ENTRY schan_QueryCredentialsAttributesW(
95  PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
96 {
97     SECURITY_STATUS ret;
98
99     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
100
101     switch (ulAttribute)
102     {
103     case SECPKG_CRED_ATTR_NAMES:
104         FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
105         ret = SEC_E_UNSUPPORTED_FUNCTION;
106         break;
107     default:
108         ret = schan_QueryCredentialsAttributes(phCredential, ulAttribute,
109          pBuffer);
110     }
111     return ret;
112 }
113
114 static SECURITY_STATUS schan_AcquireCredentialsHandle(ULONG fCredentialUse,
115  PCredHandle phCredential, PTimeStamp ptsExpiry)
116 {
117     SECURITY_STATUS ret;
118
119     if (fCredentialUse == SECPKG_CRED_BOTH)
120         ret = SEC_E_NO_CREDENTIALS;
121     else
122     {
123         /* For now, the only thing I'm interested in is the direction of the
124          * connection, so just store it.
125          */
126         phCredential->dwUpper = fCredentialUse;
127         /* According to MSDN, all versions prior to XP do this */
128         if (ptsExpiry)
129         {
130             ptsExpiry->LowPart = 0;
131             ptsExpiry->HighPart = 0;
132         }
133         ret = SEC_E_OK;
134     }
135     return ret;
136 }
137
138 static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleA(
139  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
140  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
141  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
142 {
143     TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
144      debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
145      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
146     return schan_AcquireCredentialsHandle(fCredentialUse, phCredential,
147      ptsExpiry);
148 }
149
150 static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleW(
151  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
152  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
153  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
154 {
155     TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
156      debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
157      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
158     return schan_AcquireCredentialsHandle(fCredentialUse, phCredential,
159      ptsExpiry);
160 }
161
162 /***********************************************************************
163  *              InitializeSecurityContextA
164  */
165 static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextA(
166  PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
167  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
168  PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
169  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
170 {
171     SECURITY_STATUS ret;
172
173     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
174      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
175      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
176     if(phCredential){
177         ret = SEC_E_UNSUPPORTED_FUNCTION;
178     }
179     else
180     {
181         ret = SEC_E_INVALID_HANDLE;
182     }
183     return ret;
184 }
185
186 /***********************************************************************
187  *              InitializeSecurityContextW
188  */
189 static SECURITY_STATUS SEC_ENTRY schan_InitializeSecurityContextW(
190  PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
191  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
192  PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext,
193  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
194 {
195     SECURITY_STATUS ret;
196
197     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
198      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
199      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
200     if (phCredential)
201     {
202         ret = SEC_E_UNSUPPORTED_FUNCTION;
203     }
204     else
205     {
206         ret = SEC_E_INVALID_HANDLE;
207     }
208     return ret;
209 }
210
211 static SecurityFunctionTableA schanTableA = {
212     1,
213     NULL, /* EnumerateSecurityPackagesA */
214     schan_QueryCredentialsAttributesA,
215     schan_AcquireCredentialsHandleA,
216     NULL, /* FreeCredentialsHandle */
217     NULL, /* Reserved2 */
218     schan_InitializeSecurityContextA, 
219     NULL, /* AcceptSecurityContext */
220     NULL, /* CompleteAuthToken */
221     NULL, /* DeleteSecurityContext */
222     NULL, /* ApplyControlToken */
223     NULL, /* QueryContextAttributesA */
224     NULL, /* ImpersonateSecurityContext */
225     NULL, /* RevertSecurityContext */
226     NULL, /* MakeSignature */
227     NULL, /* VerifySignature */
228     FreeContextBuffer,
229     NULL, /* QuerySecurityPackageInfoA */
230     NULL, /* Reserved3 */
231     NULL, /* Reserved4 */
232     NULL, /* ExportSecurityContext */
233     NULL, /* ImportSecurityContextA */
234     NULL, /* AddCredentialsA */
235     NULL, /* Reserved8 */
236     NULL, /* QuerySecurityContextToken */
237     NULL, /* EncryptMessage */
238     NULL, /* DecryptMessage */
239     NULL, /* SetContextAttributesA */
240 };
241
242 static SecurityFunctionTableW schanTableW = {
243     1,
244     NULL, /* EnumerateSecurityPackagesW */
245     schan_QueryCredentialsAttributesW,
246     schan_AcquireCredentialsHandleW,
247     NULL, /* FreeCredentialsHandle */
248     NULL, /* Reserved2 */
249     schan_InitializeSecurityContextW, 
250     NULL, /* AcceptSecurityContext */
251     NULL, /* CompleteAuthToken */
252     NULL, /* DeleteSecurityContext */
253     NULL, /* ApplyControlToken */
254     NULL, /* QueryContextAttributesW */
255     NULL, /* ImpersonateSecurityContext */
256     NULL, /* RevertSecurityContext */
257     NULL, /* MakeSignature */
258     NULL, /* VerifySignature */
259     FreeContextBuffer,
260     NULL, /* QuerySecurityPackageInfoW */
261     NULL, /* Reserved3 */
262     NULL, /* Reserved4 */
263     NULL, /* ExportSecurityContext */
264     NULL, /* ImportSecurityContextW */
265     NULL, /* AddCredentialsW */
266     NULL, /* Reserved8 */
267     NULL, /* QuerySecurityContextToken */
268     NULL, /* EncryptMessage */
269     NULL, /* DecryptMessage */
270     NULL, /* SetContextAttributesW */
271 };
272
273 static const WCHAR schannelComment[] = { 'S','c','h','a','n','n','e','l',' ',
274  'S','e','c','u','r','i','t','y',' ','P','a','c','k','a','g','e',0 };
275
276 void SECUR32_initSchannelSP(void)
277 {
278     SecureProvider *provider = SECUR32_addProvider(&schanTableA, &schanTableW,
279      NULL);
280
281     if (provider)
282     {
283         /* This is what Windows reports.  This shouldn't break any applications
284          * even though the functions are missing, because the wrapper will
285          * return SEC_E_UNSUPPORTED_FUNCTION if our function is NULL.
286          */
287         static const long caps =
288          SECPKG_FLAG_INTEGRITY |
289          SECPKG_FLAG_PRIVACY |
290          SECPKG_FLAG_CONNECTION |
291          SECPKG_FLAG_MULTI_REQUIRED |
292          SECPKG_FLAG_EXTENDED_ERROR |
293          SECPKG_FLAG_IMPERSONATION |
294          SECPKG_FLAG_ACCEPT_WIN32_NAME |
295          SECPKG_FLAG_STREAM;
296         static const short version = 1;
297         static const long maxToken = 16384;
298         SEC_WCHAR *uniSPName = (SEC_WCHAR *)UNISP_NAME_W,
299          *schannel = (SEC_WCHAR *)SCHANNEL_NAME_W;
300
301         const SecPkgInfoW info[] = {
302          { caps, version, UNISP_RPC_ID, maxToken, uniSPName, uniSPName },
303          { caps, version, UNISP_RPC_ID, maxToken, schannel,
304           (SEC_WCHAR *)schannelComment },
305         };
306
307         SECUR32_addPackages(provider, sizeof(info) / sizeof(info[0]), NULL,
308          info);
309     }
310 }