20#include <winpr/platform.h> 
   21#include <winpr/config.h> 
   24WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
 
   25WINPR_PRAGMA_DIAG_IGNORED_UNUSED_MACRO
 
   27#define _NO_KSECDD_IMPORT_ 1  
   31#include <winpr/sspi.h> 
   34#include <winpr/synch.h> 
   35#include <winpr/wlog.h> 
   36#include <winpr/library.h> 
   37#include <winpr/environment.h> 
   42WINPR_PRAGMA_DIAG_IGNORED_MISSING_PROTOTYPES
 
   44static wLog* g_Log = NULL;
 
   46static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
 
   47#if defined(WITH_NATIVE_SSPI) 
   48static HMODULE g_SspiModule = NULL;
 
   56#if defined(WITH_NATIVE_SSPI) 
   57static BOOL ShouldUseNativeSspi(
void);
 
   58static BOOL InitializeSspiModule_Native(
void);
 
   61#if defined(WITH_NATIVE_SSPI) 
   62BOOL ShouldUseNativeSspi(
void)
 
   66  LPCSTR sspi = 
"WINPR_NATIVE_SSPI";
 
   69  nSize = GetEnvironmentVariableA(sspi, NULL, 0);
 
   74  env = (LPSTR)malloc(nSize);
 
   79  if (GetEnvironmentVariableA(sspi, env, nSize) != nSize - 1)
 
   85  if (strcmp(env, 
"0") == 0)
 
   96#if defined(WITH_NATIVE_SSPI) 
   97BOOL InitializeSspiModule_Native(
void)
 
  101  INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW;
 
  102  INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA;
 
  103  g_SspiModule = LoadLibraryA(
"secur32.dll");
 
  106    g_SspiModule = LoadLibraryA(
"sspicli.dll");
 
  111  pInitSecurityInterfaceW =
 
  112      GetProcAddressAs(g_SspiModule, 
"InitSecurityInterfaceW", INIT_SECURITY_INTERFACE_W);
 
  113  pInitSecurityInterfaceA =
 
  114      GetProcAddressAs(g_SspiModule, 
"InitSecurityInterfaceA", INIT_SECURITY_INTERFACE_A);
 
  116  if (pInitSecurityInterfaceW)
 
  118    pSspiW = pInitSecurityInterfaceW();
 
  122      g_SspiW = &windows_SecurityFunctionTableW;
 
  123      CopyMemory(g_SspiW, pSspiW,
 
  126      g_SspiW->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
 
  128      g_SspiW->SetContextAttributesW = GetProcAddressAs(g_SspiModule, 
"SetContextAttributesW",
 
  129                                                        SET_CONTEXT_ATTRIBUTES_FN_W);
 
  131      g_SspiW->SetCredentialsAttributesW = GetProcAddressAs(
 
  132          g_SspiModule, 
"SetCredentialsAttributesW", SET_CREDENTIALS_ATTRIBUTES_FN_W);
 
  136  if (pInitSecurityInterfaceA)
 
  138    pSspiA = pInitSecurityInterfaceA();
 
  142      g_SspiA = &windows_SecurityFunctionTableA;
 
  143      CopyMemory(g_SspiA, pSspiA,
 
  146      g_SspiA->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
 
  148      g_SspiA->SetContextAttributesA = GetProcAddressAs(g_SspiModule, 
"SetContextAttributesA",
 
  149                                                        SET_CONTEXT_ATTRIBUTES_FN_W);
 
  151      g_SspiA->SetCredentialsAttributesA = GetProcAddressAs(
 
  152          g_SspiModule, 
"SetCredentialsAttributesA", SET_CREDENTIALS_ATTRIBUTES_FN_W);
 
  160static BOOL CALLBACK InitializeSspiModuleInt(WINPR_ATTR_UNUSED 
PINIT_ONCE once,
 
  161                                             WINPR_ATTR_UNUSED PVOID param,
 
  162                                             WINPR_ATTR_UNUSED PVOID* context)
 
  165#if defined(WITH_NATIVE_SSPI) 
  169    flags = *(DWORD*)param;
 
  173  g_Log = WLog_Get(
"com.winpr.sspi");
 
  174#if defined(WITH_NATIVE_SSPI) 
  176  if (flags && (flags & SSPI_INTERFACE_NATIVE))
 
  178    status = InitializeSspiModule_Native();
 
  180  else if (flags && (flags & SSPI_INTERFACE_WINPR))
 
  182    g_SspiW = winpr_InitSecurityInterfaceW();
 
  183    g_SspiA = winpr_InitSecurityInterfaceA();
 
  187  if (!status && ShouldUseNativeSspi())
 
  189    status = InitializeSspiModule_Native();
 
  196    g_SspiW = winpr_InitSecurityInterfaceW();
 
  197    g_SspiA = winpr_InitSecurityInterfaceA();
 
  203const char* GetSecurityStatusString(SECURITY_STATUS status)
 
  210    case SEC_E_INSUFFICIENT_MEMORY:
 
  211      return "SEC_E_INSUFFICIENT_MEMORY";
 
  213    case SEC_E_INVALID_HANDLE:
 
  214      return "SEC_E_INVALID_HANDLE";
 
  216    case SEC_E_UNSUPPORTED_FUNCTION:
 
  217      return "SEC_E_UNSUPPORTED_FUNCTION";
 
  219    case SEC_E_TARGET_UNKNOWN:
 
  220      return "SEC_E_TARGET_UNKNOWN";
 
  222    case SEC_E_INTERNAL_ERROR:
 
  223      return "SEC_E_INTERNAL_ERROR";
 
  225    case SEC_E_SECPKG_NOT_FOUND:
 
  226      return "SEC_E_SECPKG_NOT_FOUND";
 
  228    case SEC_E_NOT_OWNER:
 
  229      return "SEC_E_NOT_OWNER";
 
  231    case SEC_E_CANNOT_INSTALL:
 
  232      return "SEC_E_CANNOT_INSTALL";
 
  234    case SEC_E_INVALID_TOKEN:
 
  235      return "SEC_E_INVALID_TOKEN";
 
  237    case SEC_E_CANNOT_PACK:
 
  238      return "SEC_E_CANNOT_PACK";
 
  240    case SEC_E_QOP_NOT_SUPPORTED:
 
  241      return "SEC_E_QOP_NOT_SUPPORTED";
 
  243    case SEC_E_NO_IMPERSONATION:
 
  244      return "SEC_E_NO_IMPERSONATION";
 
  246    case SEC_E_LOGON_DENIED:
 
  247      return "SEC_E_LOGON_DENIED";
 
  249    case SEC_E_UNKNOWN_CREDENTIALS:
 
  250      return "SEC_E_UNKNOWN_CREDENTIALS";
 
  252    case SEC_E_NO_CREDENTIALS:
 
  253      return "SEC_E_NO_CREDENTIALS";
 
  255    case SEC_E_MESSAGE_ALTERED:
 
  256      return "SEC_E_MESSAGE_ALTERED";
 
  258    case SEC_E_OUT_OF_SEQUENCE:
 
  259      return "SEC_E_OUT_OF_SEQUENCE";
 
  261    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
 
  262      return "SEC_E_NO_AUTHENTICATING_AUTHORITY";
 
  264    case SEC_E_BAD_PKGID:
 
  265      return "SEC_E_BAD_PKGID";
 
  267    case SEC_E_CONTEXT_EXPIRED:
 
  268      return "SEC_E_CONTEXT_EXPIRED";
 
  270    case SEC_E_INCOMPLETE_MESSAGE:
 
  271      return "SEC_E_INCOMPLETE_MESSAGE";
 
  273    case SEC_E_INCOMPLETE_CREDENTIALS:
 
  274      return "SEC_E_INCOMPLETE_CREDENTIALS";
 
  276    case SEC_E_BUFFER_TOO_SMALL:
 
  277      return "SEC_E_BUFFER_TOO_SMALL";
 
  279    case SEC_E_WRONG_PRINCIPAL:
 
  280      return "SEC_E_WRONG_PRINCIPAL";
 
  282    case SEC_E_TIME_SKEW:
 
  283      return "SEC_E_TIME_SKEW";
 
  285    case SEC_E_UNTRUSTED_ROOT:
 
  286      return "SEC_E_UNTRUSTED_ROOT";
 
  288    case SEC_E_ILLEGAL_MESSAGE:
 
  289      return "SEC_E_ILLEGAL_MESSAGE";
 
  291    case SEC_E_CERT_UNKNOWN:
 
  292      return "SEC_E_CERT_UNKNOWN";
 
  294    case SEC_E_CERT_EXPIRED:
 
  295      return "SEC_E_CERT_EXPIRED";
 
  297    case SEC_E_ENCRYPT_FAILURE:
 
  298      return "SEC_E_ENCRYPT_FAILURE";
 
  300    case SEC_E_DECRYPT_FAILURE:
 
  301      return "SEC_E_DECRYPT_FAILURE";
 
  303    case SEC_E_ALGORITHM_MISMATCH:
 
  304      return "SEC_E_ALGORITHM_MISMATCH";
 
  306    case SEC_E_SECURITY_QOS_FAILED:
 
  307      return "SEC_E_SECURITY_QOS_FAILED";
 
  309    case SEC_E_UNFINISHED_CONTEXT_DELETED:
 
  310      return "SEC_E_UNFINISHED_CONTEXT_DELETED";
 
  312    case SEC_E_NO_TGT_REPLY:
 
  313      return "SEC_E_NO_TGT_REPLY";
 
  315    case SEC_E_NO_IP_ADDRESSES:
 
  316      return "SEC_E_NO_IP_ADDRESSES";
 
  318    case SEC_E_WRONG_CREDENTIAL_HANDLE:
 
  319      return "SEC_E_WRONG_CREDENTIAL_HANDLE";
 
  321    case SEC_E_CRYPTO_SYSTEM_INVALID:
 
  322      return "SEC_E_CRYPTO_SYSTEM_INVALID";
 
  324    case SEC_E_MAX_REFERRALS_EXCEEDED:
 
  325      return "SEC_E_MAX_REFERRALS_EXCEEDED";
 
  327    case SEC_E_MUST_BE_KDC:
 
  328      return "SEC_E_MUST_BE_KDC";
 
  330    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
 
  331      return "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
 
  333    case SEC_E_TOO_MANY_PRINCIPALS:
 
  334      return "SEC_E_TOO_MANY_PRINCIPALS";
 
  336    case SEC_E_NO_PA_DATA:
 
  337      return "SEC_E_NO_PA_DATA";
 
  339    case SEC_E_PKINIT_NAME_MISMATCH:
 
  340      return "SEC_E_PKINIT_NAME_MISMATCH";
 
  342    case SEC_E_SMARTCARD_LOGON_REQUIRED:
 
  343      return "SEC_E_SMARTCARD_LOGON_REQUIRED";
 
  345    case SEC_E_SHUTDOWN_IN_PROGRESS:
 
  346      return "SEC_E_SHUTDOWN_IN_PROGRESS";
 
  348    case SEC_E_KDC_INVALID_REQUEST:
 
  349      return "SEC_E_KDC_INVALID_REQUEST";
 
  351    case SEC_E_KDC_UNABLE_TO_REFER:
 
  352      return "SEC_E_KDC_UNABLE_TO_REFER";
 
  354    case SEC_E_KDC_UNKNOWN_ETYPE:
 
  355      return "SEC_E_KDC_UNKNOWN_ETYPE";
 
  357    case SEC_E_UNSUPPORTED_PREAUTH:
 
  358      return "SEC_E_UNSUPPORTED_PREAUTH";
 
  360    case SEC_E_DELEGATION_REQUIRED:
 
  361      return "SEC_E_DELEGATION_REQUIRED";
 
  363    case SEC_E_BAD_BINDINGS:
 
  364      return "SEC_E_BAD_BINDINGS";
 
  366    case SEC_E_MULTIPLE_ACCOUNTS:
 
  367      return "SEC_E_MULTIPLE_ACCOUNTS";
 
  369    case SEC_E_NO_KERB_KEY:
 
  370      return "SEC_E_NO_KERB_KEY";
 
  372    case SEC_E_CERT_WRONG_USAGE:
 
  373      return "SEC_E_CERT_WRONG_USAGE";
 
  375    case SEC_E_DOWNGRADE_DETECTED:
 
  376      return "SEC_E_DOWNGRADE_DETECTED";
 
  378    case SEC_E_SMARTCARD_CERT_REVOKED:
 
  379      return "SEC_E_SMARTCARD_CERT_REVOKED";
 
  381    case SEC_E_ISSUING_CA_UNTRUSTED:
 
  382      return "SEC_E_ISSUING_CA_UNTRUSTED";
 
  384    case SEC_E_REVOCATION_OFFLINE_C:
 
  385      return "SEC_E_REVOCATION_OFFLINE_C";
 
  387    case SEC_E_PKINIT_CLIENT_FAILURE:
 
  388      return "SEC_E_PKINIT_CLIENT_FAILURE";
 
  390    case SEC_E_SMARTCARD_CERT_EXPIRED:
 
  391      return "SEC_E_SMARTCARD_CERT_EXPIRED";
 
  393    case SEC_E_NO_S4U_PROT_SUPPORT:
 
  394      return "SEC_E_NO_S4U_PROT_SUPPORT";
 
  396    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
 
  397      return "SEC_E_CROSSREALM_DELEGATION_FAILURE";
 
  399    case SEC_E_REVOCATION_OFFLINE_KDC:
 
  400      return "SEC_E_REVOCATION_OFFLINE_KDC";
 
  402    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
 
  403      return "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
 
  405    case SEC_E_KDC_CERT_EXPIRED:
 
  406      return "SEC_E_KDC_CERT_EXPIRED";
 
  408    case SEC_E_KDC_CERT_REVOKED:
 
  409      return "SEC_E_KDC_CERT_REVOKED";
 
  411    case SEC_E_INVALID_PARAMETER:
 
  412      return "SEC_E_INVALID_PARAMETER";
 
  414    case SEC_E_DELEGATION_POLICY:
 
  415      return "SEC_E_DELEGATION_POLICY";
 
  417    case SEC_E_POLICY_NLTM_ONLY:
 
  418      return "SEC_E_POLICY_NLTM_ONLY";
 
  420    case SEC_E_NO_CONTEXT:
 
  421      return "SEC_E_NO_CONTEXT";
 
  423    case SEC_E_PKU2U_CERT_FAILURE:
 
  424      return "SEC_E_PKU2U_CERT_FAILURE";
 
  426    case SEC_E_MUTUAL_AUTH_FAILED:
 
  427      return "SEC_E_MUTUAL_AUTH_FAILED";
 
  429    case SEC_I_CONTINUE_NEEDED:
 
  430      return "SEC_I_CONTINUE_NEEDED";
 
  432    case SEC_I_COMPLETE_NEEDED:
 
  433      return "SEC_I_COMPLETE_NEEDED";
 
  435    case SEC_I_COMPLETE_AND_CONTINUE:
 
  436      return "SEC_I_COMPLETE_AND_CONTINUE";
 
  438    case SEC_I_LOCAL_LOGON:
 
  439      return "SEC_I_LOCAL_LOGON";
 
  441    case SEC_I_CONTEXT_EXPIRED:
 
  442      return "SEC_I_CONTEXT_EXPIRED";
 
  444    case SEC_I_INCOMPLETE_CREDENTIALS:
 
  445      return "SEC_I_INCOMPLETE_CREDENTIALS";
 
  447    case SEC_I_RENEGOTIATE:
 
  448      return "SEC_I_RENEGOTIATE";
 
  450    case SEC_I_NO_LSA_CONTEXT:
 
  451      return "SEC_I_NO_LSA_CONTEXT";
 
  453    case SEC_I_SIGNATURE_NEEDED:
 
  454      return "SEC_I_SIGNATURE_NEEDED";
 
  456    case SEC_I_NO_RENEGOTIATION:
 
  457      return "SEC_I_NO_RENEGOTIATION";
 
  462  return NtStatus2Tag(status);
 
  465BOOL IsSecurityStatusError(SECURITY_STATUS status)
 
  472    case SEC_I_CONTINUE_NEEDED:
 
  473    case SEC_I_COMPLETE_NEEDED:
 
  474    case SEC_I_COMPLETE_AND_CONTINUE:
 
  475    case SEC_I_LOCAL_LOGON:
 
  476    case SEC_I_CONTEXT_EXPIRED:
 
  477    case SEC_I_INCOMPLETE_CREDENTIALS:
 
  478    case SEC_I_RENEGOTIATE:
 
  479    case SEC_I_NO_LSA_CONTEXT:
 
  480    case SEC_I_SIGNATURE_NEEDED:
 
  481    case SEC_I_NO_RENEGOTIATION:
 
  493  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL);
 
  494  WLog_Print(g_Log, WLOG_DEBUG, 
"InitSecurityInterfaceExW");
 
  500  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, NULL);
 
  501  WLog_Print(g_Log, WLOG_DEBUG, 
"InitSecurityInterfaceExA");
 
  511SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesW(ULONG* pcPackages,
 
  514  SECURITY_STATUS status = 0;
 
  515  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  517  if (!(g_SspiW && g_SspiW->EnumerateSecurityPackagesW))
 
  519    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  521    return SEC_E_UNSUPPORTED_FUNCTION;
 
  524  status = g_SspiW->EnumerateSecurityPackagesW(pcPackages, ppPackageInfo);
 
  525  WLog_Print(g_Log, WLOG_DEBUG, 
"EnumerateSecurityPackagesW: %s (0x%08" PRIX32 
")",
 
  526             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  530SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesA(ULONG* pcPackages,
 
  533  SECURITY_STATUS status = 0;
 
  534  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  536  if (!(g_SspiA && g_SspiA->EnumerateSecurityPackagesA))
 
  538    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  540    return SEC_E_UNSUPPORTED_FUNCTION;
 
  543  status = g_SspiA->EnumerateSecurityPackagesA(pcPackages, ppPackageInfo);
 
  544  WLog_Print(g_Log, WLOG_DEBUG, 
"EnumerateSecurityPackagesA: %s (0x%08" PRIX32 
")",
 
  545             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  551  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  552  WLog_Print(g_Log, WLOG_DEBUG, 
"InitSecurityInterfaceW");
 
  558  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  559  WLog_Print(g_Log, WLOG_DEBUG, 
"InitSecurityInterfaceA");
 
  563SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
 
  566  SECURITY_STATUS status = 0;
 
  567  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  569  if (!(g_SspiW && g_SspiW->QuerySecurityPackageInfoW))
 
  571    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  573    return SEC_E_UNSUPPORTED_FUNCTION;
 
  576  status = g_SspiW->QuerySecurityPackageInfoW(pszPackageName, ppPackageInfo);
 
  577  WLog_Print(g_Log, WLOG_DEBUG, 
"QuerySecurityPackageInfoW: %s (0x%08" PRIX32 
")",
 
  578             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  582SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
 
  585  SECURITY_STATUS status = 0;
 
  586  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  588  if (!(g_SspiA && g_SspiA->QuerySecurityPackageInfoA))
 
  590    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  592    return SEC_E_UNSUPPORTED_FUNCTION;
 
  595  status = g_SspiA->QuerySecurityPackageInfoA(pszPackageName, ppPackageInfo);
 
  596  WLog_Print(g_Log, WLOG_DEBUG, 
"QuerySecurityPackageInfoA: %s (0x%08" PRIX32 
")",
 
  597             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  603SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleW(
 
  604    SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, 
void* pvLogonID,
 
  605    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, 
void* pvGetKeyArgument, 
PCredHandle phCredential,
 
  608  SECURITY_STATUS status = 0;
 
  609  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  611  if (!(g_SspiW && g_SspiW->AcquireCredentialsHandleW))
 
  613    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  615    return SEC_E_UNSUPPORTED_FUNCTION;
 
  618  status = g_SspiW->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
 
  619                                              pAuthData, pGetKeyFn, pvGetKeyArgument,
 
  620                                              phCredential, ptsExpiry);
 
  621  WLog_Print(g_Log, WLOG_DEBUG, 
"AcquireCredentialsHandleW: %s (0x%08" PRIX32 
")",
 
  622             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  626SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleA(
 
  627    SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, 
void* pvLogonID,
 
  628    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, 
void* pvGetKeyArgument, 
PCredHandle phCredential,
 
  631  SECURITY_STATUS status = 0;
 
  632  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  634  if (!(g_SspiA && g_SspiA->AcquireCredentialsHandleA))
 
  636    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  638    return SEC_E_UNSUPPORTED_FUNCTION;
 
  641  status = g_SspiA->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID,
 
  642                                              pAuthData, pGetKeyFn, pvGetKeyArgument,
 
  643                                              phCredential, ptsExpiry);
 
  644  WLog_Print(g_Log, WLOG_DEBUG, 
"AcquireCredentialsHandleA: %s (0x%08" PRIX32 
")",
 
  645             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  649SECURITY_STATUS SEC_ENTRY sspi_ExportSecurityContext(
PCtxtHandle phContext, ULONG fFlags,
 
  652  SECURITY_STATUS status = 0;
 
  653  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  655  if (!(g_SspiW && g_SspiW->ExportSecurityContext))
 
  657    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  659    return SEC_E_UNSUPPORTED_FUNCTION;
 
  662  status = g_SspiW->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken);
 
  663  WLog_Print(g_Log, WLOG_DEBUG, 
"ExportSecurityContext: %s (0x%08" PRIX32 
")",
 
  664             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  668SECURITY_STATUS SEC_ENTRY sspi_FreeCredentialsHandle(
PCredHandle phCredential)
 
  670  SECURITY_STATUS status = 0;
 
  671  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  673  if (!(g_SspiW && g_SspiW->FreeCredentialsHandle))
 
  675    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  677    return SEC_E_UNSUPPORTED_FUNCTION;
 
  680  status = g_SspiW->FreeCredentialsHandle(phCredential);
 
  681  WLog_Print(g_Log, WLOG_DEBUG, 
"FreeCredentialsHandle: %s (0x%08" PRIX32 
")",
 
  682             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  686SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextW(SEC_WCHAR* pszPackage,
 
  690  SECURITY_STATUS status = 0;
 
  691  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  693  if (!(g_SspiW && g_SspiW->ImportSecurityContextW))
 
  695    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  697    return SEC_E_UNSUPPORTED_FUNCTION;
 
  700  status = g_SspiW->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext);
 
  701  WLog_Print(g_Log, WLOG_DEBUG, 
"ImportSecurityContextW: %s (0x%08" PRIX32 
")",
 
  702             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  706SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextA(SEC_CHAR* pszPackage,
 
  710  SECURITY_STATUS status = 0;
 
  711  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  713  if (!(g_SspiA && g_SspiA->ImportSecurityContextA))
 
  715    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  717    return SEC_E_UNSUPPORTED_FUNCTION;
 
  720  status = g_SspiA->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext);
 
  721  WLog_Print(g_Log, WLOG_DEBUG, 
"ImportSecurityContextA: %s (0x%08" PRIX32 
")",
 
  722             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  726SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesW(
PCredHandle phCredential,
 
  727                                                           ULONG ulAttribute, 
void* pBuffer)
 
  729  SECURITY_STATUS status = 0;
 
  730  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  732  if (!(g_SspiW && g_SspiW->QueryCredentialsAttributesW))
 
  734    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  736    return SEC_E_UNSUPPORTED_FUNCTION;
 
  739  status = g_SspiW->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
 
  740  WLog_Print(g_Log, WLOG_DEBUG, 
"QueryCredentialsAttributesW: %s (0x%08" PRIX32 
")",
 
  741             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  745SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesA(
PCredHandle phCredential,
 
  746                                                           ULONG ulAttribute, 
void* pBuffer)
 
  748  SECURITY_STATUS status = 0;
 
  749  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  751  if (!(g_SspiA && g_SspiA->QueryCredentialsAttributesA))
 
  753    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  755    return SEC_E_UNSUPPORTED_FUNCTION;
 
  758  status = g_SspiA->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
 
  759  WLog_Print(g_Log, WLOG_DEBUG, 
"QueryCredentialsAttributesA: %s (0x%08" PRIX32 
")",
 
  760             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  766SECURITY_STATUS SEC_ENTRY sspi_AcceptSecurityContext(
PCredHandle phCredential,
 
  768                                                     ULONG fContextReq, ULONG TargetDataRep,
 
  773  SECURITY_STATUS status = 0;
 
  774  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  776  if (!(g_SspiW && g_SspiW->AcceptSecurityContext))
 
  778    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  780    return SEC_E_UNSUPPORTED_FUNCTION;
 
  784      g_SspiW->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep,
 
  785                                     phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
 
  786  WLog_Print(g_Log, WLOG_DEBUG, 
"AcceptSecurityContext: %s (0x%08" PRIX32 
")",
 
  787             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  793  SECURITY_STATUS status = 0;
 
  794  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  796  if (!(g_SspiW && g_SspiW->ApplyControlToken))
 
  798    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  800    return SEC_E_UNSUPPORTED_FUNCTION;
 
  803  status = g_SspiW->ApplyControlToken(phContext, pInput);
 
  804  WLog_Print(g_Log, WLOG_DEBUG, 
"ApplyControlToken: %s (0x%08" PRIX32 
")",
 
  805             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  811  SECURITY_STATUS status = 0;
 
  812  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  814  if (!(g_SspiW && g_SspiW->CompleteAuthToken))
 
  816    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  818    return SEC_E_UNSUPPORTED_FUNCTION;
 
  821  status = g_SspiW->CompleteAuthToken(phContext, pToken);
 
  822  WLog_Print(g_Log, WLOG_DEBUG, 
"CompleteAuthToken: %s (0x%08" PRIX32 
")",
 
  823             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  827SECURITY_STATUS SEC_ENTRY sspi_DeleteSecurityContext(
PCtxtHandle phContext)
 
  829  SECURITY_STATUS status = 0;
 
  830  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  832  if (!(g_SspiW && g_SspiW->DeleteSecurityContext))
 
  834    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  836    return SEC_E_UNSUPPORTED_FUNCTION;
 
  839  status = g_SspiW->DeleteSecurityContext(phContext);
 
  840  WLog_Print(g_Log, WLOG_DEBUG, 
"DeleteSecurityContext: %s (0x%08" PRIX32 
")",
 
  841             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  845SECURITY_STATUS SEC_ENTRY sspi_FreeContextBuffer(
void* pvContextBuffer)
 
  847  SECURITY_STATUS status = 0;
 
  848  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  850  if (!(g_SspiW && g_SspiW->FreeContextBuffer))
 
  852    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  854    return SEC_E_UNSUPPORTED_FUNCTION;
 
  857  status = g_SspiW->FreeContextBuffer(pvContextBuffer);
 
  858  WLog_Print(g_Log, WLOG_DEBUG, 
"FreeContextBuffer: %s (0x%08" PRIX32 
")",
 
  859             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  863SECURITY_STATUS SEC_ENTRY sspi_ImpersonateSecurityContext(
PCtxtHandle phContext)
 
  865  SECURITY_STATUS status = 0;
 
  866  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  868  if (!(g_SspiW && g_SspiW->ImpersonateSecurityContext))
 
  870    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  872    return SEC_E_UNSUPPORTED_FUNCTION;
 
  875  status = g_SspiW->ImpersonateSecurityContext(phContext);
 
  876  WLog_Print(g_Log, WLOG_DEBUG, 
"ImpersonateSecurityContext: %s (0x%08" PRIX32 
")",
 
  877             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  881SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextW(
 
  883    ULONG Reserved1, ULONG TargetDataRep, 
PSecBufferDesc pInput, ULONG Reserved2,
 
  886  SECURITY_STATUS status = 0;
 
  887  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  889  if (!(g_SspiW && g_SspiW->InitializeSecurityContextW))
 
  891    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  893    return SEC_E_UNSUPPORTED_FUNCTION;
 
  896  status = g_SspiW->InitializeSecurityContextW(
 
  897      phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
 
  898      Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
 
  899  WLog_Print(g_Log, WLOG_DEBUG, 
"InitializeSecurityContextW: %s (0x%08" PRIX32 
")",
 
  900             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  904SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextA(
 
  906    ULONG Reserved1, ULONG TargetDataRep, 
PSecBufferDesc pInput, ULONG Reserved2,
 
  909  SECURITY_STATUS status = 0;
 
  910  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  912  if (!(g_SspiA && g_SspiA->InitializeSecurityContextA))
 
  914    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  916    return SEC_E_UNSUPPORTED_FUNCTION;
 
  919  status = g_SspiA->InitializeSecurityContextA(
 
  920      phCredential, phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
 
  921      Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
 
  922  WLog_Print(g_Log, WLOG_DEBUG, 
"InitializeSecurityContextA: %s (0x%08" PRIX32 
")",
 
  923             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  927SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesW(
PCtxtHandle phContext, ULONG ulAttribute,
 
  930  SECURITY_STATUS status = 0;
 
  931  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  933  if (!(g_SspiW && g_SspiW->QueryContextAttributesW))
 
  935    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  937    return SEC_E_UNSUPPORTED_FUNCTION;
 
  940  status = g_SspiW->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
 
  941  WLog_Print(g_Log, WLOG_DEBUG, 
"QueryContextAttributesW: %s (0x%08" PRIX32 
")",
 
  942             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  946SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesA(
PCtxtHandle phContext, ULONG ulAttribute,
 
  949  SECURITY_STATUS status = 0;
 
  950  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  952  if (!(g_SspiA && g_SspiA->QueryContextAttributesA))
 
  954    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  956    return SEC_E_UNSUPPORTED_FUNCTION;
 
  959  status = g_SspiA->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
 
  960  WLog_Print(g_Log, WLOG_DEBUG, 
"QueryContextAttributesA: %s (0x%08" PRIX32 
")",
 
  961             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  965SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityContextToken(
PCtxtHandle phContext, HANDLE* phToken)
 
  967  SECURITY_STATUS status = 0;
 
  968  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  970  if (!(g_SspiW && g_SspiW->QuerySecurityContextToken))
 
  972    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  974    return SEC_E_UNSUPPORTED_FUNCTION;
 
  977  status = g_SspiW->QuerySecurityContextToken(phContext, phToken);
 
  978  WLog_Print(g_Log, WLOG_DEBUG, 
"QuerySecurityContextToken: %s (0x%08" PRIX32 
")",
 
  979             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
  983SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesW(
PCtxtHandle phContext, ULONG ulAttribute,
 
  984                                                     void* pBuffer, ULONG cbBuffer)
 
  986  SECURITY_STATUS status = 0;
 
  987  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
  989  if (!(g_SspiW && g_SspiW->SetContextAttributesW))
 
  991    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
  993    return SEC_E_UNSUPPORTED_FUNCTION;
 
  996  status = g_SspiW->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
 
  997  WLog_Print(g_Log, WLOG_DEBUG, 
"SetContextAttributesW: %s (0x%08" PRIX32 
")",
 
  998             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1002SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesA(
PCtxtHandle phContext, ULONG ulAttribute,
 
 1003                                                     void* pBuffer, ULONG cbBuffer)
 
 1005  SECURITY_STATUS status = 0;
 
 1006  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1008  if (!(g_SspiA && g_SspiA->SetContextAttributesA))
 
 1010    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1012    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1015  status = g_SspiA->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer);
 
 1016  WLog_Print(g_Log, WLOG_DEBUG, 
"SetContextAttributesA: %s (0x%08" PRIX32 
")",
 
 1017             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1021SECURITY_STATUS SEC_ENTRY sspi_RevertSecurityContext(
PCtxtHandle phContext)
 
 1023  SECURITY_STATUS status = 0;
 
 1024  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1026  if (!(g_SspiW && g_SspiW->RevertSecurityContext))
 
 1028    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1030    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1033  status = g_SspiW->RevertSecurityContext(phContext);
 
 1034  WLog_Print(g_Log, WLOG_DEBUG, 
"RevertSecurityContext: %s (0x%08" PRIX32 
")",
 
 1035             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1042                                              ULONG MessageSeqNo, PULONG pfQOP)
 
 1044  SECURITY_STATUS status = 0;
 
 1045  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1047  if (!(g_SspiW && g_SspiW->DecryptMessage))
 
 1049    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1051    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1054  status = g_SspiW->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
 
 1055  WLog_Print(g_Log, WLOG_DEBUG, 
"DecryptMessage: %s (0x%08" PRIX32 
")",
 
 1056             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1060SECURITY_STATUS SEC_ENTRY sspi_EncryptMessage(
PCtxtHandle phContext, ULONG fQOP,
 
 1063  SECURITY_STATUS status = 0;
 
 1064  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1066  if (!(g_SspiW && g_SspiW->EncryptMessage))
 
 1068    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1070    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1073  status = g_SspiW->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
 
 1074  WLog_Print(g_Log, WLOG_DEBUG, 
"EncryptMessage: %s (0x%08" PRIX32 
")",
 
 1075             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1079SECURITY_STATUS SEC_ENTRY sspi_MakeSignature(
PCtxtHandle phContext, ULONG fQOP,
 
 1082  SECURITY_STATUS status = 0;
 
 1083  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1085  if (!(g_SspiW && g_SspiW->MakeSignature))
 
 1087    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1089    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1092  status = g_SspiW->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
 
 1093  WLog_Print(g_Log, WLOG_DEBUG, 
"MakeSignature: %s (0x%08" PRIX32 
")",
 
 1094             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1099                                               ULONG MessageSeqNo, PULONG pfQOP)
 
 1101  SECURITY_STATUS status = 0;
 
 1102  InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, NULL, NULL);
 
 1104  if (!(g_SspiW && g_SspiW->VerifySignature))
 
 1106    WLog_Print(g_Log, WLOG_WARN, 
"Security module does not provide an implementation");
 
 1108    return SEC_E_UNSUPPORTED_FUNCTION;
 
 1111  status = g_SspiW->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
 
 1112  WLog_Print(g_Log, WLOG_DEBUG, 
"VerifySignature: %s (0x%08" PRIX32 
")",
 
 1113             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
 
 1117WINPR_PRAGMA_DIAG_POP
 
 1119static void zfree(WCHAR* str, 
size_t len, BOOL isWCHAR)
 
 1122    memset(str, 0, len * (isWCHAR ? 
sizeof(WCHAR) : sizeof(char)));
 
 1126void sspi_FreeAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity)
 
 1131  const BOOL wc = (identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0;
 
 1132  zfree(identity->User, identity->UserLength, wc);
 
 1133  zfree(identity->Domain, identity->DomainLength, wc);
 
 1139  size_t len = identity->PasswordLength;
 
 1140  if (len > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
 
 1141    len -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
 
 1142  zfree(identity->Password, len, wc);
 
 1144  const SEC_WINNT_AUTH_IDENTITY empty = { 0 };