libwinpr-sspi: add support for dynamic loading of SSPI module

This commit is contained in:
Marc-André Moreau
2012-08-10 18:05:37 -04:00
parent cc590eee8f
commit 92e46af233
14 changed files with 503 additions and 8 deletions

3
.gitignore vendored
View File

@@ -19,6 +19,9 @@ CPackSourceConfig.cmake
docs/api
client/X11/xfreerdp.1
# Extensions
extensions/**
# Mac OS X
.DS_Store

View File

@@ -204,6 +204,11 @@ if(NOT MSVC)
add_subdirectory(keymaps)
endif()
option(WITH_EXTENSIONS "Build extensions" ON)
if(WITH_EXTENSIONS)
add_subdirectory(extensions)
endif()
# Source package
set(CPACK_SOURCE_IGNORE_FILES "/\\\\.git/;/\\\\.gitignore;/CMakeCache.txt")

View File

@@ -41,6 +41,7 @@ struct rdp_credssp
int recv_seq_num;
freerdp* instance;
CtxtHandle context;
LPTSTR SspiModule;
rdpSettings* settings;
SecBuffer negoToken;
SecBuffer pubKeyAuth;

49
include/winpr/library.h Normal file
View File

@@ -0,0 +1,49 @@
/**
* WinPR: Windows Portable Runtime
* Library Loader
*
* Copyright 2012 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_LIBRARY_H
#define WINPR_LIBRARY_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#ifndef _WIN32
WINPR_API HMODULE LoadLibraryA(LPCSTR lpLibFileName);
WINPR_API HMODULE LoadLibraryW(LPCWSTR lpLibFileName);
WINPR_API HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
WINPR_API HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#define LoadLibraryEx LoadLibraryExW
#else
#define LoadLibrary LoadLibraryA
#define LoadLibraryEx LoadLibraryExA
#endif
WINPR_API FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
WINPR_API BOOL FreeLibrary(HMODULE hLibModule);
#endif
#endif /* WINPR_LIBRARY_H */

210
include/winpr/netsspi.h Normal file
View File

