xref: /reactos/dll/win32/secur32/wrapper.c (revision 845faec4)
1 /* Copyright (C) 2004 Juan Lang
2  *
3  * Implements secur32 functions that forward to (wrap) an SSP's implementation.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 #include "precomp.h"
20 
21 #include "wine/debug.h"
22 
23 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
24 
25 /* Tries to allocate a new SecHandle, into which it stores package (in
26  * phSec->dwUpper) and a copy of realHandle (allocated with SECUR32_ALLOC,
27  * and stored in phSec->dwLower).  SecHandle is equivalent to both a
28  * CredHandle and a CtxtHandle.
29  */
30 static SECURITY_STATUS SECUR32_makeSecHandle(PSecHandle phSec,
31  SecurePackage *package, PSecHandle realHandle)
32 {
33     SECURITY_STATUS ret;
34 
35     TRACE("%p %p %p\n", phSec, package, realHandle);
36 
37     if (phSec && package && realHandle)
38     {
39         PSecHandle newSec = HeapAlloc(GetProcessHeap(), 0, sizeof(SecHandle));
40 
41         if (newSec)
42         {
43             *newSec = *realHandle;
44             phSec->dwUpper = (ULONG_PTR)package;
45             phSec->dwLower = (ULONG_PTR)newSec;
46             ret = SEC_E_OK;
47         }
48         else
49             ret = SEC_E_INSUFFICIENT_MEMORY;
50     }
51     else
52         ret = SEC_E_INVALID_HANDLE;
53     return ret;
54 }
55 
56 /***********************************************************************
57  *		AcquireCredentialsHandleA (SECUR32.@)
58  */
59 SECURITY_STATUS WINAPI AcquireCredentialsHandleA(
60  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
61  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
62  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
63 {
64     SECURITY_STATUS ret;
65 
66     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
67      debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
68      pvGetKeyArgument, phCredential, ptsExpiry);
69     if (pszPackage)
70     {
71         SecurePackage *package = SECUR32_findPackageA(pszPackage);
72 
73         if (package && package->provider)
74         {
75             if (package->provider->fnTableA.AcquireCredentialsHandleA)
76             {
77                 CredHandle myCred;
78 
79                 ret = package->provider->fnTableA.AcquireCredentialsHandleA(
80                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
81                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
82                  ptsExpiry);
83                 if (ret == SEC_E_OK)
84                 {
85                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
86                     if (ret != SEC_E_OK)
87                         package->provider->fnTableW.FreeCredentialsHandle(
88                          &myCred);
89                 }
90             }
91             else
92                 ret = SEC_E_UNSUPPORTED_FUNCTION;
93         }
94         else
95             ret = SEC_E_SECPKG_NOT_FOUND;
96     }
97     else
98         ret = SEC_E_SECPKG_NOT_FOUND;
99     return ret;
100 }
101 
102 /***********************************************************************
103  *		AcquireCredentialsHandleW (SECUR32.@)
104  */
105 SECURITY_STATUS WINAPI AcquireCredentialsHandleW(
106  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
107  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
108  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
109 {
110     SECURITY_STATUS ret;
111 
112     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
113      debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
114      pvGetKeyArgument, phCredential, ptsExpiry);
115     if (pszPackage)
116     {
117         SecurePackage *package = SECUR32_findPackageW(pszPackage);
118 
119         if (package && package->provider)
120         {
121             if (package->provider->fnTableW.AcquireCredentialsHandleW)
122             {
123                 CredHandle myCred;
124 
125                 ret = package->provider->fnTableW.AcquireCredentialsHandleW(
126                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
127                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
128                  ptsExpiry);
129                 if (ret == SEC_E_OK)
130                 {
131                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
132                     if (ret != SEC_E_OK)
133                         package->provider->fnTableW.FreeCredentialsHandle(
134                          &myCred);
135                 }
136             }
137             else
138                 ret = SEC_E_UNSUPPORTED_FUNCTION;
139         }
140         else
141             ret = SEC_E_SECPKG_NOT_FOUND;
142     }
143     else
144         ret = SEC_E_SECPKG_NOT_FOUND;
145     return ret;
146 }
147 
148 /***********************************************************************
149  *		FreeCredentialsHandle (SECUR32.@)
150  */
151 SECURITY_STATUS WINAPI FreeCredentialsHandle(
152  PCredHandle phCredential)
153 {
154     SECURITY_STATUS ret;
155 
156     TRACE("%p\n", phCredential);
157     if (phCredential)
158     {
159         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
160         PCredHandle cred = (PCredHandle)phCredential->dwLower;
161 
162         if (package && package->provider &&
163          package->provider->fnTableW.FreeCredentialsHandle)
164             ret = package->provider->fnTableW.FreeCredentialsHandle(cred);
165         else
166             ret = SEC_E_INVALID_HANDLE;
167         HeapFree(GetProcessHeap(), 0, cred);
168     }
169     else
170         ret = SEC_E_INVALID_HANDLE;
171     return ret;
172 }
173 
174 /***********************************************************************
175  *		QueryCredentialsAttributesA (SECUR32.@)
176  */
177 SECURITY_STATUS WINAPI QueryCredentialsAttributesA(
178  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
179 {
180     SECURITY_STATUS ret;
181 
182     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
183     if (phCredential)
184     {
185         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
186         PCredHandle cred = (PCredHandle)phCredential->dwLower;
187 
188         if (package && package->provider)
189         {
190             if (package->provider->fnTableA.QueryCredentialsAttributesA)
191                 ret = package->provider->fnTableA.QueryCredentialsAttributesA(
192                  cred, ulAttribute, pBuffer);
193             else
194                 ret = SEC_E_UNSUPPORTED_FUNCTION;
195         }
196         else
197             ret = SEC_E_INVALID_HANDLE;
198     }
199     else
200         ret = SEC_E_INVALID_HANDLE;
201     return ret;
202 }
203 
204 /***********************************************************************
205  *		QueryCredentialsAttributesW (SECUR32.@)
206  */
207 SECURITY_STATUS WINAPI QueryCredentialsAttributesW(
208  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
209 {
210     SECURITY_STATUS ret;
211 
212     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
213     if (phCredential)
214     {
215         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
216         PCredHandle cred = (PCredHandle)phCredential->dwLower;
217 
218         if (package && package->provider)
219         {
220             if (package->provider->fnTableW.QueryCredentialsAttributesW)
221                 ret = package->provider->fnTableW.QueryCredentialsAttributesW(
222                  cred, ulAttribute, pBuffer);
223             else
224                 ret = SEC_E_UNSUPPORTED_FUNCTION;
225         }
226         else
227             ret = SEC_E_INVALID_HANDLE;
228     }
229     else
230         ret = SEC_E_INVALID_HANDLE;
231     return ret;
232 }
233 
234 /***********************************************************************
235  *		InitializeSecurityContextA (SECUR32.@)
236  */
237 SECURITY_STATUS WINAPI InitializeSecurityContextA(
238  PCredHandle phCredential, PCtxtHandle phContext,
239  SEC_CHAR *pszTargetName, ULONG fContextReq,
240  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
241  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
242  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
243 {
244     SECURITY_STATUS ret;
245     SecurePackage *package = NULL;
246     PCredHandle cred = NULL;
247     PCredHandle ctxt = NULL;
248 
249     TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext,
250      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
251      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
252 
253     if (phContext)
254     {
255         package = (SecurePackage *)phContext->dwUpper;
256         ctxt = (PCtxtHandle)phContext->dwLower;
257     }
258     if (phCredential)
259     {
260         package = (SecurePackage *)phCredential->dwUpper;
261         cred = (PCredHandle)phCredential->dwLower;
262     }
263 
264     if (package && package->provider)
265     {
266         if (package->provider->fnTableA.InitializeSecurityContextA)
267         {
268             CtxtHandle myCtxt;
269 
270             if (phContext)
271             {
272                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
273                 myCtxt.dwUpper = realCtxt->dwUpper;
274                 myCtxt.dwLower = realCtxt->dwLower;
275             }
276 
277             ret = package->provider->fnTableA.InitializeSecurityContextA(
278                  cred, ctxt, pszTargetName, fContextReq,
279                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
280                  pOutput, pfContextAttr, ptsExpiry);
281             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) &&
282                 phNewContext && phNewContext != phContext)
283             {
284                 SECURITY_STATUS ret2;
285                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
286                 if (ret2 != SEC_E_OK)
287                     package->provider->fnTableA.DeleteSecurityContext(&myCtxt);
288             }
289         }
290         else
291             ret = SEC_E_UNSUPPORTED_FUNCTION;
292     }
293     else
294         ret = SEC_E_INVALID_HANDLE;
295     return ret;
296 }
297 
298 /***********************************************************************
299  *		InitializeSecurityContextW (SECUR32.@)
300  */
301 SECURITY_STATUS WINAPI InitializeSecurityContextW(
302  PCredHandle phCredential, PCtxtHandle phContext,
303  SEC_WCHAR *pszTargetName, ULONG fContextReq,
304  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
305  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
306  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
307 {
308     SECURITY_STATUS ret;
309     SecurePackage *package = NULL;
310     PCredHandle cred = NULL;
311     PCredHandle ctxt = NULL;
312 
313     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
314      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
315      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
316 
317     if (phContext)
318     {
319         package = (SecurePackage *)phContext->dwUpper;
320         ctxt = (PCtxtHandle)phContext->dwLower;
321     }
322     if (phCredential)
323     {
324         package = (SecurePackage *)phCredential->dwUpper;
325         cred = (PCredHandle)phCredential->dwLower;
326     }
327 
328     if (package && package->provider)
329     {
330         if (package->provider->fnTableW.InitializeSecurityContextW)
331         {
332             CtxtHandle myCtxt;
333 
334             if (phContext)
335             {
336                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
337                 myCtxt.dwUpper = realCtxt->dwUpper;
338                 myCtxt.dwLower = realCtxt->dwLower;
339             }
340 
341             ret = package->provider->fnTableW.InitializeSecurityContextW(
342                  cred, ctxt, pszTargetName, fContextReq,
343                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
344                  pOutput, pfContextAttr, ptsExpiry);
345             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) &&
346                 phNewContext && phNewContext != phContext)
347             {
348                 SECURITY_STATUS ret2;
349                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
350                 if (ret2 != SEC_E_OK)
351                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
352             }
353         }
354         else
355             ret = SEC_E_UNSUPPORTED_FUNCTION;
356     }
357     else
358         ret = SEC_E_INVALID_HANDLE;
359     return ret;
360 }
361 
362 /***********************************************************************
363  *		AcceptSecurityContext (SECUR32.@)
364  */
365 SECURITY_STATUS WINAPI AcceptSecurityContext(
366  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
367  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
368  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
369 {
370     SECURITY_STATUS ret;
371 
372     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
373      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
374      ptsExpiry);
375     if (phCredential)
376     {
377         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
378         PCredHandle cred = (PCredHandle)phCredential->dwLower;
379 
380         if (package && package->provider)
381         {
382             if (package->provider->fnTableW.AcceptSecurityContext)
383             {
384                 CtxtHandle myCtxt;
385 
386                 if(phContext)
387                 {
388                     PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
389                     TRACE("realCtx: %p\n", realCtxt);
390                     myCtxt.dwUpper = realCtxt->dwUpper;
391                     myCtxt.dwLower = realCtxt->dwLower;
392                 }
393 
394                 ret = package->provider->fnTableW.AcceptSecurityContext(
395                  cred, phContext ? &myCtxt : NULL, pInput, fContextReq,
396                  TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry);
397                 if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED)
398                 {
399                     SECURITY_STATUS ret2;
400                     ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
401                     if (ret2 != SEC_E_OK)
402                         package->provider->fnTableW.DeleteSecurityContext(
403                          &myCtxt);
404                 }
405             }
406             else
407                 ret = SEC_E_UNSUPPORTED_FUNCTION;
408         }
409         else
410             ret = SEC_E_INVALID_HANDLE;
411     }
412     else
413         ret = SEC_E_INVALID_HANDLE;
414     return ret;
415 }
416 
417 /***********************************************************************
418  *		CompleteAuthToken (SECUR32.@)
419  */
420 SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext,
421  PSecBufferDesc pToken)
422 {
423     SECURITY_STATUS ret;
424 
425     TRACE("%p %p\n", phContext, pToken);
426     if (phContext)
427     {
428         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
429         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
430 
431         if (package && package->provider)
432         {
433             if (package->provider->fnTableW.CompleteAuthToken)
434                 ret = package->provider->fnTableW.CompleteAuthToken(ctxt,
435                  pToken);
436             else
437                 ret = SEC_E_UNSUPPORTED_FUNCTION;
438         }
439         else
440             ret = SEC_E_INVALID_HANDLE;
441     }
442     else
443         ret = SEC_E_INVALID_HANDLE;
444     return ret;
445 }
446 
447 /***********************************************************************
448  *		DeleteSecurityContext (SECUR32.@)
449  */
450 SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
451 {
452     SECURITY_STATUS ret;
453 
454     TRACE("%p\n", phContext);
455     if (phContext)
456     {
457         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
458         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
459 
460         if (package && package->provider &&
461          package->provider->fnTableW.DeleteSecurityContext)
462             ret = package->provider->fnTableW.DeleteSecurityContext(ctxt);
463         else
464             ret = SEC_E_INVALID_HANDLE;
465         HeapFree(GetProcessHeap(), 0, ctxt);
466     }
467     else
468         ret = SEC_E_INVALID_HANDLE;
469     return ret;
470 }
471 
472 /***********************************************************************
473  *		ApplyControlToken (SECUR32.@)
474  */
475 SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext,
476  PSecBufferDesc pInput)
477 {
478     SECURITY_STATUS ret;
479 
480     TRACE("%p %p\n", phContext, pInput);
481     if (phContext)
482     {
483         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
484         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
485 
486         if (package && package->provider)
487         {
488             if (package->provider->fnTableW.ApplyControlToken)
489                 ret = package->provider->fnTableW.ApplyControlToken(
490                  ctxt, pInput);
491             else
492                 ret = SEC_E_UNSUPPORTED_FUNCTION;
493         }
494         else
495             ret = SEC_E_INVALID_HANDLE;
496     }
497     else
498         ret = SEC_E_INVALID_HANDLE;
499     return ret;
500 }
501 
502 /***********************************************************************
503  *		QueryContextAttributesA (SECUR32.@)
504  */
505 SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext,
506  ULONG ulAttribute, void *pBuffer)
507 {
508     SECURITY_STATUS ret;
509 
510     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
511     if (phContext)
512     {
513         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
514         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
515 
516         if (package && package->provider)
517         {
518             if (package->provider->fnTableA.QueryContextAttributesA)
519                 ret = package->provider->fnTableA.QueryContextAttributesA(
520                  ctxt, ulAttribute, pBuffer);
521             else
522                 ret = SEC_E_UNSUPPORTED_FUNCTION;
523         }
524         else
525             ret = SEC_E_INVALID_HANDLE;
526     }
527     else
528         ret = SEC_E_INVALID_HANDLE;
529     return ret;
530 }
531 
532 /***********************************************************************
533  *		QueryContextAttributesW (SECUR32.@)
534  */
535 SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext,
536  ULONG ulAttribute, void *pBuffer)
537 {
538     SECURITY_STATUS ret;
539 
540     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
541     if (phContext)
542     {
543         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
544         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
545 
546         if (package && package->provider)
547         {
548             if (package->provider->fnTableW.QueryContextAttributesW)
549                 ret = package->provider->fnTableW.QueryContextAttributesW(
550                  ctxt, ulAttribute, pBuffer);
551             else
552                 ret = SEC_E_UNSUPPORTED_FUNCTION;
553         }
554         else
555             ret = SEC_E_INVALID_HANDLE;
556     }
557     else
558         ret = SEC_E_INVALID_HANDLE;
559     return ret;
560 }
561 
562 /***********************************************************************
563  *		ImpersonateSecurityContext (SECUR32.@)
564  */
565 SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext)
566 {
567     SECURITY_STATUS ret;
568 
569     TRACE("%p\n", phContext);
570     if (phContext)
571     {
572         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
573         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
574 
575         if (package && package->provider)
576         {
577             if (package->provider->fnTableW.ImpersonateSecurityContext)
578                 ret = package->provider->fnTableW.ImpersonateSecurityContext(
579                  ctxt);
580             else
581                 ret = SEC_E_UNSUPPORTED_FUNCTION;
582         }
583         else
584             ret = SEC_E_INVALID_HANDLE;
585     }
586     else
587         ret = SEC_E_INVALID_HANDLE;
588     return ret;
589 }
590 
591 /***********************************************************************
592  *		RevertSecurityContext (SECUR32.@)
593  */
594 SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext)
595 {
596     SECURITY_STATUS ret;
597 
598     TRACE("%p\n", phContext);
599     if (phContext)
600     {
601         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
602         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
603 
604         if (package && package->provider)
605         {
606             if (package->provider->fnTableW.RevertSecurityContext)
607                 ret = package->provider->fnTableW.RevertSecurityContext(
608                  ctxt);
609             else
610                 ret = SEC_E_UNSUPPORTED_FUNCTION;
611         }
612         else
613             ret = SEC_E_INVALID_HANDLE;
614     }
615     else
616         ret = SEC_E_INVALID_HANDLE;
617     return ret;
618 }
619 
620 /***********************************************************************
621  *		MakeSignature (SECUR32.@)
622  */
623 SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP,
624  PSecBufferDesc pMessage, ULONG MessageSeqNo)
625 {
626     SECURITY_STATUS ret;
627 
628     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
629     if (phContext)
630     {
631         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
632         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
633 
634         if (package && package->provider)
635         {
636             if (package->provider->fnTableW.MakeSignature)
637                 ret = package->provider->fnTableW.MakeSignature(
638                  ctxt, fQOP, pMessage, MessageSeqNo);
639             else
640                 ret = SEC_E_UNSUPPORTED_FUNCTION;
641         }
642         else
643             ret = SEC_E_INVALID_HANDLE;
644     }
645     else
646         ret = SEC_E_INVALID_HANDLE;
647     return ret;
648 }
649 
650 /***********************************************************************
651  *		VerifySignature (SECUR32.@)
652  */
653 SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext,
654  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
655 {
656     SECURITY_STATUS ret;
657 
658     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
659     if (phContext)
660     {
661         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
662         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
663 
664         if (package && package->provider)
665         {
666             if (package->provider->fnTableW.VerifySignature)
667                 ret = package->provider->fnTableW.VerifySignature(
668                  ctxt, pMessage, MessageSeqNo, pfQOP);
669             else
670                 ret = SEC_E_UNSUPPORTED_FUNCTION;
671         }
672         else
673             ret = SEC_E_INVALID_HANDLE;
674     }
675     else
676         ret = SEC_E_INVALID_HANDLE;
677     return ret;
678 }
679 
680 /***********************************************************************
681  *		QuerySecurityPackageInfoA (SECUR32.@)
682  */
683 SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName,
684  PSecPkgInfoA *ppPackageInfo)
685 {
686     SECURITY_STATUS ret;
687 
688     TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo);
689     if (pszPackageName)
690     {
691         SecurePackage *package = SECUR32_findPackageA(pszPackageName);
692 
693         if (package)
694         {
695             size_t bytesNeeded = sizeof(SecPkgInfoA);
696             int nameLen = 0, commentLen = 0;
697 
698             if (package->infoW.Name)
699             {
700                 nameLen = WideCharToMultiByte(CP_ACP, 0,
701                  package->infoW.Name, -1, NULL, 0, NULL, NULL);
702                 bytesNeeded += nameLen;
703             }
704             if (package->infoW.Comment)
705             {
706                 commentLen = WideCharToMultiByte(CP_ACP, 0,
707                  package->infoW.Comment, -1, NULL, 0, NULL, NULL);
708                 bytesNeeded += commentLen;
709             }
710             *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
711             if (*ppPackageInfo)
712             {
713                 PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo +
714                  sizeof(SecPkgInfoA));
715 
716                 memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
717                 if (package->infoW.Name)
718                 {
719                     (*ppPackageInfo)->Name = nextString;
720                     nextString += WideCharToMultiByte(CP_ACP, 0,
721                      package->infoW.Name, -1, nextString, nameLen, NULL, NULL);
722                 }
723                 else
724                     (*ppPackageInfo)->Name = NULL;
725                 if (package->infoW.Comment)
726                 {
727                     (*ppPackageInfo)->Comment = nextString;
728                     nextString += WideCharToMultiByte(CP_ACP, 0,
729                      package->infoW.Comment, -1, nextString, commentLen, NULL,
730                      NULL);
731                 }
732                 else
733                     (*ppPackageInfo)->Comment = NULL;
734                 ret = SEC_E_OK;
735             }
736             else
737                 ret = SEC_E_INSUFFICIENT_MEMORY;
738         }
739         else
740             ret = SEC_E_SECPKG_NOT_FOUND;
741     }
742     else
743         ret = SEC_E_SECPKG_NOT_FOUND;
744     return ret;
745 }
746 
747 /***********************************************************************
748  *		QuerySecurityPackageInfoW (SECUR32.@)
749  */
750 SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName,
751  PSecPkgInfoW *ppPackageInfo)
752 {
753     SECURITY_STATUS ret;
754     SecurePackage *package = SECUR32_findPackageW(pszPackageName);
755 
756     TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo);
757     if (package)
758     {
759         size_t bytesNeeded = sizeof(SecPkgInfoW);
760         int nameLen = 0, commentLen = 0;
761 
762         if (package->infoW.Name)
763         {
764             nameLen = lstrlenW(package->infoW.Name) + 1;
765             bytesNeeded += nameLen * sizeof(WCHAR);
766         }
767         if (package->infoW.Comment)
768         {
769             commentLen = lstrlenW(package->infoW.Comment) + 1;
770             bytesNeeded += commentLen * sizeof(WCHAR);
771         }
772         *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
773         if (*ppPackageInfo)
774         {
775             PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo +
776              sizeof(SecPkgInfoW));
777 
778             **ppPackageInfo = package->infoW;
779             if (package->infoW.Name)
780             {
781                 (*ppPackageInfo)->Name = nextString;
782                 lstrcpynW(nextString, package->infoW.Name, nameLen);
783                 nextString += nameLen;
784             }
785             else
786                 (*ppPackageInfo)->Name = NULL;
787             if (package->infoW.Comment)
788             {
789                 (*ppPackageInfo)->Comment = nextString;
790                 lstrcpynW(nextString, package->infoW.Comment, commentLen);
791             }
792             else
793                 (*ppPackageInfo)->Comment = NULL;
794             ret = SEC_E_OK;
795         }
796         else
797             ret = SEC_E_INSUFFICIENT_MEMORY;
798     }
799     else
800         ret = SEC_E_SECPKG_NOT_FOUND;
801     return ret;
802 }
803 
804 /***********************************************************************
805  *		ExportSecurityContext (SECUR32.@)
806  */
807 SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext,
808  ULONG fFlags, PSecBuffer pPackedContext, void **pToken)
809 {
810     SECURITY_STATUS ret;
811 
812     TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken);
813     if (phContext)
814     {
815         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
816         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
817 
818         if (package && package->provider)
819         {
820             if (package->provider->fnTableW.ExportSecurityContext)
821                 ret = package->provider->fnTableW.ExportSecurityContext(
822                  ctxt, fFlags, pPackedContext, pToken);
823             else
824                 ret = SEC_E_UNSUPPORTED_FUNCTION;
825         }
826         else
827             ret = SEC_E_INVALID_HANDLE;
828     }
829     else
830         ret = SEC_E_INVALID_HANDLE;
831     return ret;
832 }
833 
834 /***********************************************************************
835  *		ImportSecurityContextA (SECUR32.@)
836  */
837 SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage,
838  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
839 {
840     SECURITY_STATUS ret;
841     SecurePackage *package = SECUR32_findPackageA(pszPackage);
842 
843     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
844      phContext);
845     if (package && package->provider)
846     {
847         if (package->provider->fnTableA.ImportSecurityContextA)
848         {
849             CtxtHandle myCtxt;
850 
851             ret = package->provider->fnTableA.ImportSecurityContextA(
852              pszPackage, pPackedContext, Token, &myCtxt);
853             if (ret == SEC_E_OK)
854             {
855                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
856                 if (ret != SEC_E_OK)
857                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
858             }
859         }
860         else
861             ret = SEC_E_UNSUPPORTED_FUNCTION;
862     }
863     else
864         ret = SEC_E_SECPKG_NOT_FOUND;
865     return ret;
866 
867 }
868 
869 /***********************************************************************
870  *		ImportSecurityContextW (SECUR32.@)
871  */
872 SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage,
873  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
874 {
875     SECURITY_STATUS ret;
876     SecurePackage *package = SECUR32_findPackageW(pszPackage);
877 
878     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
879      phContext);
880     if (package && package->provider)
881     {
882         if (package->provider->fnTableW.ImportSecurityContextW)
883         {
884             CtxtHandle myCtxt;
885 
886             ret = package->provider->fnTableW.ImportSecurityContextW(
887              pszPackage, pPackedContext, Token, &myCtxt);
888             if (ret == SEC_E_OK)
889             {
890                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
891                 if (ret != SEC_E_OK)
892                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
893             }
894         }
895         else
896             ret = SEC_E_UNSUPPORTED_FUNCTION;
897     }
898     else
899         ret = SEC_E_SECPKG_NOT_FOUND;
900     return ret;
901 }
902 
903 /***********************************************************************
904  *		AddCredentialsA (SECUR32.@)
905  */
906 SECURITY_STATUS WINAPI AddCredentialsA(PCredHandle hCredentials,
907  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
908  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
909  PTimeStamp ptsExpiry)
910 {
911     SECURITY_STATUS ret;
912 
913     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
914      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
915      pvGetKeyArgument, ptsExpiry);
916     if (hCredentials)
917     {
918         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
919         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
920 
921         if (package && package->provider)
922         {
923             if (package->provider->fnTableA.AddCredentialsA)
924                 ret = package->provider->fnTableA.AddCredentialsA(
925                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
926                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
927             else
928                 ret = SEC_E_UNSUPPORTED_FUNCTION;
929         }
930         else
931             ret = SEC_E_INVALID_HANDLE;
932     }
933     else
934         ret = SEC_E_INVALID_HANDLE;
935     return ret;
936 }
937 
938 /***********************************************************************
939  *		AddCredentialsW (SECUR32.@)
940  */
941 SECURITY_STATUS WINAPI AddCredentialsW(PCredHandle hCredentials,
942  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
943  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
944  PTimeStamp ptsExpiry)
945 {
946     SECURITY_STATUS ret;
947 
948     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
949      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
950      pvGetKeyArgument, ptsExpiry);
951     if (hCredentials)
952     {
953         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
954         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
955 
956         if (package && package->provider)
957         {
958             if (package->provider->fnTableW.AddCredentialsW)
959                 ret = package->provider->fnTableW.AddCredentialsW(
960                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
961                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
962             else
963                 ret = SEC_E_UNSUPPORTED_FUNCTION;
964         }
965         else
966             ret = SEC_E_INVALID_HANDLE;
967     }
968     else
969         ret = SEC_E_INVALID_HANDLE;
970     return ret;
971 }
972 
973 /***********************************************************************
974  *		QuerySecurityContextToken (SECUR32.@)
975  */
976 SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext,
977  HANDLE *phToken)
978 {
979     SECURITY_STATUS ret;
980 
981     TRACE("%p %p\n", phContext, phToken);
982     if (phContext)
983     {
984         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
985         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
986 
987         if (package && package->provider)
988         {
989             if (package->provider->fnTableW.QuerySecurityContextToken)
990                 ret = package->provider->fnTableW.QuerySecurityContextToken(
991                  ctxt, phToken);
992             else
993                 ret = SEC_E_UNSUPPORTED_FUNCTION;
994         }
995         else
996             ret = SEC_E_INVALID_HANDLE;
997     }
998     else
999         ret = SEC_E_INVALID_HANDLE;
1000     return ret;
1001 }
1002 
1003 /***********************************************************************
1004  *		EncryptMessage (SECUR32.@)
1005  */
1006 SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
1007  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1008 {
1009     SECURITY_STATUS ret;
1010 
1011     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
1012     if (phContext)
1013     {
1014         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1015         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1016 
1017         if (package && package->provider)
1018         {
1019             if (package->provider->fnTableW.EncryptMessage)
1020                 ret = package->provider->fnTableW.EncryptMessage(
1021                  ctxt, fQOP, pMessage, MessageSeqNo);
1022             else
1023                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1024         }
1025         else
1026             ret = SEC_E_INVALID_HANDLE;
1027     }
1028     else
1029         ret = SEC_E_INVALID_HANDLE;
1030     return ret;
1031 }
1032 
1033 /***********************************************************************
1034  *		DecryptMessage (SECUR32.@)
1035  */
1036 SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext,
1037  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
1038 {
1039     SECURITY_STATUS ret;
1040 
1041     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
1042     if (phContext)
1043     {
1044         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1045         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1046 
1047         if (package && package->provider)
1048         {
1049             if (package->provider->fnTableW.DecryptMessage)
1050                 ret = package->provider->fnTableW.DecryptMessage(
1051                  ctxt, pMessage, MessageSeqNo, pfQOP);
1052             else
1053                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1054         }
1055         else
1056             ret = SEC_E_INVALID_HANDLE;
1057     }
1058     else
1059         ret = SEC_E_INVALID_HANDLE;
1060     return ret;
1061 }
1062 
1063 /***********************************************************************
1064  *		SetContextAttributesA (SECUR32.@)
1065  */
1066 SECURITY_STATUS WINAPI SetContextAttributesA(PCtxtHandle phContext,
1067  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1068 {
1069     SECURITY_STATUS ret;
1070 
1071     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1072     if (phContext)
1073     {
1074         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1075         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1076 
1077         if (package && package->provider)
1078         {
1079             if (package->provider->fnTableA.SetContextAttributesA)
1080                 ret = package->provider->fnTableA.SetContextAttributesA(
1081                  ctxt, ulAttribute, pBuffer, cbBuffer);
1082             else
1083                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1084         }
1085         else
1086             ret = SEC_E_INVALID_HANDLE;
1087     }
1088     else
1089         ret = SEC_E_INVALID_HANDLE;
1090     return ret;
1091 }
1092 
1093 /***********************************************************************
1094  *		SetContextAttributesW (SECUR32.@)
1095  */
1096 SECURITY_STATUS WINAPI SetContextAttributesW(PCtxtHandle phContext,
1097  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1098 {
1099     SECURITY_STATUS ret;
1100 
1101     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1102     if (phContext)
1103     {
1104         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1105         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1106 
1107         if (package && package->provider)
1108         {
1109             if (package->provider->fnTableW.SetContextAttributesW)
1110                 ret = package->provider->fnTableW.SetContextAttributesW(
1111                  ctxt, ulAttribute, pBuffer, cbBuffer);
1112             else
1113                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1114         }
1115         else
1116             ret = SEC_E_INVALID_HANDLE;
1117     }
1118     else
1119         ret = SEC_E_INVALID_HANDLE;
1120     return ret;
1121 }
1122