fix: GSS API init, enterprise name management, variable names and format code
authordodo040 <dorian.ducournau@gmail.com>
Mon, 3 Jul 2017 10:47:56 +0000 (12:47 +0200)
committerArmin Novak <armin.novak@thincast.com>
Mon, 13 Nov 2017 15:20:56 +0000 (16:20 +0100)
16 files changed:
CMakeLists.txt
libfreerdp/core/gateway/ntlm.c
libfreerdp/core/nla.h
winpr/include/winpr/sspi.h
winpr/libwinpr/sspi/Kerberos/kerberos.c
winpr/libwinpr/sspi/NTLM/ntlm.c
winpr/libwinpr/sspi/Negotiate/negotiate.c
winpr/libwinpr/sspi/Negotiate/negotiate.h
winpr/libwinpr/sspi/sspi.h
winpr/libwinpr/sspi/sspi_gss.c
winpr/libwinpr/sspi/sspi_gss.h
winpr/libwinpr/sspi/sspi_winpr.c
winpr/libwinpr/sspi/test/TestAcquireCredentialsHandle.c
winpr/libwinpr/sspi/test/TestInitializeSecurityContext.c
winpr/libwinpr/sspi/test/TestNTLM.c
winpr/libwinpr/sspi/test/TestQuerySecurityPackageInfo.c

index 444d6a8..2abaff8 100644 (file)
@@ -784,9 +784,11 @@ else()
        if(GSS_FLAVOUR STREQUAL "MIT") 
                message(STATUS "MIT Kerberos suppport")
                add_definitions("-DWITH_GSSAPI -DWITH_GSSAPI_MIT")
-       elseif(GSS_FLAVOUR STREQUAL "HEIMDAL")
+               include_directories(${_GSS_INCLUDE_DIR})
+       elseif(GSS_FLAVOUR STREQUAL "Heimdal")
                message(STATUS "Heimdal Kerberos support")
                add_definitions("-DWITH_GSSAPI -DWITH_GSSAPI_HEIMDAL")
+               include_directories(${_GSS_INCLUDE_DIR})
        else()
                message(STATUS "Kerberos version not detected")
        endif()
index e52a0d2..ebd12d1 100644 (file)
 
 #define TAG FREERDP_TAG("core.gateway.ntlm")
 
-BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password, SecPkgContext_Bindings* Bindings)
+BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char* password,
+                      SecPkgContext_Bindings* Bindings)
 {
        SECURITY_STATUS status;
-
        ntlm->http = http;
        ntlm->Bindings = Bindings;
-
        ntlm->table = InitSecurityInterfaceEx(0);
 
        if (!ntlm->table)
                return FALSE;
 
        sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password);
-
-       status = ntlm->table->QuerySecurityPackageInfo(NTLMSSP_NAME, &ntlm->pPackageInfo);
+       status = ntlm->table->QuerySecurityPackageInfo(NTLM_SSP_NAME, &ntlm->pPackageInfo);
 
        if (status != SEC_E_OK)
        {
                WLog_ERR(TAG, "QuerySecurityPackageInfo status %s [0x%08"PRIX32"]",
-                        GetSecurityStatusString(status), status);
+                        GetSecurityStatusString(status), status);
                return FALSE;
        }
 
        ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
-
-       status = ntlm->table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
-                                                      SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL,
-                                                      &ntlm->credentials, &ntlm->expiration);
+       status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_SSP_NAME,
+                SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL,
+                &ntlm->credentials, &ntlm->expiration);
 
        if (status != SEC_E_OK)
        {
                WLog_ERR(TAG, "AcquireCredentialsHandle status %s [0x%08"PRIX32"]",
-                        GetSecurityStatusString(status), status);
+                        GetSecurityStatusString(status), status);
                return FALSE;
        }
 
@@ -76,7 +73,6 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char*
        ZeroMemory(&ntlm->inputBuffer, sizeof(SecBuffer));
        ZeroMemory(&ntlm->outputBuffer, sizeof(SecBuffer));
        ZeroMemory(&ntlm->ContextSizes, sizeof(SecPkgContext_Sizes));
-
        ntlm->fContextReq = 0;
 
        if (ntlm->http)
@@ -87,12 +83,11 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, char* user, char* domain, char*
        else
        {
                /**
-        * flags for RPC authentication:
-        * RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
-        * ISC_REQ_USE_DCE_STYLE | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH |
-        * ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT
-        */
-
+               * flags for RPC authentication:
+               * RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
+               * ISC_REQ_USE_DCE_STYLE | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH |
+               * ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT
+               */
                ntlm->fContextReq |= ISC_REQ_USE_DCE_STYLE;
                ntlm->fContextReq |= ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH;
                ntlm->fContextReq |= ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT;
@@ -106,7 +101,6 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
        BOOL status = FALSE;
        DWORD SpnLength = 0;
        LPTSTR hostnameX = NULL;
-
 #ifdef UNICODE
        ConvertToUnicode(CP_UTF8, 0, hostname, -1, (LPWSTR*) &hostnameX, 0);
 #else
@@ -119,7 +113,6 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
        if (!ServiceClass)
        {
                ntlm->ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX);
-
                free(hostnameX);
 
                if (!ntlm->ServicePrincipalName)
@@ -136,14 +129,13 @@ BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname)
        if (!ntlm->ServicePrincipalName)
                goto error;
 
-       if (DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength, ntlm->ServicePrincipalName) != ERROR_SUCCESS)
+       if (DsMakeSpn(ServiceClass, hostnameX, NULL, 0, NULL, &SpnLength,
+                     ntlm->ServicePrincipalName) != ERROR_SUCCESS)
                goto error;
 
        status = TRUE;
-
 error:
        free(hostnameX);
-
        return status;
 }
 
@@ -228,38 +220,38 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
        }
 
        status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
-                                                       (ntlm->haveContext) ? &ntlm->context : NULL,
-                                                       (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
-                                                       ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
-                                                       (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
-                                                       0, &ntlm->context, &ntlm->outputBufferDesc,
-                                                       &ntlm->pfContextAttr, &ntlm->expiration);
-
+                (ntlm->haveContext) ? &ntlm->context : NULL,
+                (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
+                ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
+                (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
+                0, &ntlm->context, &ntlm->outputBufferDesc,
+                &ntlm->pfContextAttr, &ntlm->expiration);
        WLog_VRB(TAG, "InitializeSecurityContext status %s [0x%08"PRIX32"]",
-                GetSecurityStatusString(status), status);
+                GetSecurityStatusString(status), status);
 
-       if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK))
+       if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) ||
+           (status == SEC_E_OK))
        {
                if ((status != SEC_E_OK) && ntlm->table->CompleteAuthToken)
                {
                        SECURITY_STATUS cStatus;
-                       
                        cStatus = ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
 
                        if (cStatus != SEC_E_OK)
                        {
                                WLog_WARN(TAG, "CompleteAuthToken status  %s [0x%08"PRIX32"]",
-                                       GetSecurityStatusString(cStatus), cStatus);
+                                         GetSecurityStatusString(cStatus), cStatus);
                                return FALSE;
                        }
                }
 
-               status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes);
+               status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES,
+                        &ntlm->ContextSizes);
 
                if (status != SEC_E_OK)
                {
                        WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [0x%08"PRIX32"]",
-                                GetSecurityStatusString(status), status);
+                                GetSecurityStatusString(status), status);
                        return FALSE;
                }
 
@@ -277,7 +269,6 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
 
        ntlm->haveInputBuffer = TRUE;
        ntlm->haveContext = TRUE;
-
        return (status == SEC_I_CONTINUE_NEEDED) ? TRUE : FALSE;
 }
 
@@ -285,38 +276,40 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
 {
        free(ntlm->identity.User);
        ntlm->identity.User = NULL;
-
        free(ntlm->identity.Domain);
        ntlm->identity.Domain = NULL;
-
        free(ntlm->identity.Password);
        ntlm->identity.Password = NULL;
-
        free(ntlm->ServicePrincipalName);
        ntlm->ServicePrincipalName = NULL;
 
        if (ntlm->table)
        {
                SECURITY_STATUS status;
-
                status = ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
+
                if (status != SEC_E_OK)
                {
                        WLog_WARN(TAG, "FreeCredentialsHandle status %s [0x%08"PRIX32"]",
-                                 GetSecurityStatusString(status), status);
+                                 GetSecurityStatusString(status), status);
                }
+
                status = ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
+
                if (status != SEC_E_OK)
                {
                        WLog_WARN(TAG, "FreeContextBuffer status %s [0x%08"PRIX32"]",
-                                 GetSecurityStatusString(status), status);
+                                 GetSecurityStatusString(status), status);
                }
+
                status = ntlm->table->DeleteSecurityContext(&ntlm->context);
+
                if (status != SEC_E_OK)
                {
                        WLog_WARN(TAG, "DeleteSecurityContext status %s [0x%08"PRIX32"]",
-                                 GetSecurityStatusString(status), status);
+                                 GetSecurityStatusString(status), status);
                }
+
                ntlm->table = NULL;
        }
 }
@@ -324,9 +317,7 @@ void ntlm_client_uninit(rdpNtlm* ntlm)
 rdpNtlm* ntlm_new()
 {
        rdpNtlm* ntlm;
-
        ntlm = (rdpNtlm*) calloc(1, sizeof(rdpNtlm));
-
        return ntlm;
 }
 
@@ -342,6 +333,5 @@ void ntlm_free(rdpNtlm* ntlm)
        }
 
        ntlm_client_uninit(ntlm);
-
        free(ntlm);
 }
index 2f72b64..f01f51d 100644 (file)
@@ -38,12 +38,12 @@ typedef struct rdp_nla rdpNla;
 
 enum _NLA_STATE
 {
-       NLA_STATE_INITIAL,
-       NLA_STATE_NEGO_TOKEN,
-       NLA_STATE_PUB_KEY_AUTH,
-       NLA_STATE_AUTH_INFO,
-       NLA_STATE_POST_NEGO,
-       NLA_STATE_FINAL
+    NLA_STATE_INITIAL,
+    NLA_STATE_NEGO_TOKEN,
+    NLA_STATE_PUB_KEY_AUTH,
+    NLA_STATE_AUTH_INFO,
+    NLA_STATE_POST_NEGO,
+    NLA_STATE_FINAL
 };
 typedef enum _NLA_STATE NLA_STATE;
 
index df2d502..6491dee 100644 (file)
@@ -92,9 +92,9 @@ typedef SecPkgInfoW* PSecPkgInfoW;
 #define PSecPkgInfo PSecPkgInfoA
 #endif
 
-#define NTLMSSP_NAME           _T("NTLM")
+#define NTLM_SSP_NAME  _T("NTLM")
 #define KERBEROS_SSP_NAME      _T("Kerberos")
-#define NEGOSSP_NAME           _T("Negotiate")
+#define NEGO_SSP_NAME  _T("Negotiate")
 
 #endif
 
@@ -598,7 +598,7 @@ typedef struct _SEC_WINNT_AUTH_IDENTITY_W
        UINT16* Password;
        UINT32 PasswordLength;
        UINT32 Flags;
-} SEC_WINNT_AUTH_IDENTITY_W,*PSEC_WINNT_AUTH_IDENTITY_W;
+} SEC_WINNT_AUTH_IDENTITY_W, *PSEC_WINNT_AUTH_IDENTITY_W;
 
 typedef struct _SEC_WINNT_AUTH_IDENTITY_A
 {
@@ -610,7 +610,7 @@ typedef struct _SEC_WINNT_AUTH_IDENTITY_A
        BYTE* Password;
        UINT32 PasswordLength;
        UINT32 Flags;
-} SEC_WINNT_AUTH_IDENTITY_A,*PSEC_WINNT_AUTH_IDENTITY_A;
+} SEC_WINNT_AUTH_IDENTITY_A, *PSEC_WINNT_AUTH_IDENTITY_A;
 
 struct _SEC_WINNT_AUTH_IDENTITY
 {
@@ -645,7 +645,7 @@ typedef CtxtHandle* PCtxtHandle;
 
 #define SecIsValidHandle(x) \
        ((((PSecHandle)(x))->dwLower != ((ULONG_PTR)((INT_PTR) - 1))) && \
-               (((PSecHandle) (x))->dwUpper != ((ULONG_PTR)((INT_PTR) - 1))))
+        (((PSecHandle) (x))->dwUpper != ((ULONG_PTR)((INT_PTR) - 1))))
 
 #endif
 
@@ -697,10 +697,13 @@ struct _SecBufferDesc
 typedef struct _SecBufferDesc SecBufferDesc;
 typedef SecBufferDesc* PSecBufferDesc;
 
-typedef void (SEC_ENTRY * SEC_GET_KEY_FN)(void* Arg, void* Principal, UINT32 KeyVer, void** Key, SECURITY_STATUS* pStatus);
+typedef void (SEC_ENTRY* SEC_GET_KEY_FN)(void* Arg, void* Principal, UINT32 KeyVer, void** Key,
+        SECURITY_STATUS* pStatus);
 
-typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_A)(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo);
-typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_W)(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo);
+typedef SECURITY_STATUS(SEC_ENTRY* ENUMERATE_SECURITY_PACKAGES_FN_A)(ULONG* pcPackages,
+        PSecPkgInfoA* ppPackageInfo);
+typedef SECURITY_STATUS(SEC_ENTRY* ENUMERATE_SECURITY_PACKAGES_FN_W)(ULONG* pcPackages,
+        PSecPkgInfoW* ppPackageInfo);
 
 #ifdef UNICODE
 #define EnumerateSecurityPackages EnumerateSecurityPackagesW
