libwinpr-sspi: isolate winpr implementation
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 6 Jun 2014 02:54:31 +0000 (22:54 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Fri, 6 Jun 2014 02:54:31 +0000 (22:54 -0400)
winpr/libwinpr/sspi/CMakeLists.txt
winpr/libwinpr/sspi/sspi.c
winpr/libwinpr/sspi/sspi.h
winpr/libwinpr/sspi/sspi_winpr.c [new file with mode: 0644]
winpr/libwinpr/sspi/sspi_winpr.h [new file with mode: 0644]

index d7b8f7b..6f6332c 100644 (file)
@@ -43,6 +43,8 @@ set(${MODULE_PREFIX}_CREDSSP_SRCS
 
 set(${MODULE_PREFIX}_SRCS
        ${${MODULE_PREFIX}_CREDSSP_SRCS}
+       sspi_winpr.c
+       sspi_winpr.h
        sspi.c
        sspi.h)
 
index 564df88..c36deae 100644 (file)
 #include "config.h"
 #endif
 
-#include <stdlib.h>
-
-#include <winpr/windows.h>
-
-#include <winpr/crt.h>
-#include <winpr/sspi.h>
-#include <winpr/print.h>
-
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-
 #include "sspi.h"
 
-/* Authentication Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374731/ */
-
-#ifdef WINPR_SSPI
-
-extern const SecPkgInfoA NTLM_SecPkgInfoA;
-extern const SecPkgInfoW NTLM_SecPkgInfoW;
-extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
-extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
-
-extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
-extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
-extern const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA;
-extern const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW;
-
-extern const SecPkgInfoA SCHANNEL_SecPkgInfoA;
-extern const SecPkgInfoW SCHANNEL_SecPkgInfoW;
-extern const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA;
-extern const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW;
-
-const SecPkgInfoA* SecPkgInfoA_LIST[] =
-{
-       &NTLM_SecPkgInfoA,
-       &CREDSSP_SecPkgInfoA,
-       &SCHANNEL_SecPkgInfoA
-};
-
-const SecPkgInfoW* SecPkgInfoW_LIST[] =
-{
-       &NTLM_SecPkgInfoW,
-       &CREDSSP_SecPkgInfoW,
-       &SCHANNEL_SecPkgInfoW
-};
-
-SecurityFunctionTableA SSPI_SecurityFunctionTableA;
-SecurityFunctionTableW SSPI_SecurityFunctionTableW;
-
-struct _SecurityFunctionTableA_NAME
-{
-       SEC_CHAR* Name;
-       const SecurityFunctionTableA* SecurityFunctionTable;
-};
-typedef struct _SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME;
-
-struct _SecurityFunctionTableW_NAME
-{
-       SEC_WCHAR* Name;
-       const SecurityFunctionTableW* SecurityFunctionTable;
-};
-typedef struct _SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME;
-
-const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] =
-{
-       { "NTLM", &NTLM_SecurityFunctionTableA },
-       { "CREDSSP", &CREDSSP_SecurityFunctionTableA },
-       { "Schannel", &SCHANNEL_SecurityFunctionTableA }
-};
-
-WCHAR NTLM_NAME_W[] = { 'N','T','L','M','\0' };
-WCHAR CREDSSP_NAME_W[] = { 'C','r','e','d','S','S','P','\0' };
-WCHAR SCHANNEL_NAME_W[] = { 'S','c','h','a','n','n','e','l','\0' };
-
-const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] =
-{
-       { NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
-       { CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW },
-       { SCHANNEL_NAME_W, &SCHANNEL_SecurityFunctionTableW }
-};
-
-#endif
-
-#define SecHandle_LOWER_MAX    0xFFFFFFFF
-#define SecHandle_UPPER_MAX    0xFFFFFFFE
-
-struct _CONTEXT_BUFFER_ALLOC_ENTRY
-{
-       void* contextBuffer;
-       UINT32 allocatorIndex;
-};
-typedef struct _CONTEXT_BUFFER_ALLOC_ENTRY CONTEXT_BUFFER_ALLOC_ENTRY;
-
-struct _CONTEXT_BUFFER_ALLOC_TABLE
-{
-       UINT32 cEntries;
-       UINT32 cMaxEntries;
-       CONTEXT_BUFFER_ALLOC_ENTRY* entries;
-};
-typedef struct _CONTEXT_BUFFER_ALLOC_TABLE CONTEXT_BUFFER_ALLOC_TABLE;
-
-CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable;
-
-void sspi_ContextBufferAllocTableNew()
-{
-       size_t size;
-
-       ContextBufferAllocTable.entries = NULL;
-       ContextBufferAllocTable.cEntries = 0;
-       ContextBufferAllocTable.cMaxEntries = 4;
-
-       size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
-
-       ContextBufferAllocTable.entries = malloc(size);
-       ZeroMemory(ContextBufferAllocTable.entries, size);
-}
-
-void sspi_ContextBufferAllocTableGrow()
-{
-       size_t size;
-       ContextBufferAllocTable.cEntries = 0;
-       ContextBufferAllocTable.cMaxEntries *= 2;
-
-       size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
-       if (!size)
-               return;
-
-       ContextBufferAllocTable.entries = realloc(ContextBufferAllocTable.entries, size);
-       ZeroMemory((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], size / 2);
-}
-
-void sspi_ContextBufferAllocTableFree()
-{
-       ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
-       free(ContextBufferAllocTable.entries);
-}
-
-void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size)
-{
-       int index;
-       void* contextBuffer;
-
-       for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
-       {
-               if (ContextBufferAllocTable.entries[index].contextBuffer == NULL)
-               {
-                       contextBuffer = malloc(size);
-                       ZeroMemory(contextBuffer, size);
-                       ContextBufferAllocTable.cEntries++;
-
-                       ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
-                       ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
-
-                       return ContextBufferAllocTable.entries[index].contextBuffer;
-               }
-       }
-
-       /* no available entry was found, the table needs to be grown */
-
-       sspi_ContextBufferAllocTableGrow();
-
-       /* the next call to sspi_ContextBufferAlloc() should now succeed */
-
-       return sspi_ContextBufferAlloc(allocatorIndex, size);
-}
-
-CREDENTIALS* sspi_CredentialsNew()
-{
-       CREDENTIALS* credentials;
-
-       credentials = (CREDENTIALS*) malloc(sizeof(CREDENTIALS));
-
-       if (credentials)
-       {
-               ZeroMemory(credentials, sizeof(CREDENTIALS));
-       }
-
-       return credentials;
-}
-
-void sspi_CredentialsFree(CREDENTIALS* credentials)
-{
-       if (!credentials)
-               return;
-
-       free(credentials);
-}
-
-void sspi_SecBufferAlloc(PSecBuffer SecBuffer, ULONG size)
-{
-       SecBuffer->cbBuffer = size;
-       SecBuffer->pvBuffer = malloc(size);
-
-       if (SecBuffer->pvBuffer)
-               ZeroMemory(SecBuffer->pvBuffer, SecBuffer->cbBuffer);
-}
-
-void sspi_SecBufferFree(PSecBuffer SecBuffer)
-{
-       free(SecBuffer->pvBuffer);
-       SecBuffer->pvBuffer = NULL;
-       SecBuffer->cbBuffer = 0;
-}
-
-SecHandle* sspi_SecureHandleAlloc()
-{
-       SecHandle* handle = (SecHandle*) malloc(sizeof(SecHandle));
-       sspi_SecureHandleInit(handle);
-       return handle;
-}
-
-void sspi_SecureHandleInit(SecHandle* handle)
-{
-       if (!handle)
-               return;
-
-       memset(handle, 0xFF, sizeof(SecHandle));
-}
-
-void sspi_SecureHandleInvalidate(SecHandle* handle)
-{
-       if (!handle)
-               return;
-
-       sspi_SecureHandleInit(handle);
-}
-
-void* sspi_SecureHandleGetLowerPointer(SecHandle* handle)
-{
-       void* pointer;
-
-       if (!handle || !SecIsValidHandle(handle))
-               return NULL;
-
-       pointer = (void*) ~((size_t) handle->dwLower);
-
-       return pointer;
-}
-
-void sspi_SecureHandleSetLowerPointer(SecHandle* handle, void* pointer)
-{
-       if (!handle)
-               return;
-
-       handle->dwLower = (ULONG_PTR) (~((size_t) pointer));
-}
-
-void* sspi_SecureHandleGetUpperPointer(SecHandle* handle)
-{
-       void* pointer;
-
-       if (!handle || !SecIsValidHandle(handle))
-               return NULL;
-
-       pointer = (void*) ~((size_t) handle->dwUpper);
-
-       return pointer;
-}
-
-void sspi_SecureHandleSetUpperPointer(SecHandle* handle, void* pointer)
-{
-       if (!handle)
-               return;
-
-       handle->dwUpper = (ULONG_PTR) (~((size_t) pointer));
-}
-
-void sspi_SecureHandleFree(SecHandle* handle)
-{
-       if (!handle)
-               return;
-
-       free(handle);
-}
-
-void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* domain, char* password)
-{
-       identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
-
-       if (user)
-       {
-               identity->UserLength = ConvertToUnicode(CP_UTF8, 0, user, -1, &identity->User, 0) - 1;
-       }
-       else
-       {
-               identity->User = (UINT16*) NULL;
-               identity->UserLength = 0;
-       }
-
-       if (domain)
-       {
-               identity->DomainLength = ConvertToUnicode(CP_UTF8, 0, domain, -1, &identity->Domain, 0) - 1;
-       }
-       else
-       {
-               identity->Domain = (UINT16*) NULL;
-               identity->DomainLength = 0;
-       }
-
-       if (password)
-       {
-               identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0, password, -1, &identity->Password, 0) - 1;
-       }
-       else
-       {
-               identity->Password = NULL;
-               identity->PasswordLength = 0;
-       }
-}
-
-void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity)
-{
-       if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
-       {
-               sspi_SetAuthIdentity(identity, (char*) srcIdentity->User,
-                               (char*) srcIdentity->Domain, (char*) srcIdentity->Password);
-
-               identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
-
-               return;
-       }
-
-       identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
-
-       identity->User = identity->Domain = identity->Password = NULL;
-
-       identity->UserLength = srcIdentity->UserLength;
-
-       if (identity->UserLength > 0)
-       {
-               identity->User = (UINT16*) malloc((identity->UserLength + 1) * sizeof(WCHAR));
-               CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR));
-               identity->User[identity->UserLength] = 0;
-       }
-
-       identity->DomainLength = srcIdentity->DomainLength;
-
-       if (identity->DomainLength > 0)
-       {
-               identity->Domain = (UINT16*) malloc((identity->DomainLength + 1) * sizeof(WCHAR));
-               CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR));
-               identity->Domain[identity->DomainLength] = 0;
-       }
-
-       identity->PasswordLength = srcIdentity->PasswordLength;
-
-       if (identity->PasswordLength > 256)
-               identity->PasswordLength /= SSPI_CREDENTIALS_HASH_LENGTH_FACTOR;
-
-       if (identity->PasswordLength > 0)
-       {
-               identity->Password = (UINT16*) malloc((identity->PasswordLength + 1) * sizeof(WCHAR));
-               CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength * sizeof(WCHAR));
-               identity->Password[identity->PasswordLength] = 0;
-       }
-
-       identity->PasswordLength = srcIdentity->PasswordLength;
-}
-
-PSecBuffer sspi_FindSecBuffer(PSecBufferDesc pMessage, ULONG BufferType)
-{
-       ULONG index;
-       PSecBuffer pSecBuffer = NULL;
-
-       for (index = 0; index < pMessage->cBuffers; index++)
-       {
-               if (pMessage->pBuffers[index].BufferType == BufferType)
-               {
-                       pSecBuffer = &pMessage->pBuffers[index];
-                       break;
-               }
-       }
-
-       return pSecBuffer;
-}
-
-static BOOL sspi_initialized = FALSE;
-
-void sspi_GlobalInit()
-{
-       if (!sspi_initialized)
-       {
-               SSL_load_error_strings();
-               SSL_library_init();
-
-               sspi_ContextBufferAllocTableNew();
-               sspi_initialized = TRUE;
-       }
-}
-
-void sspi_GlobalFinish()
-{
-       if (sspi_initialized)
-       {
-               sspi_ContextBufferAllocTableFree();
-       }
-
-       sspi_initialized = FALSE;
-}
-
-#ifndef WITH_NATIVE_SSPI
-
-SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameA(const SEC_CHAR* Name)
-{
-       int index;
-       UINT32 cPackages;
-
-       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
-               {
-                       return (SecurityFunctionTableA*) SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
-               }
-       }
-
-       return NULL;
-}
-
-SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameW(const SEC_WCHAR* Name)
-{
-       return NULL;
-}
-
-SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameW(const SEC_WCHAR* Name)
-{
-       int index;
-       UINT32 cPackages;
-
-       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               if (lstrcmpW(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
-               {
-                       return (SecurityFunctionTableW*) SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
-               }
-       }
-
-       return NULL;
-}
-
-SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const SEC_CHAR* Name)
-{
-       SEC_WCHAR* NameW = NULL;
-       SecurityFunctionTableW* table;
-
-       ConvertToUnicode(CP_UTF8, 0, Name, -1, &NameW, 0);
-
-       table = sspi_GetSecurityFunctionTableWByNameW(NameW);
-       free(NameW);
-
-       return table;
-}
-
-void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer);
-void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer);
-
-void sspi_ContextBufferFree(void* contextBuffer)
-{
-       int index;
-       UINT32 allocatorIndex;
-
-       for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
-       {
-               if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
-               {
-                       contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
-                       allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
-
-                       ContextBufferAllocTable.cEntries--;
-
-                       ContextBufferAllocTable.entries[index].allocatorIndex = 0;
-                       ContextBufferAllocTable.entries[index].contextBuffer = NULL;
-
-                       switch (allocatorIndex)
-                       {
-                               case EnumerateSecurityPackagesIndex:
-                                       FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
-                                       break;
-
-                               case QuerySecurityPackageInfoIndex:
-                                       FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
-                                       break;
-                       }
-               }
-       }
-}
+#ifndef _WIN32
 
 /* Package Management */
 
 SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo)
 {
-       int index;
-       size_t size;
-       UINT32 cPackages;
-       SecPkgInfoW* pPackageInfo;
-
-       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
-       size = sizeof(SecPkgInfoW) * cPackages;
-
-       pPackageInfo = (SecPkgInfoW*) sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
-               pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
-               pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
-               pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
-               pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
-               pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
-       }
-
-       *(pcPackages) = cPackages;
-       *(ppPackageInfo) = pPackageInfo;
-
        return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo)
 {
-       int index;
-       size_t size;
-       UINT32 cPackages;
-       SecPkgInfoA* pPackageInfo;
-
-       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
-       size = sizeof(SecPkgInfoA) * cPackages;
-
-       pPackageInfo = (SecPkgInfoA*) sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
-               pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
-               pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
-               pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
-               pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
-               pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
-       }
-
-       *(pcPackages) = cPackages;
-       *(ppPackageInfo) = pPackageInfo;
-
        return SEC_E_OK;
 }
 
