diff --git a/server/proxy/config.ini b/server/proxy/config.ini index f71b7b8be..3b31b5607 100644 --- a/server/proxy/config.ini +++ b/server/proxy/config.ini @@ -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" diff --git a/server/proxy/freerdp_proxy.c b/server/proxy/freerdp_proxy.c index db5a4a734..e377cd28f 100644 --- a/server/proxy/freerdp_proxy.c +++ b/server/proxy/freerdp_proxy.c @@ -28,6 +28,7 @@ #include #include #include +#include #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; diff --git a/server/proxy/pf_config.c b/server/proxy/pf_config.c index 227b65b21..d14c682ea 100644 --- a/server/proxy/pf_config.c +++ b/server/proxy/pf_config.c @@ -22,6 +22,7 @@ #include #include #include +#include #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); diff --git a/server/proxy/pf_config.h b/server/proxy/pf_config.h index f33e88a92..199c5850e 100644 --- a/server/proxy/pf_config.h +++ b/server/proxy/pf_config.h @@ -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; diff --git a/server/proxy/pf_modules.c b/server/proxy/pf_modules.c index 3357b5c92..354781498 100644 --- a/server/proxy/pf_modules.c +++ b/server/proxy/pf_modules.c @@ -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); diff --git a/server/proxy/pf_modules.h b/server/proxy/pf_modules.h index b2f1fe0f2..efcf06615 100644 --- a/server/proxy/pf_modules.h +++ b/server/proxy/pf_modules.h @@ -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);