@@ -710,8 +713,10 @@ typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_W)(ULONG* pc
 #define ENUMERATE_SECURITY_PACKAGES_FN ENUMERATE_SECURITY_PACKAGES_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CREDENTIALS_ATTRIBUTES_FN_A)(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer);
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CREDENTIALS_ATTRIBUTES_FN_W)(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_CREDENTIALS_ATTRIBUTES_FN_A)(PCredHandle phCredential,
+        ULONG ulAttribute, void* pBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_CREDENTIALS_ATTRIBUTES_FN_W)(PCredHandle phCredential,
+        ULONG ulAttribute, void* pBuffer);
 
 #ifdef UNICODE
 #define QueryCredentialsAttributes QueryCredentialsAttributesW
@@ -721,12 +726,14 @@ typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CREDENTIALS_ATTRIBUTES_FN_W)(PCredHan
 #define QUERY_CREDENTIALS_ATTRIBUTES_FN QUERY_CREDENTIALS_ATTRIBUTES_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * ACQUIRE_CREDENTIALS_HANDLE_FN_A)(LPSTR pszPrincipal, LPSTR pszPackage,
-               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
-               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
-typedef SECURITY_STATUS (SEC_ENTRY * ACQUIRE_CREDENTIALS_HANDLE_FN_W)(LPWSTR pszPrincipal, LPWSTR pszPackage,
-               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
-               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* ACQUIRE_CREDENTIALS_HANDLE_FN_A)(LPSTR pszPrincipal,
+        LPSTR pszPackage,
+        ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+        void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* ACQUIRE_CREDENTIALS_HANDLE_FN_W)(LPWSTR pszPrincipal,
+        LPWSTR pszPackage,
+        ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+        void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
 
 #ifdef UNICODE
 #define AcquireCredentialsHandle AcquireCredentialsHandleW
@@ -736,16 +743,18 @@ typedef SECURITY_STATUS (SEC_ENTRY * ACQUIRE_CREDENTIALS_HANDLE_FN_W)(LPWSTR psz
 #define ACQUIRE_CREDENTIALS_HANDLE_FN ACQUIRE_CREDENTIALS_HANDLE_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * FREE_CREDENTIALS_HANDLE_FN)(PCredHandle phCredential);
+typedef SECURITY_STATUS(SEC_ENTRY* FREE_CREDENTIALS_HANDLE_FN)(PCredHandle phCredential);
 
-typedef SECURITY_STATUS (SEC_ENTRY * INITIALIZE_SECURITY_CONTEXT_FN_A)(PCredHandle phCredential, PCtxtHandle phContext,
-               SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
-               PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
-typedef SECURITY_STATUS (SEC_ENTRY * INITIALIZE_SECURITY_CONTEXT_FN_W)(PCredHandle phCredential, PCtxtHandle phContext,
-               SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
-               PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* INITIALIZE_SECURITY_CONTEXT_FN_A)(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
+        PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* INITIALIZE_SECURITY_CONTEXT_FN_W)(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
+        PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
 
 #ifdef UNICODE
 #define InitializeSecurityContext InitializeSecurityContextW
@@ -755,18 +764,23 @@ typedef SECURITY_STATUS (SEC_ENTRY * INITIALIZE_SECURITY_CONTEXT_FN_W)(PCredHand
 #define INITIALIZE_SECURITY_CONTEXT_FN INITIALIZE_SECURITY_CONTEXT_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * ACCEPT_SECURITY_CONTEXT_FN)(PCredHandle phCredential, PCtxtHandle phContext,
-               PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp);
+typedef SECURITY_STATUS(SEC_ENTRY* ACCEPT_SECURITY_CONTEXT_FN)(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp);
 
-typedef SECURITY_STATUS (SEC_ENTRY * COMPLETE_AUTH_TOKEN_FN)(PCtxtHandle phContext, PSecBufferDesc pToken);
+typedef SECURITY_STATUS(SEC_ENTRY* COMPLETE_AUTH_TOKEN_FN)(PCtxtHandle phContext,
+        PSecBufferDesc pToken);
 
-typedef SECURITY_STATUS (SEC_ENTRY * DELETE_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
+typedef SECURITY_STATUS(SEC_ENTRY* DELETE_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
 
-typedef SECURITY_STATUS (SEC_ENTRY * APPLY_CONTROL_TOKEN_FN)(PCtxtHandle phContext, PSecBufferDesc pInput);
+typedef SECURITY_STATUS(SEC_ENTRY* APPLY_CONTROL_TOKEN_FN)(PCtxtHandle phContext,
+        PSecBufferDesc pInput);
 
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CONTEXT_ATTRIBUTES_FN_A)(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer);
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_CONTEXT_ATTRIBUTES_FN_A)(PCtxtHandle phContext,
+        ULONG ulAttribute, void* pBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle phContext,
+        ULONG ulAttribute, void* pBuffer);
 
 #ifdef UNICODE
 #define QueryContextAttributes QueryContextAttributesW
@@ -776,18 +790,22 @@ typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle
 #define QUERY_CONTEXT_ATTRIBUTES_FN QUERY_CONTEXT_ATTRIBUTES_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * IMPERSONATE_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
+typedef SECURITY_STATUS(SEC_ENTRY* IMPERSONATE_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
 
-typedef SECURITY_STATUS (SEC_ENTRY * REVERT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
+typedef SECURITY_STATUS(SEC_ENTRY* REVERT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext);
 
-typedef SECURITY_STATUS (SEC_ENTRY * MAKE_SIGNATURE_FN)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
+typedef SECURITY_STATUS(SEC_ENTRY* MAKE_SIGNATURE_FN)(PCtxtHandle phContext, ULONG fQOP,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo);
 
-typedef SECURITY_STATUS (SEC_ENTRY * VERIFY_SIGNATURE_FN)(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
+typedef SECURITY_STATUS(SEC_ENTRY* VERIFY_SIGNATURE_FN)(PCtxtHandle phContext,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
 
-typedef SECURITY_STATUS (SEC_ENTRY * FREE_CONTEXT_BUFFER_FN)(void* pvContextBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* FREE_CONTEXT_BUFFER_FN)(void* pvContextBuffer);
 
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_PACKAGE_INFO_FN_A)(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo);
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_PACKAGE_INFO_FN_W)(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_SECURITY_PACKAGE_INFO_FN_A)(SEC_CHAR* pszPackageName,
+        PSecPkgInfoA* ppPackageInfo);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_SECURITY_PACKAGE_INFO_FN_W)(SEC_WCHAR* pszPackageName,
+        PSecPkgInfoW* ppPackageInfo);
 
 #ifdef UNICODE
 #define QuerySecurityPackageInfo QuerySecurityPackageInfoW
@@ -797,10 +815,13 @@ typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_PACKAGE_INFO_FN_W)(SEC_WCHAR
 #define QUERY_SECURITY_PACKAGE_INFO_FN QUERY_SECURITY_PACKAGE_INFO_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * EXPORT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken);
+typedef SECURITY_STATUS(SEC_ENTRY* EXPORT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext, ULONG fFlags,
+        PSecBuffer pPackedContext, HANDLE* pToken);
 
-typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_A)(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
-typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_W)(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
+typedef SECURITY_STATUS(SEC_ENTRY* IMPORT_SECURITY_CONTEXT_FN_A)(SEC_CHAR* pszPackage,
+        PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
+typedef SECURITY_STATUS(SEC_ENTRY* IMPORT_SECURITY_CONTEXT_FN_W)(SEC_WCHAR* pszPackage,
+        PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
 
 #ifdef UNICODE
 #define ImportSecurityContext ImportSecurityContextW
@@ -810,10 +831,14 @@ typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_W)(SEC_WCHAR* ps
 #define IMPORT_SECURITY_CONTEXT_FN IMPORT_SECURITY_CONTEXT_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * ADD_CREDENTIALS_FN_A)(PCredHandle hCredentials, SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
-       UINT32 fCredentialUse, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PTimeStamp ptsExpiry);
-typedef SECURITY_STATUS (SEC_ENTRY * ADD_CREDENTIALS_FN_W)(PCredHandle hCredentials, SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
-       UINT32 fCredentialUse, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* ADD_CREDENTIALS_FN_A)(PCredHandle hCredentials,
+        SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
+        UINT32 fCredentialUse, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument,
+        PTimeStamp ptsExpiry);
+typedef SECURITY_STATUS(SEC_ENTRY* ADD_CREDENTIALS_FN_W)(PCredHandle hCredentials,
+        SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
+        UINT32 fCredentialUse, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument,
+        PTimeStamp ptsExpiry);
 
 #ifdef UNICODE
 #define AddCredentials AddCredentialsW
@@ -823,14 +848,19 @@ typedef SECURITY_STATUS (SEC_ENTRY * ADD_CREDENTIALS_FN_W)(PCredHandle hCredenti
 #define ADD_CREDENTIALS_FN ADD_CREDENTIALS_FN_A
 #endif
 
-typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_CONTEXT_TOKEN_FN)(PCtxtHandle phContext, HANDLE* phToken);
+typedef SECURITY_STATUS(SEC_ENTRY* QUERY_SECURITY_CONTEXT_TOKEN_FN)(PCtxtHandle phContext,
+        HANDLE* phToken);
 
-typedef SECURITY_STATUS (SEC_ENTRY * ENCRYPT_MESSAGE_FN)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
+typedef SECURITY_STATUS(SEC_ENTRY* ENCRYPT_MESSAGE_FN)(PCtxtHandle phContext, ULONG fQOP,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo);
 
-typedef SECURITY_STATUS (SEC_ENTRY * DECRYPT_MESSAGE_FN)(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
+typedef SECURITY_STATUS(SEC_ENTRY* DECRYPT_MESSAGE_FN)(PCtxtHandle phContext,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
 
-typedef SECURITY_STATUS (SEC_ENTRY * SET_CONTEXT_ATTRIBUTES_FN_A)(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer);
-typedef SECURITY_STATUS (SEC_ENTRY * SET_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* SET_CONTEXT_ATTRIBUTES_FN_A)(PCtxtHandle phContext,
+        ULONG ulAttribute, void* pBuffer, ULONG cbBuffer);
+typedef SECURITY_STATUS(SEC_ENTRY* SET_CONTEXT_ATTRIBUTES_FN_W)(PCtxtHandle phContext,
+        ULONG ulAttribute, void* pBuffer, ULONG cbBuffer);
 
 #ifdef UNICODE
 #define SetContextAttributes SetContextAttributesW
@@ -913,8 +943,8 @@ struct _SecurityFunctionTableW
 typedef struct _SecurityFunctionTableW SecurityFunctionTableW;
 typedef SecurityFunctionTableW* PSecurityFunctionTableW;
 
-typedef PSecurityFunctionTableA (SEC_ENTRY * INIT_SECURITY_INTERFACE_A)(void);
-typedef PSecurityFunctionTableW (SEC_ENTRY * INIT_SECURITY_INTERFACE_W)(void);
+typedef PSecurityFunctionTableA(SEC_ENTRY* INIT_SECURITY_INTERFACE_A)(void);
+typedef PSecurityFunctionTableW(SEC_ENTRY* INIT_SECURITY_INTERFACE_W)(void);
 
 #ifdef UNICODE
 #define InitSecurityInterface InitSecurityInterfaceW
@@ -934,38 +964,50 @@ extern "C" {
 
 /* Package Management */
 
-WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo);
-WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo);
+WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages,
+        PSecPkgInfoA* ppPackageInfo);
+WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(ULONG* pcPackages,
+        PSecPkgInfoW* ppPackageInfo);
 
 WINPR_API PSecurityFunctionTableA SEC_ENTRY InitSecurityInterfaceA(void);
 WINPR_API PSecurityFunctionTableW SEC_ENTRY InitSecurityInterfaceW(void);
 
-WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo);
-WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo);
+WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
+        PSecPkgInfoA* ppPackageInfo);
+WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
+        PSecPkgInfoW* ppPackageInfo);
 
 /* Credential Management */
 
-WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
-               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
-               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
-WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
-               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
-               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
-
-WINPR_API SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken);
+WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal,
+        SEC_CHAR* pszPackage,
+        ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+        void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal,
+        SEC_WCHAR* pszPackage,
+        ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+        void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+
+WINPR_API SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags,
+        PSecBuffer pPackedContext, HANDLE* pToken);
 WINPR_API SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(PCredHandle phCredential);
 
-WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
-WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
+WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage,
+        PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
+WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage,
+        PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext);
 
-WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer);
-WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer);
+WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(PCredHandle phCredential,
+        ULONG ulAttribute, void* pBuffer);
+WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(PCredHandle phCredential,
+        ULONG ulAttribute, void* pBuffer);
 
 /* Context Management */
 
-WINPR_API SECURITY_STATUS SEC_ENTRY AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext,
-               PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp);
+WINPR_API SECURITY_STATUS SEC_ENTRY AcceptSecurityContext(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp);
 
 WINPR_API SECURITY_STATUS SEC_ENTRY ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput);
 WINPR_API SECURITY_STATUS SEC_ENTRY CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken);