-void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer)
-{
-       int index;
-       UINT32 cPackages;
-       SecPkgInfoA* pPackageInfo = (SecPkgInfoA*) contextBuffer;
-
-       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               if (pPackageInfo[index].Name)
-                       free(pPackageInfo[index].Name);
-
-               if (pPackageInfo[index].Comment)
-                       free(pPackageInfo[index].Comment);
-       }
-
-       free(pPackageInfo);
-}
-
 SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceW(void)
 {
-       return &SSPI_SecurityFunctionTableW;
+       return &winpr_SecurityFunctionTableW;
 }
 
 SecurityFunctionTableA* SEC_ENTRY InitSecurityInterfaceA(void)
 {
-       return &SSPI_SecurityFunctionTableA;
+       return &winpr_SecurityFunctionTableA;
 }
 
 SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo)
 {
-       int index;
-       size_t size;
-       UINT32 cPackages;
-       SecPkgInfoW* pPackageInfo;
-
-       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               if (lstrcmpW(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
-               {
-                       size = sizeof(SecPkgInfoW);
-                       pPackageInfo = (SecPkgInfoW*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
-
-                       pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
-                       pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
-                       pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
-                       pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
-                       pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
-                       pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
-
-                       *(ppPackageInfo) = pPackageInfo;
-
-                       return SEC_E_OK;
-               }
-       }
-
-       *(ppPackageInfo) = NULL;
-
-       return SEC_E_SECPKG_NOT_FOUND;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo)
 {
-       int index;
-       size_t size;
-       UINT32 cPackages;
-       SecPkgInfoA* pPackageInfo;
-
-       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
-
-       for (index = 0; index < (int) cPackages; index++)
-       {
-               if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
-               {
-                       size = sizeof(SecPkgInfoA);
-                       pPackageInfo = (SecPkgInfoA*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
-
-                       pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
-                       pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
-                       pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
-                       pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
-                       pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
-                       pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
-
-                       *(ppPackageInfo) = pPackageInfo;
-
-                       return SEC_E_OK;
-               }
-       }
-
-       *(ppPackageInfo) = NULL;
-
-       return SEC_E_SECPKG_NOT_FOUND;
-}
-
-void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer)
-{
-       SecPkgInfo* pPackageInfo = (SecPkgInfo*) contextBuffer;
-
-       if (pPackageInfo->Name)
-               free(pPackageInfo->Name);
-
-       if (pPackageInfo->Comment)
-               free(pPackageInfo->Comment);
-
-       free(pPackageInfo);
+       return SEC_E_OK;
 }
 
 /* Credential Management */
@@ -686,38 +63,14 @@ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC
                ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
                void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
 {
-       SECURITY_STATUS status;
-       SecurityFunctionTableW* table = sspi_GetSecurityFunctionTableWByNameW(pszPackage);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->AcquireCredentialsHandleW == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse,
-                       pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
-
-       return status;
+       return SEC_E_OK;
 }
 
 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)
 {
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table = sspi_GetSecurityFunctionTableAByNameA(pszPackage);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->AcquireCredentialsHandleA == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse,
-                       pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken)
@@ -727,26 +80,7 @@ SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFl
 
 SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(PCredHandle phCredential)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->FreeCredentialsHandle == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->FreeCredentialsHandle(phCredential);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext)