@@ -0,0 +1,210 @@
/**
* WinPR: Windows Portable Runtime
* Network Security Support Provider Interface (NetSSPI)
*
* Copyright 2012 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_NETSSPI_H
#define WINPR_NETSSPI_H
#include <winpr/sspi.h>
#define NETSSPI_ENUMERATE_SECURITY_PACKAGES 1
#define NETSSPI_QUERY_CREDENTIALS_ATTRIBUTES 3
#define NETSSPI_ACQUIRE_CREDENTIALS_HANDLE 4
#define NETSSPI_FREE_CREDENTIALS_HANDLE 5
#define NETSSPI_INITIALIZE_SECURITY_CONTEXT 7
#define NETSSPI_ACCEPT_SECURITY_CONTEXT 8
#define NETSSPI_COMPLETE_AUTH_TOKEN 9
#define NETSSPI_DELETE_SECURITY_CONTEXT 10
#define NETSSPI_APPLY_CONTROL_TOKEN 11
#define NETSSPI_QUERY_CONTEXT_ATTRIBUTES 12
#define NETSSPI_IMPERSONATE_SECURITY_CONTEXT 13
#define NETSSPI_REVERT_SECURITY_CONTEXT 14
#define NETSSPI_MAKE_SIGNATURE 15
#define NETSSPI_VERIFY_SIGNATURE 16
#define NETSSPI_FREE_CONTEXT_BUFFER 17
#define NETSSPI_QUERY_SECURITY_PACKAGE_INFO 18
#define NETSSPI_EXPORT_SECURITY_CONTEXT 21
#define NETSSPI_IMPORT_SECURITY_CONTEXT 22
#define NETSSPI_ADD_CREDENTIALS 23
#define NETSSPI_QUERY_SECURITY_CONTEXT_TOKEN 25
#define NETSSPI_ENCRYPT_MESSAGE 26
#define NETSSPI_DECRYPT_MESSAGE 27
#define NETSSPI_SET_CONTEXT_ATTRIBUTES 28
#define NETSSPI_FLAGS_UNICODE 0x80
#define NETSSPI_FIELD_01 0x000001
#define NETSSPI_FIELD_02 0x000002
#define NETSSPI_FIELD_03 0x000004
#define NETSSPI_FIELD_04 0x000008
#define NETSSPI_FIELD_05 0x000010
#define NETSSPI_FIELD_06 0x000020
#define NETSSPI_FIELD_07 0x000040
#define NETSSPI_FIELD_08 0x000080
#define NETSSPI_FIELD_09 0x000100
#define NETSSPI_FIELD_10 0x000200
#define NETSSPI_FIELD_11 0x000400
#define NETSSPI_FIELD_12 0x000800
#define NETSSPI_FIELD_13 0x001000
#define NETSSPI_FIELD_14 0x002000
#define NETSSPI_FIELD_15 0x004000
#define NETSSPI_FIELD_16 0x008000
#define NETSSPI_FIELD_17 0x010000
#define NETSSPI_FIELD_18 0x020000
#define NETSSPI_FIELD_19 0x040000
#define NETSSPI_FIELD_20 0x080000
#define NETSSPI_FIELD_21 0x100000
#define NETSSPI_FIELD_22 0x200000
#define NETSSPI_FIELD_23 0x400000
#define NETSSPI_FIELD_24 0x800000
#define NETSSPI_HEADER_REQ_LENGTH 10
#define NETSSPI_HEADER_RSP_LENGTH 10
struct _NETSSPI_STRING
{
UINT16 Length;
BYTE* Buffer;
};
typedef struct _NETSSPI_STRING NETSSPI_STRING;
struct _NETSSPI_HANDLE
{
UINT64 dwLower;
UINT64 dwUpper;
};
typedef struct _NETSSPI_HANDLE NETSSPI_HANDLE;
struct _NETSSPI_TIMESTAMP
{
UINT32 LowPart;
INT32 HighPart;
};
typedef struct _NETSSPI_TIMESTAMP NETSSPI_TIMESTAMP;
struct _NETSSPI_LUID
{
UINT32 LowPart;
INT32 HighPart;
};
typedef struct _NETSSPI_LUID NETSSPI_LUID;
struct _NETSSPI_AUTH_IDENTITY
{
UINT32 Flags;
NETSSPI_STRING User;
NETSSPI_STRING Domain;
NETSSPI_STRING Password;
};
typedef struct _NETSSPI_AUTH_IDENTITY NETSSPI_AUTH_IDENTITY;
struct _NETSSPI_SEC_BUFFER
{
UINT32 cbBuffer;
UINT32 BufferType;
void* pvBuffer;
};
typedef struct _NETSSPI_SEC_BUFFER NETSSPI_SEC_BUFFER;
struct _NETSSPI_SEC_BUFFER_DESC
{
UINT32 ulVersion;
UINT32 cBuffers;
NETSSPI_SEC_BUFFER* pBuffers;
};
typedef struct _NETSSPI_SEC_BUFFER_DESC NETSSPI_SEC_BUFFER_DESC;
struct _NETSSPI_HEADER_REQ
{
UINT32 TotalLength;
UINT8 Flags;
UINT8 FunctionId;
UINT32 ExtFlags;
};
typedef struct _NETSSPI_HEADER_REQ NETSSPI_HEADER_REQ;
struct _NETSSPI_HEADER_RSP
{
UINT32 TotalLength;
UINT8 Flags;
UINT8 FunctionId;
UINT32 Status;
};
typedef struct _NETSSPI_HEADER_RSP NETSSPI_HEADER_RSP;
struct _NETSSPI_QUERY_SECURITY_PACKAGE_INFO_REQ
{
NETSSPI_STRING PackageName;
};
typedef struct _NETSSPI_QUERY_SECURITY_PACKAGE_INFO_REQ NETSSPI_QUERY_SECURITY_PACKAGE_INFO_REQ;
struct _NETSSPI_QUERY_SECURITY_PACKAGE_INFO_RSP
{
UINT32 fCapabilities;
UINT16 wVersion;
UINT16 wRPCID;
UINT32 cbMaxToken;
NETSSPI_STRING Name;
NETSSPI_STRING Comment;
};
typedef struct _NETSSPI_QUERY_SECURITY_PACKAGE_INFO_RSP NETSSPI_QUERY_SECURITY_PACKAGE_INFO_RSP;
struct _NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_REQ
{
NETSSPI_STRING Principal;
NETSSPI_STRING Package;
UINT32 fCredentialUse;
NETSSPI_LUID LogonID;
UINT16 AuthDataType;
UINT32 AuthDataLength;
NETSSPI_AUTH_IDENTITY identity;
};
typedef struct _NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_REQ NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_REQ;
struct _NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_RSP
{
NETSSPI_HANDLE Credential;
NETSSPI_TIMESTAMP Expiry;
};
typedef struct _NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_RSP NETSSPI_ACQUIRE_CREDENTIALS_HANDLE_RSP;
struct _NETSSPI_ACCEPT_SECURITY_CONTEXT_REQ
{
NETSSPI_HANDLE Credential;
NETSSPI_HANDLE Context;
NETSSPI_SEC_BUFFER_DESC Input;
UINT32 fContextReq;
UINT32 TargetDataRep;
NETSSPI_HANDLE NewContext;
NETSSPI_SEC_BUFFER_DESC Output;
UINT32 fContextAttr;
NETSSPI_TIMESTAMP TimeStamp;
};
typedef struct _NETSSPI_ACCEPT_SECURITY_CONTEXT_REQ NETSSPI_ACCEPT_SECURITY_CONTEXT_REQ;
struct _NETSSPI_ACCEPT_SECURITY_CONTEXT_RSP
{
NETSSPI_HANDLE Context;
NETSSPI_HANDLE NewContext;
NETSSPI_SEC_BUFFER_DESC Output;
UINT32 fContextAttr;
NETSSPI_TIMESTAMP TimeStamp;
};
typedef struct _NETSSPI_ACCEPT_SECURITY_CONTEXT_RSP NETSSPI_ACCEPT_SECURITY_CONTEXT_RSP;
#endif /* WINPR_NETSSPI_H */