@@ -973,26 +1015,35 @@ WINPR_API SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext)
 WINPR_API SECURITY_STATUS SEC_ENTRY FreeContextBuffer(void* pvContextBuffer);
 WINPR_API SECURITY_STATUS SEC_ENTRY ImpersonateSecurityContext(PCtxtHandle phContext);
 
-WINPR_API SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
-               SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
-               PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
-WINPR_API SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext,
-               SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
-               PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
-               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
-
-WINPR_API SECURITY_STATUS SEC_ENTRY QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer);
-WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken);
-WINPR_API SECURITY_STATUS SEC_ENTRY SetContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer);
+WINPR_API SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
+        PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
+WINPR_API SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(PCredHandle phCredential,
+        PCtxtHandle phContext,
+        SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
+        PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
+        PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
+
+WINPR_API SECURITY_STATUS SEC_ENTRY QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute,
+        void* pBuffer);
+WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext,
+        HANDLE* phToken);
+WINPR_API SECURITY_STATUS SEC_ENTRY SetContextAttributes(PCtxtHandle phContext, ULONG ulAttribute,
+        void* pBuffer, ULONG cbBuffer);
 WINPR_API SECURITY_STATUS SEC_ENTRY RevertSecurityContext(PCtxtHandle phContext);
 
 /* Message Support */
 
-WINPR_API SECURITY_STATUS SEC_ENTRY DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
-WINPR_API SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
-WINPR_API SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo);
-WINPR_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP);
+WINPR_API SECURITY_STATUS SEC_ENTRY DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage,
+        ULONG MessageSeqNo, PULONG pfQOP);
+WINPR_API SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo);
+WINPR_API SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP,
+        PSecBufferDesc pMessage, ULONG MessageSeqNo);
+WINPR_API SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage,
+        ULONG MessageSeqNo, PULONG pfQOP);
 
 #ifdef __cplusplus
 }
@@ -1072,8 +1123,8 @@ typedef struct _SecPkgContext_AuthNtlmMessage SecPkgContext_AuthNtlmMessage;
 #define SSPI_INTERFACE_WINPR   0x00000001
 #define SSPI_INTERFACE_NATIVE  0x00000002
 
-typedef PSecurityFunctionTableA (SEC_ENTRY * INIT_SECURITY_INTERFACE_EX_A)(DWORD flags);
-typedef PSecurityFunctionTableW (SEC_ENTRY * INIT_SECURITY_INTERFACE_EX_W)(DWORD flags);
+typedef PSecurityFunctionTableA(SEC_ENTRY* INIT_SECURITY_INTERFACE_EX_A)(DWORD flags);
+typedef PSecurityFunctionTableW(SEC_ENTRY* INIT_SECURITY_INTERFACE_EX_W)(DWORD flags);
 
 WINPR_API void sspi_GlobalInit(void);
 WINPR_API void sspi_GlobalFinish(void);
@@ -1081,8 +1132,10 @@ WINPR_API void sspi_GlobalFinish(void);
 WINPR_API void* sspi_SecBufferAlloc(PSecBuffer SecBuffer, ULONG size);
 WINPR_API void sspi_SecBufferFree(PSecBuffer SecBuffer);
 
-WINPR_API int sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, const char* domain, const char* password);
-WINPR_API int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity);
+WINPR_API int sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, const char* user,
+                                   const char* domain, const char* password);
+WINPR_API int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity,
+                                    SEC_WINNT_AUTH_IDENTITY* srcIdentity);
 
 WINPR_API const char* GetSecurityStatusString(SECURITY_STATUS status);
 
index 194af7f..51d9e29 100644 (file)
 
 #include "kerberos.h"
 
+#ifdef WITH_GSSAPI_HEIMDAL
+#include <krb5-protos.h>
+#endif
+
 #include "../sspi.h"
 #include "../../log.h"
 #define TAG WINPR_TAG("sspi.Kerberos")
@@ -285,6 +289,8 @@ int init_creds(LPCWSTR username, size_t username_len, LPCWSTR password, size_t p
        char* lusername = NULL;
        char* lrealm = NULL;
        char* lpassword = NULL;
+       int flags = 0;
+       char* pstr = NULL;
        size_t krb_name_len = 0;
        size_t lrealm_len = 0;
        size_t lusername_len = 0;
@@ -341,7 +347,14 @@ int init_creds(LPCWSTR username, size_t username_len, LPCWSTR password, size_t p
 #ifdef WITH_DEBUG_NLA
        WLog_DBG(TAG, "copied string is %s\n", krb_name);
 #endif
-       ret = krb5_parse_name(ctx, krb_name, &principal);
+       pstr = strchr(lusername, '@');
+
+       if (pstr != NULL)
+               flags = KRB5_PRINCIPAL_PARSE_ENTERPRISE;
+
+       /* Use the specified principal name. */
+       ret = krb5_parse_name_flags(ctx, krb_name, flags,
+                                   &principal);
 
        if (ret)
        {
@@ -439,9 +452,8 @@ SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextA(PCredHandle phCred
                                               context->credentials->identity.Password,
                                               context->credentials->identity.PasswordLength))
                                        return SEC_E_NO_CREDENTIALS;
-                               else
-                                       WLog_INFO(TAG, "Authenticated to Kerberos v5 via login/password");
 
+                               WLog_INFO(TAG, "Authenticated to Kerberos v5 via login/password");
                                /* retry GSSAPI call */
                                context->major_status = sspi_gss_init_sec_context(&(context->minor_status),
                                                        context->cred, &(context->gss_ctx), context->target_name,
@@ -452,6 +464,7 @@ SECURITY_STATUS SEC_ENTRY kerberos_InitializeSecurityContextA(PCredHandle phCred
                                if (SSPI_GSS_ERROR(context->major_status))
                                {
                                        /* We can't use Kerberos */
+                                       WLog_ERR(TAG, "Init GSS security context failed : can't use Kerberos");
                                        return SEC_E_INTERNAL_ERROR;
                                }
                        }
index 0dadbcf..5349798 100644 (file)
@@ -681,7 +681,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
        return SEC_E_OK;
 }
 
-SECURITY_STATUS ntlm_computeProofValue(NTLM_CONTEXT *ntlm, SecBuffer *ntproof)
+SECURITY_STATUS ntlm_computeProofValue(NTLM_CONTEXT* ntlm, SecBuffer* ntproof)
 {
        BYTE* blob;
        SecBuffer* target = &ntlm->ChallengeTargetInfo;
@@ -689,33 +689,29 @@ SECURITY_STATUS ntlm_computeProofValue(NTLM_CONTEXT *ntlm, SecBuffer *ntproof)
        if (!sspi_SecBufferAlloc(ntproof, 36 + target->cbBuffer))
                return SEC_E_INSUFFICIENT_MEMORY;
 
-       blob = (BYTE *)ntproof->pvBuffer;
-
+       blob = (BYTE*)ntproof->pvBuffer;
        CopyMemory(blob, ntlm->ServerChallenge, 8); /* Server challenge. */
        blob[8] = 1; /* Response version. */
        blob[9] = 1; /* Highest response version understood by the client. */
        /* Reserved 6B. */
-
        CopyMemory(&blob[16], ntlm->Timestamp, 8); /* Time. */
        CopyMemory(&blob[24], ntlm->ClientChallenge, 8); /* Client challenge. */
        /* Reserved 4B. */
        /* Server name. */
        CopyMemory(&blob[36], target->pvBuffer, target->cbBuffer);
-
        return SEC_E_OK;
-
 }
 
-SECURITY_STATUS ntlm_computeMicValue(NTLM_CONTEXT *ntlm, SecBuffer *micvalue)
+SECURITY_STATUS ntlm_computeMicValue(NTLM_CONTEXT* ntlm, SecBuffer* micvalue)
 {
        BYTE* blob;
        ULONG msgSize = ntlm->NegotiateMessage.cbBuffer + ntlm->ChallengeMessage.cbBuffer +
-                                       ntlm->AuthenticateMessage.cbBuffer;
+                       ntlm->AuthenticateMessage.cbBuffer;
 
        if (!sspi_SecBufferAlloc(micvalue, msgSize))
                return SEC_E_INSUFFICIENT_MEMORY;
 
-       blob = (BYTE *) micvalue->pvBuffer;
+       blob = (BYTE*) micvalue->pvBuffer;
        CopyMemory(blob, ntlm->NegotiateMessage.pvBuffer, ntlm->NegotiateMessage.cbBuffer);
        blob += ntlm->NegotiateMessage.cbBuffer;
        CopyMemory(blob, ntlm->ChallengeMessage.pvBuffer, ntlm->ChallengeMessage.cbBuffer);
@@ -723,7 +719,6 @@ SECURITY_STATUS ntlm_computeMicValue(NTLM_CONTEXT *ntlm, SecBuffer *micvalue)
        CopyMemory(blob, ntlm->AuthenticateMessage.pvBuffer, ntlm->AuthenticateMessage.cbBuffer);
        blob += ntlm->MessageIntegrityCheckOffset;
        ZeroMemory(blob, 16);
-
        return SEC_E_OK;
 }
 
index 315e3c7..a86be7c 100644 (file)
@@ -43,6 +43,36 @@ static BOOL ErrorInitContextKerberos = FALSE;
 static BOOL ErrorInitContextKerberos = TRUE;
 #endif
 
+const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
+{
+       0x00083BB3, /* fCapabilities */
+       1, /* wVersion */
+       0x0009, /* wRPCID */
+       0x00002FE0, /* cbMaxToken */
+       "Negotiate", /* Name */
+       "Microsoft Package Negotiator" /* Comment */
+};
+
+WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', '\0' };
+
+WCHAR NEGOTIATE_SecPkgInfoW_Comment[] =
+{
+       'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ',
+       'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ',
+       'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', '\0'
+};
+
+const SecPkgInfoW NEGOTIATE_SecPkgInfoW =
+{
+       0x00083BB3, /* fCapabilities */
+       1, /* wVersion */
+       0x0009, /* wRPCID */
+       0x00002FE0, /* cbMaxToken */
+       NEGOTIATE_SecPkgInfoW_Name, /* Name */
+       NEGOTIATE_SecPkgInfoW_Comment /* Comment */
+};
+
+
 void negotiate_SetSubPackage(NEGOTIATE_CONTEXT* context, const char* name)
 {
        if (strcmp(name, KERBEROS_SSP_NAME) == 0)
@@ -73,7 +103,7 @@ NEGOTIATE_CONTEXT* negotiate_ContextNew()
        context->NegotiateFlags = 0;
        context->state = NEGOTIATE_STATE_INITIAL;
        SecInvalidateHandle(&(context->SubContext));
-       negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
+       negotiate_SetSubPackage(context, (const char*) KERBEROS_SSP_NAME);
        return context;
 }
 
@@ -100,7 +130,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCre
                        return SEC_E_INTERNAL_ERROR;
 
                sspi_SecureHandleSetLowerPointer(phNewContext, context);
-               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
+               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGO_SSP_NAME);
        }
 
        /* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
@@ -108,7 +138,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCre
        {
                if (!pInput)
                {
-                       negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
+                       negotiate_SetSubPackage(context, (const char*) KERBEROS_SSP_NAME);
                }
 
                status = context->sspiW->InitializeSecurityContextW(phCredential, &(context->SubContext),
@@ -129,7 +159,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(PCredHandle phCre
                if (!pInput)
                {
                        context->sspiA->DeleteSecurityContext(&(context->SubContext));
-                       negotiate_SetSubPackage(context, NTLMSSP_NAME);
+                       negotiate_SetSubPackage(context, (const char*) NTLM_SSP_NAME);
                }
 
                status = context->sspiW->InitializeSecurityContextW(phCredential, &(context->SubContext),
@@ -158,7 +188,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCre
                        return SEC_E_INTERNAL_ERROR;
 
                sspi_SecureHandleSetLowerPointer(phNewContext, context);
-               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
+               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGO_SSP_NAME);
        }
 
        /* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
@@ -166,7 +196,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCre
        {
                if (!pInput)
                {
-                       negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
+                       negotiate_SetSubPackage(context, (const char*) KERBEROS_SSP_NAME);
                }
 
                status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext),
@@ -187,7 +217,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCre
                if (!pInput)
                {
                        context->sspiA->DeleteSecurityContext(&(context->SubContext));
-                       negotiate_SetSubPackage(context, NTLMSSP_NAME);
+                       negotiate_SetSubPackage(context, (const char*) NTLM_SSP_NAME);
                }
 
                status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext),
@@ -215,10 +245,11 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredenti
                        return SEC_E_INTERNAL_ERROR;
 
                sspi_SecureHandleSetLowerPointer(phNewContext, context);
-               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOSSP_NAME);
+               sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGO_SSP_NAME);
        }
 
-       negotiate_SetSubPackage(context, NTLMSSP_NAME); /* server-side Kerberos not yet implemented */
+       negotiate_SetSubPackage(context,
+                               (const char*) NTLM_SSP_NAME); /* server-side Kerberos not yet implemented */
        status = context->sspiA->AcceptSecurityContext(phCredential, &(context->SubContext),
                 pInput, fContextReq, TargetDataRep, &(context->SubContext),
                 pOutput, pfContextAttr, ptsTimeStamp);
@@ -400,7 +431,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrin
                sspi_CopyAuthIdentity(&(credentials->identity), identity);
 
        sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
-       sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOSSP_NAME);
+       sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGO_SSP_NAME);
        return SEC_E_OK;
 }
 