@@ -761,50 +95,12 @@ SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffe
 
 SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
 {
-       SEC_WCHAR* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableW* table;
-
-       Name = (SEC_WCHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableWByNameW(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->QueryCredentialsAttributesW == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->QueryCredentialsAttributesA == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
-
-       return status;
+       return SEC_E_OK;
 }
 
 /* Context Management */
@@ -813,27 +109,7 @@ SECURITY_STATUS SEC_ENTRY AcceptSecurityContext(PCredHandle phCredential, PCtxtH
                PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
                PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->AcceptSecurityContext == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq,
-                       TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput)
@@ -848,35 +124,11 @@ SECURITY_STATUS SEC_ENTRY CompleteAuthToken(PCtxtHandle phContext, PSecBufferDes
 
 SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext)
 {
-       char* Name = NULL;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->DeleteSecurityContext == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->DeleteSecurityContext(phContext);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY FreeContextBuffer(void* pvContextBuffer)
 {
-       if (!pvContextBuffer)
-               return SEC_E_INVALID_HANDLE;
-
-       sspi_ContextBufferFree(pvContextBuffer);
-
        return SEC_E_OK;
 }
 
@@ -890,28 +142,7 @@ SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(PCredHandle phCredential, P
                PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
                PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
 {
-       SEC_CHAR* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableW* table;
-
-       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableWByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->InitializeSecurityContextW == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->InitializeSecurityContextW(phCredential, phContext,
-                       pszTargetName, fContextReq, Reserved1, TargetDataRep,
-                       pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext,
@@ -919,76 +150,17 @@ SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(PCredHandle phCredential, P
                PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
                PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
 {
-       SEC_CHAR* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->InitializeSecurityContextA == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->InitializeSecurityContextA(phCredential, phContext,
-                       pszTargetName, fContextReq, Reserved1, TargetDataRep,
-                       pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
 {
-       SEC_CHAR* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableW* table;
-
-       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableWByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->QueryContextAttributesW == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
 {
-       SEC_CHAR* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->QueryContextAttributesA == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken)
@@ -1010,162 +182,22 @@ SECURITY_STATUS SEC_ENTRY RevertSecurityContext(PCtxtHandle phContext)
 
 SECURITY_STATUS SEC_ENTRY DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->DecryptMessage == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->EncryptMessage == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->MakeSignature == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
-
-       return status;
+       return SEC_E_OK;
 }
 
 SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
 {
-       char* Name;
-       SECURITY_STATUS status;
-       SecurityFunctionTableA* table;
-
-       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
-
-       if (!Name)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       table = sspi_GetSecurityFunctionTableAByNameA(Name);
-
-       if (!table)
-               return SEC_E_SECPKG_NOT_FOUND;
-
-       if (table->VerifySignature == NULL)
-               return SEC_E_UNSUPPORTED_FUNCTION;
-
-       status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
-
-       return status;
+       return SEC_E_OK;
 }
 
-SecurityFunctionTableA SSPI_SecurityFunctionTableA =
-{
-       1, /* dwVersion */
-       EnumerateSecurityPackagesA, /* EnumerateSecurityPackages */
-       QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
-       AcquireCredentialsHandleA, /* AcquireCredentialsHandle */
-       FreeCredentialsHandle, /* FreeCredentialsHandle */
-       NULL, /* Reserved2 */
-       InitializeSecurityContextA, /* InitializeSecurityContext */
-       AcceptSecurityContext, /* AcceptSecurityContext */
-       CompleteAuthToken, /* CompleteAuthToken */
-       DeleteSecurityContext, /* DeleteSecurityContext */
-       ApplyControlToken, /* ApplyControlToken */
-       QueryContextAttributesA, /* QueryContextAttributes */
-       ImpersonateSecurityContext, /* ImpersonateSecurityContext */
-       RevertSecurityContext, /* RevertSecurityContext */
-       MakeSignature, /* MakeSignature */
-       VerifySignature, /* VerifySignature */
-       FreeContextBuffer, /* FreeContextBuffer */
-       QuerySecurityPackageInfoA, /* QuerySecurityPackageInfo */
-       NULL, /* Reserved3 */
-       NULL, /* Reserved4 */
-       ExportSecurityContext, /* ExportSecurityContext */
-       ImportSecurityContextA, /* ImportSecurityContext */
-       NULL, /* AddCredentials */
-       NULL, /* Reserved8 */
-       QuerySecurityContextToken, /* QuerySecurityContextToken */
-       EncryptMessage, /* EncryptMessage */
-       DecryptMessage, /* DecryptMessage */
-       SetContextAttributes, /* SetContextAttributes */
-};
-
-SecurityFunctionTableW SSPI_SecurityFunctionTableW =
-{
-       1, /* dwVersion */
-       EnumerateSecurityPackagesW, /* EnumerateSecurityPackages */
-       QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
-       AcquireCredentialsHandleW, /* AcquireCredentialsHandle */
-       FreeCredentialsHandle, /* FreeCredentialsHandle */
-       NULL, /* Reserved2 */
-       InitializeSecurityContextW, /* InitializeSecurityContext */
-       AcceptSecurityContext, /* AcceptSecurityContext */
-       CompleteAuthToken, /* CompleteAuthToken */
-       DeleteSecurityContext, /* DeleteSecurityContext */
-       ApplyControlToken, /* ApplyControlToken */
-       QueryContextAttributesW, /* QueryContextAttributes */
-       ImpersonateSecurityContext, /* ImpersonateSecurityContext */
-       RevertSecurityContext, /* RevertSecurityContext */
-       MakeSignature, /* MakeSignature */
-       VerifySignature, /* VerifySignature */
-       FreeContextBuffer, /* FreeContextBuffer */
-       QuerySecurityPackageInfoW, /* QuerySecurityPackageInfo */
-       NULL, /* Reserved3 */
-       NULL, /* Reserved4 */
-       ExportSecurityContext, /* ExportSecurityContext */
-       ImportSecurityContextW, /* ImportSecurityContext */
-       NULL, /* AddCredentials */
-       NULL, /* Reserved8 */
-       QuerySecurityContextToken, /* QuerySecurityContextToken */
-       EncryptMessage, /* EncryptMessage */
-       DecryptMessage, /* DecryptMessage */
-       SetContextAttributes, /* SetContextAttributes */
-};
-
 #endif
index 60f5e05..9ea3573 100644 (file)
@@ -2,7 +2,7 @@
  * WinPR: Windows Portable Runtime
  * Security Support Provider Interface (SSPI)
  *
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c
new file mode 100644 (file)
index 0000000..bbd8331
--- /dev/null
@@ -0,0 +1,1165 @@
+/**
+ * FreeRDP: A Remote Desktop Protocol Implementation
+ * Security Support Provider Interface (SSPI)
+ *
+ * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+
+#include <winpr/windows.h>
+
+#include <winpr/crt.h>
+#include <winpr/sspi.h>
+#include <winpr/print.h>
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#include "sspi.h"
+
+#include "sspi_winpr.h"
+
+/* Authentication Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374731/ */
+
+extern const SecPkgInfoA NTLM_SecPkgInfoA;
+extern const SecPkgInfoW NTLM_SecPkgInfoW;
+extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
+extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
+
+extern const SecPkgInfoA CREDSSP_SecPkgInfoA;
+extern const SecPkgInfoW CREDSSP_SecPkgInfoW;
+extern const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA;
+extern const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW;
+
+extern const SecPkgInfoA SCHANNEL_SecPkgInfoA;
+extern const SecPkgInfoW SCHANNEL_SecPkgInfoW;
+extern const SecurityFunctionTableA SCHANNEL_SecurityFunctionTableA;
+extern const SecurityFunctionTableW SCHANNEL_SecurityFunctionTableW;
+
+const SecPkgInfoA* SecPkgInfoA_LIST[] =
+{
+       &NTLM_SecPkgInfoA,
+       &CREDSSP_SecPkgInfoA,
+       &SCHANNEL_SecPkgInfoA
+};
+
+const SecPkgInfoW* SecPkgInfoW_LIST[] =
+{
+       &NTLM_SecPkgInfoW,
+       &CREDSSP_SecPkgInfoW,
+       &SCHANNEL_SecPkgInfoW
+};
+
+SecurityFunctionTableA winpr_SecurityFunctionTableA;
+SecurityFunctionTableW winpr_SecurityFunctionTableW;
+
+struct _SecurityFunctionTableA_NAME
+{
+       SEC_CHAR* Name;
+       const SecurityFunctionTableA* SecurityFunctionTable;
+};
+typedef struct _SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME;
+
+struct _SecurityFunctionTableW_NAME
+{
+       SEC_WCHAR* Name;
+       const SecurityFunctionTableW* SecurityFunctionTable;
+};
+typedef struct _SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME;
+
+const SecurityFunctionTableA_NAME SecurityFunctionTableA_NAME_LIST[] =
+{
+       { "NTLM", &NTLM_SecurityFunctionTableA },
+       { "CREDSSP", &CREDSSP_SecurityFunctionTableA },
+       { "Schannel", &SCHANNEL_SecurityFunctionTableA }
+};
+
+WCHAR NTLM_NAME_W[] = { 'N','T','L','M','\0' };
+WCHAR CREDSSP_NAME_W[] = { 'C','r','e','d','S','S','P','\0' };
+WCHAR SCHANNEL_NAME_W[] = { 'S','c','h','a','n','n','e','l','\0' };
+
+const SecurityFunctionTableW_NAME SecurityFunctionTableW_NAME_LIST[] =
+{
+       { NTLM_NAME_W, &NTLM_SecurityFunctionTableW },
+       { CREDSSP_NAME_W, &CREDSSP_SecurityFunctionTableW },
+       { SCHANNEL_NAME_W, &SCHANNEL_SecurityFunctionTableW }
+};
+
+#define SecHandle_LOWER_MAX    0xFFFFFFFF
+#define SecHandle_UPPER_MAX    0xFFFFFFFE
+
+struct _CONTEXT_BUFFER_ALLOC_ENTRY
+{
+       void* contextBuffer;
+       UINT32 allocatorIndex;
+};
+typedef struct _CONTEXT_BUFFER_ALLOC_ENTRY CONTEXT_BUFFER_ALLOC_ENTRY;
+
+struct _CONTEXT_BUFFER_ALLOC_TABLE
+{
+       UINT32 cEntries;
+       UINT32 cMaxEntries;
+       CONTEXT_BUFFER_ALLOC_ENTRY* entries;
+};
+typedef struct _CONTEXT_BUFFER_ALLOC_TABLE CONTEXT_BUFFER_ALLOC_TABLE;
+
+CONTEXT_BUFFER_ALLOC_TABLE ContextBufferAllocTable;
+
+void sspi_ContextBufferAllocTableNew()
+{
+       size_t size;
+
+       ContextBufferAllocTable.entries = NULL;
+       ContextBufferAllocTable.cEntries = 0;
+       ContextBufferAllocTable.cMaxEntries = 4;
+
+       size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
+
+       ContextBufferAllocTable.entries = malloc(size);
+       ZeroMemory(ContextBufferAllocTable.entries, size);
+}
+
+void sspi_ContextBufferAllocTableGrow()
+{
+       size_t size;
+       ContextBufferAllocTable.cEntries = 0;
+       ContextBufferAllocTable.cMaxEntries *= 2;
+
+       size = sizeof(CONTEXT_BUFFER_ALLOC_ENTRY) * ContextBufferAllocTable.cMaxEntries;
+       if (!size)
+               return;
+
+       ContextBufferAllocTable.entries = realloc(ContextBufferAllocTable.entries, size);
+       ZeroMemory((void*) &ContextBufferAllocTable.entries[ContextBufferAllocTable.cMaxEntries / 2], size / 2);
+}
+
+void sspi_ContextBufferAllocTableFree()
+{
+       ContextBufferAllocTable.cEntries = ContextBufferAllocTable.cMaxEntries = 0;
+       free(ContextBufferAllocTable.entries);
+}
+
+void* sspi_ContextBufferAlloc(UINT32 allocatorIndex, size_t size)
+{
+       int index;
+       void* contextBuffer;
+
+       for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
+       {
+               if (ContextBufferAllocTable.entries[index].contextBuffer == NULL)
+               {
+                       contextBuffer = malloc(size);
+                       ZeroMemory(contextBuffer, size);
+                       ContextBufferAllocTable.cEntries++;
+
+                       ContextBufferAllocTable.entries[index].contextBuffer = contextBuffer;
+                       ContextBufferAllocTable.entries[index].allocatorIndex = allocatorIndex;
+
+                       return ContextBufferAllocTable.entries[index].contextBuffer;
+               }
+       }
+
+       /* no available entry was found, the table needs to be grown */
+
+       sspi_ContextBufferAllocTableGrow();
+
+       /* the next call to sspi_ContextBufferAlloc() should now succeed */
+
+       return sspi_ContextBufferAlloc(allocatorIndex, size);
+}
+
+CREDENTIALS* sspi_CredentialsNew()
+{
+       CREDENTIALS* credentials;
+
+       credentials = (CREDENTIALS*) malloc(sizeof(CREDENTIALS));
+
+       if (credentials)
+       {
+               ZeroMemory(credentials, sizeof(CREDENTIALS));
+       }
+
+       return credentials;
+}
+
+void sspi_CredentialsFree(CREDENTIALS* credentials)
+{
+       if (!credentials)
+               return;
+
+       free(credentials);
+}
+
+void sspi_SecBufferAlloc(PSecBuffer SecBuffer, ULONG size)
+{
+       SecBuffer->cbBuffer = size;
+       SecBuffer->pvBuffer = malloc(size);
+
+       if (SecBuffer->pvBuffer)
+               ZeroMemory(SecBuffer->pvBuffer, SecBuffer->cbBuffer);
+}
+
+void sspi_SecBufferFree(PSecBuffer SecBuffer)
+{
+       free(SecBuffer->pvBuffer);
+       SecBuffer->pvBuffer = NULL;
+       SecBuffer->cbBuffer = 0;
+}
+
+SecHandle* sspi_SecureHandleAlloc()
+{
+       SecHandle* handle = (SecHandle*) malloc(sizeof(SecHandle));
+       sspi_SecureHandleInit(handle);
+       return handle;
+}
+
+void sspi_SecureHandleInit(SecHandle* handle)
+{
+       if (!handle)
+               return;
+
+       memset(handle, 0xFF, sizeof(SecHandle));
+}
+
+void sspi_SecureHandleInvalidate(SecHandle* handle)
+{
+       if (!handle)
+               return;
+
+       sspi_SecureHandleInit(handle);
+}
+
+void* sspi_SecureHandleGetLowerPointer(SecHandle* handle)
+{
+       void* pointer;
+
+       if (!handle || !SecIsValidHandle(handle))
+               return NULL;
+
+       pointer = (void*) ~((size_t) handle->dwLower);
+
+       return pointer;
+}
+
+void sspi_SecureHandleSetLowerPointer(SecHandle* handle, void* pointer)
+{
+       if (!handle)
+               return;
+
+       handle->dwLower = (ULONG_PTR) (~((size_t) pointer));
+}
+
+void* sspi_SecureHandleGetUpperPointer(SecHandle* handle)
+{
+       void* pointer;
+
+       if (!handle || !SecIsValidHandle(handle))
+               return NULL;
+
+       pointer = (void*) ~((size_t) handle->dwUpper);
+
+       return pointer;
+}
+
+void sspi_SecureHandleSetUpperPointer(SecHandle* handle, void* pointer)
+{
+       if (!handle)
+               return;
+
+       handle->dwUpper = (ULONG_PTR) (~((size_t) pointer));
+}
+
+void sspi_SecureHandleFree(SecHandle* handle)
+{
+       if (!handle)
+               return;
+
+       free(handle);
+}
+
+void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* domain, char* password)
+{
+       identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+
+       if (user)
+       {
+               identity->UserLength = ConvertToUnicode(CP_UTF8, 0, user, -1, &identity->User, 0) - 1;
+       }
+       else
+       {
+               identity->User = (UINT16*) NULL;
+               identity->UserLength = 0;
+       }
+
+       if (domain)
+       {
+               identity->DomainLength = ConvertToUnicode(CP_UTF8, 0, domain, -1, &identity->Domain, 0) - 1;
+       }
+       else
+       {
+               identity->Domain = (UINT16*) NULL;
+               identity->DomainLength = 0;
+       }
+
+       if (password)
+       {
+               identity->PasswordLength = ConvertToUnicode(CP_UTF8, 0, password, -1, &identity->Password, 0) - 1;
+       }
+       else
+       {
+               identity->Password = NULL;
+               identity->PasswordLength = 0;
+       }
+}
+
+void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDENTITY* srcIdentity)
+{
+       if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
+       {
+               sspi_SetAuthIdentity(identity, (char*) srcIdentity->User,
+                               (char*) srcIdentity->Domain, (char*) srcIdentity->Password);
+
+               identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+
+               return;
+       }
+
+       identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+
+       identity->User = identity->Domain = identity->Password = NULL;
+
+       identity->UserLength = srcIdentity->UserLength;
+
+       if (identity->UserLength > 0)
+       {
+               identity->User = (UINT16*) malloc((identity->UserLength + 1) * sizeof(WCHAR));
+               CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR));
+               identity->User[identity->UserLength] = 0;
+       }
+
+       identity->DomainLength = srcIdentity->DomainLength;
+
+       if (identity->DomainLength > 0)
+       {
+               identity->Domain = (UINT16*) malloc((identity->DomainLength + 1) * sizeof(WCHAR));
+               CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR));
+               identity->Domain[identity->DomainLength] = 0;
+       }
+
+       identity->PasswordLength = srcIdentity->PasswordLength;
+
+       if (identity->PasswordLength > 256)
+               identity->PasswordLength /= SSPI_CREDENTIALS_HASH_LENGTH_FACTOR;
+
+       if (identity->PasswordLength > 0)
+       {
+               identity->Password = (UINT16*) malloc((identity->PasswordLength + 1) * sizeof(WCHAR));
+               CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength * sizeof(WCHAR));
+               identity->Password[identity->PasswordLength] = 0;
+       }
+
+       identity->PasswordLength = srcIdentity->PasswordLength;
+}
+
+PSecBuffer sspi_FindSecBuffer(PSecBufferDesc pMessage, ULONG BufferType)
+{
+       ULONG index;
+       PSecBuffer pSecBuffer = NULL;
+
+       for (index = 0; index < pMessage->cBuffers; index++)
+       {
+               if (pMessage->pBuffers[index].BufferType == BufferType)
+               {
+                       pSecBuffer = &pMessage->pBuffers[index];
+                       break;
+               }
+       }
+
+       return pSecBuffer;
+}
+
+static BOOL sspi_initialized = FALSE;
+
+void sspi_GlobalInit()
+{
+       if (!sspi_initialized)
+       {
+               SSL_load_error_strings();
+               SSL_library_init();
+
+               sspi_ContextBufferAllocTableNew();
+               sspi_initialized = TRUE;
+       }
+}
+
+void sspi_GlobalFinish()
+{
+       if (sspi_initialized)
+       {
+               sspi_ContextBufferAllocTableFree();
+       }
+
+       sspi_initialized = FALSE;
+}
+
+SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameA(const SEC_CHAR* Name)
+{
+       int index;
+       UINT32 cPackages;
+
+       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               if (strcmp(Name, SecurityFunctionTableA_NAME_LIST[index].Name) == 0)
+               {
+                       return (SecurityFunctionTableA*) SecurityFunctionTableA_NAME_LIST[index].SecurityFunctionTable;
+               }
+       }
+
+       return NULL;
+}
+
+SecurityFunctionTableA* sspi_GetSecurityFunctionTableAByNameW(const SEC_WCHAR* Name)
+{
+       return NULL;
+}
+
+SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameW(const SEC_WCHAR* Name)
+{
+       int index;
+       UINT32 cPackages;
+
+       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               if (lstrcmpW(Name, SecurityFunctionTableW_NAME_LIST[index].Name) == 0)
+               {
+                       return (SecurityFunctionTableW*) SecurityFunctionTableW_NAME_LIST[index].SecurityFunctionTable;
+               }
+       }
+
+       return NULL;
+}
+
+SecurityFunctionTableW* sspi_GetSecurityFunctionTableWByNameA(const SEC_CHAR* Name)
+{
+       SEC_WCHAR* NameW = NULL;
+       SecurityFunctionTableW* table;
+
+       ConvertToUnicode(CP_UTF8, 0, Name, -1, &NameW, 0);
+
+       table = sspi_GetSecurityFunctionTableWByNameW(NameW);
+       free(NameW);
+
+       return table;
+}
+
+void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer);
+void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer);
+
+void sspi_ContextBufferFree(void* contextBuffer)
+{
+       int index;
+       UINT32 allocatorIndex;
+
+       for (index = 0; index < (int) ContextBufferAllocTable.cMaxEntries; index++)
+       {
+               if (contextBuffer == ContextBufferAllocTable.entries[index].contextBuffer)
+               {
+                       contextBuffer = ContextBufferAllocTable.entries[index].contextBuffer;
+                       allocatorIndex = ContextBufferAllocTable.entries[index].allocatorIndex;
+
+                       ContextBufferAllocTable.cEntries--;
+
+                       ContextBufferAllocTable.entries[index].allocatorIndex = 0;
+                       ContextBufferAllocTable.entries[index].contextBuffer = NULL;
+
+                       switch (allocatorIndex)
+                       {
+                               case EnumerateSecurityPackagesIndex:
+                                       FreeContextBuffer_EnumerateSecurityPackages(contextBuffer);
+                                       break;
+
+                               case QuerySecurityPackageInfoIndex:
+                                       FreeContextBuffer_QuerySecurityPackageInfo(contextBuffer);
+                                       break;
+                       }
+               }
+       }
+}
+
+/* Package Management */
+
+SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo)
+{
+       int index;
+       size_t size;
+       UINT32 cPackages;
+       SecPkgInfoW* pPackageInfo;
+
+       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
+       size = sizeof(SecPkgInfoW) * cPackages;
+
+       pPackageInfo = (SecPkgInfoW*) sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               pPackageInfo[index].fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
+               pPackageInfo[index].wVersion = SecPkgInfoW_LIST[index]->wVersion;
+               pPackageInfo[index].wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
+               pPackageInfo[index].cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
+               pPackageInfo[index].Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
+               pPackageInfo[index].Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
+       }
+
+       *(pcPackages) = cPackages;
+       *(ppPackageInfo) = pPackageInfo;
+
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo)
+{
+       int index;
+       size_t size;
+       UINT32 cPackages;
+       SecPkgInfoA* pPackageInfo;
+
+       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
+       size = sizeof(SecPkgInfoA) * cPackages;
+
+       pPackageInfo = (SecPkgInfoA*) sspi_ContextBufferAlloc(EnumerateSecurityPackagesIndex, size);
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               pPackageInfo[index].fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
+               pPackageInfo[index].wVersion = SecPkgInfoA_LIST[index]->wVersion;
+               pPackageInfo[index].wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
+               pPackageInfo[index].cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
+               pPackageInfo[index].Name = _strdup(SecPkgInfoA_LIST[index]->Name);
+               pPackageInfo[index].Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
+       }
+
+       *(pcPackages) = cPackages;
+       *(ppPackageInfo) = pPackageInfo;
+
+       return SEC_E_OK;
+}
+
+void FreeContextBuffer_EnumerateSecurityPackages(void* contextBuffer)
+{
+       int index;
+       UINT32 cPackages;
+       SecPkgInfoA* pPackageInfo = (SecPkgInfoA*) contextBuffer;
+
+       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               if (pPackageInfo[index].Name)
+                       free(pPackageInfo[index].Name);
+
+               if (pPackageInfo[index].Comment)
+                       free(pPackageInfo[index].Comment);
+       }
+
+       free(pPackageInfo);
+}
+
+SecurityFunctionTableW* SEC_ENTRY winpr_InitSecurityInterfaceW(void)
+{
+       return &winpr_SecurityFunctionTableW;
+}
+
+SecurityFunctionTableA* SEC_ENTRY winpr_InitSecurityInterfaceA(void)
+{
+       return &winpr_SecurityFunctionTableA;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo)
+{
+       int index;
+       size_t size;
+       UINT32 cPackages;
+       SecPkgInfoW* pPackageInfo;
+
+       cPackages = sizeof(SecPkgInfoW_LIST) / sizeof(*(SecPkgInfoW_LIST));
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               if (lstrcmpW(pszPackageName, SecPkgInfoW_LIST[index]->Name) == 0)
+               {
+                       size = sizeof(SecPkgInfoW);
+                       pPackageInfo = (SecPkgInfoW*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
+
+                       pPackageInfo->fCapabilities = SecPkgInfoW_LIST[index]->fCapabilities;
+                       pPackageInfo->wVersion = SecPkgInfoW_LIST[index]->wVersion;
+                       pPackageInfo->wRPCID = SecPkgInfoW_LIST[index]->wRPCID;
+                       pPackageInfo->cbMaxToken = SecPkgInfoW_LIST[index]->cbMaxToken;
+                       pPackageInfo->Name = _wcsdup(SecPkgInfoW_LIST[index]->Name);
+                       pPackageInfo->Comment = _wcsdup(SecPkgInfoW_LIST[index]->Comment);
+
+                       *(ppPackageInfo) = pPackageInfo;
+
+                       return SEC_E_OK;
+               }
+       }
+
+       *(ppPackageInfo) = NULL;
+
+       return SEC_E_SECPKG_NOT_FOUND;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo)
+{
+       int index;
+       size_t size;
+       UINT32 cPackages;
+       SecPkgInfoA* pPackageInfo;
+
+       cPackages = sizeof(SecPkgInfoA_LIST) / sizeof(*(SecPkgInfoA_LIST));
+
+       for (index = 0; index < (int) cPackages; index++)
+       {
+               if (strcmp(pszPackageName, SecPkgInfoA_LIST[index]->Name) == 0)
+               {
+                       size = sizeof(SecPkgInfoA);
+                       pPackageInfo = (SecPkgInfoA*) sspi_ContextBufferAlloc(QuerySecurityPackageInfoIndex, size);
+
+                       pPackageInfo->fCapabilities = SecPkgInfoA_LIST[index]->fCapabilities;
+                       pPackageInfo->wVersion = SecPkgInfoA_LIST[index]->wVersion;
+                       pPackageInfo->wRPCID = SecPkgInfoA_LIST[index]->wRPCID;
+                       pPackageInfo->cbMaxToken = SecPkgInfoA_LIST[index]->cbMaxToken;
+                       pPackageInfo->Name = _strdup(SecPkgInfoA_LIST[index]->Name);
+                       pPackageInfo->Comment = _strdup(SecPkgInfoA_LIST[index]->Comment);
+
+                       *(ppPackageInfo) = pPackageInfo;
+
+                       return SEC_E_OK;
+               }
+       }
+
+       *(ppPackageInfo) = NULL;
+
+       return SEC_E_SECPKG_NOT_FOUND;
+}
+
+void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer)
+{
+       SecPkgInfo* pPackageInfo = (SecPkgInfo*) contextBuffer;
+
+       if (pPackageInfo->Name)
+               free(pPackageInfo->Name);
+
+       if (pPackageInfo->Comment)
+               free(pPackageInfo->Comment);
+
+       free(pPackageInfo);
+}
+
+/* Credential Management */
+
+SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
+               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
+{
+       SECURITY_STATUS status;
+       SecurityFunctionTableW* table = sspi_GetSecurityFunctionTableWByNameW(pszPackage);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->AcquireCredentialsHandleW == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse,
+                       pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
+               ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+               void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
+{
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table = sspi_GetSecurityFunctionTableAByNameA(pszPackage);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->AcquireCredentialsHandleA == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse,
+                       pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(PCredHandle phCredential)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->FreeCredentialsHandle == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->FreeCredentialsHandle(phCredential);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
+{
+       SEC_WCHAR* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableW* table;
+
+       Name = (SEC_WCHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableWByNameW(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->QueryCredentialsAttributesW == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->QueryCredentialsAttributesA == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer);
+
+       return status;
+}
+
+/* Context Management */
+
+SECURITY_STATUS SEC_ENTRY winpr_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext,
+               PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
+               PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->AcceptSecurityContext == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq,
+                       TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(PCtxtHandle phContext)
+{
+       char* Name = NULL;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->DeleteSecurityContext == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->DeleteSecurityContext(phContext);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_FreeContextBuffer(void* pvContextBuffer)
+{
+       if (!pvContextBuffer)
+               return SEC_E_INVALID_HANDLE;
+
+       sspi_ContextBufferFree(pvContextBuffer);
+
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(PCtxtHandle phContext)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_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)
+{
+       SEC_CHAR* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableW* table;
+
+       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableWByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->InitializeSecurityContextW == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->InitializeSecurityContextW(phCredential, phContext,
+                       pszTargetName, fContextReq, Reserved1, TargetDataRep,
+                       pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_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)
+{
+       SEC_CHAR* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phCredential);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->InitializeSecurityContextA == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->InitializeSecurityContextA(phCredential, phContext,
+                       pszTargetName, fContextReq, Reserved1, TargetDataRep,
+                       pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
+{
+       SEC_CHAR* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableW* table;
+
+       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableWByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->QueryContextAttributesW == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
+{
+       SEC_CHAR* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (SEC_CHAR*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->QueryContextAttributesA == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
+{
+       return SEC_E_OK;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(PCtxtHandle phContext)
+{
+       return SEC_E_OK;
+}
+
+/* Message Support */
+
+SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->DecryptMessage == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->EncryptMessage == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->EncryptMessage(phContext, fQOP, pMessage, MessageSeqNo);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->MakeSignature == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo);
+
+       return status;
+}
+
+SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
+{
+       char* Name;
+       SECURITY_STATUS status;
+       SecurityFunctionTableA* table;
+
+       Name = (char*) sspi_SecureHandleGetUpperPointer(phContext);
+
+       if (!Name)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       table = sspi_GetSecurityFunctionTableAByNameA(Name);
+
+       if (!table)
+               return SEC_E_SECPKG_NOT_FOUND;
+
+       if (table->VerifySignature == NULL)
+               return SEC_E_UNSUPPORTED_FUNCTION;
+
+       status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
+
+       return status;
+}
+
+SecurityFunctionTableA winpr_SecurityFunctionTableA =
+{
+       1, /* dwVersion */
+       winpr_EnumerateSecurityPackagesA, /* EnumerateSecurityPackages */
+       winpr_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
+       winpr_AcquireCredentialsHandleA, /* AcquireCredentialsHandle */
+       winpr_FreeCredentialsHandle, /* FreeCredentialsHandle */
+       NULL, /* Reserved2 */
+       winpr_InitializeSecurityContextA, /* InitializeSecurityContext */
+       winpr_AcceptSecurityContext, /* AcceptSecurityContext */
+       winpr_CompleteAuthToken, /* CompleteAuthToken */
+       winpr_DeleteSecurityContext, /* DeleteSecurityContext */
+       winpr_ApplyControlToken, /* ApplyControlToken */
+       winpr_QueryContextAttributesA, /* QueryContextAttributes */
+       winpr_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
+       winpr_RevertSecurityContext, /* RevertSecurityContext */
+       winpr_MakeSignature, /* MakeSignature */
+       winpr_VerifySignature, /* VerifySignature */
+       winpr_FreeContextBuffer, /* FreeContextBuffer */
+       winpr_QuerySecurityPackageInfoA, /* QuerySecurityPackageInfo */
+       NULL, /* Reserved3 */
+       NULL, /* Reserved4 */
+       winpr_ExportSecurityContext, /* ExportSecurityContext */
+       winpr_ImportSecurityContextA, /* ImportSecurityContext */
+       NULL, /* AddCredentials */
+       NULL, /* Reserved8 */
+       winpr_QuerySecurityContextToken, /* QuerySecurityContextToken */
+       winpr_EncryptMessage, /* EncryptMessage */
+       winpr_DecryptMessage, /* DecryptMessage */
+       winpr_SetContextAttributes, /* SetContextAttributes */
+};
+
+SecurityFunctionTableW winpr_SecurityFunctionTableW =
+{
+       1, /* dwVersion */
+       winpr_EnumerateSecurityPackagesW, /* EnumerateSecurityPackages */
+       winpr_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
+       winpr_AcquireCredentialsHandleW, /* AcquireCredentialsHandle */
+       winpr_FreeCredentialsHandle, /* FreeCredentialsHandle */
+       NULL, /* Reserved2 */
+       winpr_InitializeSecurityContextW, /* InitializeSecurityContext */
+       winpr_AcceptSecurityContext, /* AcceptSecurityContext */
+       winpr_CompleteAuthToken, /* CompleteAuthToken */
+       winpr_DeleteSecurityContext, /* DeleteSecurityContext */
+       winpr_ApplyControlToken, /* ApplyControlToken */
+       winpr_QueryContextAttributesW, /* QueryContextAttributes */
+       winpr_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
+       winpr_RevertSecurityContext, /* RevertSecurityContext */
+       winpr_MakeSignature, /* MakeSignature */
+       winpr_VerifySignature, /* VerifySignature */
+       winpr_FreeContextBuffer, /* FreeContextBuffer */
+       winpr_QuerySecurityPackageInfoW, /* QuerySecurityPackageInfo */
+       NULL, /* Reserved3 */
+       NULL, /* Reserved4 */
+       winpr_ExportSecurityContext, /* ExportSecurityContext */
+       winpr_ImportSecurityContextW, /* ImportSecurityContext */
+       NULL, /* AddCredentials */
+       NULL, /* Reserved8 */
+       winpr_QuerySecurityContextToken, /* QuerySecurityContextToken */
+       winpr_EncryptMessage, /* EncryptMessage */
+       winpr_DecryptMessage, /* DecryptMessage */
+       winpr_SetContextAttributes, /* SetContextAttributes */
+};
diff --git a/winpr/libwinpr/sspi/sspi_winpr.h b/winpr/libwinpr/sspi/sspi_winpr.h
new file mode 100644 (file)
index 0000000..13a1819
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * WinPR: Windows Portable Runtime
+ * Security Support Provider Interface (SSPI)
+ *
+ * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WINPR_SSPI_WINPR_H
+#define WINPR_SSPI_WINPR_H
+
+#include <winpr/sspi.h>
+
+
+
+#endif /* WINPR_SSPI_WINPR_H */