View File

@@ -883,14 +883,19 @@ 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);
#ifdef UNICODE
#define InitSecurityInterface InitSecurityInterfaceW
#define SecurityFunctionTable SecurityFunctionTableW
#define PSecurityFunctionTable PSecurityFunctionTableW
#define INIT_SECURITY_INTERFACE INIT_SECURITY_INTERFACE_W
#else
#define InitSecurityInterface InitSecurityInterfaceA
#define SecurityFunctionTable SecurityFunctionTableA
#define PSecurityFunctionTable PSecurityFunctionTableA
#define INIT_SECURITY_INTERFACE INIT_SECURITY_INTERFACE_A
#endif
/* Package Management */

View File

@@ -223,4 +223,7 @@ typedef LONG NTSTATUS;
typedef NTSTATUS *PNTSTATUS;
#endif
typedef void* HMODULE;
typedef void* FARPROC;
#endif /* WINPR_WTYPES_H */

View File

@@ -41,7 +41,9 @@ else()
endif()
target_link_libraries(freerdp-crypto winpr-sspi)
target_link_libraries(freerdp-crypto winpr-library)
target_link_libraries(freerdp-crypto freerdp-utils)
target_link_libraries(freerdp-crypto ${OPENSSL_LIBRARIES})
install(TARGETS freerdp-crypto DESTINATION ${CMAKE_INSTALL_LIBDIR})

View File

