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