@@ -433,7 +464,7 @@ SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(SEC_CHAR* pszPrinc
                sspi_CopyAuthIdentity(&(credentials->identity), identity);
 
        sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials);
-       sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGOSSP_NAME);
+       sspi_SecureHandleSetUpperPointer(phCredential, (void*) NEGO_SSP_NAME);
        return SEC_E_OK;
 }
 
@@ -582,31 +613,3 @@ const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW =
        negotiate_SetContextAttributesW, /* SetContextAttributes */
 };
 
-const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
-{
-       0x00083BB3, /* fCapabilities */
-       1, /* wVersion */
-       0x0009, /* wRPCID */
-       0x00002FE0, /* cbMaxToken */
-       "Negotiate", /* Name */
-       "Microsoft Package Negotiator" /* Comment */
-};
-
-WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', '\0' };
-
-WCHAR NEGOTIATE_SecPkgInfoW_Comment[] =
-{
-       'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ',
-       'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ',
-       'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', '\0'
-};
-
-const SecPkgInfoW NEGOTIATE_SecPkgInfoW =
-{
-       0x00083BB3, /* fCapabilities */
-       1, /* wVersion */
-       0x0009, /* wRPCID */
-       0x00002FE0, /* cbMaxToken */
-       NEGOTIATE_SecPkgInfoW_Name, /* Name */
-       NEGOTIATE_SecPkgInfoW_Comment /* Comment */
-};
index ac50e96..b4fc031 100644 (file)
 
 enum _NEGOTIATE_STATE
 {
-       NEGOTIATE_STATE_INITIAL,
-       NEGOTIATE_STATE_NEGOINIT,
-       NEGOTIATE_STATE_NEGORESP,
-       NEGOTIATE_STATE_FINAL
+    NEGOTIATE_STATE_INITIAL,
+    NEGOTIATE_STATE_NEGOINIT,
+    NEGOTIATE_STATE_NEGORESP,
+    NEGOTIATE_STATE_FINAL
 };
 typedef enum _NEGOTIATE_STATE NEGOTIATE_STATE;
 
index 2a73ad1..0c89343 100644 (file)
@@ -53,34 +53,34 @@ void sspi_SecureHandleFree(SecHandle* handle);
 
 enum SecurityFunctionTableIndex
 {
-       EnumerateSecurityPackagesIndex = 1,
-       Reserved1Index = 2,
-       QueryCredentialsAttributesIndex = 3,
-       AcquireCredentialsHandleIndex = 4,
-       FreeCredentialsHandleIndex = 5,
-       Reserved2Index = 6,
-       InitializeSecurityContextIndex = 7,
-       AcceptSecurityContextIndex = 8,
-       CompleteAuthTokenIndex = 9,
-       DeleteSecurityContextIndex = 10,
-       ApplyControlTokenIndex = 11,
-       QueryContextAttributesIndex = 12,
-       ImpersonateSecurityContextIndex = 13,
-       RevertSecurityContextIndex = 14,
-       MakeSignatureIndex = 15,
-       VerifySignatureIndex = 16,
-       FreeContextBufferIndex = 17,
-       QuerySecurityPackageInfoIndex = 18,
-       Reserved3Index = 19,
-       Reserved4Index = 20,
-       ExportSecurityContextIndex = 21,
-       ImportSecurityContextIndex = 22,
-       AddCredentialsIndex = 23,
-       Reserved8Index = 24,
-       QuerySecurityContextTokenIndex = 25,
-       EncryptMessageIndex = 26,
-       DecryptMessageIndex = 27,
-       SetContextAttributesIndex = 28
+    EnumerateSecurityPackagesIndex = 1,
+    Reserved1Index = 2,
+    QueryCredentialsAttributesIndex = 3,
+    AcquireCredentialsHandleIndex = 4,
+    FreeCredentialsHandleIndex = 5,
+    Reserved2Index = 6,
+    InitializeSecurityContextIndex = 7,
+    AcceptSecurityContextIndex = 8,
+    CompleteAuthTokenIndex = 9,
+    DeleteSecurityContextIndex = 10,
+    ApplyControlTokenIndex = 11,
+    QueryContextAttributesIndex = 12,
+    ImpersonateSecurityContextIndex = 13,
+    RevertSecurityContextIndex = 14,
+    MakeSignatureIndex = 15,
+    VerifySignatureIndex = 16,
+    FreeContextBufferIndex = 17,
+    QuerySecurityPackageInfoIndex = 18,
+    Reserved3Index = 19,
+    Reserved4Index = 20,
+    ExportSecurityContextIndex = 21,
+    ImportSecurityContextIndex = 22,
+    AddCredentialsIndex = 23,
+    Reserved8Index = 24,
+    QuerySecurityContextTokenIndex = 25,
+    EncryptMessageIndex = 26,
+    DecryptMessageIndex = 27,
+    SetContextAttributesIndex = 28
 };
 
 BOOL IsSecurityStatusError(SECURITY_STATUS status);
index d2a5ec2..0b33462 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2015 ANSSI, Author Thomas Calderon
  * Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
+#include <inttypes.h>
+#include <stddef.h>
+
+#include "../../include/winpr/synch.h"
+#include "../../include/winpr/wlog.h"
+#include "../../include/winpr/wtypes.h"
+
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 #include "../../log.h"
 #define TAG WINPR_TAG("sspi.gss")
 
