server: proxy: specify which modules to load in config

This commit is contained in:
Kobi Mizrachi 2020-01-21 14:56:49 +02:00 committed by akallabeth
parent 8c5d96784d
commit 18be45eca1
6 changed files with 79 additions and 68 deletions

View File

@ -41,6 +41,11 @@ TextOnly = FALSE
MaxTextLength = 10 # 0 for no limit.
[Plugins]
; This is an optional, comma seperated string,
; of required plugins that the proxy won't start without having them loaded.
; An optional, comma separated list of paths to modules that the proxy should load at startup.
;
; Modules = "proxy-demo-plugin.so"
; An optional, comma separated list of required plugins (names),
; that the proxy won't start without having them loaded.
;
; Required = "demo"

View File

@ -28,6 +28,7 @@
#include <winpr/collections.h>
#include <stdlib.h>
#include <signal.h>
#include <winpr/cmdline.h>
#define TAG PROXY_TAG("server")
@ -48,7 +49,35 @@ static void cleanup_handler(int signum)
pf_server_free(server);
WLog_INFO(TAG, "exiting.");
exit(signum);
exit(0);
}
static void pf_server_register_signal_handlers(void)
{
signal(SIGINT, cleanup_handler);
signal(SIGTERM, cleanup_handler);
#ifndef _WIN32
signal(SIGQUIT, cleanup_handler);
signal(SIGKILL, cleanup_handler);
#endif
}
static BOOL is_all_required_modules_loaded(proxyConfig* config)
{
size_t i;
for (i = 0; i < config->RequiredPluginsCount; i++)
{
const char* plugin_name = config->RequiredPlugins[i];
if (!pf_modules_is_plugin_loaded(plugin_name))
{
WLog_ERR(TAG, "Required plugin '%s' is not loaded. stopping.", plugin_name);
return FALSE;
}
}
return TRUE;
}
int main(int argc, char* argv[])
@ -57,24 +86,7 @@ int main(int argc, char* argv[])
const char* config_path = "config.ini";
int status = -1;
if (argc > 1)
config_path = argv[1];
/* Register cleanup handler for graceful termination */
signal(SIGINT, cleanup_handler);
signal(SIGTERM, cleanup_handler);
#ifndef _WIN32
signal(SIGQUIT, cleanup_handler);
signal(SIGKILL, cleanup_handler);
#endif
if (!pf_modules_init(FREERDP_PROXY_PLUGINDIR))
{
WLog_ERR(TAG, "failed to initialize proxy plugins!");
goto fail;
}
pf_modules_list_loaded_plugins();
pf_server_register_signal_handlers();
config = pf_server_config_load(config_path);
if (!config)
@ -82,6 +94,17 @@ int main(int argc, char* argv[])
pf_server_config_print(config);
if (!pf_modules_init(FREERDP_PROXY_PLUGINDIR, (const char**)config->Modules,
config->ModulesCount))
{
WLog_ERR(TAG, "failed to initialize proxy modules!");
goto fail;
}
pf_modules_list_loaded_plugins();
if (!is_all_required_modules_loaded(config))
goto fail;
server = pf_server_new(config);
if (!server)
goto fail;

View File

