server: proxy: specify which modules to load in config
authorKobi Mizrachi <kmizrachi18@gmail.com>
Tue, 21 Jan 2020 12:56:49 +0000 (14:56 +0200)
committerakallabeth <akallabeth@users.noreply.github.com>
Wed, 22 Jan 2020 13:18:21 +0000 (14:18 +0100)
server/proxy/config.ini
server/proxy/freerdp_proxy.c
server/proxy/pf_config.c
server/proxy/pf_config.h
server/proxy/pf_modules.c
server/proxy/pf_modules.h

index f71b7b8..3b31b56 100644 (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"
index db5a4a7..e377cd2 100644 (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,33 +49,44 @@ static void cleanup_handler(int signum)
        pf_server_free(server);
 
        WLog_INFO(TAG, "exiting.");
-       exit(signum);
+       exit(0);
 }
 
-int main(int argc, char* argv[])
+static void pf_server_register_signal_handlers(void)
 {
-       proxyConfig* config = NULL;
-       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))
+static BOOL is_all_required_modules_loaded(proxyConfig* config)
+{
+       size_t i;
+
+       for (i = 0; i < config->RequiredPluginsCount; i++)
        {
-               WLog_ERR(TAG, "failed to initialize proxy plugins!");
-               goto fail;
+               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;
+               }
        }
 
-       pf_modules_list_loaded_plugins();
+       return TRUE;
+}
+
+int main(int argc, char* argv[])
+{
+       proxyConfig* config = NULL;
+       const char* config_path = "config.ini";
+       int status = -1;
+
+       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;
index 227b65b..d14c682 100644 (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);
index f33e88a..199c585 100644 (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;
index 3357b5c..3547814 100644 (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);
index b2f1fe0..efcf066 100644 (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);