-int sspi_GssApiInit();
+static GSSAPI_FUNCTION_TABLE* g_GssApi = NULL;
+static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
+
+#ifdef WITH_GSSAPI
+
+#include <gssapi/gssapi.h>
+
+GSSAPI_FUNCTION_TABLE g_GssApiLink =
+{
+       (fn_sspi_gss_acquire_cred) gss_acquire_cred, /* gss_acquire_cred */
+       (fn_sspi_gss_release_cred) gss_release_cred, /* gss_release_cred */
+       (fn_sspi_gss_init_sec_context) gss_init_sec_context, /* gss_init_sec_context */
+       (fn_sspi_gss_accept_sec_context) gss_accept_sec_context, /* gss_accept_sec_context */
+       (fn_sspi_gss_process_context_token) gss_process_context_token, /* gss_process_context_token */
+       (fn_sspi_gss_delete_sec_context) gss_delete_sec_context, /* gss_delete_sec_context */
+       (fn_sspi_gss_context_time) gss_context_time, /* gss_context_time */
+       (fn_sspi_gss_get_mic) gss_get_mic, /* gss_get_mic */
+       (fn_sspi_gss_verify_mic) gss_verify_mic, /* gss_verify_mic */
+       (fn_sspi_gss_wrap) gss_wrap, /* gss_wrap */
+       (fn_sspi_gss_unwrap) gss_unwrap, /* gss_unwrap */
+       (fn_sspi_gss_display_status) gss_display_status, /* gss_display_status */
+       (fn_sspi_gss_indicate_mechs) gss_indicate_mechs, /* gss_indicate_mechs */
+       (fn_sspi_gss_compare_name) gss_compare_name, /* gss_compare_name */
+       (fn_sspi_gss_display_name) gss_display_name, /* gss_display_name */
+       (fn_sspi_gss_import_name) gss_import_name, /* gss_import_name */
+       (fn_sspi_gss_release_name) gss_release_name, /* gss_release_name */
+       (fn_sspi_gss_release_buffer) gss_release_buffer, /* gss_release_buffer */
+       (fn_sspi_gss_release_oid_set) gss_release_oid_set, /* gss_release_oid_set */
+       (fn_sspi_gss_inquire_cred) gss_inquire_cred, /* gss_inquire_cred */
+       (fn_sspi_gss_inquire_context) gss_inquire_context, /* gss_inquire_context */
+       (fn_sspi_gss_wrap_size_limit) gss_wrap_size_limit, /* gss_wrap_size_limit */
+#if 0
+       (fn_sspi_gss_import_name_object) gss_import_name_object, /* gss_import_name_object */
+       (fn_sspi_gss_export_name_object) gss_export_name_object, /* gss_export_name_object */
+#else
+       (fn_sspi_gss_import_name_object) NULL, /* gss_import_name_object */
+       (fn_sspi_gss_export_name_object) NULL, /* gss_export_name_object */
+#endif
+       (fn_sspi_gss_add_cred) gss_add_cred, /* gss_add_cred */
+       (fn_sspi_gss_inquire_cred_by_mech) gss_inquire_cred_by_mech, /* gss_inquire_cred_by_mech */
+       (fn_sspi_gss_export_sec_context) gss_export_sec_context, /* gss_export_sec_context */
+       (fn_sspi_gss_import_sec_context) gss_import_sec_context, /* gss_import_sec_context */
+       (fn_sspi_gss_release_oid) gss_release_oid, /* gss_release_oid */
+       (fn_sspi_gss_create_empty_oid_set) gss_create_empty_oid_set, /* gss_create_empty_oid_set */
+       (fn_sspi_gss_add_oid_set_member) gss_add_oid_set_member, /* gss_add_oid_set_member */
+       (fn_sspi_gss_test_oid_set_member) gss_test_oid_set_member, /* gss_test_oid_set_member */
+#ifdef WITH_GSSAPI_MIT
+       (fn_sspi_gss_str_to_oid) gss_str_to_oid, /* gss_str_to_oid */
+#else
+       (fn_sspi_gss_str_to_oid) NULL, /* gss_str_to_oid */
+#endif
+       (fn_sspi_gss_oid_to_str) gss_oid_to_str, /* gss_oid_to_str */
+       (fn_sspi_gss_inquire_names_for_mech) gss_inquire_names_for_mech, /* gss_inquire_names_for_mech */
+       (fn_sspi_gss_inquire_mechs_for_name) gss_inquire_mechs_for_name, /* gss_inquire_mechs_for_name */
+       (fn_sspi_gss_sign) gss_sign, /* gss_sign */
+       (fn_sspi_gss_verify) gss_verify, /* gss_verify */
+       (fn_sspi_gss_seal) gss_seal, /* gss_seal */
+       (fn_sspi_gss_unseal) gss_unseal, /* gss_unseal */
+       (fn_sspi_gss_export_name) gss_export_name, /* gss_export_name */
+       (fn_sspi_gss_duplicate_name) gss_duplicate_name, /* gss_duplicate_name */
+       (fn_sspi_gss_canonicalize_name) gss_canonicalize_name, /* gss_canonicalize_name */
+       (fn_sspi_gss_pseudo_random) gss_pseudo_random, /* gss_pseudo_random */
+       (fn_sspi_gss_store_cred) gss_store_cred, /* gss_store_cred */
+#ifdef WITH_GSSAPI_MIT
+       (fn_sspi_gss_set_neg_mechs) gss_set_neg_mechs, /* gss_set_neg_mechs */
+#else
+       (fn_sspi_gss_set_neg_mechs) NULL, /* gss_set_neg_mechs */
+#endif
+};
+
+#endif
+
+GSSAPI_FUNCTION_TABLE* SEC_ENTRY gssApi_InitSecurityInterface(void)
+{
+#ifdef WITH_GSSAPI
+       return &g_GssApiLink;
+#else
+       return NULL;
+#endif
+}
+
+static BOOL CALLBACK sspi_GssApiInit(PINIT_ONCE once, PVOID param, PVOID* context)
+{
+       g_GssApi = gssApi_InitSecurityInterface();
 
-GSSAPI_FUNCTION_TABLE g_GssApi;
-static BOOL g_Initialized = FALSE;
+       if (!g_GssApi)
+               return FALSE;
 
-#define GSSAPI_STUB_CALL(_name, ...) \
-       if (!g_Initialized) \
-               sspi_GssApiInit(); \
-       if (!g_GssApi.gss_ ## _name) \
-               return 0; \
-       return g_GssApi.gss_ ## _name ( __VA_ARGS__ )
+       return TRUE;
+}
 
 /**
  * SSPI GSSAPI OIDs
@@ -62,8 +149,9 @@ sspi_gss_OID SSPI_GSS_C_NT_HOSTBASED_SERVICE = &g_SSPI_GSS_C_NT_HOSTBASED_SERVIC
 sspi_gss_OID SSPI_GSS_C_NT_ANONYMOUS = &g_SSPI_GSS_C_NT_ANONYMOUS;
 sspi_gss_OID SSPI_GSS_C_NT_EXPORT_NAME = &g_SSPI_GSS_C_NT_EXPORT_NAME;
 
+
 /**
- * SSPI GSSAPI Wrapper Stubs
+ * SSPI GSSAPI
  */
 
 UINT32 SSPI_GSSAPI sspi_gss_acquire_cred(
@@ -76,15 +164,33 @@ UINT32 SSPI_GSSAPI sspi_gss_acquire_cred(
     sspi_gss_OID_set* actual_mechs,
     UINT32* time_rec)
 {
-       GSSAPI_STUB_CALL(acquire_cred, minor_status, desired_name, time_req,
-                        desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_acquire_cred))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_acquire_cred(minor_status, desired_name, time_req,
+                                           desired_mechs, cred_usage, output_cred_handle, actual_mechs, time_rec);
+       WLog_DBG(TAG, "gss_acquire_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_release_cred(
     UINT32* minor_status,
     sspi_gss_cred_id_t* cred_handle)
 {
-       GSSAPI_STUB_CALL(release_cred, minor_status, cred_handle);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_release_cred))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_release_cred(minor_status, cred_handle);
+       WLog_DBG(TAG, "gss_release_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_init_sec_context(
@@ -102,9 +208,18 @@ UINT32 SSPI_GSSAPI sspi_gss_init_sec_context(
     UINT32* ret_flags,
     UINT32* time_rec)
 {
-       GSSAPI_STUB_CALL(init_sec_context, minor_status, claimant_cred_handle, context_handle,
-                        target_name, mech_type, req_flags, time_req, input_chan_bindings,
-                        input_token, actual_mech_type, output_token, ret_flags, time_rec);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_init_sec_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_init_sec_context(minor_status, claimant_cred_handle, context_handle,
+                                               target_name, mech_type, req_flags, time_req, input_chan_bindings,
+                                               input_token, actual_mech_type, output_token, ret_flags, time_rec);
+       WLog_DBG(TAG, "gss_init_sec_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_accept_sec_context(
@@ -120,9 +235,18 @@ UINT32 SSPI_GSSAPI sspi_gss_accept_sec_context(
     UINT32* time_rec,
     sspi_gss_cred_id_t* delegated_cred_handle)
 {
-       GSSAPI_STUB_CALL(accept_sec_context, minor_status, context_handle, acceptor_cred_handle,
-                        input_token_buffer, input_chan_bindings, src_name, mech_type, output_token,
-                        ret_flags, time_rec, delegated_cred_handle);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_accept_sec_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_accept_sec_context(minor_status, context_handle, acceptor_cred_handle,
+                input_token_buffer, input_chan_bindings, src_name, mech_type, output_token,
+                ret_flags, time_rec, delegated_cred_handle);
+       WLog_DBG(TAG, "gss_accept_sec_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_process_context_token(
@@ -130,7 +254,16 @@ UINT32 SSPI_GSSAPI sspi_gss_process_context_token(
     sspi_gss_ctx_id_t context_handle,
     sspi_gss_buffer_t token_buffer)
 {
-       GSSAPI_STUB_CALL(process_context_token, minor_status, context_handle, token_buffer);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_process_context_token))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_process_context_token(minor_status, context_handle, token_buffer);
+       WLog_DBG(TAG, "gss_process_context_token: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_delete_sec_context(
@@ -138,7 +271,16 @@ UINT32 SSPI_GSSAPI sspi_gss_delete_sec_context(
     sspi_gss_ctx_id_t* context_handle,
     sspi_gss_buffer_t output_token)
 {
-       GSSAPI_STUB_CALL(delete_sec_context, minor_status, context_handle, output_token);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_delete_sec_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_delete_sec_context(minor_status, context_handle, output_token);
+       WLog_DBG(TAG, "gss_delete_sec_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_context_time(
@@ -146,7 +288,16 @@ UINT32 SSPI_GSSAPI sspi_gss_context_time(
     sspi_gss_ctx_id_t context_handle,
     UINT32* time_rec)
 {
-       GSSAPI_STUB_CALL(context_time, minor_status, context_handle, time_rec);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_context_time))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_context_time(minor_status, context_handle, time_rec);
+       WLog_DBG(TAG, "gss_context_time: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_get_mic(
@@ -156,7 +307,17 @@ UINT32 SSPI_GSSAPI sspi_gss_get_mic(
     sspi_gss_buffer_t message_buffer,
     sspi_gss_buffer_t message_token)
 {
-       GSSAPI_STUB_CALL(get_mic, minor_status, context_handle, qop_req, message_buffer, message_token);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_get_mic))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_get_mic(minor_status, context_handle, qop_req, message_buffer,
+                                      message_token);
+       WLog_DBG(TAG, "gss_get_mic: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_verify_mic(
@@ -166,8 +327,17 @@ UINT32 SSPI_GSSAPI sspi_gss_verify_mic(
     sspi_gss_buffer_t message_token,
     sspi_gss_qop_t* qop_state)
 {
-       GSSAPI_STUB_CALL(verify_mic, minor_status, context_handle, message_buffer, message_token,
-                        qop_state);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_verify_mic))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_verify_mic(minor_status, context_handle, message_buffer, message_token,
+                                         qop_state);
+       WLog_DBG(TAG, "gss_verify_mic: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_wrap(
@@ -179,8 +349,17 @@ UINT32 SSPI_GSSAPI sspi_gss_wrap(
     int* conf_state,
     sspi_gss_buffer_t output_message_buffer)
 {
-       GSSAPI_STUB_CALL(wrap, minor_status, context_handle, conf_req_flag,
-                        qop_req, input_message_buffer, conf_state, output_message_buffer);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_wrap))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_wrap(minor_status, context_handle, conf_req_flag,
+                                   qop_req, input_message_buffer, conf_state, output_message_buffer);
+       WLog_DBG(TAG, "gss_acquire_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_unwrap(
@@ -191,8 +370,17 @@ UINT32 SSPI_GSSAPI sspi_gss_unwrap(
     int* conf_state,
     sspi_gss_qop_t* qop_state)
 {
-       GSSAPI_STUB_CALL(unwrap, minor_status, context_handle, input_message_buffer,
-                        output_message_buffer, conf_state, qop_state);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_unwrap))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_unwrap(minor_status, context_handle, input_message_buffer,
+                                     output_message_buffer, conf_state, qop_state);
+       WLog_DBG(TAG, "gss_unwrap: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_display_status(
@@ -203,15 +391,33 @@ UINT32 SSPI_GSSAPI sspi_gss_display_status(
     UINT32* message_context,
     sspi_gss_buffer_t status_string)
 {
-       GSSAPI_STUB_CALL(display_status, minor_status, status_value, status_type,
-                        mech_type, message_context, status_string);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_display_status))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_display_status(minor_status, status_value, status_type,
+                                             mech_type, message_context, status_string);
+       WLog_DBG(TAG, "gss_display_status: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_indicate_mechs(
     UINT32* minor_status,
     sspi_gss_OID_set* mech_set)
 {
-       GSSAPI_STUB_CALL(indicate_mechs, minor_status, mech_set);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_indicate_mechs))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_indicate_mechs(minor_status, mech_set);
+       WLog_DBG(TAG, "gss_indicate_mechs: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_compare_name(
@@ -220,7 +426,16 @@ UINT32 SSPI_GSSAPI sspi_gss_compare_name(
     sspi_gss_name_t name2,
     int* name_equal)
 {
-       GSSAPI_STUB_CALL(compare_name, minor_status, name1, name2, name_equal);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_compare_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_compare_name(minor_status, name1, name2, name_equal);
+       WLog_DBG(TAG, "gss_compare_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_display_name(
@@ -229,7 +444,16 @@ UINT32 SSPI_GSSAPI sspi_gss_display_name(
     sspi_gss_buffer_t output_name_buffer,
     sspi_gss_OID* output_name_type)
 {
-       GSSAPI_STUB_CALL(display_name, minor_status, input_name, output_name_buffer, output_name_type);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_display_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_display_name(minor_status, input_name, output_name_buffer, output_name_type);
+       WLog_DBG(TAG, "gss_display_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_import_name(
@@ -238,28 +462,64 @@ UINT32 SSPI_GSSAPI sspi_gss_import_name(
     sspi_gss_OID input_name_type,
     sspi_gss_name_t* output_name)
 {
-       GSSAPI_STUB_CALL(import_name, minor_status, input_name_buffer, input_name_type, output_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_import_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_import_name(minor_status, input_name_buffer, input_name_type, output_name);
+       WLog_DBG(TAG, "gss_import_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_release_name(
     UINT32* minor_status,
     sspi_gss_name_t* input_name)
 {
-       GSSAPI_STUB_CALL(release_name, minor_status, input_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_release_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_release_name(minor_status, input_name);
+       WLog_DBG(TAG, "gss_release_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_release_buffer(
     UINT32* minor_status,
     sspi_gss_buffer_t buffer)
 {
-       GSSAPI_STUB_CALL(release_buffer, minor_status, buffer);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_release_buffer))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_release_buffer(minor_status, buffer);
+       WLog_DBG(TAG, "gss_release_buffer: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_release_oid_set(
     UINT32* minor_status,
     sspi_gss_OID_set* set)
 {
-       GSSAPI_STUB_CALL(release_oid_set, minor_status, set);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_release_oid_set))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_release_oid_set(minor_status, set);
+       WLog_DBG(TAG, "gss_release_oid_set: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_inquire_cred(
@@ -270,7 +530,17 @@ UINT32 SSPI_GSSAPI sspi_gss_inquire_cred(
     sspi_gss_cred_usage_t* cred_usage,
     sspi_gss_OID_set* mechanisms)
 {
-       GSSAPI_STUB_CALL(inquire_cred, minor_status, cred_handle, name, lifetime, cred_usage, mechanisms);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_inquire_cred))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_inquire_cred(minor_status, cred_handle, name, lifetime, cred_usage,
+                                           mechanisms);
+       WLog_DBG(TAG, "gss_inquire_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_inquire_context(
@@ -284,8 +554,17 @@ UINT32 SSPI_GSSAPI sspi_gss_inquire_context(
     int* locally_initiated,
     int* open)
 {
-       GSSAPI_STUB_CALL(inquire_context, minor_status, context_handle, src_name, targ_name,
-                        lifetime_rec, mech_type, ctx_flags, locally_initiated, open);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_inquire_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_inquire_context(minor_status, context_handle, src_name, targ_name,
+                                              lifetime_rec, mech_type, ctx_flags, locally_initiated, open);
+       WLog_DBG(TAG, "gss_inquire_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_wrap_size_limit(
@@ -296,8 +575,17 @@ UINT32 SSPI_GSSAPI sspi_gss_wrap_size_limit(
     UINT32 req_output_size,
     UINT32* max_input_size)
 {
-       GSSAPI_STUB_CALL(wrap_size_limit, minor_status, context_handle,
-                        conf_req_flag, qop_req, req_output_size, max_input_size);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_wrap_size_limit))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_wrap_size_limit(minor_status, context_handle,
+                                              conf_req_flag, qop_req, req_output_size, max_input_size);
+       WLog_DBG(TAG, "gss_wrap_size_limit: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_import_name_object(
@@ -306,7 +594,16 @@ UINT32 SSPI_GSSAPI sspi_gss_import_name_object(
     sspi_gss_OID input_name_type,
     sspi_gss_name_t* output_name)
 {
-       GSSAPI_STUB_CALL(import_name_object, minor_status, input_name, input_name_type, output_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_import_name_object))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_import_name_object(minor_status, input_name, input_name_type, output_name);
+       WLog_DBG(TAG, "gss_import_name_object: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_export_name_object(
@@ -315,7 +612,16 @@ UINT32 SSPI_GSSAPI sspi_gss_export_name_object(
     sspi_gss_OID desired_name_type,
     void** output_name)
 {
-       GSSAPI_STUB_CALL(export_name_object, minor_status, input_name, desired_name_type, output_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_export_name_object))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_export_name_object(minor_status, input_name, desired_name_type, output_name);
+       WLog_DBG(TAG, "gss_export_name_object: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_add_cred(
@@ -331,9 +637,19 @@ UINT32 SSPI_GSSAPI sspi_gss_add_cred(
     UINT32* initiator_time_rec,
     UINT32* acceptor_time_rec)
 {
-       GSSAPI_STUB_CALL(add_cred, minor_status, input_cred_handle, desired_name, desired_mech, cred_usage,
-                        initiator_time_req, acceptor_time_req, output_cred_handle, actual_mechs, initiator_time_rec,
-                        acceptor_time_rec);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_add_cred))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_add_cred(minor_status, input_cred_handle, desired_name, desired_mech,
+                                       cred_usage,
+                                       initiator_time_req, acceptor_time_req, output_cred_handle, actual_mechs, initiator_time_rec,
+                                       acceptor_time_rec);
+       WLog_DBG(TAG, "gss_add_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_inquire_cred_by_mech(
@@ -345,8 +661,17 @@ UINT32 SSPI_GSSAPI sspi_gss_inquire_cred_by_mech(
     UINT32* acceptor_lifetime,
     sspi_gss_cred_usage_t* cred_usage)
 {
-       GSSAPI_STUB_CALL(inquire_cred_by_mech, minor_status, cred_handle, mech_type, name,
-                        initiator_lifetime, acceptor_lifetime, cred_usage);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_inquire_cred_by_mech))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_inquire_cred_by_mech(minor_status, cred_handle, mech_type, name,
+                initiator_lifetime, acceptor_lifetime, cred_usage);
+       WLog_DBG(TAG, "gss_inquire_cred_by_mech: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_export_sec_context(
@@ -354,7 +679,16 @@ UINT32 SSPI_GSSAPI sspi_gss_export_sec_context(
     sspi_gss_ctx_id_t* context_handle,
     sspi_gss_buffer_t interprocess_token)
 {
-       GSSAPI_STUB_CALL(export_sec_context, minor_status, context_handle, interprocess_token);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_export_sec_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_export_sec_context(minor_status, context_handle, interprocess_token);
+       WLog_DBG(TAG, "gss_export_sec_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_import_sec_context(
@@ -362,21 +696,48 @@ UINT32 SSPI_GSSAPI sspi_gss_import_sec_context(
     sspi_gss_buffer_t interprocess_token,
     sspi_gss_ctx_id_t* context_handle)
 {
-       GSSAPI_STUB_CALL(import_sec_context, minor_status, interprocess_token, context_handle);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_import_sec_context))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_import_sec_context(minor_status, interprocess_token, context_handle);
+       WLog_DBG(TAG, "gss_import_sec_context: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_release_oid(
     UINT32* minor_status,
     sspi_gss_OID* oid)
 {
-       GSSAPI_STUB_CALL(release_oid, minor_status, oid);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_release_oid))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_release_oid(minor_status, oid);
+       WLog_DBG(TAG, "gss_release_oid: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_create_empty_oid_set(
     UINT32* minor_status,
     sspi_gss_OID_set* oid_set)
 {
-       GSSAPI_STUB_CALL(create_empty_oid_set, minor_status, oid_set);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_create_empty_oid_set))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_create_empty_oid_set(minor_status, oid_set);
+       WLog_DBG(TAG, "gss_create_empty_oid_set: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_add_oid_set_member(
@@ -384,7 +745,16 @@ UINT32 SSPI_GSSAPI sspi_gss_add_oid_set_member(
     sspi_gss_OID member_oid,
     sspi_gss_OID_set* oid_set)
 {
-       GSSAPI_STUB_CALL(add_oid_set_member, minor_status, member_oid, oid_set);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_add_oid_set_member))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_add_oid_set_member(minor_status, member_oid, oid_set);
+       WLog_DBG(TAG, "gss_add_oid_set_member: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_test_oid_set_member(
@@ -393,7 +763,16 @@ UINT32 SSPI_GSSAPI sspi_gss_test_oid_set_member(
     sspi_gss_OID_set set,
     int* present)
 {
-       GSSAPI_STUB_CALL(test_oid_set_member, minor_status, member, set, present);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_test_oid_set_member))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_test_oid_set_member(minor_status, member, set, present);
+       WLog_DBG(TAG, "gss_test_oid_set_member: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_str_to_oid(
@@ -401,7 +780,16 @@ UINT32 SSPI_GSSAPI sspi_gss_str_to_oid(
     sspi_gss_buffer_t oid_str,
     sspi_gss_OID* oid)
 {
-       GSSAPI_STUB_CALL(str_to_oid, minor_status, oid_str, oid);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_str_to_oid))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_str_to_oid(minor_status, oid_str, oid);
+       WLog_DBG(TAG, "gss_str_to_oid: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_oid_to_str(
@@ -409,7 +797,16 @@ UINT32 SSPI_GSSAPI sspi_gss_oid_to_str(
     sspi_gss_OID oid,
     sspi_gss_buffer_t oid_str)
 {
-       GSSAPI_STUB_CALL(oid_to_str, minor_status, oid, oid_str);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_oid_to_str))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_oid_to_str(minor_status, oid, oid_str);
+       WLog_DBG(TAG, "gss_oid_to_str: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_inquire_names_for_mech(
@@ -417,7 +814,16 @@ UINT32 SSPI_GSSAPI sspi_gss_inquire_names_for_mech(
     sspi_gss_OID mechanism,
     sspi_gss_OID_set* name_types)
 {
-       GSSAPI_STUB_CALL(inquire_names_for_mech, minor_status, mechanism, name_types);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_inquire_names_for_mech))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_inquire_names_for_mech(minor_status, mechanism, name_types);
+       WLog_DBG(TAG, "gss_inquire_names_for_mech: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_inquire_mechs_for_name(
@@ -425,7 +831,16 @@ UINT32 SSPI_GSSAPI sspi_gss_inquire_mechs_for_name(
     const sspi_gss_name_t input_name,
     sspi_gss_OID_set* mech_types)
 {
-       GSSAPI_STUB_CALL(inquire_mechs_for_name, minor_status, input_name, mech_types);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_inquire_mechs_for_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_inquire_mechs_for_name(minor_status, input_name, mech_types);
+       WLog_DBG(TAG, "gss_inquire_mechs_for_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_sign(
@@ -435,7 +850,16 @@ UINT32 SSPI_GSSAPI sspi_gss_sign(
     sspi_gss_buffer_t message_buffer,
     sspi_gss_buffer_t message_token)
 {
-       GSSAPI_STUB_CALL(sign, minor_status, context_handle, qop_req, message_buffer, message_token);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_sign))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_sign(minor_status, context_handle, qop_req, message_buffer, message_token);
+       WLog_DBG(TAG, "gss_sign: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_verify(
@@ -445,7 +869,17 @@ UINT32 SSPI_GSSAPI sspi_gss_verify(
     sspi_gss_buffer_t token_buffer,
     int* qop_state)
 {
-       GSSAPI_STUB_CALL(verify, minor_status, context_handle, message_buffer, token_buffer, qop_state);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_verify))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_verify(minor_status, context_handle, message_buffer, token_buffer,
+                                     qop_state);
+       WLog_DBG(TAG, "gss_verify: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_seal(
@@ -457,8 +891,17 @@ UINT32 SSPI_GSSAPI sspi_gss_seal(
     int* conf_state,
     sspi_gss_buffer_t output_message_buffer)
 {
-       GSSAPI_STUB_CALL(seal, minor_status, context_handle, conf_req_flag, qop_req,
-                        input_message_buffer, conf_state, output_message_buffer);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_seal))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_seal(minor_status, context_handle, conf_req_flag, qop_req,
+                                   input_message_buffer, conf_state, output_message_buffer);
+       WLog_DBG(TAG, "gss_seal: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_unseal(
@@ -469,8 +912,18 @@ UINT32 SSPI_GSSAPI sspi_gss_unseal(
     int* conf_state,
     int* qop_state)
 {
-       GSSAPI_STUB_CALL(unseal, minor_status, context_handle, input_message_buffer, output_message_buffer,
-                        conf_state, qop_state);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_unseal))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_unseal(minor_status, context_handle, input_message_buffer,
+                                     output_message_buffer,
+                                     conf_state, qop_state);
+       WLog_DBG(TAG, "gss_unseal: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_export_name(
@@ -478,7 +931,16 @@ UINT32 SSPI_GSSAPI sspi_gss_export_name(
     const sspi_gss_name_t input_name,
     sspi_gss_buffer_t exported_name)
 {
-       GSSAPI_STUB_CALL(export_name, minor_status, input_name, exported_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_export_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_export_name(minor_status, input_name, exported_name);
+       WLog_DBG(TAG, "gss_export_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_duplicate_name(
@@ -486,7 +948,16 @@ UINT32 SSPI_GSSAPI sspi_gss_duplicate_name(
     const sspi_gss_name_t input_name,
     sspi_gss_name_t* dest_name)
 {
-       GSSAPI_STUB_CALL(duplicate_name, minor_status, input_name, dest_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_duplicate_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_duplicate_name(minor_status, input_name, dest_name);
+       WLog_DBG(TAG, "gss_duplicate_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_canonicalize_name(
@@ -495,7 +966,16 @@ UINT32 SSPI_GSSAPI sspi_gss_canonicalize_name(
     const sspi_gss_OID mech_type,
     sspi_gss_name_t* output_name)
 {
-       GSSAPI_STUB_CALL(canonicalize_name, minor_status, input_name, mech_type, output_name);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_canonicalize_name))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_canonicalize_name(minor_status, input_name, mech_type, output_name);
+       WLog_DBG(TAG, "gss_canonicalize_name: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_pseudo_random(
@@ -506,8 +986,17 @@ UINT32 SSPI_GSSAPI sspi_gss_pseudo_random(
     ssize_t desired_output_len,
     sspi_gss_buffer_t prf_out)
 {
-       GSSAPI_STUB_CALL(pseudo_random, minor_status, context, prf_key, prf_in, desired_output_len,
-                        prf_out);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_pseudo_random))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_pseudo_random(minor_status, context, prf_key, prf_in, desired_output_len,
+                                            prf_out);
+       WLog_DBG(TAG, "gss_pseudo_random: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_store_cred(
@@ -520,8 +1009,17 @@ UINT32 SSPI_GSSAPI sspi_gss_store_cred(
     sspi_gss_OID_set* elements_stored,
     sspi_gss_cred_usage_t* cred_usage_stored)
 {
-       GSSAPI_STUB_CALL(store_cred, minor_status, input_cred_handle, input_usage, desired_mech,
-                        overwrite_cred, default_cred, elements_stored, cred_usage_stored);
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
+
+       if (!(g_GssApi && g_GssApi->gss_store_cred))
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = g_GssApi->gss_store_cred(minor_status, input_cred_handle, input_usage, desired_mech,
+                                         overwrite_cred, default_cred, elements_stored, cred_usage_stored);
+       WLog_DBG(TAG, "gss_store_cred: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
 
 UINT32 SSPI_GSSAPI sspi_gss_set_neg_mechs(
@@ -529,138 +1027,14 @@ UINT32 SSPI_GSSAPI sspi_gss_set_neg_mechs(
     sspi_gss_cred_id_t cred_handle,
     const sspi_gss_OID_set mech_set)
 {
-       GSSAPI_STUB_CALL(set_neg_mechs, minor_status, cred_handle, mech_set);
-}
-
-#ifdef WITH_GSSAPI
+       SECURITY_STATUS status;
+       InitOnceExecuteOnce(&g_Initialized, sspi_GssApiInit, NULL, NULL);
 
-#include <gssapi/gssapi.h>
+       if (!(g_GssApi && g_GssApi->gss_set_neg_mechs))
+               return SEC_E_UNSUPPORTED_FUNCTION;
 
-GSSAPI_FUNCTION_TABLE g_GssApiLink =
-{
-       (fn_sspi_gss_acquire_cred) gss_acquire_cred, /* gss_acquire_cred */
-       (fn_sspi_gss_release_cred) gss_release_cred, /* gss_release_cred */
-       (fn_sspi_gss_init_sec_context) gss_init_sec_context, /* gss_init_sec_context */
-       (fn_sspi_gss_accept_sec_context) gss_accept_sec_context, /* gss_accept_sec_context */
-       (fn_sspi_gss_process_context_token) gss_process_context_token, /* gss_process_context_token */
-       (fn_sspi_gss_delete_sec_context) gss_delete_sec_context, /* gss_delete_sec_context */
-       (fn_sspi_gss_context_time) gss_context_time, /* gss_context_time */
-       (fn_sspi_gss_get_mic) gss_get_mic, /* gss_get_mic */
-       (fn_sspi_gss_verify_mic) gss_verify_mic, /* gss_verify_mic */
-       (fn_sspi_gss_wrap) gss_wrap, /* gss_wrap */
-       (fn_sspi_gss_unwrap) gss_unwrap, /* gss_unwrap */
-       (fn_sspi_gss_display_status) gss_display_status, /* gss_display_status */
-       (fn_sspi_gss_indicate_mechs) gss_indicate_mechs, /* gss_indicate_mechs */
-       (fn_sspi_gss_compare_name) gss_compare_name, /* gss_compare_name */
-       (fn_sspi_gss_display_name) gss_display_name, /* gss_display_name */
-       (fn_sspi_gss_import_name) gss_import_name, /* gss_import_name */
-       (fn_sspi_gss_release_name) gss_release_name, /* gss_release_name */
-       (fn_sspi_gss_release_buffer) gss_release_buffer, /* gss_release_buffer */
-       (fn_sspi_gss_release_oid_set) gss_release_oid_set, /* gss_release_oid_set */
-       (fn_sspi_gss_inquire_cred) gss_inquire_cred, /* gss_inquire_cred */
-       (fn_sspi_gss_inquire_context) gss_inquire_context, /* gss_inquire_context */
-       (fn_sspi_gss_wrap_size_limit) gss_wrap_size_limit, /* gss_wrap_size_limit */
-#if 0
-       (fn_sspi_gss_import_name_object) gss_import_name_object, /* gss_import_name_object */
-       (fn_sspi_gss_export_name_object) gss_export_name_object, /* gss_export_name_object */
-#else
-       (fn_sspi_gss_import_name_object) NULL, /* gss_import_name_object */
-       (fn_sspi_gss_export_name_object) NULL, /* gss_export_name_object */
-#endif
-       (fn_sspi_gss_add_cred) gss_add_cred, /* gss_add_cred */
-       (fn_sspi_gss_inquire_cred_by_mech) gss_inquire_cred_by_mech, /* gss_inquire_cred_by_mech */
-       (fn_sspi_gss_export_sec_context) gss_export_sec_context, /* gss_export_sec_context */
-       (fn_sspi_gss_import_sec_context) gss_import_sec_context, /* gss_import_sec_context */
-       (fn_sspi_gss_release_oid) gss_release_oid, /* gss_release_oid */
-       (fn_sspi_gss_create_empty_oid_set) gss_create_empty_oid_set, /* gss_create_empty_oid_set */
-       (fn_sspi_gss_add_oid_set_member) gss_add_oid_set_member, /* gss_add_oid_set_member */
-       (fn_sspi_gss_test_oid_set_member) gss_test_oid_set_member, /* gss_test_oid_set_member */
-#ifdef WITH_GSSAPI_MIT
-       (fn_sspi_gss_str_to_oid) gss_str_to_oid, /* gss_str_to_oid */
-#else
-       (fn_sspi_gss_str_to_oid) NULL, /* gss_str_to_oid */
-#endif
-       (fn_sspi_gss_oid_to_str) gss_oid_to_str, /* gss_oid_to_str */
-       (fn_sspi_gss_inquire_names_for_mech) gss_inquire_names_for_mech, /* gss_inquire_names_for_mech */
-       (fn_sspi_gss_inquire_mechs_for_name) gss_inquire_mechs_for_name, /* gss_inquire_mechs_for_name */
-       (fn_sspi_gss_sign) gss_sign, /* gss_sign */
-       (fn_sspi_gss_verify) gss_verify, /* gss_verify */
-       (fn_sspi_gss_seal) gss_seal, /* gss_seal */
-       (fn_sspi_gss_unseal) gss_unseal, /* gss_unseal */
-       (fn_sspi_gss_export_name) gss_export_name, /* gss_export_name */
-       (fn_sspi_gss_duplicate_name) gss_duplicate_name, /* gss_duplicate_name */
-       (fn_sspi_gss_canonicalize_name) gss_canonicalize_name, /* gss_canonicalize_name */
-       (fn_sspi_gss_pseudo_random) gss_pseudo_random, /* gss_pseudo_random */
-       (fn_sspi_gss_store_cred) gss_store_cred, /* gss_store_cred */
-#ifdef WITH_GSSAPI_MIT
-       (fn_sspi_gss_set_neg_mechs) gss_set_neg_mechs, /* gss_set_neg_mechs */
-#else
-       (fn_sspi_gss_set_neg_mechs) NULL, /* gss_set_neg_mechs */
-#endif
-};
-
-#endif
-
-GSSAPI_FUNCTION_TABLE g_GssApi =
-{
-       NULL, /* gss_acquire_cred */
-       NULL, /* gss_release_cred */
-       NULL, /* gss_init_sec_context */
-       NULL, /* gss_accept_sec_context */
-       NULL, /* gss_process_context_token */
-       NULL, /* gss_delete_sec_context */
-       NULL, /* gss_context_time */
-       NULL, /* gss_get_mic */
-       NULL, /* gss_verify_mic */
-       NULL, /* gss_wrap */
-       NULL, /* gss_unwrap */
-       NULL, /* gss_display_status */
-       NULL, /* gss_indicate_mechs */
-       NULL, /* gss_compare_name */
-       NULL, /* gss_display_name */
-       NULL, /* gss_import_name */
-       NULL, /* gss_release_name */
-       NULL, /* gss_release_buffer */
-       NULL, /* gss_release_oid_set */
-       NULL, /* gss_inquire_cred */
-       NULL, /* gss_inquire_context */
-       NULL, /* gss_wrap_size_limit */
-       NULL, /* gss_import_name_object */
-       NULL, /* gss_export_name_object */
-       NULL, /* gss_add_cred */
-       NULL, /* gss_inquire_cred_by_mech */
-       NULL, /* gss_export_sec_context */
-       NULL, /* gss_import_sec_context */
-       NULL, /* gss_release_oid */
-       NULL, /* gss_create_empty_oid_set */
-       NULL, /* gss_add_oid_set_member */
-       NULL, /* gss_test_oid_set_member */
-       NULL, /* gss_str_to_oid */
-       NULL, /* gss_oid_to_str */
-       NULL, /* gss_inquire_names_for_mech */
-       NULL, /* gss_inquire_mechs_for_name */
-       NULL, /* gss_sign */
-       NULL, /* gss_verify */
-       NULL, /* gss_seal */
-       NULL, /* gss_unseal */
-       NULL, /* gss_export_name */
-       NULL, /* gss_duplicate_name */
-       NULL, /* gss_canonicalize_name */
-       NULL, /* gss_pseudo_random */
-       NULL, /* gss_store_cred */
-       NULL, /* gss_set_neg_mechs */
-};
-
-int sspi_GssApiInit()
-{
-       if (g_Initialized)
-               return 1;
-
-       g_Initialized = TRUE;
-#ifdef WITH_GSSAPI
-       CopyMemory(&g_GssApi, &g_GssApiLink, sizeof(GSSAPI_FUNCTION_TABLE));
-       return 1;
-#else
-       return -1;
-#endif
+       status = g_GssApi->gss_set_neg_mechs(minor_status, cred_handle, mech_set);
+       WLog_DBG(TAG, "gss_set_neg_mechs: %s (0x%08"PRIX32")",
+                GetSecurityStatusString(status), status);
+       return status;
 }
index 4ad9988..ad4f219 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright 2015 ANSSI, Author Thomas Calderon
  * Copyright 2015 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -870,6 +871,8 @@ struct _GSSAPI_FUNCTION_TABLE
 };
 typedef struct _GSSAPI_FUNCTION_TABLE GSSAPI_FUNCTION_TABLE;
 
+GSSAPI_FUNCTION_TABLE* SEC_ENTRY gssApi_InitSecurityInterface(void);
+
 #ifdef __cplusplus
 extern "C" {
 #endif
index cff5178..a8b1d6a 100644 (file)
@@ -275,6 +275,7 @@ void sspi_SecBufferFree(PSecBuffer SecBuffer)
 
        if (SecBuffer->pvBuffer)
                memset(SecBuffer->pvBuffer, 0, SecBuffer->cbBuffer);
+
        free(SecBuffer->pvBuffer);
        SecBuffer->pvBuffer = NULL;
        SecBuffer->cbBuffer = 0;
index 7c4eda7..1a99e52 100644 (file)
@@ -16,14 +16,12 @@ int TestAcquireCredentialsHandle(int argc, char* argv[])
        SEC_WINNT_AUTH_IDENTITY identity;
        SecurityFunctionTable* table;
        SecPkgCredentials_Names credential_names;
-
        sspi_GlobalInit();
-
        table = InitSecurityInterface();
-
        identity.User = (UINT16*) _strdup(test_User);
        identity.Domain = (UINT16*) _strdup(test_Domain);
        identity.Password = (UINT16*) _strdup(test_Password);
+
        if (!identity.User || !identity.Domain || !identity.Password)
        {
                free(identity.User);
@@ -32,13 +30,13 @@ int TestAcquireCredentialsHandle(int argc, char* argv[])
                fprintf(stderr, "Memory allocation failed\n");
                return -1;
        }
+
        identity.UserLength = strlen(test_User);
        identity.DomainLength = strlen(test_Domain);
        identity.PasswordLength = strlen(test_Password);
        identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
-
-       status = table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
-                       SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
+       status = table->AcquireCredentialsHandle(NULL, NTLM_SSP_NAME,
+                SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
 
        if (status != SEC_E_OK)
        {
@@ -55,7 +53,6 @@ int TestAcquireCredentialsHandle(int argc, char* argv[])
        }
 
        sspi_GlobalFinish();
-
        return 0;
 }
 
index ac91a25..f618736 100644 (file)
@@ -24,12 +24,9 @@ int TestInitializeSecurityContext(int argc, char* argv[])
        PSecBuffer p_SecBuffer;
        SecBuffer output_SecBuffer;
        SecBufferDesc output_SecBuffer_desc;
-
        sspi_GlobalInit();
-
        table = InitSecurityInterface();
-
-       status = QuerySecurityPackageInfo(NTLMSSP_NAME, &pPackageInfo);
+       status = QuerySecurityPackageInfo(NTLM_SSP_NAME, &pPackageInfo);
 
        if (status != SEC_E_OK)
        {
@@ -38,10 +35,10 @@ int TestInitializeSecurityContext(int argc, char* argv[])
        }
 
        cbMaxLen = pPackageInfo->cbMaxToken;
-
        identity.User = (UINT16*) _strdup(test_User);
        identity.Domain = (UINT16*) _strdup(test_Domain);
        identity.Password = (UINT16*) _strdup(test_Password);
+
        if (!identity.User || !identity.Domain || !identity.Password)
        {
                free(identity.User);
@@ -55,9 +52,8 @@ int TestInitializeSecurityContext(int argc, char* argv[])
        identity.DomainLength = strlen(test_Domain);
        identity.PasswordLength = strlen(test_Password);
        identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
-
-       status = table->AcquireCredentialsHandle(NULL, NTLMSSP_NAME,
-                       SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
+       status = table->AcquireCredentialsHandle(NULL, NTLM_SSP_NAME,
+                SECPKG_CRED_OUTBOUND, NULL, &identity, NULL, NULL, &credentials, &expiration);
 
        if (status != SEC_E_OK)
        {
@@ -66,9 +62,10 @@ int TestInitializeSecurityContext(int argc, char* argv[])
                return -1;
        }
 
-       fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE;
-
+       fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY |
+                     ISC_REQ_DELEGATE;
        output_buffer = malloc(cbMaxLen);
+
        if (!output_buffer)
        {
                printf("Memory allocation failed\n");
@@ -79,13 +76,11 @@ int TestInitializeSecurityContext(int argc, char* argv[])
        output_SecBuffer_desc.ulVersion = 0;
        output_SecBuffer_desc.cBuffers = 1;
        output_SecBuffer_desc.pBuffers = &output_SecBuffer;
-
        output_SecBuffer.cbBuffer = cbMaxLen;
        output_SecBuffer.BufferType = SECBUFFER_TOKEN;
        output_SecBuffer.pvBuffer = output_buffer;
-
        status = table->InitializeSecurityContext(&credentials, NULL, NULL, fContextReq, 0, 0, NULL, 0,
-                       &context, &output_SecBuffer_desc, &pfContextAttr, &expiration);
+                &context, &output_SecBuffer_desc, &pfContextAttr, &expiration);
 
        if (status != SEC_I_CONTINUE_NEEDED)
        {
@@ -94,18 +89,14 @@ int TestInitializeSecurityContext(int argc, char* argv[])
                return -1;
        }
 
-       printf("cBuffers: %"PRIu32" ulVersion: %"PRIu32"\n", output_SecBuffer_desc.cBuffers, output_SecBuffer_desc.ulVersion);
-
+       printf("cBuffers: %"PRIu32" ulVersion: %"PRIu32"\n", output_SecBuffer_desc.cBuffers,
+              output_SecBuffer_desc.ulVersion);
        p_SecBuffer = &output_SecBuffer_desc.pBuffers[0];
-
-       printf("BufferType: 0x%08"PRIX32" cbBuffer: %"PRIu32"\n", p_SecBuffer->BufferType, p_SecBuffer->cbBuffer);
-
+       printf("BufferType: 0x%08"PRIX32" cbBuffer: %"PRIu32"\n", p_SecBuffer->BufferType,
+              p_SecBuffer->cbBuffer);
        table->FreeCredentialsHandle(&credentials);
-
        FreeContextBuffer(pPackageInfo);
-
        sspi_GlobalFinish();
-
        return 0;
 }
 
index ffac39d..539d993 100644 (file)
@@ -11,50 +11,50 @@ static BYTE TEST_NTLM_CLIENT_CHALLENGE[8] = { 0x20, 0xc0, 0x2b, 0x3d, 0xc0, 0x61
 static BYTE TEST_NTLM_SERVER_CHALLENGE[8] = { 0xa4, 0xf1, 0xba, 0xa6, 0x7c, 0xdc, 0x1a, 0x12 };
 
 static BYTE TEST_NTLM_NEGOTIATE[] =
-       "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x06\x03\x80\x25\x00\x00\x00\x0f";
+    "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x06\x03\x80\x25\x00\x00\x00\x0f";
 
 static BYTE TEST_NTLM_CHALLENGE[] =
-       "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x00\x00\x00\x00"
-       "\x38\x00\x00\x00\x07\x82\x88\xa2\xa4\xf1\xba\xa6\x7c\xdc\x1a\x12"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x66\x00\x66\x00\x38\x00\x00\x00"
-       "\x06\x03\x80\x25\x00\x00\x00\x0f\x02\x00\x0e\x00\x4e\x00\x45\x00"
-       "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00"
-       "\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00"
-       "\x6c\x00\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00"
-       "\x2e\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00"
-       "\x6e\x00\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00"
-       "\x08\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x00\x00\x00\x00";
+    "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x00\x00\x00\x00"
+    "\x38\x00\x00\x00\x07\x82\x88\xa2\xa4\xf1\xba\xa6\x7c\xdc\x1a\x12"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x66\x00\x66\x00\x38\x00\x00\x00"
+    "\x06\x03\x80\x25\x00\x00\x00\x0f\x02\x00\x0e\x00\x4e\x00\x45\x00"
+    "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00"
+    "\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00"
+    "\x6c\x00\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00"
+    "\x2e\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00"
+    "\x6e\x00\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00"
+    "\x08\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x00\x00\x00\x00";
 
 static BYTE TEST_NTLM_AUTHENTICATE[] =
-       "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
-       "\x82\x00\x00\x00\x08\x01\x08\x01\x9a\x00\x00\x00\x0c\x00\x0c\x00"
-       "\x58\x00\x00\x00\x10\x00\x10\x00\x64\x00\x00\x00\x0e\x00\x0e\x00"
-       "\x74\x00\x00\x00\x00\x00\x00\x00\xa2\x01\x00\x00\x05\x82\x88\xa2"
-       "\x06\x03\x80\x25\x00\x00\x00\x0f\x12\xe5\x5a\xf5\x80\xee\x3f\x29"
-       "\xe1\xde\x90\x4d\x73\x77\x06\x25\x44\x00\x6f\x00\x6d\x00\x61\x00"
-       "\x69\x00\x6e\x00\x55\x00\x73\x00\x65\x00\x72\x00\x6e\x00\x61\x00"
-       "\x6d\x00\x65\x00\x4e\x00\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00"
-       "\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x14\x68\xc8\x98\x12"
-       "\xe7\x39\xd8\x76\x1b\xe9\xf7\x54\xb5\xe3\x01\x01\x00\x00\x00\x00"
-       "\x00\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x20\xc0\x2b\x3d\xc0\x61"
-       "\xa7\x73\x00\x00\x00\x00\x02\x00\x0e\x00\x4e\x00\x45\x00\x57\x00"
-       "\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00\x45\x00"
-       "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00\x6c\x00"
-       "\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00\x2e\x00"
-       "\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00\x6e\x00"
-       "\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00\x08\x00"
-       "\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x06\x00\x04\x00\x02\x00\x00\x00"
-       "\x08\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
-       "\x00\x20\x00\x00\x1e\x10\xf5\x2c\x54\x2f\x2e\x77\x1c\x13\xbf\xc3"
-       "\x3f\xe1\x7b\x28\x7e\x0b\x93\x5a\x39\xd2\xce\x12\xd7\xbd\x8c\x4e"
-       "\x2b\xb5\x0b\xf5\x0a\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x1a\x00\x48\x00\x54\x00"
-       "\x54\x00\x50\x00\x2f\x00\x72\x00\x77\x00\x2e\x00\x6c\x00\x6f\x00"
-       "\x63\x00\x61\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
-       "\x00\x00";
+    "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
+    "\x82\x00\x00\x00\x08\x01\x08\x01\x9a\x00\x00\x00\x0c\x00\x0c\x00"
+    "\x58\x00\x00\x00\x10\x00\x10\x00\x64\x00\x00\x00\x0e\x00\x0e\x00"
+    "\x74\x00\x00\x00\x00\x00\x00\x00\xa2\x01\x00\x00\x05\x82\x88\xa2"
+    "\x06\x03\x80\x25\x00\x00\x00\x0f\x12\xe5\x5a\xf5\x80\xee\x3f\x29"
+    "\xe1\xde\x90\x4d\x73\x77\x06\x25\x44\x00\x6f\x00\x6d\x00\x61\x00"
+    "\x69\x00\x6e\x00\x55\x00\x73\x00\x65\x00\x72\x00\x6e\x00\x61\x00"
+    "\x6d\x00\x65\x00\x4e\x00\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00"
+    "\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x14\x68\xc8\x98\x12"
+    "\xe7\x39\xd8\x76\x1b\xe9\xf7\x54\xb5\xe3\x01\x01\x00\x00\x00\x00"
+    "\x00\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x20\xc0\x2b\x3d\xc0\x61"
+    "\xa7\x73\x00\x00\x00\x00\x02\x00\x0e\x00\x4e\x00\x45\x00\x57\x00"
+    "\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00\x45\x00"
+    "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00\x6c\x00"
+    "\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00\x2e\x00"
+    "\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00\x6e\x00"
+    "\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00\x08\x00"
+    "\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x06\x00\x04\x00\x02\x00\x00\x00"
+    "\x08\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
+    "\x00\x20\x00\x00\x1e\x10\xf5\x2c\x54\x2f\x2e\x77\x1c\x13\xbf\xc3"
+    "\x3f\xe1\x7b\x28\x7e\x0b\x93\x5a\x39\xd2\xce\x12\xd7\xbd\x8c\x4e"
+    "\x2b\xb5\x0b\xf5\x0a\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x1a\x00\x48\x00\x54\x00"
+    "\x54\x00\x50\x00\x2f\x00\x72\x00\x77\x00\x2e\x00\x6c\x00\x6f\x00"
+    "\x63\x00\x61\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+    "\x00\x00";
 
 #define TEST_SSPI_INTERFACE SSPI_INTERFACE_WINPR
 
@@ -72,7 +72,7 @@ static const BYTE TEST_NTLM_HASH[16] =
 static const BYTE TEST_NTLM_V2_HASH[16] =
 { 0x4c, 0x7f, 0x70, 0x6f, 0x7d, 0xde, 0x05, 0xa9, 0xd1, 0xa0, 0xf4, 0xe7, 0xff, 0xe3, 0xbf, 0xb8 };
 
-#define NTLM_PACKAGE_NAME      NTLMSSP_NAME
+#define NTLM_PACKAGE_NAME      NTLM_SSP_NAME
 
 struct _TEST_NTLM_CLIENT
 {
@@ -97,7 +97,8 @@ struct _TEST_NTLM_CLIENT
 };
 typedef struct _TEST_NTLM_CLIENT TEST_NTLM_CLIENT;
 
-int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm, const char* user, const char* domain, const char* password)
+int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm, const char* user, const char* domain,
+                          const char* password)
 {
        SECURITY_STATUS status;
        SecInvalidateHandle(&(ntlm->context));
@@ -108,18 +109,18 @@ int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm, const char* user, const char*
        if (status != SEC_E_OK)
        {
                fprintf(stderr, "QuerySecurityPackageInfo status: %s (0x%08"PRIX32")\n",
-                               GetSecurityStatusString(status), status);
+                       GetSecurityStatusString(status), status);
                return -1;
        }
 
        ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
        status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
-                        SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration);
+                SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration);
 
        if (status != SEC_E_OK)
        {
                fprintf(stderr, "AcquireCredentialsHandle status: %s (0x%08"PRIX32")\n",
-                               GetSecurityStatusString(status), status);
+                       GetSecurityStatusString(status), status);
                return -1;
        }
 
@@ -236,12 +237,12 @@ int test_ntlm_client_authenticate(TEST_NTLM_CLIENT* ntlm)
        }
 
        status = ntlm->table->InitializeSecurityContext(&ntlm->credentials,
-                        (ntlm->haveContext) ? &ntlm->context : NULL,
-                        (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
-                        ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
-                        (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
-                        0, &ntlm->context, &ntlm->outputBufferDesc,
-                        &ntlm->pfContextAttr, &ntlm->expiration);
+                (ntlm->haveContext) ? &ntlm->context : NULL,
+                (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL,
+                ntlm->fContextReq, 0, SECURITY_NATIVE_DREP,
+                (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL,
+                0, &ntlm->context, &ntlm->outputBufferDesc,
+                &ntlm->pfContextAttr, &ntlm->expiration);
 
        if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
        {
@@ -319,19 +320,19 @@ int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm)
        if (status != SEC_E_OK)
        {
                fprintf(stderr, "QuerySecurityPackageInfo status: %s (0x%08"PRIX32")\n",
-                               GetSecurityStatusString(status), status);
+                       GetSecurityStatusString(status), status);
                return -1;
        }
 
        ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
        status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
-                        SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL,
-                        &ntlm->credentials, &ntlm->expiration);
+                SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL,
+                &ntlm->credentials, &ntlm->expiration);
 
        if (status != SEC_E_OK)
        {
                fprintf(stderr, "AcquireCredentialsHandle status: %s (0x%08"PRIX32")\n",
-                               GetSecurityStatusString(status), status);
+                       GetSecurityStatusString(status), status);
                return -1;
        }
 
@@ -388,13 +389,14 @@ int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
        ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
        ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
        ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
+
        if (!ntlm->outputBuffer[0].pvBuffer)
                return -1;
 
        status = ntlm->table->AcceptSecurityContext(&ntlm->credentials,
-                        ntlm->haveContext? &ntlm->context: NULL,
-                        &ntlm->inputBufferDesc, ntlm->fContextReq, SECURITY_NATIVE_DREP, &ntlm->context,
-                        &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration);
+                ntlm->haveContext ? &ntlm->context : NULL,
+                &ntlm->inputBufferDesc, ntlm->fContextReq, SECURITY_NATIVE_DREP, &ntlm->context,
+                &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration);
 
        if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
        {
@@ -402,7 +404,8 @@ int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
                SecPkgContext_AuthNtlmHash AuthNtlmHash;
                ZeroMemory(&AuthIdentity, sizeof(SecPkgContext_AuthIdentity));
                ZeroMemory(&AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
-               status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_AUTH_IDENTITY, &AuthIdentity);
+               status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_AUTH_IDENTITY,
+                        &AuthIdentity);
 
                if (status == SEC_E_OK)
                {
@@ -420,7 +423,7 @@ int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
                                }
 
                                status = ntlm->table->SetContextAttributes(&ntlm->context,
-                                                SECPKG_ATTR_AUTH_NTLM_HASH, &AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
+                                        SECPKG_ATTR_AUTH_NTLM_HASH, &AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
                        }
                }
 
@@ -436,7 +439,7 @@ int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
        if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED))
        {
                fprintf(stderr, "AcceptSecurityContext status: %s (0x%08"PRIX32")\n",
-                               GetSecurityStatusString(status), status);
+                       GetSecurityStatusString(status), status);
                return -1; /* Access Denied */
        }
 
@@ -475,11 +478,13 @@ int TestNTLM(int argc, char* argv[])
         * Client Initialization
         */
        client = test_ntlm_client_new();
+
        if (!client)
        {
                printf("Memory allocation failed");
                return -1;
        }
+
        status = test_ntlm_client_init(client, TEST_NTLM_USER, TEST_NTLM_DOMAIN, TEST_NTLM_PASSWORD);
 
        if (status < 0)
@@ -492,11 +497,13 @@ int TestNTLM(int argc, char* argv[])
         * Server Initialization
         */
        server = test_ntlm_server_new();
+
        if (!server)
        {
                printf("Memory allocation failed\n");
                return -1;
        }
+
        status = test_ntlm_server_init(server);
 
        if (status < 0)
@@ -524,24 +531,25 @@ int TestNTLM(int argc, char* argv[])
                CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
                AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
                client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
-                                                                                       &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
+                                                   &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
                AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
                client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
-                                                                                       &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
+                                                   &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
                CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
                CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
                client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE,
-                                                                                       &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
+                                                   &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
                client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE,
-                                                                                       &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
+                                                   &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
        }
 
        pSecBuffer = &(client->outputBuffer[0]);
 
        if (!DynamicTest)
        {
-               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_NEGOTIATE) -1;
+               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_NEGOTIATE) - 1;
                pSecBuffer->pvBuffer = (void*) malloc(pSecBuffer->cbBuffer);
+
                if (!pSecBuffer->pvBuffer)
                {
                        printf("Memory allocation failed\n");
@@ -577,16 +585,16 @@ int TestNTLM(int argc, char* argv[])
                CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
                AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
                client->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
-                                                                                       &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
+                                                   &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
                AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
                client->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
-                                                                                       &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
+                                                   &AuthNtlmTimestamp, sizeof(SecPkgContext_AuthNtlmTimestamp));
                CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
                CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
                server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE,
-                                                                                       &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
+                                                   &AuthNtlmClientChallenge, sizeof(SecPkgContext_AuthNtlmClientChallenge));
                server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE,
-                                                                                       &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
+                                                   &AuthNtlmServerChallenge, sizeof(SecPkgContext_AuthNtlmServerChallenge));
        }
 
        pSecBuffer = &(server->outputBuffer[0]);
@@ -594,19 +602,21 @@ int TestNTLM(int argc, char* argv[])
        if (!DynamicTest)
        {
                SecPkgContext_AuthNtlmMessage AuthNtlmMessage;
-               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_CHALLENGE) -1;
+               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_CHALLENGE) - 1;
                pSecBuffer->pvBuffer = (void*) malloc(pSecBuffer->cbBuffer);
+
                if (!pSecBuffer->pvBuffer)
                {
                        printf("Memory allocation failed\n");
                        return -1;
                }
+
                CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_CHALLENGE, pSecBuffer->cbBuffer);
                AuthNtlmMessage.type = 2;
                AuthNtlmMessage.length = pSecBuffer->cbBuffer;
                AuthNtlmMessage.buffer = (BYTE*) pSecBuffer->pvBuffer;
                server->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_MESSAGE,
-                                                                                       &AuthNtlmMessage, sizeof(SecPkgContext_AuthNtlmMessage));
+                                                   &AuthNtlmMessage, sizeof(SecPkgContext_AuthNtlmMessage));
        }
 
        fprintf(stderr, "NTLM_CHALLENGE (length = %"PRIu32"):\n", pSecBuffer->cbBuffer);
@@ -631,13 +641,15 @@ int TestNTLM(int argc, char* argv[])
 
        if (!DynamicTest)
        {
-               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_AUTHENTICATE) -1;
+               pSecBuffer->cbBuffer = sizeof(TEST_NTLM_AUTHENTICATE) - 1;
                pSecBuffer->pvBuffer = (void*) malloc(pSecBuffer->cbBuffer);
+
                if (!pSecBuffer->pvBuffer)
                {
                        printf("Memory allocation failed\n");
                        return -1;
                }
+
                CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_AUTHENTICATE, pSecBuffer->cbBuffer);
        }
 
index c86e199..a738e0b 100644 (file)
@@ -8,10 +8,8 @@ int TestQuerySecurityPackageInfo(int argc, char* argv[])
 {
        SECURITY_STATUS status;
        SecPkgInfo* pPackageInfo;
-
        sspi_GlobalInit();
-
-       status = QuerySecurityPackageInfo(NTLMSSP_NAME, &pPackageInfo);
+       status = QuerySecurityPackageInfo(NTLM_SSP_NAME, &pPackageInfo);
 
        if (status != SEC_E_OK)
        {
@@ -21,9 +19,7 @@ int TestQuerySecurityPackageInfo(int argc, char* argv[])
 
        _tprintf(_T("\nQuerySecurityPackageInfo:\n"));
        _tprintf(_T("\"%s\", \"%s\"\n"), pPackageInfo->Name, pPackageInfo->Comment);
-
        sspi_GlobalFinish();
-
        return 0;
 }