@ -22,6 +22,7 @@
#include <string.h>
#include <winpr/crt.h>
#include <winpr/collections.h>
#include <winpr/cmdline.h>
#include "pf_log.h"
#include "pf_server.h"
@ -188,27 +189,16 @@ static BOOL pf_config_load_clipboard(wIniFile* ini, proxyConfig* config)
static BOOL pf_config_load_modules(wIniFile* ini, proxyConfig* config)
{
const char* modules_to_load;
const char* required_modules;
char* tmp;
/* make sure that all required modules are loaded */
modules_to_load = IniFile_GetKeyValueString(ini, "Plugins", "Modules");
required_modules = IniFile_GetKeyValueString(ini, "Plugins", "Required");
if (!required_modules)
return TRUE;
tmp = strtok((char*)required_modules, ",");
while (tmp != NULL)
{
if (!pf_modules_is_plugin_loaded(tmp))
{
WLog_ERR(TAG, "Required plugin '%s' is not loaded. stopping.", tmp);
return FALSE;
}
tmp = strtok(NULL, ",");
}
config->Modules = CommandLineParseCommaSeparatedValues(modules_to_load, &config->ModulesCount);
config->RequiredPlugins =
CommandLineParseCommaSeparatedValues(required_modules, &config->RequiredPluginsCount);
return TRUE;
}
@ -249,13 +239,13 @@ proxyConfig* pf_server_config_load(const char* path)
if (!ini)
{
WLog_ERR(TAG, "pf_server_load_config(): IniFile_New() failed!");
WLog_ERR(TAG, "[%s]: IniFile_New() failed!", __FUNCTION__);
return FALSE;
}
if (IniFile_ReadFile(ini, path) < 0)
{
WLog_ERR(TAG, "pf_server_load_config(): IniFile_ReadFile() failed!");
WLog_ERR(TAG, "[%s] failed to parse ini file: '%s'", __FUNCTION__, path);
goto out;
}
@ -347,6 +337,8 @@ void pf_server_config_free(proxyConfig* config)
return;
free(config->CapturesDirectory);
free(config->RequiredPlugins);
free(config->Modules);
free(config->TargetHost);
free(config->Host);
free(config);

View File

@ -66,6 +66,13 @@ struct proxy_config
/* session capture */
BOOL SessionCapture;
char* CapturesDirectory;
/* modules */
char** Modules; /* module file names to load */
size_t ModulesCount;
char** RequiredPlugins; /* required plugin names */
size_t RequiredPluginsCount;
};
typedef struct proxy_config proxyConfig;

View File

@ -217,7 +217,7 @@ static BOOL pf_modules_register_plugin(proxyPlugin* plugin_to_register)
{
if (strcmp(plugin->name, plugin_to_register->name) == 0)
{
WLog_ERR(TAG, "can not register plugin '%s', it is already registered!");
WLog_ERR(TAG, "can not register plugin '%s', it is already registered!", plugin->name);
return FALSE;
}
}
@ -313,33 +313,22 @@ error:
return FALSE;
}
BOOL pf_modules_init(const char* modules_directory)
BOOL pf_modules_init(const char* root_dir, const char** modules, size_t count)
{
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
char* find_path;
size_t i;
if (!PathFileExistsA(modules_directory))
if (!PathFileExistsA(root_dir))
{
if (!CreateDirectoryA(modules_directory, NULL))
if (!CreateDirectoryA(root_dir, NULL))
{
WLog_ERR(TAG, "error occurred while creating modules directory: %s", modules_directory);
WLog_ERR(TAG, "error occurred while creating modules directory: %s", root_dir);
return FALSE;
}
return TRUE;
}
WLog_DBG(TAG, "searching plugins in directory %s", modules_directory);
find_path = GetCombinedPath(modules_directory, "*.so");
hFind = FindFirstFile(find_path, &ffd);
free(find_path);
if (INVALID_HANDLE_VALUE == hFind)
{
WLog_ERR(TAG, "FindFirstFile failed!");
return FALSE;
}
WLog_DBG(TAG, "modules root directory: %s", root_dir);
plugins_list = ArrayList_New(FALSE);
@ -357,21 +346,16 @@ BOOL pf_modules_init(const char* modules_directory)
goto error;
}
do
for (i = 0; i < count; i++)
{
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
char* fullpath = GetCombinedPath(modules_directory, ffd.cFileName);
pf_modules_load_module(fullpath);
free(fullpath);
}
} while (FindNextFile(hFind, &ffd) != 0);
char* fullpath = GetCombinedPath(root_dir, modules[i]);
pf_modules_load_module(fullpath);
free(fullpath);
}
FindClose(hFind);
return TRUE;
error:
FindClose(hFind);
ArrayList_Free(plugins_list);
plugins_list = NULL;
ArrayList_Free(handles_list);

View File

@ -48,7 +48,7 @@ enum _PF_HOOK_TYPE
HOOK_LAST
};
BOOL pf_modules_init(const char* modules_directory_path);
BOOL pf_modules_init(const char* root_dir, const char** modules, size_t count);
BOOL pf_modules_is_plugin_loaded(const char* plugin_name);
void pf_modules_list_loaded_plugins(void);