secur32: Output extra data in NTLM sign & seal test to diagnose failures seen on...
[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 static char nego_name_A[] = "Negotiate";
32 static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0};
33
34 static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential,
35         ULONG ulAttribute, PVOID pBuffer)
36 {
37     SECURITY_STATUS ret;
38
39     /* FIXME: More attributes to be added here. Need to fix the sspi.h header
40      * for that, too.
41      */
42     switch(ulAttribute)
43     {
44         default:
45             ret = SEC_E_UNSUPPORTED_FUNCTION;
46     }
47     return ret;
48 }
49
50 /***********************************************************************
51  *              QueryCredentialsAttributesA
52  */
53 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
54         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
55 {
56     SECURITY_STATUS ret;
57
58     TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
59
60     switch(ulAttribute)
61     {
62         case SECPKG_CRED_ATTR_NAMES:
63             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
64             ret = SEC_E_UNSUPPORTED_FUNCTION;
65             break;
66         default:
67             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
68                     pBuffer);
69     }
70     return ret;
71 }
72
73 /***********************************************************************
74  *              QueryCredentialsAttributesW
75  */
76 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
77         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
78 {
79     SECURITY_STATUS ret;
80
81     TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
82
83     switch(ulAttribute)
84     {
85         case SECPKG_CRED_ATTR_NAMES:
86             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
87             ret = SEC_E_UNSUPPORTED_FUNCTION;
88             break;
89         default:
90             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
91                     pBuffer);
92     }
93     return ret;
94 }
95
96
97 /***********************************************************************
98  *              AcquireCredentialsHandleA
99  */
100 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
101  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
102  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
103  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
104 {
105     TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n",
106      debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
107      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
108     return SEC_E_UNSUPPORTED_FUNCTION;
109 }
110
111 /***********************************************************************
112  *              AcquireCredentialsHandleW
113  */
114 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
115  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
116  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
117  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
118 {
119     TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n",
120      debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
121      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
122     return SEC_E_UNSUPPORTED_FUNCTION;
123 }
124
125 /***********************************************************************
126  *              InitializeSecurityContextA
127  */
128 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
129  PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, 
130  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
131  PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, 
132  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
133 {
134     SECURITY_STATUS ret;
135
136     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
137      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
138      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
139     if(phCredential){
140         ret = SEC_E_UNSUPPORTED_FUNCTION;
141     }
142     else
143     {
144         ret = SEC_E_INVALID_HANDLE;
145     }
146     return ret;
147 }
148
149 /***********************************************************************
150  *              InitializeSecurityContextW
151  */
152 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
153  PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
154  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
155  PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, 
156  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
157 {
158     SECURITY_STATUS ret;
159
160     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
161      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
162      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
163     if (phCredential)
164     {
165         ret = SEC_E_UNSUPPORTED_FUNCTION;
166     }
167     else
168     {
169         ret = SEC_E_INVALID_HANDLE;
170     }
171     return ret;
172 }
173
174 /***********************************************************************
175  *              AcceptSecurityContext
176  */
177 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
178  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
179  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, 
180  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
181 {
182     SECURITY_STATUS ret;
183
184     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
185      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
186      ptsExpiry);
187     if (phCredential)
188     {
189         ret = SEC_E_UNSUPPORTED_FUNCTION;
190     }
191     else
192     {
193         ret = SEC_E_INVALID_HANDLE;
194     }
195     return ret;
196 }
197
198 /***********************************************************************
199  *              CompleteAuthToken
200  */
201 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
202  PSecBufferDesc pToken)
203 {
204     SECURITY_STATUS ret;
205
206     TRACE("%p %p\n", phContext, pToken);
207     if (phContext)
208     {
209         ret = SEC_E_UNSUPPORTED_FUNCTION;
210     }
211     else
212     {
213         ret = SEC_E_INVALID_HANDLE;
214     }
215     return ret;
216 }
217
218 /***********************************************************************
219  *              DeleteSecurityContext
220  */
221 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
222 {
223     SECURITY_STATUS ret;
224
225     TRACE("%p\n", phContext);
226     if (phContext)
227     {
228         ret = SEC_E_UNSUPPORTED_FUNCTION;
229     }
230     else
231     {
232         ret = SEC_E_INVALID_HANDLE;
233     }
234     return ret;
235 }
236
237 /***********************************************************************
238  *              ApplyControlToken
239  */
240 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
241  PSecBufferDesc pInput)
242 {
243     SECURITY_STATUS ret;
244
245     TRACE("%p %p\n", phContext, pInput);
246     if (phContext)
247     {
248         ret = SEC_E_UNSUPPORTED_FUNCTION;
249     }
250     else
251     {
252         ret = SEC_E_INVALID_HANDLE;
253     }
254     return ret;
255 }
256
257 /***********************************************************************
258  *              QueryContextAttributesW
259  */
260 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext,
261  ULONG ulAttribute, void *pBuffer)
262 {
263     SECURITY_STATUS ret;
264
265     /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
266      * the SecurePackage part and the dwLower part is the actual context 
267      * handle. It should be easy to extract the context attributes from that.
268      */
269     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
270     if (phContext)
271     {
272         ret = SEC_E_UNSUPPORTED_FUNCTION;
273     }
274     else
275     {
276         ret = SEC_E_INVALID_HANDLE;
277     }
278     return ret;
279 }
280
281 /***********************************************************************
282  *              QueryContextAttributesA
283  */
284 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
285  ULONG ulAttribute, void *pBuffer)
286 {
287     return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
288 }
289
290 /***********************************************************************
291  *              ImpersonateSecurityContext
292  */
293 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
294 {
295     SECURITY_STATUS ret;
296
297     TRACE("%p\n", phContext);
298     if (phContext)
299     {
300         ret = SEC_E_UNSUPPORTED_FUNCTION;
301     }
302     else
303     {
304         ret = SEC_E_INVALID_HANDLE;
305     }
306     return ret;
307 }
308
309 /***********************************************************************
310  *              RevertSecurityContext
311  */
312 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
313 {
314     SECURITY_STATUS ret;
315
316     TRACE("%p\n", phContext);
317     if (phContext)
318     {
319         ret = SEC_E_UNSUPPORTED_FUNCTION;
320     }
321     else
322     {
323         ret = SEC_E_INVALID_HANDLE;
324     }
325     return ret;
326 }
327
328 /***********************************************************************
329  *              MakeSignature
330  */
331 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
332  PSecBufferDesc pMessage, ULONG MessageSeqNo)
333 {
334     SECURITY_STATUS ret;
335
336     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
337     if (phContext)
338     {
339         ret = SEC_E_UNSUPPORTED_FUNCTION;
340     }
341     else
342     {
343         ret = SEC_E_INVALID_HANDLE;
344     }
345     return ret;
346 }
347
348 /***********************************************************************
349  *              VerifySignature
350  */
351 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
352  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
353 {
354     SECURITY_STATUS ret;
355
356     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
357     if (phContext)
358     {
359         ret = SEC_E_UNSUPPORTED_FUNCTION;
360     }
361     else
362     {
363         ret = SEC_E_INVALID_HANDLE;
364     }
365     return ret;
366 }
367
368
369
370 static const SecurityFunctionTableA negoTableA = {
371     1,
372     NULL,   /* EnumerateSecurityPackagesA */
373     nego_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
374     nego_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
375     FreeCredentialsHandle,              /* FreeCredentialsHandle */
376     NULL,   /* Reserved2 */
377     nego_InitializeSecurityContextA,    /* InitializeSecurityContextA */
378     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
379     nego_CompleteAuthToken,             /* CompleteAuthToken */
380     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
381     nego_ApplyControlToken,             /* ApplyControlToken */
382     nego_QueryContextAttributesA,       /* QueryContextAttributesA */
383     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
384     nego_RevertSecurityContext,         /* RevertSecurityContext */
385     nego_MakeSignature,                 /* MakeSignature */
386     nego_VerifySignature,               /* VerifySignature */
387     FreeContextBuffer,                  /* FreeContextBuffer */
388     NULL,   /* QuerySecurityPackageInfoA */
389     NULL,   /* Reserved3 */
390     NULL,   /* Reserved4 */
391     NULL,   /* ExportSecurityContext */
392     NULL,   /* ImportSecurityContextA */
393     NULL,   /* AddCredentialsA */
394     NULL,   /* Reserved8 */
395     NULL,   /* QuerySecurityContextToken */
396     NULL,   /* EncryptMessage */
397     NULL,   /* DecryptMessage */
398     NULL,   /* SetContextAttributesA */
399 };
400
401 static const SecurityFunctionTableW negoTableW = {
402     1,
403     NULL,   /* EnumerateSecurityPackagesW */
404     nego_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
405     nego_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
406     FreeCredentialsHandle,              /* FreeCredentialsHandle */
407     NULL,   /* Reserved2 */
408     nego_InitializeSecurityContextW,    /* InitializeSecurityContextW */
409     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
410     nego_CompleteAuthToken,             /* CompleteAuthToken */
411     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
412     nego_ApplyControlToken,             /* ApplyControlToken */
413     nego_QueryContextAttributesW,       /* QueryContextAttributesW */
414     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
415     nego_RevertSecurityContext,         /* RevertSecurityContext */
416     nego_MakeSignature,                 /* MakeSignature */
417     nego_VerifySignature,               /* VerifySignature */
418     FreeContextBuffer,                  /* FreeContextBuffer */
419     NULL,   /* QuerySecurityPackageInfoW */
420     NULL,   /* Reserved3 */
421     NULL,   /* Reserved4 */
422     NULL,   /* ExportSecurityContext */
423     NULL,   /* ImportSecurityContextW */
424     NULL,   /* AddCredentialsW */
425     NULL,   /* Reserved8 */
426     NULL,   /* QuerySecurityContextToken */
427     NULL,   /* EncryptMessage */
428     NULL,   /* DecryptMessage */
429     NULL,   /* SetContextAttributesW */
430 };
431
432 static WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o',
433     'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o',
434     't', 'i', 'a', 't', 'o', 'r', 0};
435
436 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
437
438
439
440 void SECUR32_initNegotiateSP(void)
441 {
442     SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
443             NULL);
444     /* According to Windows, Negotiate has the following capabilities. 
445      */
446     
447     static const LONG caps = 
448         SECPKG_FLAG_INTEGRITY |
449             SECPKG_FLAG_PRIVACY |
450             SECPKG_FLAG_CONNECTION |
451         SECPKG_FLAG_MULTI_REQUIRED |
452             SECPKG_FLAG_EXTENDED_ERROR |
453             SECPKG_FLAG_IMPERSONATION |
454             SECPKG_FLAG_ACCEPT_WIN32_NAME |
455             SECPKG_FLAG_READONLY_WITH_CHECKSUM;
456
457     static const USHORT version = 1;
458     static const USHORT rpcid = 15;
459     static const ULONG  max_token = 12000;
460     const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W,
461         negotiate_comment_W};
462     const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A,
463         negotiate_comment_A};
464
465     SECUR32_addPackages(provider, 1L, &infoA, &infoW);        
466 }