server: proxy: refactor configuration loader
authorkubistika <kmizrachi18@gmail.com>
Sat, 3 Aug 2019 13:46:59 +0000 (16:46 +0300)
committerkubistika <kmizrachi18@gmail.com>
Mon, 5 Aug 2019 07:54:07 +0000 (10:54 +0300)
server/proxy/config.ini
server/proxy/freerdp_proxy.c
server/proxy/pf_config.c
server/proxy/pf_config.h

index fe29861..91c1b23 100644 (file)
@@ -18,19 +18,14 @@ Port = 3389
 Mouse = 1
 Keyboard = 1
 
-[Graphics]
-GFX = 1
-BitmapUpdate = 1
-
 [Security]
 NlaSecurity = 0
 TlsSecurity = 1
 RdpSecurity = 1
 
 [Channels]
-WhitelistMode = 0
-AllowedChannels = "cliprdr,Microsoft::Windows::RDS::Video::Control"
-DeniedChannels = "Microsoft::Windows::RDS::Geometry"
+GFX = 1
+DisplayControl = 1
 
 [Filters]
 ; FilterName = FilterPath
index 80fa85a..9ec237a 100644 (file)
@@ -32,9 +32,6 @@ int main(int argc, char* argv[])
 {
        const char* cfg = "config.ini";
        int status = 0;
-       DWORD ld;
-       UINT32 i;
-       UINT32 count;
        proxyConfig* config = calloc(1, sizeof(proxyConfig));
 
        if (!config)
@@ -43,38 +40,8 @@ int main(int argc, char* argv[])
        if (argc > 1)
                cfg = argv[1];
 
-       ld = pf_server_load_config(cfg, config);
-
-       switch (ld)
-       {
-               case CONFIG_PARSE_SUCCESS:
-                       WLog_DBG(TAG, "Configuration parsed successfully");
-                       break;
-
-               case CONFIG_PARSE_ERROR:
-                       WLog_ERR(TAG, "An error occured while parsing configuration file, exiting...");
-                       goto fail;
-
-               case CONFIG_INVALID:
-                       goto fail;
-       }
-
-       if (config->WhitelistMode)
-       {
-               WLog_INFO(TAG, "Channels mode: WHITELIST");
-               count = ArrayList_Count(config->AllowedChannels);
-
-               for (i = 0; i < count; i++)
-                       WLog_INFO(TAG, "Allowing %s", (char*) ArrayList_GetItem(config->AllowedChannels, i));
-       }
-       else
-       {
-               WLog_INFO(TAG, "Channels mode: BLACKLIST");
-               count = ArrayList_Count(config->BlockedChannels);
-
-               for (i = 0; i < count; i++)
-                       WLog_INFO(TAG, "Blocking %s", (char*) ArrayList_GetItem(config->BlockedChannels, i));
-       }
+       if (!pf_server_config_load(cfg, config))
+               goto fail;
 
        status = pf_server_start(config);
 fail:
index 4802631..3a2f9c8 100644 (file)
 
 #define TAG PROXY_TAG("config")
 
-#define CHANNELS_SEPERATOR ","
+#define CONFIG_PRINT_SECTION(section) WLog_INFO(TAG, "\t%s:", section)
+#define CONFIG_PRINT_STR(config, key) WLog_INFO(TAG, "\t\t%s: %s", #key, config->key)
+#define CONFIG_PRINT_BOOL(config, key) WLog_INFO(TAG, "\t\t%s: %s", #key, config->key ? "TRUE" : "FALSE")
+#define CONFIG_PRINT_UINT16(config, key) WLog_INFO(TAG, "\t\t%s: %"PRIu16"", #key, config->key);
 
-wArrayList* parse_string_array_from_str(const char* str)
+#define CONFIG_GET_STR(ini, section, key) IniFile_GetKeyValueString(ini, section, key)
+#define CONFIG_GET_BOOL(ini, section, key) IniFile_GetKeyValueInt(ini, section, key)
+
+static BOOL pf_config_get_uint16(wIniFile* ini, const char* section, const char* key, UINT16* result)
 {
-       wArrayList* list = ArrayList_New(FALSE);
-       char* s;
-       char* temp;
-       char* token;
+       int val;
 
-       if (list == NULL)
+       val = IniFile_GetKeyValueInt(ini, section, key);
+       if ((val < 0) || (val > UINT16_MAX))
        {
-               WLog_ERR(TAG, "parse_string_array_from_str(): ArrayList_New failed!");
-               return NULL;
+               WLog_ERR(TAG, "pf_config_get_uint16(): invalid value %d for section '%s', key '%s'!", val, section, key);
+               return FALSE;
        }
 
+       *result = (UINT16) val;
+       return TRUE;
+}
+
+static BOOL pf_config_load_server(wIniFile* ini, proxyConfig* config)
+{
+       config->Host = _strdup(CONFIG_GET_STR(ini, "Server", "Host"));
+       config->LocalOnly = CONFIG_GET_BOOL(ini, "Server", "LocalOnly");
        
-       temp = s = _strdup(str);
-       if (!s)
-       {
-               WLog_ERR(TAG, "parse_string_array_from_str(): strdup failed!");
-               return NULL;
-       }
+       if (!pf_config_get_uint16(ini, "Server", "Port", &config->Port))
+               return FALSE;
 
-       if (s == NULL)
-       {
-               WLog_ERR(TAG, "parse_string_array_from_str(): strdup failed!");
-               goto error;
-       }
+       return TRUE;
+}
 
-       while ((token = StrSep(&temp, CHANNELS_SEPERATOR)) != NULL)
-       {
-               char* current_token = _strdup(token);
+static BOOL pf_config_load_target(wIniFile* ini, proxyConfig* config)
+{
+       config->TargetHost = _strdup(CONFIG_GET_STR(ini, "Target", "Host"));
+       config->UseLoadBalanceInfo = CONFIG_GET_BOOL(ini, "Target", "UseLoadBalanceInfo");
 
-               if (current_token == NULL)
-               {
-                       WLog_ERR(TAG, "parse_string_array_from_str(): strdup failed!");
-                       goto error;
-               }
+       if (pf_config_get_uint16(ini, "Target", "Port", &config->TargetPort))
+               return TRUE;
 
-               if (ArrayList_Add(list, current_token) < 0)
-               {
-                       free(current_token);
-                       goto error;
-               }
-       }
+       return FALSE;
+}
 
-       free(s);
-       return list;
-error:
-       free(s);
-       ArrayList_Free(list);
-       return NULL;
+static BOOL pf_config_load_channels(wIniFile* ini, proxyConfig* config)
+{
+       config->GFX = CONFIG_GET_BOOL(ini, "Channels", "GFX");
+       config->DisplayControl = CONFIG_GET_BOOL(ini, "Channels", "DisplayControl");
+       return TRUE;
 }
 
-static BOOL pf_server_is_config_valid(proxyConfig* config)
+static BOOL pf_config_load_input(wIniFile* ini, proxyConfig* config)
 {
-       if (config->Host == NULL)
-       {
-               WLog_ERR(TAG, "Configuration value for `Server.Host` is not valid");
-               return FALSE;
-       }
+       config->Keyboard = CONFIG_GET_BOOL(ini, "Input", "Keyboard");
+       config->Mouse = CONFIG_GET_BOOL(ini, "Input", "Mouse");
+       return TRUE;
+}
 
-       if (config->Port <= 0)
-       {
-               WLog_ERR(TAG, "Configuration value for `Server.Port` is not valid");
+static BOOL pf_config_load_security(wIniFile* ini, proxyConfig* config)
+{
+       config->TlsSecurity = CONFIG_GET_BOOL(ini, "Security", "TlsSecurity");
+       config->NlaSecurity = CONFIG_GET_BOOL(ini, "Security", "NlaSecurity");
+       config->RdpSecurity = CONFIG_GET_BOOL(ini, "Security", "RdpSecurity");
+       return TRUE;
+}
+
+static BOOL pf_config_load_filters(wIniFile* ini, proxyConfig* config)
+{
+       UINT32 index;
+       int filters_count;
+       char** filters_names;
+
+       if (!pf_filters_init(&config->Filters))
                return FALSE;
-       }
 
-       if (!config->UseLoadBalanceInfo)
+       filters_names = IniFile_GetSectionKeyNames(ini, "Filters", &filters_count);
+
+       for (index = 0; index < filters_count; index++)
        {
-               if (config->TargetHost == NULL)
-               {
-                       WLog_ERR(TAG, "Configuration value for `Target.Host` is not valid");
-                       return FALSE;
-               }
+               char* filter_name = filters_names[index];
+               const char* path = CONFIG_GET_STR(ini, "Filters", filter_name);
 
-               if (config->TargetPort <= 0)
+               if (!pf_filters_register_new(config->Filters, path, filter_name))
                {
-                       WLog_ERR(TAG, "Configuration value for `Target.Port` is not valid");
-                       return FALSE;
+                       WLog_DBG(TAG, "pf_config_load_filters(): failed to register %s (%s)", filter_name, path);
+                       continue;
                }
+
+               WLog_DBG(TAG, "pf_config_load_filters(): filter %s is registered", filter_name);
        }
 
        return TRUE;
 }
 
-DWORD pf_server_load_config(const char* path, proxyConfig* config)
+BOOL pf_server_config_load(const char* path, proxyConfig* config)
 {
-       const char* input;
-       char** filters_names;
-       int rc;
-       int filters_count = 0;
-       UINT32 index;
-       DWORD result = CONFIG_PARSE_ERROR;
+       BOOL ok = FALSE;
        wIniFile* ini = IniFile_New();
 
        if (!ini)
-               return CONFIG_PARSE_ERROR;
+       {
+               WLog_ERR(TAG, "pf_server_load_config(): IniFile_New() failed!");
+               return FALSE;
+       }
 
        if (IniFile_ReadFile(ini, path) < 0)
+       {
+               WLog_ERR(TAG, "pf_server_load_config(): IniFile_ReadFile() failed!");
                goto out;
+       }
 
-       /* server */
-       config->Host = _strdup(IniFile_GetKeyValueString(ini, "Server", "Host"));
-       config->LocalOnly = IniFile_GetKeyValueInt(ini, "Server", "LocalOnly");
-       rc = IniFile_GetKeyValueInt(ini, "Server", "Port");
-
-       if ((rc < 0) || (rc > UINT16_MAX))
+       if (!pf_config_load_server(ini, config))
                goto out;
 
-       config->Port = (UINT16)rc;
-       /* target */
-       config->UseLoadBalanceInfo = IniFile_GetKeyValueInt(ini, "Target", "UseLoadBalanceInfo");
-       config->TargetHost = _strdup(IniFile_GetKeyValueString(ini, "Target", "Host"));
-       rc = IniFile_GetKeyValueInt(ini, "Target", "Port");
-
-       if ((rc < 0) || (rc > UINT16_MAX))
+       if (!pf_config_load_target(ini, config))
                goto out;
 
-       config->TargetPort = (UINT16)rc;
-       /* graphics */
-       config->GFX = IniFile_GetKeyValueInt(ini, "Graphics", "GFX");
-       config->BitmapUpdate = IniFile_GetKeyValueInt(ini, "Graphics", "BitmapUpdate");
-       /* input */
-       config->Keyboard = IniFile_GetKeyValueInt(ini, "Input", "Keyboard");
-       config->Mouse = IniFile_GetKeyValueInt(ini, "Input", "Mouse");
-       /* security */
-       config->TlsSecurity = IniFile_GetKeyValueInt(ini, "Security", "TlsSecurity");
-       config->NlaSecurity = IniFile_GetKeyValueInt(ini, "Security", "NlaSecurity");
-       config->RdpSecurity = IniFile_GetKeyValueInt(ini, "Security", "RdpSecurity");
-       /* channels filtering */
-       config->WhitelistMode = IniFile_GetKeyValueInt(ini, "Channels", "WhitelistMode");
-       input = IniFile_GetKeyValueString(ini, "Channels", "AllowedChannels");
-       /* filters api */
-
-       if (input)
-       {
-               config->AllowedChannels = parse_string_array_from_str(input);
-
-               if (config->AllowedChannels == NULL)
-                       goto out;
-       }
-
-       input = IniFile_GetKeyValueString(ini, "Channels", "DeniedChannels");
-
-       if (input)
-       {
-               config->BlockedChannels = parse_string_array_from_str(input);
-
-               if (config->BlockedChannels == NULL)
-                       goto out;
-       }
-
-       result = CONFIG_PARSE_SUCCESS;
+       if (!pf_config_load_channels(ini, config))
+               goto out;
 
-       if (!pf_filters_init(&config->Filters))
+       if (!pf_config_load_input(ini, config))
                goto out;
-               
-       filters_names = IniFile_GetSectionKeyNames(ini, "Filters", &filters_count);
 
-       for (index = 0; index < filters_count; index++)
-       {
-               char* filter_name = filters_names[index];
-               const char* path = IniFile_GetKeyValueString(ini, "Filters", filter_name);
+       if (!pf_config_load_security(ini, config))
+               goto out;
 
-               if (!pf_filters_register_new(config->Filters, path, filter_name))
-               {
-                       WLog_DBG(TAG, "pf_server_load_config(): failed to register %s (%s)", filter_name, path);
-               }
-               else
-               {
-                       WLog_DBG(TAG, "pf_server_load_config(): registered filter %s (%s) successfully", filter_name, path);
-               }
-       }
+       if (!pf_config_load_filters(ini, config))
+               goto out;
 
+       ok = TRUE;
 out:
        IniFile_Free(ini);
-
-       if (!pf_server_is_config_valid(config))
-               return CONFIG_INVALID;
-
-       return result;
+       return ok;
 }
 
 void pf_server_config_free(proxyConfig* config)
 {
        pf_filters_unregister_all(config->Filters);
-       ArrayList_Free(config->AllowedChannels);
-       ArrayList_Free(config->BlockedChannels);
        free(config->TargetHost);
        free(config->Host);
        free(config);
index a432cff..be1ae2e 100644 (file)
 #ifndef FREERDP_SERVER_PROXY_PFCONFIG_H
 #define FREERDP_SERVER_PROXY_PFCONFIG_H
 
-#define CONFIG_PARSE_SUCCESS 0
-#define CONFIG_PARSE_ERROR      1
-#define CONFIG_INVALID                  2
-
 #include <winpr/ini.h>
 
 #include "pf_filters.h"
@@ -42,10 +38,6 @@ struct proxy_config
        char* TargetHost;
        UINT16 TargetPort;
 
-       /* graphics */
-       BOOL GFX;
-       BOOL BitmapUpdate;
-
        /* input */
        BOOL Keyboard;
        BOOL Mouse;
@@ -56,10 +48,8 @@ struct proxy_config
        BOOL RdpSecurity;
 
        /* channels */
-       BOOL WhitelistMode;
-
-       wArrayList* AllowedChannels;
-       wArrayList* BlockedChannels;
+       BOOL GFX;
+       BOOL DisplayControl;
 
        /* filters */
        filters_list* Filters;
@@ -67,7 +57,7 @@ struct proxy_config
 
 typedef struct proxy_config proxyConfig;
 
-DWORD pf_server_load_config(const char* path, proxyConfig* config);
+BOOL pf_server_config_load(const char* path, proxyConfig* config);
 void pf_server_config_free(proxyConfig* config);
 
 #endif /* FREERDP_SERVER_PROXY_PFCONFIG_H */