xref: /reactos/dll/win32/secur32/thunks.c (revision c2c66aff)
1 /* Copyright (C) 2004 Juan Lang
2  *
3  * This file implements thunks between wide char and multibyte functions for
4  * SSPs that only provide one or the other.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 #include "precomp.h"
21 
22 #include "wine/debug.h"
23 
24 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
25 
thunk_AcquireCredentialsHandleA(SEC_CHAR * pszPrincipal,SEC_CHAR * pszPackage,ULONG fCredentialsUse,PLUID pvLogonID,PVOID pAuthData,SEC_GET_KEY_FN pGetKeyFn,PVOID pvGetKeyArgument,PCredHandle phCredential,PTimeStamp ptsExpiry)26 SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA(
27  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
28  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
29  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
30 {
31     SECURITY_STATUS ret;
32 
33     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
34      debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
35      pvGetKeyArgument, phCredential, ptsExpiry);
36     if (pszPackage)
37     {
38         UNICODE_STRING principal, package;
39 
40         RtlCreateUnicodeStringFromAsciiz(&principal, pszPrincipal);
41         RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
42         ret = AcquireCredentialsHandleW(principal.Buffer, package.Buffer,
43          fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument,
44          phCredential, ptsExpiry);
45         RtlFreeUnicodeString(&principal);
46         RtlFreeUnicodeString(&package);
47     }
48     else
49         ret = SEC_E_SECPKG_NOT_FOUND;
50     return ret;
51 }
52 
thunk_AcquireCredentialsHandleW(SEC_WCHAR * pszPrincipal,SEC_WCHAR * pszPackage,ULONG fCredentialsUse,PLUID pvLogonID,PVOID pAuthData,SEC_GET_KEY_FN pGetKeyFn,PVOID pvGetKeyArgument,PCredHandle phCredential,PTimeStamp ptsExpiry)53 SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW(
54  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
55  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
56  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
57 {
58     SECURITY_STATUS ret;
59 
60     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
61      debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
62      pvGetKeyArgument, phCredential, ptsExpiry);
63     if (pszPackage)
64     {
65         PSTR principal, package;
66 
67         principal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
68         package = SECUR32_AllocMultiByteFromWide(pszPackage);
69         ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse,
70          pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential,
71          ptsExpiry);
72         HeapFree(GetProcessHeap(), 0, principal);
73         HeapFree(GetProcessHeap(), 0, package);
74     }
75     else
76         ret = SEC_E_SECPKG_NOT_FOUND;
77     return ret;
78 }
79 
80 /* thunking is pretty dicey for these--the output type depends on ulAttribute,
81  * so we have to know about every type the caller does
82  */
thunk_QueryCredentialsAttributesA(PCredHandle phCredential,ULONG ulAttribute,void * pBuffer)83 SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA(
84  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
85 {
86     SECURITY_STATUS ret;
87 
88     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
89     if (phCredential)
90     {
91         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
92         PCredHandle cred = (PCredHandle)phCredential->dwLower;
93 
94         if (package && package->provider)
95         {
96             if (package->provider->fnTableW.QueryCredentialsAttributesW)
97             {
98                 ret = package->provider->fnTableW.QueryCredentialsAttributesW(
99                  cred, ulAttribute, pBuffer);
100                 if (ret == SEC_E_OK)
101                 {
102                     switch (ulAttribute)
103                     {
104                         case SECPKG_CRED_ATTR_NAMES:
105                         {
106                             PSecPkgCredentials_NamesW names =
107                              (PSecPkgCredentials_NamesW)pBuffer;
108                             SEC_WCHAR *oldUser = names->sUserName;
109 
110                             if (oldUser)
111                             {
112                                 names->sUserName =
113                                  (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
114                                 package->provider->fnTableW.FreeContextBuffer(
115                                  oldUser);
116                             }
117                             break;
118                         }
119                         default:
120                             WARN("attribute type %d unknown\n", ulAttribute);
121                             ret = SEC_E_INTERNAL_ERROR;
122                     }
123                 }
124             }
125             else
126                 ret = SEC_E_UNSUPPORTED_FUNCTION;
127         }
128         else
129             ret = SEC_E_INVALID_HANDLE;
130     }
131     else
132         ret = SEC_E_INVALID_HANDLE;
133     return ret;
134 }
135 
thunk_QueryCredentialsAttributesW(PCredHandle phCredential,ULONG ulAttribute,void * pBuffer)136 SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW(
137  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
138 {
139     SECURITY_STATUS ret;
140 
141     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
142     if (phCredential)
143     {
144         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
145         PCredHandle cred = (PCredHandle)phCredential->dwLower;
146 
147         if (package && package->provider)
148         {
149             if (package->provider->fnTableA.QueryCredentialsAttributesA)
150             {
151                 ret = package->provider->fnTableA.QueryCredentialsAttributesA(
152                  cred, ulAttribute, pBuffer);
153                 if (ret == SEC_E_OK)
154                 {
155                     switch (ulAttribute)
156                     {
157                         case SECPKG_CRED_ATTR_NAMES:
158                         {
159                             PSecPkgCredentials_NamesA names =
160                              (PSecPkgCredentials_NamesA)pBuffer;
161                             SEC_CHAR *oldUser = names->sUserName;
162 
163                             if (oldUser)
164                             {
165                                 names->sUserName =
166                                  (PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
167                                 package->provider->fnTableA.FreeContextBuffer(
168                                  oldUser);
169                             }
170                             break;
171                         }
172                         default:
173                             WARN("attribute type %d unknown\n", ulAttribute);
174                             ret = SEC_E_INTERNAL_ERROR;
175                     }
176                 }
177             }
178             else
179                 ret = SEC_E_UNSUPPORTED_FUNCTION;
180         }
181         else
182             ret = SEC_E_INVALID_HANDLE;
183     }
184     else
185         ret = SEC_E_INVALID_HANDLE;
186     return ret;
187 }
188 
thunk_InitializeSecurityContextA(PCredHandle phCredential,PCtxtHandle phContext,SEC_CHAR * pszTargetName,ULONG fContextReq,ULONG Reserved1,ULONG TargetDataRep,PSecBufferDesc pInput,ULONG Reserved2,PCtxtHandle phNewContext,PSecBufferDesc pOutput,ULONG * pfContextAttr,PTimeStamp ptsExpiry)189 SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextA(
190  PCredHandle phCredential, PCtxtHandle phContext,
191  SEC_CHAR *pszTargetName, ULONG fContextReq,
192  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
193  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
194  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
195 {
196     SECURITY_STATUS ret;
197 
198     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
199      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
200      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
201     if (phCredential)
202     {
203         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
204 
205         if (package && package->provider)
206         {
207             if (package->provider->fnTableW.InitializeSecurityContextW)
208             {
209                 UNICODE_STRING target;
210 
211                 RtlCreateUnicodeStringFromAsciiz(&target, pszTargetName);
212                 ret = package->provider->fnTableW.InitializeSecurityContextW(
213                  phCredential, phContext, target.Buffer, fContextReq, Reserved1,
214                  TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
215                  pfContextAttr, ptsExpiry);
216                 RtlFreeUnicodeString(&target);
217             }
218             else
219                 ret = SEC_E_UNSUPPORTED_FUNCTION;
220         }
221         else
222             ret = SEC_E_INVALID_HANDLE;
223     }
224     else
225         ret = SEC_E_INVALID_HANDLE;
226     return ret;
227 }
228 
thunk_InitializeSecurityContextW(PCredHandle phCredential,PCtxtHandle phContext,SEC_WCHAR * pszTargetName,ULONG fContextReq,ULONG Reserved1,ULONG TargetDataRep,PSecBufferDesc pInput,ULONG Reserved2,PCtxtHandle phNewContext,PSecBufferDesc pOutput,ULONG * pfContextAttr,PTimeStamp ptsExpiry)229 SECURITY_STATUS SEC_ENTRY thunk_InitializeSecurityContextW(
230  PCredHandle phCredential, PCtxtHandle phContext,
231  SEC_WCHAR *pszTargetName, ULONG fContextReq,
232  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
233  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
234  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
235 {
236     SECURITY_STATUS ret;
237 
238     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
239      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
240      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
241     if (phCredential)
242     {
243         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
244 
245         if (package && package->provider)
246         {
247             if (package->provider->fnTableA.InitializeSecurityContextA)
248             {
249                 PSTR target = SECUR32_AllocMultiByteFromWide(pszTargetName);
250 
251                 ret = package->provider->fnTableA.InitializeSecurityContextA(
252                  phCredential, phContext, target, fContextReq, Reserved1,
253                  TargetDataRep, pInput, Reserved2, phNewContext, pOutput,
254                  pfContextAttr, ptsExpiry);
255                 HeapFree(GetProcessHeap(), 0, target);
256             }
257             else
258                 ret = SEC_E_UNSUPPORTED_FUNCTION;
259         }
260         else
261             ret = SEC_E_INVALID_HANDLE;
262     }
263     else
264         ret = SEC_E_INVALID_HANDLE;
265     return ret;
266 }
267 
thunk_AddCredentialsA(PCredHandle hCredentials,SEC_CHAR * pszPrincipal,SEC_CHAR * pszPackage,ULONG fCredentialUse,void * pAuthData,SEC_GET_KEY_FN pGetKeyFn,void * pvGetKeyArgument,PTimeStamp ptsExpiry)268 SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials,
269  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
270  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
271  PTimeStamp ptsExpiry)
272 {
273     SECURITY_STATUS ret;
274 
275     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
276      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
277      pvGetKeyArgument, ptsExpiry);
278     if (hCredentials)
279     {
280         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
281         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
282 
283         if (package && package->provider)
284         {
285             if (package->provider->fnTableW.AddCredentialsW)
286             {
287                 UNICODE_STRING szPrincipal, szPackage;
288 
289                 RtlCreateUnicodeStringFromAsciiz(&szPrincipal, pszPrincipal);
290                 RtlCreateUnicodeStringFromAsciiz(&szPackage, pszPackage);
291                 ret = package->provider->fnTableW.AddCredentialsW(
292                  cred, szPrincipal.Buffer, szPackage.Buffer, fCredentialUse,
293                  pAuthData, pGetKeyFn, pvGetKeyArgument, ptsExpiry);
294                 RtlFreeUnicodeString(&szPrincipal);
295                 RtlFreeUnicodeString(&szPackage);
296             }
297             else
298                 ret = SEC_E_UNSUPPORTED_FUNCTION;
299         }
300         else
301             ret = SEC_E_INVALID_HANDLE;
302     }
303     else
304         ret = SEC_E_INVALID_HANDLE;
305     return ret;
306 }
307 
thunk_AddCredentialsW(PCredHandle hCredentials,SEC_WCHAR * pszPrincipal,SEC_WCHAR * pszPackage,ULONG fCredentialUse,void * pAuthData,SEC_GET_KEY_FN pGetKeyFn,void * pvGetKeyArgument,PTimeStamp ptsExpiry)308 SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials,
309  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
310  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
311  PTimeStamp ptsExpiry)
312 {
313     SECURITY_STATUS ret;
314 
315     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
316      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
317      pvGetKeyArgument, ptsExpiry);
318     if (hCredentials)
319     {
320         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
321         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
322 
323         if (package && package->provider)
324         {
325             if (package->provider->fnTableA.AddCredentialsA)
326             {
327                 PSTR szPrincipal = SECUR32_AllocMultiByteFromWide(pszPrincipal);
328                 PSTR szPackage = SECUR32_AllocMultiByteFromWide(pszPackage);
329 
330                 ret = package->provider->fnTableA.AddCredentialsA(
331                  cred, szPrincipal, szPackage, fCredentialUse, pAuthData,
332                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
333                 HeapFree(GetProcessHeap(), 0, szPrincipal);
334                 HeapFree(GetProcessHeap(), 0, szPackage);
335             }
336             else
337                 ret = SEC_E_UNSUPPORTED_FUNCTION;
338         }
339         else
340             ret = SEC_E_INVALID_HANDLE;
341     }
342     else
343         ret = SEC_E_INVALID_HANDLE;
344     return ret;
345 }
346 
_copyPackageInfoFlatWToA(const SecPkgInfoW * infoW)347 static PSecPkgInfoA _copyPackageInfoFlatWToA(const SecPkgInfoW *infoW)
348 {
349     PSecPkgInfoA ret;
350 
351     if (infoW)
352     {
353         size_t bytesNeeded = sizeof(SecPkgInfoA);
354         int nameLen = 0, commentLen = 0;
355 
356         if (infoW->Name)
357         {
358             nameLen = WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1,
359              NULL, 0, NULL, NULL);
360             bytesNeeded += nameLen;
361         }
362         if (infoW->Comment)
363         {
364             commentLen = WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1,
365              NULL, 0, NULL, NULL);
366             bytesNeeded += commentLen;
367         }
368         ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
369         if (ret)
370         {
371             PSTR nextString = (PSTR)((PBYTE)ret + sizeof(SecPkgInfoA));
372 
373             memcpy(ret, infoW, sizeof(SecPkgInfoA));
374             if (infoW->Name)
375             {
376                 ret->Name = nextString;
377                 WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, nextString,
378                  nameLen, NULL, NULL);
379                 nextString += nameLen;
380             }
381             else
382                 ret->Name = NULL;
383             if (infoW->Comment)
384             {
385                 ret->Comment = nextString;
386                 WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, nextString,
387                  nameLen, NULL, NULL);
388             }
389             else
390                 ret->Comment = NULL;
391         }
392     }
393     else
394         ret = NULL;
395     return ret;
396 }
397 
thunk_ContextAttributesWToA(SecurePackage * package,ULONG ulAttribute,void * pBuffer)398 static SECURITY_STATUS thunk_ContextAttributesWToA(SecurePackage *package,
399  ULONG ulAttribute, void *pBuffer)
400 {
401     SECURITY_STATUS ret = SEC_E_OK;
402 
403     if (package && pBuffer)
404     {
405         switch (ulAttribute)
406         {
407             case SECPKG_ATTR_NAMES:
408             {
409                 PSecPkgContext_NamesW names = (PSecPkgContext_NamesW)pBuffer;
410                 SEC_WCHAR *oldUser = names->sUserName;
411 
412                 if (oldUser)
413                 {
414                     names->sUserName =
415                      (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser);
416                     package->provider->fnTableW.FreeContextBuffer(oldUser);
417                 }
418                 break;
419             }
420             case SECPKG_ATTR_AUTHORITY:
421             {
422                 PSecPkgContext_AuthorityW names =
423                  (PSecPkgContext_AuthorityW)pBuffer;
424                 SEC_WCHAR *oldAuth = names->sAuthorityName;
425 
426                 if (oldAuth)
427                 {
428                     names->sAuthorityName =
429                      (PWSTR)SECUR32_AllocMultiByteFromWide(oldAuth);
430                     package->provider->fnTableW.FreeContextBuffer(oldAuth);
431                 }
432                 break;
433             }
434             case SECPKG_ATTR_KEY_INFO:
435             {
436                 PSecPkgContext_KeyInfoW info = (PSecPkgContext_KeyInfoW)pBuffer;
437                 SEC_WCHAR *oldSigAlgName = info->sSignatureAlgorithmName;
438                 SEC_WCHAR *oldEncAlgName = info->sEncryptAlgorithmName;
439 
440                 if (oldSigAlgName)
441                 {
442                     info->sSignatureAlgorithmName =
443                      (PWSTR)SECUR32_AllocMultiByteFromWide(oldSigAlgName);
444                     package->provider->fnTableW.FreeContextBuffer(
445                      oldSigAlgName);
446                 }
447                 if (oldEncAlgName)
448                 {
449                     info->sEncryptAlgorithmName =
450                      (PWSTR)SECUR32_AllocMultiByteFromWide(oldEncAlgName);
451                     package->provider->fnTableW.FreeContextBuffer(
452                      oldEncAlgName);
453                 }
454                 break;
455             }
456             case SECPKG_ATTR_PACKAGE_INFO:
457             {
458                 PSecPkgContext_PackageInfoW info =
459                  (PSecPkgContext_PackageInfoW)pBuffer;
460                 PSecPkgInfoW oldPkgInfo = info->PackageInfo;
461 
462                 if (oldPkgInfo)
463                 {
464                     info->PackageInfo = (PSecPkgInfoW)
465                      _copyPackageInfoFlatWToA(oldPkgInfo);
466                     package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
467                 }
468                 break;
469             }
470             case SECPKG_ATTR_NEGOTIATION_INFO:
471             {
472                 PSecPkgContext_NegotiationInfoW info =
473                  (PSecPkgContext_NegotiationInfoW)pBuffer;
474                 PSecPkgInfoW oldPkgInfo = info->PackageInfo;
475 
476                 if (oldPkgInfo)
477                 {
478                     info->PackageInfo = (PSecPkgInfoW)
479                      _copyPackageInfoFlatWToA(oldPkgInfo);
480                     package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
481                 }
482                 break;
483             }
484             case SECPKG_ATTR_NATIVE_NAMES:
485             {
486                 PSecPkgContext_NativeNamesW names =
487                  (PSecPkgContext_NativeNamesW)pBuffer;
488                 PWSTR oldClient = names->sClientName;
489                 PWSTR oldServer = names->sServerName;
490 
491                 if (oldClient)
492                 {
493                     names->sClientName = (PWSTR)SECUR32_AllocMultiByteFromWide(
494                      oldClient);
495                     package->provider->fnTableW.FreeContextBuffer(oldClient);
496                 }
497                 if (oldServer)
498                 {
499                     names->sServerName = (PWSTR)SECUR32_AllocMultiByteFromWide(
500                      oldServer);
501                     package->provider->fnTableW.FreeContextBuffer(oldServer);
502                 }
503                 break;
504             }
505             case SECPKG_ATTR_CREDENTIAL_NAME:
506             {
507                 PSecPkgContext_CredentialNameW name =
508                  (PSecPkgContext_CredentialNameW)pBuffer;
509                 PWSTR oldCred = name->sCredentialName;
510 
511                 if (oldCred)
512                 {
513                     name->sCredentialName =
514                      (PWSTR)SECUR32_AllocMultiByteFromWide(oldCred);
515                     package->provider->fnTableW.FreeContextBuffer(oldCred);
516                 }
517                 break;
518             }
519             /* no thunking needed: */
520             case SECPKG_ATTR_ACCESS_TOKEN:
521             case SECPKG_ATTR_DCE_INFO:
522             case SECPKG_ATTR_FLAGS:
523             case SECPKG_ATTR_LIFESPAN:
524             case SECPKG_ATTR_PASSWORD_EXPIRY:
525             case SECPKG_ATTR_SESSION_KEY:
526             case SECPKG_ATTR_SIZES:
527             case SECPKG_ATTR_STREAM_SIZES:
528             case SECPKG_ATTR_TARGET_INFORMATION:
529                 break;
530             default:
531                 WARN("attribute type %d unknown\n", ulAttribute);
532                 ret = SEC_E_INTERNAL_ERROR;
533         }
534     }
535     else
536         ret = SEC_E_INVALID_TOKEN;
537     return ret;
538 }
539 
thunk_QueryContextAttributesA(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer)540 SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA(PCtxtHandle phContext,
541  ULONG ulAttribute, void *pBuffer)
542 {
543     SECURITY_STATUS ret;
544 
545     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
546     if (phContext)
547     {
548         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
549         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
550 
551         if (package && package->provider)
552         {
553             if (package->provider->fnTableW.QueryContextAttributesW)
554             {
555                 ret = package->provider->fnTableW.QueryContextAttributesW(
556                  ctxt, ulAttribute, pBuffer);
557                 if (ret == SEC_E_OK)
558                     ret = thunk_ContextAttributesWToA(package, ulAttribute,
559                      pBuffer);
560             }
561             else
562                 ret = SEC_E_UNSUPPORTED_FUNCTION;
563         }
564         else
565             ret = SEC_E_INVALID_HANDLE;
566     }
567     else
568         ret = SEC_E_INVALID_HANDLE;
569     return ret;
570 }
571 
_copyPackageInfoFlatAToW(const SecPkgInfoA * infoA)572 static PSecPkgInfoW _copyPackageInfoFlatAToW(const SecPkgInfoA *infoA)
573 {
574     PSecPkgInfoW ret;
575 
576     if (infoA)
577     {
578         size_t bytesNeeded = sizeof(SecPkgInfoW);
579         int nameLen = 0, commentLen = 0;
580 
581         if (infoA->Name)
582         {
583             nameLen = MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1,
584              NULL, 0);
585             bytesNeeded += nameLen * sizeof(WCHAR);
586         }
587         if (infoA->Comment)
588         {
589             commentLen = MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1,
590              NULL, 0);
591             bytesNeeded += commentLen * sizeof(WCHAR);
592         }
593         ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
594         if (ret)
595         {
596             PWSTR nextString = (PWSTR)((PBYTE)ret + sizeof(SecPkgInfoW));
597 
598             memcpy(ret, infoA, sizeof(SecPkgInfoA));
599             if (infoA->Name)
600             {
601                 ret->Name = nextString;
602                 MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, nextString,
603                  nameLen);
604                 nextString += nameLen;
605             }
606             else
607                 ret->Name = NULL;
608             if (infoA->Comment)
609             {
610                 ret->Comment = nextString;
611                 MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, nextString,
612                  commentLen);
613             }
614             else
615                 ret->Comment = NULL;
616         }
617     }
618     else
619         ret = NULL;
620     return ret;
621 }
622 
thunk_ContextAttributesAToW(SecurePackage * package,ULONG ulAttribute,void * pBuffer)623 static SECURITY_STATUS thunk_ContextAttributesAToW(SecurePackage *package,
624  ULONG ulAttribute, void *pBuffer)
625 {
626     SECURITY_STATUS ret = SEC_E_OK;
627 
628     if (package && pBuffer)
629     {
630         switch (ulAttribute)
631         {
632             case SECPKG_ATTR_NAMES:
633             {
634                 PSecPkgContext_NamesA names = (PSecPkgContext_NamesA)pBuffer;
635                 SEC_CHAR *oldUser = names->sUserName;
636 
637                 if (oldUser)
638                 {
639                     names->sUserName =
640                      (PSTR)SECUR32_AllocWideFromMultiByte(oldUser);
641                     package->provider->fnTableW.FreeContextBuffer(oldUser);
642                 }
643                 break;
644             }
645             case SECPKG_ATTR_AUTHORITY:
646             {
647                 PSecPkgContext_AuthorityA names =
648                  (PSecPkgContext_AuthorityA)pBuffer;
649                 SEC_CHAR *oldAuth = names->sAuthorityName;
650 
651                 if (oldAuth)
652                 {
653                     names->sAuthorityName =
654                      (PSTR)SECUR32_AllocWideFromMultiByte(oldAuth);
655                     package->provider->fnTableW.FreeContextBuffer(oldAuth);
656                 }
657                 break;
658             }
659             case SECPKG_ATTR_KEY_INFO:
660             {
661                 PSecPkgContext_KeyInfoA info = (PSecPkgContext_KeyInfoA)pBuffer;
662                 SEC_CHAR *oldSigAlgName = info->sSignatureAlgorithmName;
663                 SEC_CHAR *oldEncAlgName = info->sEncryptAlgorithmName;
664 
665                 if (oldSigAlgName)
666                 {
667                     info->sSignatureAlgorithmName =
668                      (PSTR)SECUR32_AllocWideFromMultiByte(oldSigAlgName);
669                     package->provider->fnTableW.FreeContextBuffer(
670                      oldSigAlgName);
671                 }
672                 if (oldEncAlgName)
673                 {
674                     info->sEncryptAlgorithmName =
675                      (PSTR)SECUR32_AllocWideFromMultiByte(
676                      oldEncAlgName);
677                     package->provider->fnTableW.FreeContextBuffer(
678                      oldEncAlgName);
679                 }
680                 break;
681             }
682             case SECPKG_ATTR_PACKAGE_INFO:
683             {
684                 PSecPkgContext_PackageInfoA info =
685                  (PSecPkgContext_PackageInfoA)pBuffer;
686                 PSecPkgInfoA oldPkgInfo = info->PackageInfo;
687 
688                 if (oldPkgInfo)
689                 {
690                     info->PackageInfo = (PSecPkgInfoA)
691                      _copyPackageInfoFlatAToW(oldPkgInfo);
692                     package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
693                 }
694                 break;
695             }
696             case SECPKG_ATTR_NEGOTIATION_INFO:
697             {
698                 PSecPkgContext_NegotiationInfoA info =
699                  (PSecPkgContext_NegotiationInfoA)pBuffer;
700                 PSecPkgInfoA oldPkgInfo = info->PackageInfo;
701 
702                 if (oldPkgInfo)
703                 {
704                     info->PackageInfo = (PSecPkgInfoA)
705                      _copyPackageInfoFlatAToW(oldPkgInfo);
706                     package->provider->fnTableW.FreeContextBuffer(oldPkgInfo);
707                 }
708                 break;
709             }
710             case SECPKG_ATTR_NATIVE_NAMES:
711             {
712                 PSecPkgContext_NativeNamesA names =
713                  (PSecPkgContext_NativeNamesA)pBuffer;
714                 PSTR oldClient = names->sClientName;
715                 PSTR oldServer = names->sServerName;
716 
717                 if (oldClient)
718                 {
719                     names->sClientName = (PSTR)SECUR32_AllocWideFromMultiByte(
720                      oldClient);
721                     package->provider->fnTableW.FreeContextBuffer(oldClient);
722                 }
723                 if (oldServer)
724                 {
725                     names->sServerName = (PSTR)SECUR32_AllocWideFromMultiByte(
726                      oldServer);
727                     package->provider->fnTableW.FreeContextBuffer(oldServer);
728                 }
729                 break;
730             }
731             case SECPKG_ATTR_CREDENTIAL_NAME:
732             {
733                 PSecPkgContext_CredentialNameA name =
734                  (PSecPkgContext_CredentialNameA)pBuffer;
735                 PSTR oldCred = name->sCredentialName;
736 
737                 if (oldCred)
738                 {
739                     name->sCredentialName =
740                      (PSTR)SECUR32_AllocWideFromMultiByte(oldCred);
741                     package->provider->fnTableW.FreeContextBuffer(oldCred);
742                 }
743                 break;
744             }
745             /* no thunking needed: */
746             case SECPKG_ATTR_ACCESS_TOKEN:
747             case SECPKG_ATTR_DCE_INFO:
748             case SECPKG_ATTR_FLAGS:
749             case SECPKG_ATTR_LIFESPAN:
750             case SECPKG_ATTR_PASSWORD_EXPIRY:
751             case SECPKG_ATTR_SESSION_KEY:
752             case SECPKG_ATTR_SIZES:
753             case SECPKG_ATTR_STREAM_SIZES:
754             case SECPKG_ATTR_TARGET_INFORMATION:
755                 break;
756             default:
757                 WARN("attribute type %d unknown\n", ulAttribute);
758                 ret = SEC_E_INTERNAL_ERROR;
759         }
760     }
761     else
762         ret = SEC_E_INVALID_TOKEN;
763     return ret;
764 }
765 
thunk_QueryContextAttributesW(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer)766 SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW(PCtxtHandle phContext,
767  ULONG ulAttribute, void *pBuffer)
768 {
769     SECURITY_STATUS ret;
770 
771     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
772     if (phContext)
773     {
774         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
775         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
776 
777         if (package && package->provider)
778         {
779             if (package->provider->fnTableA.QueryContextAttributesA)
780             {
781                 ret = package->provider->fnTableA.QueryContextAttributesA(
782                  ctxt, ulAttribute, pBuffer);
783                 if (ret == SEC_E_OK)
784                     ret = thunk_ContextAttributesAToW(package, ulAttribute,
785                      pBuffer);
786             }
787             else
788                 ret = SEC_E_UNSUPPORTED_FUNCTION;
789         }
790         else
791             ret = SEC_E_INVALID_HANDLE;
792     }
793     else
794         ret = SEC_E_INVALID_HANDLE;
795     return ret;
796 }
797 
thunk_SetContextAttributesA(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer,ULONG cbBuffer)798 SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext,
799  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
800 {
801     SECURITY_STATUS ret;
802 
803     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
804     if (phContext)
805     {
806         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
807         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
808 
809         if (package && package->provider && pBuffer && cbBuffer)
810         {
811             if (package->provider->fnTableW.SetContextAttributesW)
812             {
813                 /* TODO: gotta validate size too! */
814                 ret = thunk_ContextAttributesWToA(package, ulAttribute,
815                  pBuffer);
816                 if (ret == SEC_E_OK)
817                     ret = package->provider->fnTableW.SetContextAttributesW(
818                      ctxt, ulAttribute, pBuffer, cbBuffer);
819             }
820             else
821                 ret = SEC_E_UNSUPPORTED_FUNCTION;
822         }
823         else
824             ret = SEC_E_INVALID_HANDLE;
825     }
826     else
827         ret = SEC_E_INVALID_HANDLE;
828     return ret;
829 }
830 
thunk_SetContextAttributesW(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer,ULONG cbBuffer)831 SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext,
832  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
833 {
834     SECURITY_STATUS ret;
835 
836     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
837     if (phContext)
838     {
839         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
840         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
841 
842         if (package && package->provider && pBuffer && cbBuffer)
843         {
844             if (package->provider->fnTableA.SetContextAttributesA)
845             {
846                 /* TODO: gotta validate size too! */
847                 ret = thunk_ContextAttributesAToW(package, ulAttribute,
848                  pBuffer);
849                 if (ret == SEC_E_OK)
850                     ret = package->provider->fnTableA.SetContextAttributesA(
851                      ctxt, ulAttribute, pBuffer, cbBuffer);
852             }
853             else
854                 ret = SEC_E_UNSUPPORTED_FUNCTION;
855         }
856         else
857             ret = SEC_E_INVALID_HANDLE;
858     }
859     else
860         ret = SEC_E_INVALID_HANDLE;
861     return ret;
862 }
863 
thunk_ImportSecurityContextA(SEC_CHAR * pszPackage,PSecBuffer pPackedContext,void * Token,PCtxtHandle phContext)864 SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA(
865  SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
866  PCtxtHandle phContext)
867 {
868     SECURITY_STATUS ret;
869     UNICODE_STRING package;
870 
871     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
872      phContext);
873     RtlCreateUnicodeStringFromAsciiz(&package, pszPackage);
874     ret = ImportSecurityContextW(package.Buffer, pPackedContext, Token,
875      phContext);
876     RtlFreeUnicodeString(&package);
877     return ret;
878 }
879 
thunk_ImportSecurityContextW(SEC_WCHAR * pszPackage,PSecBuffer pPackedContext,void * Token,PCtxtHandle phContext)880 SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW(
881  SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token,
882  PCtxtHandle phContext)
883 {
884     SECURITY_STATUS ret;
885     PSTR package = SECUR32_AllocMultiByteFromWide(pszPackage);
886 
887     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
888      phContext);
889     ret = ImportSecurityContextA(package, pPackedContext, Token, phContext);
890     HeapFree(GetProcessHeap(), 0, package);
891     return ret;
892 }
893