@@ -29,6 +29,9 @@
#include <winpr/crt.h>
#include <winpr/sspi.h>
#include <winpr/print.h>
#include <winpr/tchar.h>
#include <winpr/library.h>
#include <winpr/registry.h>
/**
* TSRequest ::= SEQUENCE {
@@ -390,20 +393,43 @@ int credssp_server_authenticate(rdpCredssp* credssp)
#ifdef WITH_NATIVE_SSPI
{
HMODULE hSSPI;
INIT_SECURITY_INTERFACE InitSecurityInterface;
PSecurityFunctionTable pSecurityInterface = NULL;
INIT_SECURITY_INTERFACE pInitSecurityInterface;
hSSPI = LoadLibrary(_T("secur32.dll"));
#ifdef UNICODE
InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
#else
InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
#endif
credssp->table = (*InitSecurityInterface)();
credssp->table = (*pInitSecurityInterface)();
}
#else
credssp->table = InitSecurityInterface();
if (credssp->SspiModule)
{
HMODULE hSSPI;
INIT_SECURITY_INTERFACE pInitSecurityInterface;
hSSPI = LoadLibrary(credssp->SspiModule);
if (!hSSPI)
{
_tprintf(_T("Failed to load SSPI module: %s\n"), credssp->SspiModule);
return 0;
}
#ifdef UNICODE
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW");
#else
pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA");
#endif
credssp->table = (*pInitSecurityInterface)();
}
else
{
credssp->table = InitSecurityInterface();
}
#endif
status = credssp->table->QuerySecurityPackageInfo(NLA_PKG_NAME, &pPackageInfo);
@@ -1223,6 +1249,11 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings)
if (credssp != NULL)
{
HKEY hKey;
LONG status;
DWORD dwType;
DWORD dwSize;
credssp->instance = instance;
credssp->settings = settings;
credssp->server = settings->server_mode;
@@ -1232,6 +1263,29 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTls* tls, rdpSettings* settings)
ZeroMemory(&credssp->negoToken, sizeof(SecBuffer));
ZeroMemory(&credssp->pubKeyAuth, sizeof(SecBuffer));
ZeroMemory(&credssp->authInfo, sizeof(SecBuffer));
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\Server"),
0, KEY_READ | KEY_WOW64_64KEY, &hKey);
if (status == ERROR_SUCCESS)
{
status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType, NULL, &dwSize);
if (status == ERROR_SUCCESS)
{
credssp->SspiModule = (LPTSTR) malloc(dwSize + sizeof(TCHAR));
status = RegQueryValueEx(hKey, _T("SspiModule"), NULL, &dwType,
(BYTE*) credssp->SspiModule, &dwSize);
if (status == ERROR_SUCCESS)
{
_tprintf(_T("Using SSPI Module: %s\n"), credssp->SspiModule);
RegCloseKey(hKey);
}
}
}
}
return credssp;

View File

@@ -36,6 +36,7 @@ add_subdirectory(rpc)
add_subdirectory(sspicli)
add_subdirectory(sspi)
add_subdirectory(registry)
add_subdirectory(library)
add_subdirectory(tools)

View File

@@ -0,0 +1,28 @@
# WinPR: Windows Portable Runtime
# libwinpr-library cmake build script
#
# Copyright 2011 O.S. Systems Software Ltda.
# Copyright 2011 Otavio Salvador <otavio@ossystems.com.br>
# Copyright 2011 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.
set(WINPR_LIBRARY_SRCS
library.c)
add_library(winpr-library ${WINPR_LIBRARY_SRCS})
set_target_properties(winpr-library PROPERTIES VERSION ${FREERDP_VERSION_FULL} SOVERSION ${FREERDP_VERSION} PREFIX "lib")
install(TARGETS winpr-library DESTINATION ${CMAKE_INSTALL_LIBDIR})

133
winpr/library/library.c Normal file
View File

@@ -0,0 +1,133 @@
/**
* WinPR: Windows Portable Runtime
* Library Loader
*
* Copyright 2012 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.
*/
#include <winpr/library.h>
/**
* api-ms-win-core-libraryloader-l1-1-1.dll:
*
* AddDllDirectory
* DisableThreadLibraryCalls
* EnumResourceLanguagesExA
* EnumResourceLanguagesExW
* EnumResourceNamesExA
* EnumResourceNamesExW
* EnumResourceTypesExA
* EnumResourceTypesExW
* FindResourceExW
* FindStringOrdinal
* FreeLibrary
* FreeLibraryAndExitThread
* FreeResource
* GetModuleFileNameA
* GetModuleFileNameW
* GetModuleHandleA
* GetModuleHandleExA
* GetModuleHandleExW
* GetModuleHandleW
* GetProcAddress
* LoadLibraryExA
* LoadLibraryExW
* LoadResource
* LoadStringA
* LoadStringW
* LockResource
* QueryOptionalDelayLoadedAPI
* RemoveDllDirectory
* SetDefaultDllDirectories
* SizeofResource
*/
#ifndef _WIN32
#include <dlfcn.h>
#include <unistd.h>
HMODULE LoadLibraryA(LPCSTR lpLibFileName)
{
HMODULE library;
library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
if (library == NULL)
{
printf("LoadLibraryA: failed to open %s: %s\n", lpLibFileName, dlerror());
return NULL;
}
return library;
}
HMODULE LoadLibraryW(LPCWSTR lpLibFileName)
{
return (HMODULE) NULL;
}
HMODULE LoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
HMODULE library;
library = dlopen(lpLibFileName, RTLD_LOCAL | RTLD_LAZY);
if (library == NULL)
{
printf("LoadLibraryA: failed to open %s: %s\n", lpLibFileName, dlerror());
return NULL;
}
return library;
}
HMODULE LoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags)
{
return (HMODULE) NULL;
}
FARPROC GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
FARPROC proc;
proc = dlsym(hModule, lpProcName);
if (proc == NULL)
{
printf("GetProcAddress: could not find procedure %s: %s\n", lpProcName, dlerror());
return (FARPROC) NULL;
}
return proc;
}
BOOL FreeLibrary(HMODULE hLibModule)
{
int status;
status = dlclose(hLibModule);
if (status == 0)
{
printf("FreeLibrary() failure: %s\n", dlerror());
return FALSE;
}
return TRUE;
}
#endif

