From a1d486f112c4c1e52a9a02527723aeca57e3b7f9 Mon Sep 17 00:00:00 2001 From: dlandon Date: Thu, 4 Apr 2024 13:05:36 -0500 Subject: [PATCH] Add password encryption and create_proxy.sh script to create the proxy.cfg file needed by set_proxy. --- emhttp/plugins/dynamix/OutgoingProxy.page | 22 ++-- .../dynamix/include/OutgoingProxyLib.php | 104 ++++++++++++++++-- .../plugins/dynamix/scripts/create_proxy.sh | 61 ++++++++++ .../plugins/dynamix/scripts/outgoingproxy.sh | 49 +++------ 4 files changed, 183 insertions(+), 53 deletions(-) create mode 100644 emhttp/plugins/dynamix/scripts/create_proxy.sh diff --git a/emhttp/plugins/dynamix/OutgoingProxy.page b/emhttp/plugins/dynamix/OutgoingProxy.page index aaa953036..f1100424d 100644 --- a/emhttp/plugins/dynamix/OutgoingProxy.page +++ b/emhttp/plugins/dynamix/OutgoingProxy.page @@ -36,36 +36,32 @@ $cfg['proxy_name_1'] = $cfg['proxy_name_1'] ?? ""; $cfg['proxy_name_2'] = $cfg['proxy_name_2'] ?? ""; $cfg['proxy_name_3'] = $cfg['proxy_name_3'] ?? ""; -/* Get the encrypted url. */ -$proxy_1_url = $cfg['proxy_url_1'] ?? ""; - /* Parse the url, user, and password from the full url for proxy 1. */ -$url_array = get_url($cfg['proxy_url_1'] ?? ""); +$url_array = get_proxy_info($cfg['proxy_url_1'] ?? "", $cfg['proxy_user_1'] ?? "", $cfg['proxy_pass_1'] ?? ""); $cfg['proxy_url_1'] = $url_array['url']; $cfg['proxy_user_1'] = $url_array['user']; $cfg['proxy_pass_1'] = $url_array['pass']; - -/* Get the encrypted url. */ -$proxy_2_url = $cfg['proxy_url_2'] ?? ""; +$proxy_1_url = $url_array['full_url']; /* Parse the url, user, and password from the full url for proxy 2. */ -$url_array = get_url($cfg['proxy_url_2'] ?? ""); +$url_array = get_proxy_info($cfg['proxy_url_2'] ?? "", $cfg['proxy_user_2'] ?? "", $cfg['proxy_pass_2'] ?? ""); $cfg['proxy_url_2'] = $url_array['url']; $cfg['proxy_user_2'] = $url_array['user']; $cfg['proxy_pass_2'] = $url_array['pass']; - -/* Get the encrypted url. */ -$proxy_3_url = $cfg['proxy_url_3'] ?? ""; +$proxy_2_url = $url_array['full_url']; /* Parse the url, user, and password from the full url for proxy 3. */ -$url_array = get_url($cfg['proxy_url_3'] ?? ""); +$url_array = get_proxy_info($cfg['proxy_url_3'] ?? "", $cfg['proxy_user_3'] ?? "", $cfg['proxy_pass_3'] ?? ""); $cfg['proxy_url_3'] = $url_array['url']; $cfg['proxy_user_3'] = $url_array['user']; $cfg['proxy_pass_3'] = $url_array['pass']; +$proxy_3_url = $url_array['full_url']; + +outgoingproxy_log("*** plg_config_file ".$plg_config_file); ?>
- + diff --git a/emhttp/plugins/dynamix/include/OutgoingProxyLib.php b/emhttp/plugins/dynamix/include/OutgoingProxyLib.php index 0a3b07b23..fd2a0f51a 100644 --- a/emhttp/plugins/dynamix/include/OutgoingProxyLib.php +++ b/emhttp/plugins/dynamix/include/OutgoingProxyLib.php @@ -12,7 +12,7 @@ $opmPlugin = "dynamix"; /* UI config file location. */ -$plg_config_file = "/boot/config/proxy.cfg"; +$plg_config_file = "/boot/config/plugins/".$opmPlugin."/proxy.cfg"; /* Output config file location for set_proxy script. */ $proxy_config_file = "/boot/config/proxy.cfg"; @@ -39,6 +39,21 @@ function parse_plugin_config() { return($cfg); } +/* Write values to plugin config file. */ +function write_plugin_config($config) { + global $plg_config_file; + + /* Rewrite config file. */ + /* Convert the array to an INI string. */ + $iniString = ''; + foreach ($config as $key => $value) { + $iniString .= "$key=\"$value\"\n"; + } + + /* Write the INI string to a file. */ + file_put_contents($plg_config_file, $iniString); +} + /* Check to see if the proxy is online and available. */ function proxy_online($proxyUrl) { @@ -70,15 +85,25 @@ function proxy_online($proxyUrl) { } /* Get the URL with the user and password parsed from the url. */ -function get_url($cfg_url) { +function get_proxy_info($cfg_url, $cfg_user = "", $cfg_pass = "") { + /* Passed in values: + cfg_url - can be with or without credentials (user and password). + cfg_user - user from config file. + cfg_pass - encrypted password from the config file. + */ + /* An array is returned with the following values. */ $return = [ - 'url' => '', - 'user' => '', - 'pass' => '', + 'url' => '', /* URL without credentials. */ + 'user' => '', /* User. */ + 'pass' => '', /* Unencrypted password. */ + 'full_url' => '', /* Full URL with credentials urlencoded. */ ]; if ($cfg_url) { + /* Decrypt password. */ + $cfg_pass = decrypt_data($cfg_pass); + /* Parse the URL by removing the user and password. */ $urlComponents = parse_url($cfg_url); @@ -94,15 +119,76 @@ function get_url($cfg_url) { /* Extract the credentials. */ if (strpos($cfg_url, '%') !== false) { /* The credentials are urlencoded. */ - $return['user'] = urldecode($user); - $return['pass'] = urldecode($pass); + $return['user'] = $user ? urldecode($user) : $cfg_user; + $return['pass'] = $pass ? urldecode($pass) : $cfg_pass; } else { /* The credentials are not urlencoded. */ - $return['user'] = $user; - $return['pass'] = $pass; + $return['user'] = $user ? $user : $cfg_user; + $return['pass'] = $pass ? $pass : $cfg_pass; + } + + /* Put together the full url. */ + if (($return['user']) && ($return['pass'])) { + $return['full_url'] = "http://".urlencode($return['user']).":".urlencode($return['pass'])."@".$host.":".$port; + } else { + $return['full_url'] = $return['url']; } } return($return); } + +/* Get configuration parameter. */ +function get_config($variable) { + + $config = parse_plugin_config(); + + return $config[$variable] ?? ""; +} + +/* Set configuration parameter. */ +function set_config($variable, $value) { + + $config = parse_plugin_config(); + + $config[$variable] = $value; + + write_plugin_config($config); +} + +/* Encrypt data. */ +function encrypt_data($data) { + $key = get_config("key"); + if ((! $key) || strlen($key) != 32) { + $key = substr(base64_encode(openssl_random_pseudo_bytes(32)), 0, 32); + set_config("key", $key); + } + $iv = get_config("iv"); + if ((! $iv) || strlen($iv) != 16) { + $iv = substr(base64_encode(openssl_random_pseudo_bytes(16)), 0, 16); + set_config("iv", $iv); + } + + /* Encrypt the data using aes256. */ + $value = trim(openssl_encrypt($data, 'aes256', $key, $options=0, $iv)); + + return $value; +} + +/* Decrypt data. */ +function decrypt_data($data) { + $key = get_config("key"); + $iv = get_config("iv"); + + /* Decrypt the data using aes256. */ + $value = openssl_decrypt($data, 'aes256', $key, $options=0, $iv); + + /* Make sure the data is UTF-8 encoded. */ + if (! mb_check_encoding($value, 'UTF-8')) { + outgoingproxy_log("Warning: Data is not UTF-8 encoded"); + $value = ""; + } + + return $value; +} ?> diff --git a/emhttp/plugins/dynamix/scripts/create_proxy.sh b/emhttp/plugins/dynamix/scripts/create_proxy.sh new file mode 100644 index 000000000..87df4f017 --- /dev/null +++ b/emhttp/plugins/dynamix/scripts/create_proxy.sh @@ -0,0 +1,61 @@ +#!/usr/bin/php + $value) { + $iniString .= "$key=\"$value\"\n"; + } + + /* Write the INI string to the plugin config file. */ + $directoryPath = dirname($proxy_file); + + /* Check if the directory exists. */ + if (!is_dir($directoryPath)) { + /* Create the directory if it doesn't exist. */ + mkdir($directoryPath, 0755, true); + } + + file_put_contents($proxy_file, $iniString); +} + +/* Main entry point, */ +/* Use the default proxy config file if one isn't passed to the script. */ +$proxy_file = isset($argv[1]) ? $argv[1] : $proxy_config_file; +create_proxy($proxy_file); +?> diff --git a/emhttp/plugins/dynamix/scripts/outgoingproxy.sh b/emhttp/plugins/dynamix/scripts/outgoingproxy.sh index 5858ac9a0..f2012ca7b 100644 --- a/emhttp/plugins/dynamix/scripts/outgoingproxy.sh +++ b/emhttp/plugins/dynamix/scripts/outgoingproxy.sh @@ -15,7 +15,7 @@ require_once("plugins/".$opmPlugin."/include/OutgoingProxyLib.php"); /* Save settings and update config. */ function apply() { - global $opmPlugin, $proxy_config_file; + global $opmPlugin, $plg_config_file, $proxy_config_file; /* Process the new configuration. */ $cfg = parse_plugin_config(); @@ -31,8 +31,6 @@ function apply() { /* Confirm the url is in the proper format. */ if (strpos($url, 'http://') !== false && preg_match('/:\d+$/', $url)) { /* The string contains 'http://' and a port designation at the end */ - $proxy_user = "proxy_user_".$i; - $proxy_pass = "proxy_pass_".$i; /* Parse the URL components. */ $urlComponents = parse_url($url); @@ -43,42 +41,28 @@ function apply() { $user = isset($urlComponents['user']) ? $urlComponents['user'] : ''; $pass = isset($urlComponents['pass']) ? $urlComponents['pass'] : ''; + /* Remove credentials from the entered URL. */ + $cfg[$proxy_url] = "http://".$host.':'.$port; + /* Use the entered user if not blank. */ - $cfg_user = $cfg[$proxy_user] ?? ""; - $user = $cfg_user ? $cfg_user : $user; - $encodedUser = (strpos($user, '%') === false) ? urlencode($user) : $user; + $cfg_user = $cfg[$proxy_user] ?? ""; + $cfg[$proxy_user] = $cfg_user ? $cfg_user : urldecode($user); + $encodedUser = (strpos($cfg[$proxy_user], '%') === false) ? urlencode($cfg[$proxy_user]) : $cfg[$proxy_user]; /* Use the entered pass if not blank. */ - $cfg_pass = $cfg[$proxy_pass] ?? ""; - $pass = $cfg_pass ? $cfg_pass : $pass; - $encodedPass = (strpos($pass, '%') === false) ? urlencode($pass) : $pass; - - /* Reconstruct the URL with new credentials. */ - if (($host) && ($port)) { - $constructedUrl = 'http://'; - if (($encodedUser) && ($encodedPass)) { - $constructedUrl .= $encodedUser.':'.$encodedPass.'@'; - } - $constructedUrl .= $host.':'.$port; - } else { - $constructedUrl = ""; - } + $cfg_pass = $cfg[$proxy_pass] ?? ""; + $cfg[$proxy_pass] = $cfg_pass ? $cfg_pass : urldecode($pass); + $encodedPass = (strpos($cfg[$proxy_pass], '%') === false) ? urlencode($cfg[$proxy_pass]) : $cfg[$proxy_pass]; + $cfg[$proxy_pass] = encrypt_data($cfg[$proxy_pass]); } else { /* The string does not contain 'http://' and/or a port designation at the end */ - $constructedUrl = ""; + $cfg[$proxy_url] = ""; } - - /* Save the constructed url. */ - $cfg[$proxy_url] = $constructedUrl; } else if (! $name) { $cfg[$proxy_url] = ""; } - - /* Remove user and pass from the configuration file. */ - unset($cfg[$proxy_user]); - unset($cfg[$proxy_pass]); } - + /* Rewrite config file. */ /* Convert the array to an INI string. */ $iniString = ''; @@ -86,8 +70,11 @@ function apply() { $iniString .= "$key=\"$value\"\n"; } - /* Write the INI string to a file. */ - file_put_contents($proxy_config_file, $iniString); + /* Write the INI string to the plugin config file. */ + file_put_contents($plg_config_file, $iniString); + + /* Create the proxy file for the set_proxy script. */ + exec("/plugins/".$opmPlugin."/create_proxy.sh"); /* Let things settle. */ sleep(1);