Add settings to load a custom SSPI shared library module
This commit is contained in:
parent
4c4b5bfd87
commit
1d5c0be5ec
@ -1772,6 +1772,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
arg->Value))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "sspi-module")
|
||||
{
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_SspiModule, arg->Value))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
CommandLineSwitchCase(arg, "redirect-prefer")
|
||||
{
|
||||
size_t count = 0;
|
||||
|
@ -351,6 +351,8 @@ static const COMMAND_LINE_ARGUMENT_A global_cmd_args[] = {
|
||||
"SPN authentication service class" },
|
||||
{ "ssh-agent", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, "ssh-agent",
|
||||
"SSH Agent forwarding channel" },
|
||||
{ "sspi-module", COMMAND_LINE_VALUE_REQUIRED, "<SSPI module path>", NULL, NULL, -1, NULL,
|
||||
"SSPI shared library module file path" },
|
||||
{ "disable-output", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
|
||||
"Deactivate all graphics decoding in the client session. Useful for load tests with many "
|
||||
"simultaneous connections" },
|
||||
|
@ -635,6 +635,7 @@ typedef struct
|
||||
#define FreeRDP_NtlmSamFile (1103)
|
||||
#define FreeRDP_FIPSMode (1104)
|
||||
#define FreeRDP_TlsSecLevel (1105)
|
||||
#define FreeRDP_SspiModule (1106)
|
||||
#define FreeRDP_MstscCookieMode (1152)
|
||||
#define FreeRDP_CookieMaxLength (1153)
|
||||
#define FreeRDP_PreconnectionId (1154)
|
||||
@ -1119,7 +1120,8 @@ struct rdp_settings
|
||||
ALIGN64 char* NtlmSamFile; /* 1103 */
|
||||
ALIGN64 BOOL FIPSMode; /* 1104 */
|
||||
ALIGN64 UINT32 TlsSecLevel; /* 1105 */
|
||||
UINT64 padding1152[1152 - 1106]; /* 1106 */
|
||||
ALIGN64 char* SspiModule; /* 1106 */
|
||||
UINT64 padding1152[1152 - 1107]; /* 1107 */
|
||||
|
||||
/* Connection Cookie */
|
||||
ALIGN64 BOOL MstscCookieMode; /* 1152 */
|
||||
|
@ -2574,6 +2574,9 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id)
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return settings->SmartcardPrivateKey;
|
||||
|
||||
case FreeRDP_SspiModule:
|
||||
return settings->SspiModule;
|
||||
|
||||
case FreeRDP_TargetNetAddress:
|
||||
return settings->TargetNetAddress;
|
||||
|
||||
@ -2832,6 +2835,9 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id)
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return settings->SmartcardPrivateKey;
|
||||
|
||||
case FreeRDP_SspiModule:
|
||||
return settings->SspiModule;
|
||||
|
||||
case FreeRDP_TargetNetAddress:
|
||||
return settings->TargetNetAddress;
|
||||
|
||||
@ -3100,6 +3106,9 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char*
|
||||
case FreeRDP_SmartcardPrivateKey:
|
||||
return update_string(&settings->SmartcardPrivateKey, cnv.cc, len, cleanup);
|
||||
|
||||
case FreeRDP_SspiModule:
|
||||
return update_string(&settings->SspiModule, cnv.cc, len, cleanup);
|
||||
|
||||
case FreeRDP_TargetNetAddress:
|
||||
return update_string(&settings->TargetNetAddress, cnv.cc, len, cleanup);
|
||||
|
||||
|
@ -387,6 +387,7 @@ static const struct settings_str_entry settings_map[] = {
|
||||
{ FreeRDP_ShellWorkingDirectory, 7, "FreeRDP_ShellWorkingDirectory" },
|
||||
{ FreeRDP_SmartcardCertificate, 7, "FreeRDP_SmartcardCertificate" },
|
||||
{ FreeRDP_SmartcardPrivateKey, 7, "FreeRDP_SmartcardPrivateKey" },
|
||||
{ FreeRDP_SspiModule, 7, "FreeRDP_SspiModule" },
|
||||
{ FreeRDP_TargetNetAddress, 7, "FreeRDP_TargetNetAddress" },
|
||||
{ FreeRDP_TransportDumpFile, 7, "FreeRDP_TransportDumpFile" },
|
||||
{ FreeRDP_Username, 7, "FreeRDP_Username" },
|
||||
|
@ -1051,7 +1051,10 @@ static int nla_client_init(rdpNla* nla)
|
||||
#else
|
||||
nla->ServicePrincipalName = spn;
|
||||
#endif
|
||||
nla->table = InitSecurityInterfaceEx(0);
|
||||
|
||||
if (!nla_sspi_module_init(nla))
|
||||
return -1;
|
||||
|
||||
nla->status = nla_update_package_name(nla);
|
||||
if (nla->status != SEC_E_OK)
|
||||
return -1;
|
||||
@ -1381,31 +1384,8 @@ static int nla_server_init(rdpNla* nla)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nla->SspiModule)
|
||||
{
|
||||
HMODULE hSSPI;
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface;
|
||||
hSSPI = LoadLibraryX(nla->SspiModule);
|
||||
|
||||
if (!hSSPI)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to load SSPI module: %s", nla->SspiModule);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
pInitSecurityInterface =
|
||||
(INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceW");
|
||||
#else
|
||||
pInitSecurityInterface =
|
||||
(INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceA");
|
||||
#endif
|
||||
nla->table = pInitSecurityInterface();
|
||||
}
|
||||
else
|
||||
{
|
||||
nla->table = InitSecurityInterfaceEx(0);
|
||||
}
|
||||
if (!nla_sspi_module_init(nla))
|
||||
return -1;
|
||||
|
||||
nla->status = nla_update_package_name(nla);
|
||||
|
||||
@ -2724,6 +2704,14 @@ rdpNla* nla_new(rdpContext* context, rdpTransport* transport)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (settings->SspiModule)
|
||||
{
|
||||
nla->SspiModule = _strdup(settings->SspiModule);
|
||||
|
||||
if (!nla->SspiModule)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* init to 0 or we end up freeing a bad pointer if the alloc fails */
|
||||
if (!nla_sec_buffer_alloc(&nla->ClientNonce, NonceLength))
|
||||
goto cleanup;
|
||||
@ -2814,6 +2802,9 @@ void nla_free(rdpNla* nla)
|
||||
free(nla->SamFile);
|
||||
nla->SamFile = NULL;
|
||||
|
||||
free(nla->SspiModule);
|
||||
nla->SspiModule = NULL;
|
||||
|
||||
nla_buffer_free(nla);
|
||||
sspi_SecBufferFree(&nla->ClientNonce);
|
||||
sspi_SecBufferFree(&nla->PublicKey);
|
||||
@ -2864,6 +2855,65 @@ BOOL nla_set_service_principal(rdpNla* nla, LPTSTR principal)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL nla_set_sspi_module(rdpNla* nla, const char* sspiModule)
|
||||
{
|
||||
if (!nla)
|
||||
return FALSE;
|
||||
|
||||
if (nla->SspiModule)
|
||||
{
|
||||
free(nla->SspiModule);
|
||||
nla->SspiModule = NULL;
|
||||
}
|
||||
|
||||
if (!sspiModule)
|
||||
return TRUE;
|
||||
|
||||
#ifdef UNICODE
|
||||
ConvertToUnicode(CP_UTF8, 0, sspiModule, -1, &nla->SspiModule, 0);
|
||||
#else
|
||||
nla->SspiModule = _strdup(sspiModule);
|
||||
#endif
|
||||
|
||||
if (!nla->SspiModule)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL nla_sspi_module_init(rdpNla* nla)
|
||||
{
|
||||
if (!nla)
|
||||
return FALSE;
|
||||
|
||||
if (nla->SspiModule)
|
||||
{
|
||||
INIT_SECURITY_INTERFACE pInitSecurityInterface;
|
||||
HMODULE hSSPI = LoadLibraryX(nla->SspiModule);
|
||||
|
||||
if (!hSSPI)
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to load SSPI module: %s", nla->SspiModule);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef UNICODE
|
||||
pInitSecurityInterface =
|
||||
(INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceW");
|
||||
#else
|
||||
pInitSecurityInterface =
|
||||
(INIT_SECURITY_INTERFACE)GetProcAddress(hSSPI, "InitSecurityInterfaceA");
|
||||
#endif
|
||||
nla->table = pInitSecurityInterface();
|
||||
}
|
||||
else
|
||||
{
|
||||
nla->table = InitSecurityInterfaceEx(0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL nla_impersonate(rdpNla* nla)
|
||||
{
|
||||
if (!nla)
|
||||
|
@ -62,6 +62,9 @@ FREERDP_LOCAL DWORD nla_get_error(rdpNla* nla);
|
||||
|
||||
FREERDP_LOCAL BOOL nla_set_service_principal(rdpNla* nla, LPTSTR principal);
|
||||
|
||||
FREERDP_LOCAL BOOL nla_set_sspi_module(rdpNla* nla, const char* sspiModule);
|
||||
FREERDP_LOCAL BOOL nla_sspi_module_init(rdpNla* nla);
|
||||
|
||||
FREERDP_LOCAL BOOL nla_impersonate(rdpNla* nla);
|
||||
FREERDP_LOCAL BOOL nla_revert_to_self(rdpNla* nla);
|
||||
|
||||
|
@ -396,6 +396,7 @@ static const size_t string_list_indices[] = {
|
||||
FreeRDP_ShellWorkingDirectory,
|
||||
FreeRDP_SmartcardCertificate,
|
||||
FreeRDP_SmartcardPrivateKey,
|
||||
FreeRDP_SspiModule,
|
||||
FreeRDP_TargetNetAddress,
|
||||
FreeRDP_TransportDumpFile,
|
||||
FreeRDP_Username,
|
||||
|
@ -70,6 +70,13 @@ elseif(WITH_GSSAPI)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This option MUST be off to avoid symbol conflicts when loading an external SSPI module library
|
||||
option(SSPI_DLL "Define and export SSPI API symbols for usage as a Windows SSPI DLL replacement" OFF)
|
||||
|
||||
if(SSPI_DLL)
|
||||
add_definitions("-DSSPI_DLL")
|
||||
endif()
|
||||
|
||||
include(CMakeDependentOption)
|
||||
CMAKE_DEPENDENT_OPTION(WITH_GSS_NO_NTLM_FALLBACK "Do not fall back to NTLM if no kerberos ticket available" OFF "WITH_GSSAPI" OFF)
|
||||
if (WITH_GSS_NO_NTLM_FALLBACK)
|
||||
|
@ -1053,6 +1053,8 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifdef SSPI_DLL
|
||||
|
||||
/* Package Management */
|
||||
|
||||
WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages,
|
||||
@ -1148,6 +1150,8 @@ extern "C"
|
||||
PSecBufferDesc pMessage, ULONG MessageSeqNo,
|
||||
PULONG pfQOP);
|
||||
|
||||
#endif /* SSPI_DLL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -39,6 +39,8 @@ typedef LONG SECURITY_STATUS;
|
||||
#pragma GCC diagnostic ignored "-Wmissing-prototypes"
|
||||
#endif
|
||||
|
||||
#ifdef SSPI_DLL
|
||||
|
||||
/**
|
||||
* Standard SSPI API
|
||||
*/
|
||||
@ -322,6 +324,8 @@ SSPI_EXPORT SECURITY_STATUS SEC_ENTRY VerifySignature(void* phContext, void* pMe
|
||||
return sspi_VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
|
||||
}
|
||||
|
||||
#endif /* SSPI_DLL */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user