secur32: Use opaque type schan_imp_session in schan_imp interface.
[wine] / dlls / secur32 / negotiate.c
1 /*
2  * Copyright 2005 Kai Blin
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  *
18  * This file implements the negotiate provider.
19  * FIXME: So far, this beast doesn't do anything.
20  */
21 #include <assert.h>
22 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "sspi.h"
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
30
31 /* Disable for now, see longer comment for SECUR32_initNegotiateSP below */
32 #if 0
33 static char nego_name_A[] = "Negotiate";
34 static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0};
35 #endif
36
37 static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential,
38         ULONG ulAttribute, PVOID pBuffer)
39 {
40     SECURITY_STATUS ret;
41
42     /* FIXME: More attributes to be added here. Need to fix the sspi.h header
43      * for that, too.
44      */
45     switch(ulAttribute)
46     {
47         default:
48             ret = SEC_E_UNSUPPORTED_FUNCTION;
49     }
50     return ret;
51 }
52
53 /***********************************************************************
54  *              QueryCredentialsAttributesA
55  */
56 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
57         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
58 {
59     SECURITY_STATUS ret;
60
61     TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
62
63     switch(ulAttribute)
64     {
65         case SECPKG_CRED_ATTR_NAMES:
66             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
67             ret = SEC_E_UNSUPPORTED_FUNCTION;
68             break;
69         default:
70             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
71                     pBuffer);
72     }
73     return ret;
74 }
75
76 /***********************************************************************
77  *              QueryCredentialsAttributesW
78  */
79 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
80         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
81 {
82     SECURITY_STATUS ret;
83
84     TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
85
86     switch(ulAttribute)
87     {
88         case SECPKG_CRED_ATTR_NAMES:
89             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
90             ret = SEC_E_UNSUPPORTED_FUNCTION;
91             break;
92         default:
93             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
94                     pBuffer);
95     }
96     return ret;
97 }
98
99
100 /***********************************************************************
101  *              AcquireCredentialsHandleA
102  */
103 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
104  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
105  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
106  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
107 {
108     TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n",
109      debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
110      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
111     return SEC_E_UNSUPPORTED_FUNCTION;
112 }
113
114 /***********************************************************************
115  *              AcquireCredentialsHandleW
116  */
117 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
118  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
119  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
120  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
121 {
122     TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n",
123      debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
124      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
125     return SEC_E_UNSUPPORTED_FUNCTION;
126 }
127
128 /***********************************************************************
129  *              InitializeSecurityContextA
130  */
131 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
132  PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, 
133  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
134  PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, 
135  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
136 {
137     SECURITY_STATUS ret;
138
139     TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext,
140      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
141      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
142     if(phCredential){
143         ret = SEC_E_UNSUPPORTED_FUNCTION;
144     }
145     else
146     {
147         ret = SEC_E_INVALID_HANDLE;
148     }
149     return ret;
150 }
151
152 /***********************************************************************
153  *              InitializeSecurityContextW
154  */
155 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
156  PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
157  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
158  PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, 
159  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
160 {
161     SECURITY_STATUS ret;
162
163     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
164      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
165      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
166     if (phCredential)
167     {
168         ret = SEC_E_UNSUPPORTED_FUNCTION;
169     }
170     else
171     {
172         ret = SEC_E_INVALID_HANDLE;
173     }
174     return ret;
175 }
176
177 /***********************************************************************
178  *              AcceptSecurityContext
179  */
180 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
181  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
182  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, 
183  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
184 {
185     SECURITY_STATUS ret;
186
187     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
188      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
189      ptsExpiry);
190     if (phCredential)
191     {
192         ret = SEC_E_UNSUPPORTED_FUNCTION;
193     }
194     else
195     {
196         ret = SEC_E_INVALID_HANDLE;
197     }
198     return ret;
199 }
200
201 /***********************************************************************
202  *              CompleteAuthToken
203  */
204 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
205  PSecBufferDesc pToken)
206 {
207     SECURITY_STATUS ret;
208
209     TRACE("%p %p\n", phContext, pToken);
210     if (phContext)
211     {
212         ret = SEC_E_UNSUPPORTED_FUNCTION;
213     }
214     else
215     {
216         ret = SEC_E_INVALID_HANDLE;
217     }
218     return ret;
219 }
220
221 /***********************************************************************
222  *              DeleteSecurityContext
223  */
224 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
225 {
226     SECURITY_STATUS ret;
227
228     TRACE("%p\n", phContext);
229     if (phContext)
230     {
231         ret = SEC_E_UNSUPPORTED_FUNCTION;
232     }
233     else
234     {
235         ret = SEC_E_INVALID_HANDLE;
236     }
237     return ret;
238 }
239
240 /***********************************************************************
241  *              ApplyControlToken
242  */
243 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
244  PSecBufferDesc pInput)
245 {
246     SECURITY_STATUS ret;
247
248     TRACE("%p %p\n", phContext, pInput);
249     if (phContext)
250     {
251         ret = SEC_E_UNSUPPORTED_FUNCTION;
252     }
253     else
254     {
255         ret = SEC_E_INVALID_HANDLE;
256     }
257     return ret;
258 }
259
260 /***********************************************************************
261  *              QueryContextAttributesW
262  */
263 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext,
264  ULONG ulAttribute, void *pBuffer)
265 {
266     SECURITY_STATUS ret;
267
268     /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
269      * the SecurePackage part and the dwLower part is the actual context 
270      * handle. It should be easy to extract the context attributes from that.
271      */
272     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
273     if (phContext)
274     {
275         ret = SEC_E_UNSUPPORTED_FUNCTION;
276     }
277     else
278     {
279         ret = SEC_E_INVALID_HANDLE;
280     }
281     return ret;
282 }
283
284 /***********************************************************************
285  *              QueryContextAttributesA
286  */
287 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
288  ULONG ulAttribute, void *pBuffer)
289 {
290     return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
291 }
292
293 /***********************************************************************
294  *              ImpersonateSecurityContext
295  */
296 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
297 {
298     SECURITY_STATUS ret;
299
300     TRACE("%p\n", phContext);
301     if (phContext)
302     {
303         ret = SEC_E_UNSUPPORTED_FUNCTION;
304     }
305     else
306     {
307         ret = SEC_E_INVALID_HANDLE;
308     }
309     return ret;
310 }
311
312 /***********************************************************************
313  *              RevertSecurityContext
314  */
315 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
316 {
317     SECURITY_STATUS ret;
318
319     TRACE("%p\n", phContext);
320     if (phContext)
321     {
322         ret = SEC_E_UNSUPPORTED_FUNCTION;
323     }
324     else
325     {
326         ret = SEC_E_INVALID_HANDLE;
327     }
328     return ret;
329 }
330
331 /***********************************************************************
332  *              MakeSignature
333  */
334 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
335  PSecBufferDesc pMessage, ULONG MessageSeqNo)
336 {
337     SECURITY_STATUS ret;
338
339     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
340     if (phContext)
341     {
342         ret = SEC_E_UNSUPPORTED_FUNCTION;
343     }
344     else
345     {
346         ret = SEC_E_INVALID_HANDLE;
347     }
348     return ret;
349 }
350
351 /***********************************************************************
352  *              VerifySignature
353  */
354 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
355  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
356 {
357     SECURITY_STATUS ret;
358
359     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
360     if (phContext)
361     {
362         ret = SEC_E_UNSUPPORTED_FUNCTION;
363     }
364     else
365     {
366         ret = SEC_E_INVALID_HANDLE;
367     }
368     return ret;
369 }
370
371
372
373 static const SecurityFunctionTableA negoTableA = {
374     1,
375     NULL,   /* EnumerateSecurityPackagesA */
376     nego_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
377     nego_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
378     FreeCredentialsHandle,              /* FreeCredentialsHandle */
379     NULL,   /* Reserved2 */
380     nego_InitializeSecurityContextA,    /* InitializeSecurityContextA */
381     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
382     nego_CompleteAuthToken,             /* CompleteAuthToken */
383     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
384     nego_ApplyControlToken,             /* ApplyControlToken */
385     nego_QueryContextAttributesA,       /* QueryContextAttributesA */
386     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
387     nego_RevertSecurityContext,         /* RevertSecurityContext */
388     nego_MakeSignature,                 /* MakeSignature */
389     nego_VerifySignature,               /* VerifySignature */
390     FreeContextBuffer,                  /* FreeContextBuffer */
391     NULL,   /* QuerySecurityPackageInfoA */
392     NULL,   /* Reserved3 */
393     NULL,   /* Reserved4 */
394     NULL,   /* ExportSecurityContext */
395     NULL,   /* ImportSecurityContextA */
396     NULL,   /* AddCredentialsA */
397     NULL,   /* Reserved8 */
398     NULL,   /* QuerySecurityContextToken */
399     NULL,   /* EncryptMessage */
400     NULL,   /* DecryptMessage */
401     NULL,   /* SetContextAttributesA */
402 };
403
404 static const SecurityFunctionTableW negoTableW = {
405     1,
406     NULL,   /* EnumerateSecurityPackagesW */
407     nego_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
408     nego_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
409     FreeCredentialsHandle,              /* FreeCredentialsHandle */
410     NULL,   /* Reserved2 */
411     nego_InitializeSecurityContextW,    /* InitializeSecurityContextW */
412     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
413     nego_CompleteAuthToken,             /* CompleteAuthToken */
414     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
415     nego_ApplyControlToken,             /* ApplyControlToken */
416     nego_QueryContextAttributesW,       /* QueryContextAttributesW */
417     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
418     nego_RevertSecurityContext,         /* RevertSecurityContext */
419     nego_MakeSignature,                 /* MakeSignature */
420     nego_VerifySignature,               /* VerifySignature */
421     FreeContextBuffer,                  /* FreeContextBuffer */
422     NULL,   /* QuerySecurityPackageInfoW */
423     NULL,   /* Reserved3 */
424     NULL,   /* Reserved4 */
425     NULL,   /* ExportSecurityContext */
426     NULL,   /* ImportSecurityContextW */
427     NULL,   /* AddCredentialsW */
428     NULL,   /* Reserved8 */
429     NULL,   /* QuerySecurityContextToken */
430     NULL,   /* EncryptMessage */
431     NULL,   /* DecryptMessage */
432     NULL,   /* SetContextAttributesW */
433 };
434
435 /* Disable for now, see comment below.*/
436 #if 0
437 static WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o',
438     'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o',
439     't', 'i', 'a', 't', 'o', 'r', 0};
440
441 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
442 #endif
443
444
445 void SECUR32_initNegotiateSP(void)
446 {
447 /* Disable until we really implement a Negotiate provider.
448  * For now, the NTLM provider will pretend to be the Negotiate provider as well.
449  * Windows seems to be able to deal with it, and it makes several programs
450  * happy. */
451 #if 0
452     SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
453             NULL);
454     /* According to Windows, Negotiate has the following capabilities. 
455      */
456     
457     static const LONG caps = 
458         SECPKG_FLAG_INTEGRITY |
459             SECPKG_FLAG_PRIVACY |
460             SECPKG_FLAG_CONNECTION |
461         SECPKG_FLAG_MULTI_REQUIRED |
462             SECPKG_FLAG_EXTENDED_ERROR |
463             SECPKG_FLAG_IMPERSONATION |
464             SECPKG_FLAG_ACCEPT_WIN32_NAME |
465             SECPKG_FLAG_READONLY_WITH_CHECKSUM;
466
467     static const USHORT version = 1;
468     static const USHORT rpcid = 15;
469     static const ULONG  max_token = 12000;
470     const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W,
471         negotiate_comment_W};
472     const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A,
473         negotiate_comment_A};
474
475     SECUR32_addPackages(provider, 1L, &infoA, &infoW);
476 #endif
477 }