FreeRDP
sspi.c
1 
20 #include <winpr/platform.h>
21 #include <winpr/config.h>
22 
23 WINPR_PRAGMA_DIAG_PUSH
24 WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
25 WINPR_PRAGMA_DIAG_IGNORED_UNUSED_MACRO
26 
27 #define _NO_KSECDD_IMPORT_ 1 // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
28 
29 WINPR_PRAGMA_DIAG_POP
30 
31 #include <winpr/sspi.h>
32 
33 #include <winpr/crt.h>
34 #include <winpr/synch.h>
35 #include <winpr/wlog.h>
36 #include <winpr/library.h>
37 #include <winpr/environment.h>
38 
39 #include "sspi.h"
40 
41 WINPR_PRAGMA_DIAG_PUSH
42 WINPR_PRAGMA_DIAG_IGNORED_MISSING_PROTOTYPES
43 
44 static wLog* g_Log = NULL;
45 
46 static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
47 #if defined(WITH_NATIVE_SSPI)
48 static HMODULE g_SspiModule = NULL;
49 static SecurityFunctionTableW windows_SecurityFunctionTableW = { 0 };
50 static SecurityFunctionTableA windows_SecurityFunctionTableA = { 0 };
51 #endif
52 
53 static SecurityFunctionTableW* g_SspiW = NULL;
54 static SecurityFunctionTableA* g_SspiA = NULL;
55 
56 #if defined(WITH_NATIVE_SSPI)
57 static BOOL ShouldUseNativeSspi(void);
58 static BOOL InitializeSspiModule_Native(void);
59 #endif
60 
61 #if defined(WITH_NATIVE_SSPI)
62 BOOL ShouldUseNativeSspi(void)
63 {
64  BOOL status = FALSE;
65 #ifdef _WIN32
66  LPCSTR sspi = "WINPR_NATIVE_SSPI";
67  DWORD nSize;
68  char* env = NULL;
69  nSize = GetEnvironmentVariableA(sspi, NULL, 0);
70 
71  if (!nSize)
72  return TRUE;
73 
74  env = (LPSTR)malloc(nSize);
75 
76  if (!env)
77  return TRUE;
78 
79  if (GetEnvironmentVariableA(sspi, env, nSize) != nSize - 1)
80  {
81  free(env);
82  return TRUE;
83  }
84 
85  if (strcmp(env, "0") == 0)
86  status = FALSE;
87  else
88  status = TRUE;
89 
90  free(env);
91 #endif
92  return status;
93 }
94 #endif
95 
96 #if defined(WITH_NATIVE_SSPI)
97 BOOL InitializeSspiModule_Native(void)
98 {
99  SecurityFunctionTableW* pSspiW = NULL;
100  SecurityFunctionTableA* pSspiA = NULL;
101  INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW;
102  INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA;
103  g_SspiModule = LoadLibraryA("secur32.dll");
104 
105  if (!g_SspiModule)
106  g_SspiModule = LoadLibraryA("sspicli.dll");
107 
108  if (!g_SspiModule)
109  return FALSE;
110 
111  pInitSecurityInterfaceW =
112  GetProcAddressAs(g_SspiModule, "InitSecurityInterfaceW", INIT_SECURITY_INTERFACE_W);
113  pInitSecurityInterfaceA =
114  GetProcAddressAs(g_SspiModule, "InitSecurityInterfaceA", INIT_SECURITY_INTERFACE_A);
115 
116  if (pInitSecurityInterfaceW)
117  {
118  pSspiW = pInitSecurityInterfaceW();
119 
120  if (pSspiW)
121  {
122  g_SspiW = &windows_SecurityFunctionTableW;
123  CopyMemory(g_SspiW, pSspiW,
124  FIELD_OFFSET(SecurityFunctionTableW, SetContextAttributesW));
125 
126  g_SspiW->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
127 
128  g_SspiW->SetContextAttributesW = GetProcAddressAs(g_SspiModule, "SetContextAttributesW",
129  SET_CONTEXT_ATTRIBUTES_FN_W);
130 
131  g_SspiW->SetCredentialsAttributesW = GetProcAddressAs(
132  g_SspiModule, "SetCredentialsAttributesW", SET_CREDENTIALS_ATTRIBUTES_FN_W);
133  }
134  }
135 
136  if (pInitSecurityInterfaceA)
137  {
138  pSspiA = pInitSecurityInterfaceA();
139 
140  if (pSspiA)
141  {
142  g_SspiA = &windows_SecurityFunctionTableA;
143  CopyMemory(g_SspiA, pSspiA,
144  FIELD_OFFSET(SecurityFunctionTableA, SetContextAttributesA));
145 
146  g_SspiA->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
147 
148  g_SspiA->SetContextAttributesA = GetProcAddressAs(g_SspiModule, "SetContextAttributesA",
149  SET_CONTEXT_ATTRIBUTES_FN_W);
150 
151  g_SspiA->SetCredentialsAttributesA = GetProcAddressAs(
152  g_SspiModule, "SetCredentialsAttributesA", SET_CREDENTIALS_ATTRIBUTES_FN_W);
153  }
154  }
155 
156  return TRUE;
157 }
158 #endif
159 
160 static BOOL CALLBACK InitializeSspiModuleInt(PINIT_ONCE once, PVOID param, PVOID* context)
161 {
162  BOOL status = FALSE;
163 #if defined(WITH_NATIVE_SSPI)
164  DWORD flags = 0;
165 
166  if (param)
167  flags = *(DWORD*)param;
168 
169 #endif
170  sspi_GlobalInit();
171  g_Log = WLog_Get("com.winpr.sspi");
172 #if defined(WITH_NATIVE_SSPI)
173 
174  if (flags && (flags & SSPI_INTERFACE_NATIVE))
175  {
176  status = InitializeSspiModule_Native();
177  }
178  else if (flags && (flags & SSPI_INTERFACE_WINPR))
179  {
180  g_SspiW = winpr_InitSecurityInterfaceW();
181  g_SspiA = winpr_InitSecurityInterfaceA();
182  status = TRUE;
183  }
184 
185  if (!status && ShouldUseNativeSspi())
186  {
187  status = InitializeSspiModule_Native();
188  }
189 
190 #endif
191 
192  if (!status)
193  {
194  g_SspiW = winpr_InitSecurityInterfaceW();
195  g_SspiA = winpr_InitSecurityInterfaceA();
196  }
197 
198  return TRUE;
199 }
200 
201 const char* GetSecurityStatusString(SECURITY_STATUS status)
202 {
203  switch (status)
204  {
205  case SEC_E_OK:
206  return "SEC_E_OK";
207 
208  case SEC_E_INSUFFICIENT_MEMORY:
209  return "SEC_E_INSUFFICIENT_MEMORY";
210 
211  case SEC_E_INVALID_HANDLE:
212  return "SEC_E_INVALID_HANDLE";
213 
214  case SEC_E_UNSUPPORTED_FUNCTION:
215  return "SEC_E_UNSUPPORTED_FUNCTION";
216 
217  case SEC_E_TARGET_UNKNOWN:
218  return "SEC_E_TARGET_UNKNOWN";
219 
220  case SEC_E_INTERNAL_ERROR:
221  return "SEC_E_INTERNAL_ERROR";
222 
223  case SEC_E_SECPKG_NOT_FOUND:
224  return "SEC_E_SECPKG_NOT_FOUND";
225 
226  case SEC_E_NOT_OWNER:
227  return "SEC_E_NOT_OWNER";
228 
229  case SEC_E_CANNOT_INSTALL:
230  return "SEC_E_CANNOT_INSTALL";
231 
232  case SEC_E_INVALID_TOKEN:
233  return "SEC_E_INVALID_TOKEN";
234 
235  case SEC_E_CANNOT_PACK:
236  return "SEC_E_CANNOT_PACK";
237 
238  case SEC_E_QOP_NOT_SUPPORTED:
239  return "SEC_E_QOP_NOT_SUPPORTED";
240 
241  case SEC_E_NO_IMPERSONATION:
242  return "SEC_E_NO_IMPERSONATION";
243 
244  case SEC_E_LOGON_DENIED:
245  return "SEC_E_LOGON_DENIED";
246 
247  case SEC_E_UNKNOWN_CREDENTIALS:
248  return "SEC_E_UNKNOWN_CREDENTIALS";
249 
250  case SEC_E_NO_CREDENTIALS:
251  return "SEC_E_NO_CREDENTIALS";
252 
253  case SEC_E_MESSAGE_ALTERED:
254  return "SEC_E_MESSAGE_ALTERED";
255 
256  case SEC_E_OUT_OF_SEQUENCE:
257  return "SEC_E_OUT_OF_SEQUENCE";
258 
259  case SEC_E_NO_AUTHENTICATING_AUTHORITY:
260  return "SEC_E_NO_AUTHENTICATING_AUTHORITY";
261 
262  case SEC_E_BAD_PKGID:
263  return "SEC_E_BAD_PKGID";
264 
265  case SEC_E_CONTEXT_EXPIRED:
266  return "SEC_E_CONTEXT_EXPIRED";
267 
268  case SEC_E_INCOMPLETE_MESSAGE:
269  return "SEC_E_INCOMPLETE_MESSAGE";
270 
271  case SEC_E_INCOMPLETE_CREDENTIALS:
272  return "SEC_E_INCOMPLETE_CREDENTIALS";
273 
274  case SEC_E_BUFFER_TOO_SMALL:
275  return "SEC_E_BUFFER_TOO_SMALL";
276 
277  case SEC_E_WRONG_PRINCIPAL:
278  return "SEC_E_WRONG_PRINCIPAL";
279 
280  case SEC_E_TIME_SKEW:
281  return "SEC_E_TIME_SKEW";
282 
283  case SEC_E_UNTRUSTED_ROOT:
284  return "SEC_E_UNTRUSTED_ROOT";
285 
286  case SEC_E_ILLEGAL_MESSAGE:
287  return "SEC_E_ILLEGAL_MESSAGE";
288 
289  case SEC_E_CERT_UNKNOWN:
290  return "SEC_E_CERT_UNKNOWN";
291 
292  case SEC_E_CERT_EXPIRED:
293  return "SEC_E_CERT_EXPIRED";
294 
295  case SEC_E_ENCRYPT_FAILURE:
296  return "SEC_E_ENCRYPT_FAILURE";
297 
298  case SEC_E_DECRYPT_FAILURE:
299  return "SEC_E_DECRYPT_FAILURE";
300 
301  case SEC_E_ALGORITHM_MISMATCH:
302  return "SEC_E_ALGORITHM_MISMATCH";
303 
304  case SEC_E_SECURITY_QOS_FAILED:
305  return "SEC_E_SECURITY_QOS_FAILED";
306 
307  case SEC_E_UNFINISHED_CONTEXT_DELETED:
308  return "SEC_E_UNFINISHED_CONTEXT_DELETED";
309 
310  case SEC_E_NO_TGT_REPLY:
311  return "SEC_E_NO_TGT_REPLY";
312 
313  case SEC_E_NO_IP_ADDRESSES:
314  return "SEC_E_NO_IP_ADDRESSES";
315 
316  case SEC_E_WRONG_CREDENTIAL_HANDLE:
317  return "SEC_E_WRONG_CREDENTIAL_HANDLE";
318 
319  case SEC_E_CRYPTO_SYSTEM_INVALID:
320  return "SEC_E_CRYPTO_SYSTEM_INVALID";
321 
322  case SEC_E_MAX_REFERRALS_EXCEEDED:
323  return "SEC_E_MAX_REFERRALS_EXCEEDED";
324 
325  case SEC_E_MUST_BE_KDC:
326  return "SEC_E_MUST_BE_KDC";
327 
328  case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
329  return "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
330 
331  case SEC_E_TOO_MANY_PRINCIPALS:
332  return "SEC_E_TOO_MANY_PRINCIPALS";
333 
334  case SEC_E_NO_PA_DATA:
335  return "SEC_E_NO_PA_DATA";
336 
337  case SEC_E_PKINIT_NAME_MISMATCH:
338  return "SEC_E_PKINIT_NAME_MISMATCH";
339 
340  case SEC_E_SMARTCARD_LOGON_REQUIRED:
341  return "SEC_E_SMARTCARD_LOGON_REQUIRED";
342 
343  case SEC_E_SHUTDOWN_IN_PROGRESS:
344  return "SEC_E_SHUTDOWN_IN_PROGRESS";
345 
346  case SEC_E_KDC_INVALID_REQUEST:
347  return "SEC_E_KDC_INVALID_REQUEST";
348 
349  case SEC_E_KDC_UNABLE_TO_REFER:
350  return "SEC_E_KDC_UNABLE_TO_REFER";
351 
352  case SEC_E_KDC_UNKNOWN_ETYPE:
353  return "SEC_E_KDC_UNKNOWN_ETYPE";
354 
355  case SEC_E_UNSUPPORTED_PREAUTH:
356  return "SEC_E_UNSUPPORTED_PREAUTH";
357 
358  case SEC_E_DELEGATION_REQUIRED:
359  return "SEC_E_DELEGATION_REQUIRED";
360 
361  case SEC_E_BAD_BINDINGS:
362  return "SEC_E_BAD_BINDINGS";
363 
364  case SEC_E_MULTIPLE_ACCOUNTS:
365  return "SEC_E_MULTIPLE_ACCOUNTS";
366 
367  case SEC_E_NO_KERB_KEY:
368  return "SEC_E_NO_KERB_KEY";
369 
370  case SEC_E_CERT_WRONG_USAGE:
371  return "SEC_E_CERT_WRONG_USAGE";
372 
373  case SEC_E_DOWNGRADE_DETECTED:
374  return "SEC_E_DOWNGRADE_DETECTED";
375 
376  case SEC_E_SMARTCARD_CERT_REVOKED:
377  return "SEC_E_SMARTCARD_CERT_REVOKED";
378 
379  case SEC_E_ISSUING_CA_UNTRUSTED:
380  return "SEC_E_ISSUING_CA_UNTRUSTED";
381 
382  case SEC_E_REVOCATION_OFFLINE_C:
383  return "SEC_E_REVOCATION_OFFLINE_C";
384 
385  case SEC_E_PKINIT_CLIENT_FAILURE:
386  return "SEC_E_PKINIT_CLIENT_FAILURE";
387 
388  case SEC_E_SMARTCARD_CERT_EXPIRED:
389  return "SEC_E_SMARTCARD_CERT_EXPIRED";
390 
391  case SEC_E_NO_S4U_PROT_SUPPORT:
392  return "SEC_E_NO_S4U_PROT_SUPPORT";
393 
394  case SEC_E_CROSSREALM_DELEGATION_FAILURE:
395  return "SEC_E_CROSSREALM_DELEGATION_FAILURE";
396 
397  case SEC_E_REVOCATION_OFFLINE_KDC:
398  return "SEC_E_REVOCATION_OFFLINE_KDC";
399 
400  case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
401  return "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
402 
403  case SEC_E_KDC_CERT_EXPIRED:
404  return "SEC_E_KDC_CERT_EXPIRED";
405 
406  case SEC_E_KDC_CERT_REVOKED:
407  return "SEC_E_KDC_CERT_REVOKED";
408 
409  case SEC_E_INVALID_PARAMETER:
410  return "SEC_E_INVALID_PARAMETER";
411 
412  case SEC_E_DELEGATION_POLICY:
413  return "SEC_E_DELEGATION_POLICY";
414 
415  case SEC_E_POLICY_NLTM_ONLY:
416  return "SEC_E_POLICY_NLTM_ONLY";
417 
418  case SEC_E_NO_CONTEXT:
419  return "SEC_E_NO_CONTEXT";
420 
421  case SEC_E_PKU2U_CERT_FAILURE:
422  return "SEC_E_PKU2U_CERT_FAILURE";
423 
424  case SEC_E_MUTUAL_AUTH_FAILED:
425  return "SEC_E_MUTUAL_AUTH_FAILED";
426 
427  case SEC_I_CONTINUE_NEEDED:
428  return "SEC_I_CONTINUE_NEEDED";
429 
430  case SEC_I_COMPLETE_NEEDED:
431  return "SEC_I_COMPLETE_NEEDED";
432 
433  case SEC_I_COMPLETE_AND_CONTINUE:
434  return "SEC_I_COMPLETE_AND_CONTINUE";
435 
436  case SEC_I_LOCAL_LOGON:
437  return "SEC_I_LOCAL_LOGON";
438 
439  case SEC_I_CONTEXT_EXPIRED:
440  return "SEC_I_CONTEXT_EXPIRED";
441 
442  case SEC_I_INCOMPLETE_CREDENTIALS:
443  return "SEC_I_INCOMPLETE_CREDENTIALS";
444 
445  case SEC_I_RENEGOTIATE:
446  return "SEC_I_RENEGOTIATE";
447 
448  case SEC_I_NO_LSA_CONTEXT:
449  return "SEC_I_NO_LSA_CONTEXT";
450 
451  case SEC_I_SIGNATURE_NEEDED:
452  return "SEC_I_SIGNATURE_NEEDED";
453 
454  case SEC_I_NO_RENEGOTIATION:
455  return "SEC_I_NO_RENEGOTIATION";
456  default:
457  break;
458  }
459 
460  return NtStatus2Tag((DWORD)status);
461 }
462 
463 BOOL IsSecurityStatusError(SECURITY_STATUS status)
464 {
465  BOOL error = TRUE;
466 
467  switch (status)
468  {
469  case SEC_E_OK:
470  case SEC_I_CONTINUE_NEEDED:
471  case SEC_I_COMPLETE_NEEDED:
472  case SEC_I_COMPLETE_AND_CONTINUE:
473  case SEC_I_LOCAL_LOGON:
474  case SEC_I_CONTEXT_EXPIRED:
475  case SEC_I_INCOMPLETE_CREDENTIALS:
476  case SEC_I_RENEGOTIATE:
477  case SEC_I_NO_LSA_CONTEXT:
478  case SEC_I_SIGNATURE_NEEDED:
479  case SEC_I_NO_RENEGOTIATION:
480  error = FALSE;
481  break;
482  default:
483  break;
484  }
485 
486  return error;
487 }
488 
489 SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceExW(DWORD flags)
490 {
491  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL);
492  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExW");
493  return g_SspiW;
494 }
495 
496 SecurityFunctionTableA* SEC_ENTRY InitSecurityInterfaceExA(DWORD flags)
497 {
498  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL);
499  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExA");
500  return g_SspiA;
501 }
502 
507 /* Package Management */
508 
509 SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesW(ULONG* pcPackages,
510  PSecPkgInfoW* ppPackageInfo)
511 {
512  SECURITY_STATUS status = 0;
513  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
514 
515  if (!(g_SspiW && g_SspiW->EnumerateSecurityPackagesW))
516  {
517  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
518 
519  return SEC_E_UNSUPPORTED_FUNCTION;
520  }
521 
522  status = g_SspiW->EnumerateSecurityPackagesW(pcPackages, ppPackageInfo);
523  WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesW: %s (0x%08" PRIX32 ")",
524  GetSecurityStatusString(status), status);
525  return status;
526 }
527 
528 SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesA(ULONG* pcPackages,
529  PSecPkgInfoA* ppPackageInfo)
530 {
531  SECURITY_STATUS status = 0;
532  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
533 
534  if (!(g_SspiA && g_SspiA->EnumerateSecurityPackagesA))
535  {
536  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
537 
538  return SEC_E_UNSUPPORTED_FUNCTION;
539  }
540 
541  status = g_SspiA->EnumerateSecurityPackagesA(pcPackages, ppPackageInfo);
542  WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesA: %s (0x%08" PRIX32 ")",
543  GetSecurityStatusString(status), status);
544  return status;
545 }
546 
547 SecurityFunctionTableW* SEC_ENTRY sspi_InitSecurityInterfaceW(void)
548 {
549  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
550  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceW");
551  return g_SspiW;
552 }
553 
554 SecurityFunctionTableA* SEC_ENTRY sspi_InitSecurityInterfaceA(void)
555 {
556  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
557  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceA");
558  return g_SspiA;
559 }
560 
561 SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
562  PSecPkgInfoW* ppPackageInfo)
563 {
564  SECURITY_STATUS status = 0;
565  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
566 
567  if (!(g_SspiW && g_SspiW->QuerySecurityPackageInfoW))
568  {
569  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
570 
571  return SEC_E_UNSUPPORTED_FUNCTION;
572  }
573 
574  status = g_SspiW->QuerySecurityPackageInfoW(pszPackageName, ppPackageInfo);
575  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoW: %s (0x%08" PRIX32 ")",
576  GetSecurityStatusString(status), status);
577  return status;
578 }
579 
580 SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
581  PSecPkgInfoA* ppPackageInfo)
582 {
583  SECURITY_STATUS status = 0;
584  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
585 
586  if (!(g_SspiA && g_SspiA->QuerySecurityPackageInfoA))
587  {
588  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
589 
590  return SEC_E_UNSUPPORTED_FUNCTION;
591  }
592 
593  status = g_SspiA->QuerySecurityPackageInfoA(pszPackageName, ppPackageInfo);
594  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoA: %s (0x%08" PRIX32 ")",
595  GetSecurityStatusString(status), status);
596  return status;
597 }
598 
599 /* Credential Management */
600 
601 SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleW(
602  SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
603  void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
604  PTimeStamp ptsExpiry)
605 {
606  SECURITY_STATUS status = 0;
607  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
608 
609  if (!(g_SspiW && g_SspiW->AcquireCredentialsHandleW))
610  {
611  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
612 
613  return SEC_E_UNSUPPORTED_FUNCTION;
614  }
615 
616  status = g_SspiW->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
617  pAuthData, pGetKeyFn, pvGetKeyArgument,
618  phCredential, ptsExpiry);
619  WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleW: %s (0x%08" PRIX32 ")",
620  GetSecurityStatusString(status), status);
621  return status;
622 }
623 
624 SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleA(
625  SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
626  void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
627  PTimeStamp ptsExpiry)
628 {
629  SECURITY_STATUS status = 0;
630  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
631 
632  if (!(g_SspiA && g_SspiA->AcquireCredentialsHandleA))
633  {
634  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
635 
636  return SEC_E_UNSUPPORTED_FUNCTION;
637  }
638 
639  status = g_SspiA->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
640  pAuthData, pGetKeyFn, pvGetKeyArgument,
641  phCredential, ptsExpiry);
642  WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleA: %s (0x%08" PRIX32 ")",
643  GetSecurityStatusString(status), status);
644  return status;
645 }
646 
647 SECURITY_STATUS SEC_ENTRY sspi_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags,
648  PSecBuffer pPackedContext, HANDLE* pToken)
649 {
650  SECURITY_STATUS status = 0;
651  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
652 
653  if (!(g_SspiW && g_SspiW->ExportSecurityContext))
654  {
655  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
656 
657  return SEC_E_UNSUPPORTED_FUNCTION;
658  }
659 
660  status = g_SspiW->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
661  WLog_Print(g_Log, WLOG_DEBUG, "ExportSecurityContext: %s (0x%08" PRIX32 ")",
662  GetSecurityStatusString(status), status);
663  return status;
664 }
665 
666 SECURITY_STATUS SEC_ENTRY sspi_FreeCredentialsHandle(PCredHandle phCredential)
667 {
668  SECURITY_STATUS status = 0;
669  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
670 
671  if (!(g_SspiW && g_SspiW->FreeCredentialsHandle))
672  {
673  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
674 
675  return SEC_E_UNSUPPORTED_FUNCTION;
676  }
677 
678  status = g_SspiW->FreeCredentialsHandle(phCredential);
679  WLog_Print(g_Log, WLOG_DEBUG, "FreeCredentialsHandle: %s (0x%08" PRIX32 ")",
680  GetSecurityStatusString(status), status);
681  return status;
682 }
683 
684 SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextW(SEC_WCHAR* pszPackage,
685  PSecBuffer pPackedContext, HANDLE pToken,
686  PCtxtHandle phContext)
687 {
688  SECURITY_STATUS status = 0;
689  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
690 
691  if (!(g_SspiW && g_SspiW->ImportSecurityContextW))
692  {
693  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
694 
695  return SEC_E_UNSUPPORTED_FUNCTION;
696  }
697 
698  status = g_SspiW->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
699  WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextW: %s (0x%08" PRIX32 ")",
700  GetSecurityStatusString(status), status);
701  return status;
702 }
703 
704 SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextA(SEC_CHAR* pszPackage,
705  PSecBuffer pPackedContext, HANDLE pToken,
706  PCtxtHandle phContext)
707 {
708  SECURITY_STATUS status = 0;
709  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
710 
711  if (!(g_SspiA && g_SspiA->ImportSecurityContextA))
712  {
713  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
714 
715  return SEC_E_UNSUPPORTED_FUNCTION;
716  }
717 
718  status = g_SspiA->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
719  WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextA: %s (0x%08" PRIX32 ")",
720  GetSecurityStatusString(status), status);
721  return status;
722 }
723 
724 SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesW(PCredHandle phCredential,
725  ULONG ulAttribute, void* pBuffer)
726 {
727  SECURITY_STATUS status = 0;
728  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
729 
730  if (!(g_SspiW && g_SspiW->QueryCredentialsAttributesW))
731  {
732  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
733 
734  return SEC_E_UNSUPPORTED_FUNCTION;
735  }
736 
737  status = g_SspiW->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
738  WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesW: %s (0x%08" PRIX32 ")",
739  GetSecurityStatusString(status), status);
740  return status;
741 }
742 
743 SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesA(PCredHandle phCredential,
744  ULONG ulAttribute, void* pBuffer)
745 {
746  SECURITY_STATUS status = 0;
747  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
748 
749  if (!(g_SspiA && g_SspiA->QueryCredentialsAttributesA))
750  {
751  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
752 
753  return SEC_E_UNSUPPORTED_FUNCTION;
754  }
755 
756  status = g_SspiA->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
757  WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesA: %s (0x%08" PRIX32 ")",
758  GetSecurityStatusString(status), status);
759  return status;
760 }
761 
762 /* Context Management */
763 
764 SECURITY_STATUS SEC_ENTRY sspi_AcceptSecurityContext(PCredHandle phCredential,
765  PCtxtHandle phContext, PSecBufferDesc pInput,
766  ULONG fContextReq, ULONG TargetDataRep,
767  PCtxtHandle phNewContext,
768  PSecBufferDesc pOutput, PULONG pfContextAttr,
769  PTimeStamp ptsTimeStamp)
770 {
771  SECURITY_STATUS status = 0;
772  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
773 
774  if (!(g_SspiW && g_SspiW->AcceptSecurityContext))
775  {
776  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
777 
778  return SEC_E_UNSUPPORTED_FUNCTION;
779  }
780 
781  status =
782  g_SspiW->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
783  phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
784  WLog_Print(g_Log, WLOG_DEBUG, "AcceptSecurityContext: %s (0x%08" PRIX32 ")",
785  GetSecurityStatusString(status), status);
786  return status;
787 }
788 
789 SECURITY_STATUS SEC_ENTRY sspi_ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput)
790 {
791  SECURITY_STATUS status = 0;
792  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
793 
794  if (!(g_SspiW && g_SspiW->ApplyControlToken))
795  {
796  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
797 
798  return SEC_E_UNSUPPORTED_FUNCTION;
799  }
800 
801  status = g_SspiW->ApplyControlToken(phContext, pInput);
802  WLog_Print(g_Log, WLOG_DEBUG, "ApplyControlToken: %s (0x%08" PRIX32 ")",
803  GetSecurityStatusString(status), status);
804  return status;
805 }
806 
807 SECURITY_STATUS SEC_ENTRY sspi_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
808 {
809  SECURITY_STATUS status = 0;
810  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
811 
812  if (!(g_SspiW && g_SspiW->CompleteAuthToken))
813  {
814  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
815 
816  return SEC_E_UNSUPPORTED_FUNCTION;
817  }
818 
819  status = g_SspiW->CompleteAuthToken(phContext, pToken);
820  WLog_Print(g_Log, WLOG_DEBUG, "CompleteAuthToken: %s (0x%08" PRIX32 ")",
821  GetSecurityStatusString(status), status);
822  return status;
823 }
824 
825 SECURITY_STATUS SEC_ENTRY sspi_DeleteSecurityContext(PCtxtHandle phContext)
826 {
827  SECURITY_STATUS status = 0;
828  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
829 
830  if (!(g_SspiW && g_SspiW->DeleteSecurityContext))
831  {
832  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
833 
834  return SEC_E_UNSUPPORTED_FUNCTION;
835  }
836 
837  status = g_SspiW->DeleteSecurityContext(phContext);
838  WLog_Print(g_Log, WLOG_DEBUG, "DeleteSecurityContext: %s (0x%08" PRIX32 ")",
839  GetSecurityStatusString(status), status);
840  return status;
841 }
842 
843 SECURITY_STATUS SEC_ENTRY sspi_FreeContextBuffer(void* pvContextBuffer)
844 {
845  SECURITY_STATUS status = 0;
846  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
847 
848  if (!(g_SspiW && g_SspiW->FreeContextBuffer))
849  {
850  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
851 
852  return SEC_E_UNSUPPORTED_FUNCTION;
853  }
854 
855  status = g_SspiW->FreeContextBuffer(pvContextBuffer);
856  WLog_Print(g_Log, WLOG_DEBUG, "FreeContextBuffer: %s (0x%08" PRIX32 ")",
857  GetSecurityStatusString(status), status);
858  return status;
859 }
860 
861 SECURITY_STATUS SEC_ENTRY sspi_ImpersonateSecurityContext(PCtxtHandle phContext)
862 {
863  SECURITY_STATUS status = 0;
864  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
865 
866  if (!(g_SspiW && g_SspiW->ImpersonateSecurityContext))
867  {
868  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
869 
870  return SEC_E_UNSUPPORTED_FUNCTION;
871  }
872 
873  status = g_SspiW->ImpersonateSecurityContext(phContext);
874  WLog_Print(g_Log, WLOG_DEBUG, "ImpersonateSecurityContext: %s (0x%08" PRIX32 ")",
875  GetSecurityStatusString(status), status);
876  return status;
877 }
878 
879 SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextW(
880  PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq,
881  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
882  PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
883 {
884  SECURITY_STATUS status = 0;
885  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
886 
887  if (!(g_SspiW && g_SspiW->InitializeSecurityContextW))
888  {
889  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
890 
891  return SEC_E_UNSUPPORTED_FUNCTION;
892  }
893 
894  status = g_SspiW->InitializeSecurityContextW(
895  phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
896  Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
897  WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextW: %s (0x%08" PRIX32 ")",
898  GetSecurityStatusString(status), status);
899  return status;
900 }
901 
902 SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextA(
903  PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq,
904  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
905  PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
906 {
907  SECURITY_STATUS status = 0;
908  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
909 
910  if (!(g_SspiA && g_SspiA->InitializeSecurityContextA))
911  {
912  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
913 
914  return SEC_E_UNSUPPORTED_FUNCTION;
915  }
916 
917  status = g_SspiA->InitializeSecurityContextA(
918  phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
919  Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
920  WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextA: %s (0x%08" PRIX32 ")",
921  GetSecurityStatusString(status), status);
922  return status;
923 }
924 
925 SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
926  void* pBuffer)
927 {
928  SECURITY_STATUS status = 0;
929  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
930 
931  if (!(g_SspiW && g_SspiW->QueryContextAttributesW))
932  {
933  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
934 
935  return SEC_E_UNSUPPORTED_FUNCTION;
936  }
937 
938  status = g_SspiW->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
939  WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesW: %s (0x%08" PRIX32 ")",
940  GetSecurityStatusString(status), status);
941  return status;
942 }
943 
944 SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
945  void* pBuffer)
946 {
947  SECURITY_STATUS status = 0;
948  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
949 
950  if (!(g_SspiA && g_SspiA->QueryContextAttributesA))
951  {
952  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
953 
954  return SEC_E_UNSUPPORTED_FUNCTION;
955  }
956 
957  status = g_SspiA->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
958  WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesA: %s (0x%08" PRIX32 ")",
959  GetSecurityStatusString(status), status);
960  return status;
961 }
962 
963 SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken)
964 {
965  SECURITY_STATUS status = 0;
966  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
967 
968  if (!(g_SspiW && g_SspiW->QuerySecurityContextToken))
969  {
970  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
971 
972  return SEC_E_UNSUPPORTED_FUNCTION;
973  }
974 
975  status = g_SspiW->QuerySecurityContextToken(phContext, phToken);
976  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityContextToken: %s (0x%08" PRIX32 ")",
977  GetSecurityStatusString(status), status);
978  return status;
979 }
980 
981 SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
982  void* pBuffer, ULONG cbBuffer)
983 {
984  SECURITY_STATUS status = 0;
985  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
986 
987  if (!(g_SspiW && g_SspiW->SetContextAttributesW))
988  {
989  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
990 
991  return SEC_E_UNSUPPORTED_FUNCTION;
992  }
993 
994  status = g_SspiW->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
995  WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesW: %s (0x%08" PRIX32 ")",
996  GetSecurityStatusString(status), status);
997  return status;
998 }
999 
1000 SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
1001  void* pBuffer, ULONG cbBuffer)
1002 {
1003  SECURITY_STATUS status = 0;
1004  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1005 
1006  if (!(g_SspiA && g_SspiA->SetContextAttributesA))
1007  {
1008  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1009 
1010  return SEC_E_UNSUPPORTED_FUNCTION;
1011  }
1012 
1013  status = g_SspiA->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
1014  WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesA: %s (0x%08" PRIX32 ")",
1015  GetSecurityStatusString(status), status);
1016  return status;
1017 }
1018 
1019 SECURITY_STATUS SEC_ENTRY sspi_RevertSecurityContext(PCtxtHandle phContext)
1020 {
1021  SECURITY_STATUS status = 0;
1022  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1023 
1024  if (!(g_SspiW && g_SspiW->RevertSecurityContext))
1025  {
1026  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1027 
1028  return SEC_E_UNSUPPORTED_FUNCTION;
1029  }
1030 
1031  status = g_SspiW->RevertSecurityContext(phContext);
1032  WLog_Print(g_Log, WLOG_DEBUG, "RevertSecurityContext: %s (0x%08" PRIX32 ")",
1033  GetSecurityStatusString(status), status);
1034  return status;
1035 }
1036 
1037 /* Message Support */
1038 
1039 SECURITY_STATUS SEC_ENTRY sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage,
1040  ULONG MessageSeqNo, PULONG pfQOP)
1041 {
1042  SECURITY_STATUS status = 0;
1043  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1044 
1045  if (!(g_SspiW && g_SspiW->DecryptMessage))
1046  {
1047  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1048 
1049  return SEC_E_UNSUPPORTED_FUNCTION;
1050  }
1051 
1052  status = g_SspiW->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
1053  WLog_Print(g_Log, WLOG_DEBUG, "DecryptMessage: %s (0x%08" PRIX32 ")",
1054  GetSecurityStatusString(status), status);
1055  return status;
1056 }
1057 
1058 SECURITY_STATUS SEC_ENTRY sspi_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
1059  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1060 {
1061  SECURITY_STATUS status = 0;
1062  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1063 
1064  if (!(g_SspiW && g_SspiW->EncryptMessage))
1065  {
1066  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1067 
1068  return SEC_E_UNSUPPORTED_FUNCTION;
1069  }
1070 
1071  status = g_SspiW->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
1072  WLog_Print(g_Log, WLOG_DEBUG, "EncryptMessage: %s (0x%08" PRIX32 ")",
1073  GetSecurityStatusString(status), status);
1074  return status;
1075 }
1076 
1077 SECURITY_STATUS SEC_ENTRY sspi_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
1078  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1079 {
1080  SECURITY_STATUS status = 0;
1081  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1082 
1083  if (!(g_SspiW && g_SspiW->MakeSignature))
1084  {
1085  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1086 
1087  return SEC_E_UNSUPPORTED_FUNCTION;
1088  }
1089 
1090  status = g_SspiW->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
1091  WLog_Print(g_Log, WLOG_DEBUG, "MakeSignature: %s (0x%08" PRIX32 ")",
1092  GetSecurityStatusString(status), status);
1093  return status;
1094 }
1095 
1096 SECURITY_STATUS SEC_ENTRY sspi_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage,
1097  ULONG MessageSeqNo, PULONG pfQOP)
1098 {
1099  SECURITY_STATUS status = 0;
1100  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
1101 
1102  if (!(g_SspiW && g_SspiW->VerifySignature))
1103  {
1104  WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
1105 
1106  return SEC_E_UNSUPPORTED_FUNCTION;
1107  }
1108 
1109  status = g_SspiW->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1110  WLog_Print(g_Log, WLOG_DEBUG, "VerifySignature: %s (0x%08" PRIX32 ")",
1111  GetSecurityStatusString(status), status);
1112  return status;
1113 }
1114 
1115 WINPR_PRAGMA_DIAG_POP
1116 
1117 void sspi_FreeAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity)
1118 {
1119  if (!identity)
1120  return;
1121  free(identity->User);
1122  identity->UserLength = (UINT32)0;
1123  identity->User = NULL;
1124 
1125  free(identity->Domain);
1126  identity->DomainLength = (UINT32)0;
1127  identity->Domain = NULL;
1128 
1129  if (identity->PasswordLength > 0)
1130  memset(identity->Password, 0, identity->PasswordLength);
1131  free(identity->Password);
1132  identity->Password = NULL;
1133  identity->PasswordLength = (UINT32)0;
1134 }