View File

@@ -65,6 +65,7 @@ if (NOT WIN32)
endif()
target_link_libraries(winpr-sspi winpr-utils)
target_link_libraries(winpr-sspi winpr-registry)
target_link_libraries(winpr-sspi ${ZLIB_LIBRARIES})
target_link_libraries(winpr-sspi ${OPENSSL_LIBRARIES})

View File

@@ -1051,7 +1051,7 @@ SecurityFunctionTableA SSPI_SecurityFunctionTableA =
CompleteAuthToken, /* CompleteAuthToken */
DeleteSecurityContext, /* DeleteSecurityContext */
ApplyControlToken, /* ApplyControlToken */
QueryContextAttributes, /* QueryContextAttributes */
QueryContextAttributesA, /* QueryContextAttributes */
ImpersonateSecurityContext, /* ImpersonateSecurityContext */
RevertSecurityContext, /* RevertSecurityContext */
MakeSignature, /* MakeSignature */
@@ -1083,7 +1083,7 @@ SecurityFunctionTableW SSPI_SecurityFunctionTableW =
CompleteAuthToken, /* CompleteAuthToken */
DeleteSecurityContext, /* DeleteSecurityContext */
ApplyControlToken, /* ApplyControlToken */
QueryContextAttributes, /* QueryContextAttributes */
QueryContextAttributesW, /* QueryContextAttributes */
ImpersonateSecurityContext, /* ImpersonateSecurityContext */
RevertSecurityContext, /* RevertSecurityContext */
MakeSignature, /* MakeSignature */