From 340660da4bcceaaf0c312d79aeab0b74feef2436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Dvo=C5=99=C3=A1k?= Date: Sat, 21 May 2016 16:53:51 +0200 Subject: [PATCH] =?UTF-8?q?Issue=20#96=20Authentication=20fields=20for=20w?= =?UTF-8?q?ebsite/services=20-=20File=20functions.inc.php=20-=20modified?= =?UTF-8?q?=20and=20added=20features=20psm=5Fcurl=5Fget=20parameters=20for?= =?UTF-8?q?=20website=5Fusername=20and=20website=5Fpassword=20-=20File=20f?= =?UTF-8?q?unctions.inc.php=20-=20new=20features=20and=20psm=5Fpassword=5F?= =?UTF-8?q?encrypt=20psm=5Fpassword=5Fdecrypt=20to=20encrypt=20and=20decry?= =?UTF-8?q?pt=20passwords=20-=20Adjusted=20basic=20language=20EN=20and=20s?= =?UTF-8?q?upplemented=20by=20new=20language=20CZ=20phrase=20-=20ConfigCon?= =?UTF-8?q?troller.php=20-=20adjusted=20executeIndex=20method=20of=20passw?= =?UTF-8?q?ord=20encryption=20key=20for=20each=20installation=20separately?= =?UTF-8?q?=20+=20executeSave=20method=20of=20saving=20the=20settings=20+?= =?UTF-8?q?=20added=20labels=20to=20methods=20getLabels=20-=20AbstractServ?= =?UTF-8?q?erController.php=20-=20adjusted=20method=20getServers=20a=20log?= =?UTF-8?q?in=20password=20of=20the=20name=20-=20ServerController.php=20-?= =?UTF-8?q?=20adjusted=20executeEdit=20method=20for=20storing=20informatio?= =?UTF-8?q?n=20about=20name=20and=20password=20+=20executeSave=20method=20?= =?UTF-8?q?of=20storage=20in=20a=20database=20+=20method=20getLabels=20on?= =?UTF-8?q?=20labels=20-=20Installer.php=20-=20adjusted=20method=20install?= =?UTF-8?q?=20a=20new=20configuration=20values=20=E2=80=8B=E2=80=8Bfor=20t?= =?UTF-8?q?he=20encryption=20key=20passwords=20+=20method=20installTables?= =?UTF-8?q?=20a=20new=20table=20structure=20servers=20+=20method=20upgrade?= =?UTF-8?q?320=20the=20new=20structure=20-=20StatusUpdater.php=20-=20adjus?= =?UTF-8?q?ted=20method=20update=20the=20transmission=20website=5Fusername?= =?UTF-8?q?=20and=20website=5Fpassword=20+=20method=20updateWebsite=20adju?= =?UTF-8?q?sted=20parameters=20passed=20to=20the=20function=20psm=5Fcurl?= =?UTF-8?q?=5Fget=20-=20Modified=20template:=20config/config.tpl.html,=20s?= =?UTF-8?q?erver/update.tpl.html,=20view.tpl.html=20-=20Adapted=20javascri?= =?UTF-8?q?pt=20scripts.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/includes/functions.inc.php | 68 ++++++++++++++++++- src/lang/cs_CZ.lang.php | 9 +++ src/lang/en_US.lang.php | 9 +++ .../Config/Controller/ConfigController.php | 4 ++ .../Controller/AbstractServerController.php | 4 +- .../Server/Controller/ServerController.php | 11 +++ src/psm/Util/Install/Installer.php | 11 +++ src/psm/Util/Server/Updater/StatusUpdater.php | 8 ++- .../default/module/config/config.tpl.html | 12 +++- .../module/server/server/update.tpl.html | 35 ++++++++-- .../module/server/server/view.tpl.html | 8 +++ static/js/scripts.js | 45 ++++++++++-- 12 files changed, 210 insertions(+), 14 deletions(-) diff --git a/src/includes/functions.inc.php b/src/includes/functions.inc.php index 3ca0cbc7..36203f8f 100644 --- a/src/includes/functions.inc.php +++ b/src/includes/functions.inc.php @@ -291,9 +291,11 @@ function psm_parse_msg($status, $type, $vars) { * @param boolean $body return body? * @param int $timeout connection timeout in seconds. defaults to PSM_CURL_TIMEOUT (10 secs). * @param boolean $add_agent add user agent? + * @param string|bool $website_username Username website + * @param string|bool $website_password Password website * @return string cURL result */ -function psm_curl_get($href, $header = false, $body = true, $timeout = null, $add_agent = true) { +function psm_curl_get($href, $header = false, $body = true, $timeout = null, $add_agent = true, $website_username = false, $website_password = false) { $timeout = $timeout == null ? PSM_CURL_TIMEOUT : intval($timeout); $ch = curl_init(); @@ -306,7 +308,13 @@ function psm_curl_get($href, $header = false, $body = true, $timeout = null, $ad curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_ENCODING, ''); + + if($website_username !== false && $website_password !== false && !empty($website_username) && !empty($website_password)) { + curl_setopt($ch, CURLOPT_USERPWD, $website_username . ":" . $website_password); + } + curl_setopt($ch, CURLOPT_URL, $href); + if($add_agent) { curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; phpservermon/'.PSM_VERSION.'; +http://www.phpservermonitor.org)'); } @@ -611,4 +619,62 @@ function psm_no_cache() { header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); +} + +/** + * Encrypts the password for storage in the database + * + * @param string $password + * @return string + * @author Pavel Laupe Dvorak + */ +function psm_password_encrypt($password) +{ + $key = psm_get_conf('password_encrypt_key'); + + $iv = mcrypt_create_iv( + mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), + MCRYPT_DEV_URANDOM + ); + + $encrypted = base64_encode( + $iv . + mcrypt_encrypt( + MCRYPT_RIJNDAEL_128, + hash('sha256', $key, true), + $password, + MCRYPT_MODE_CBC, + $iv + ) + ); + + return $encrypted; +} + +/** + * Decrypts password stored in the database for future use + * + * @param string $encryptedString + * @return string + * @author Pavel Laupe Dvorak + */ +function psm_password_decrypt($encryptedString) +{ + $key = psm_get_conf('password_encrypt_key'); + + $data = base64_decode($encryptedString); + $iv = substr($data, 0, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)); + + $decrypted = rtrim( + mcrypt_decrypt( + MCRYPT_RIJNDAEL_128, + hash('sha256', $key, true), + substr($data, mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)), + MCRYPT_MODE_CBC, + $iv + ), + "\0" + ); + + return $decrypted; } \ No newline at end of file diff --git a/src/lang/cs_CZ.lang.php b/src/lang/cs_CZ.lang.php index 5156acce..3485d0e2 100644 --- a/src/lang/cs_CZ.lang.php +++ b/src/lang/cs_CZ.lang.php @@ -122,6 +122,13 @@ $sm_lang = array( 'domain' => 'Doména/IP', 'timeout' => 'Časový limit', 'timeout_description' => 'Počet vteřin čekání na odpověď serveru.', + 'authentication_settings' => 'Nastavení autentizace (volitelný)', + 'website_username' => 'Uživatelské jméno', + 'website_username_description' => 'Uživatelské jméno pro přístup na stránku. (Pouze Apache autorizace je podporovaná.)', + 'website_password' => 'Heslo', + 'website_password_description' => 'Heslo pro přístup na stránku. Heslo je v databázi šifrované a NENÍ uloženo v čistém textu.', + 'fieldset_monitoring' => 'Monitoring', + 'fieldset_permissions' => 'Oprávnění', 'port' => 'Port', 'custom_port' => 'Uživatelský Port', 'popular_ports' => 'Populární Porty', @@ -180,6 +187,8 @@ $sm_lang = array( 'general' => 'Obecné', 'language' => 'Jazyk', 'show_update' => 'Kontrolovat aktualizace?', + 'password_encrypt_key' => 'Šifrovací klíč pro hesla', + 'password_encrypt_key_note' => 'Tímto klíčem se šifrují hesla, která se ukládají u serverů pro přístup na webové stránky. Pokud klíč změníte budou uložená hesla neplatná!', 'email_status' => 'Povolit odesílání e-mailu', 'email_from_email' => 'E-mailová adresa odesilatele', 'email_from_name' => 'Jméno odesilatele', diff --git a/src/lang/en_US.lang.php b/src/lang/en_US.lang.php index 56799a7c..54440b82 100644 --- a/src/lang/en_US.lang.php +++ b/src/lang/en_US.lang.php @@ -121,6 +121,13 @@ $sm_lang = array( 'domain' => 'Domain/IP', 'timeout' => 'Timeout', 'timeout_description' => 'Number of seconds to wait for the server to respond.', + 'authentication_settings' => 'Authentication Settings (Optional)', + 'website_username' => 'Username', + 'website_username_description' => 'Username to access the site. (Only Apache authentication is supported.)', + 'website_password' => 'Password', + 'website_password_description' => 'Password to access the site. The password is encrypted in the database and is not stored in plain text.', + 'fieldset_monitoring' => 'Monitoring', + 'fieldset_permissions' => 'Permissions', 'port' => 'Port', 'custom_port' => 'Custom Port', 'popular_ports' => 'Popular Ports', @@ -179,6 +186,8 @@ $sm_lang = array( 'general' => 'General', 'language' => 'Language', 'show_update' => 'Check for updates?', + 'password_encrypt_key' => 'The encryption key password', + 'password_encrypt_key_note' => 'This key is used to encrypt passwords that are stored on servers for access to websites. If the key will change the stored password is invalid!', 'email_status' => 'Allow sending email', 'email_from_email' => 'Email from address', 'email_from_name' => 'Email from name', diff --git a/src/psm/Module/Config/Controller/ConfigController.php b/src/psm/Module/Config/Controller/ConfigController.php index 254d9416..6dcc295e 100644 --- a/src/psm/Module/Config/Controller/ConfigController.php +++ b/src/psm/Module/Config/Controller/ConfigController.php @@ -117,6 +117,7 @@ class ConfigController extends AbstractController { $tpl_data['email_smtp_security_selected_' . $smtp_sec] = 'selected="selected"'; $tpl_data['auto_refresh_servers'] = (isset($config['auto_refresh_servers'])) ? $config['auto_refresh_servers'] : '0'; $tpl_data['log_retention_period'] = (isset($config['log_retention_period'])) ? $config['log_retention_period'] : '365'; + $tpl_data['password_encrypt_key'] = (isset($config['password_encrypt_key'])) ? $config['password_encrypt_key'] : sha1(microtime()); foreach($this->checkboxes as $input_key) { $tpl_data[$input_key . '_checked'] = @@ -159,6 +160,7 @@ class ConfigController extends AbstractController { : '', 'auto_refresh_servers' => intval(psm_POST('auto_refresh_servers', 0)), 'log_retention_period' => intval(psm_POST('log_retention_period', 365)), + 'password_encrypt_key' => psm_POST('password_encrypt_key', sha1(microtime())), ); foreach($this->checkboxes as $input_key) { $clean[$input_key] = (isset($_POST[$input_key])) ? '1': '0'; @@ -294,6 +296,8 @@ class ConfigController extends AbstractController { 'label_general' => psm_get_lang('config', 'general'), 'label_language' => psm_get_lang('config', 'language'), 'label_show_update' => psm_get_lang('config', 'show_update'), + 'label_password_encrypt_key' => psm_get_lang('config', 'password_encrypt_key'), + 'label_password_encrypt_key_note' => psm_get_lang('config', 'password_encrypt_key_note'), 'label_email_status' => psm_get_lang('config', 'email_status'), 'label_email_from_email' => psm_get_lang('config', 'email_from_email'), 'label_email_from_name' => psm_get_lang('config', 'email_from_name'), diff --git a/src/psm/Module/Server/Controller/AbstractServerController.php b/src/psm/Module/Server/Controller/AbstractServerController.php index 187c2360..79069e9c 100644 --- a/src/psm/Module/Server/Controller/AbstractServerController.php +++ b/src/psm/Module/Server/Controller/AbstractServerController.php @@ -75,7 +75,9 @@ abstract class AbstractServerController extends AbstractController { `s`.`pushover`, `s`.`warning_threshold`, `s`.`warning_threshold_counter`, - `s`.`timeout` + `s`.`timeout`, + `s`.`website_username`, + `s`.`website_password` FROM `".PSM_DB_PREFIX."servers` AS `s` {$sql_join} {$sql_where} diff --git a/src/psm/Module/Server/Controller/ServerController.php b/src/psm/Module/Server/Controller/ServerController.php index 9b813135..a22838f3 100644 --- a/src/psm/Module/Server/Controller/ServerController.php +++ b/src/psm/Module/Server/Controller/ServerController.php @@ -199,6 +199,8 @@ class ServerController extends AbstractServerController { 'default_value_timeout' => PSM_CURL_TIMEOUT, 'edit_value_pattern' => $edit_server['pattern'], 'edit_value_warning_threshold' => $edit_server['warning_threshold'], + 'edit_website_username' => $edit_server['website_username'], + 'edit_website_password' => psm_password_decrypt($edit_server['website_password']), 'edit_type_selected_' . $edit_server['type'] => 'selected="selected"', 'edit_active_selected_' . $edit_server['active'] => 'selected="selected"', 'edit_email_selected_' . $edit_server['email'] => 'selected="selected"', @@ -235,6 +237,8 @@ class ServerController extends AbstractServerController { 'label' => trim(strip_tags(psm_POST('label', ''))), 'ip' => trim(strip_tags(psm_POST('ip', ''))), 'timeout' => (isset($_POST['timeout']) && intval($_POST['timeout']) > 0) ? intval($_POST['timeout']) : null, + 'website_username' => psm_POST('website_username', null), + 'website_password' => (isset($_POST['website_password'])) ? psm_password_encrypt(psm_POST('website_password')) : '', 'port' => intval(psm_POST('port', 0)), 'type' => psm_POST('type', ''), 'pattern' => psm_POST('pattern', ''), @@ -390,6 +394,13 @@ class ServerController extends AbstractServerController { 'label_domain' => psm_get_lang('servers', 'domain'), 'label_timeout' => psm_get_lang('servers', 'timeout'), 'label_timeout_description' => psm_get_lang('servers', 'timeout_description'), + 'label_authentication_settings' => psm_get_lang('servers', 'authentication_settings'), + 'label_website_username' => psm_get_lang('servers', 'website_username'), + 'label_website_username_description' => psm_get_lang('servers', 'website_username_description'), + 'label_website_password' => psm_get_lang('servers', 'website_password'), + 'label_website_password_description' => psm_get_lang('servers', 'website_password_description'), + 'label_fieldset_monitoring' => psm_get_lang('servers', 'fieldset_monitoring'), + 'label_fieldset_permissions' => psm_get_lang('servers', 'fieldset_permissions'), 'label_port' => psm_get_lang('servers', 'port'), 'label_custom_port' => psm_get_lang('servers', 'custom_port'), 'label_please_select' => psm_get_lang('servers', 'please_select'), diff --git a/src/psm/Util/Install/Installer.php b/src/psm/Util/Install/Installer.php index 68b7fa2b..82ace432 100644 --- a/src/psm/Util/Install/Installer.php +++ b/src/psm/Util/Install/Installer.php @@ -146,6 +146,7 @@ class Installer { ('sms_from', '1234567890'), ('pushover_status', '0'), ('pushover_api_token', ''), + ('password_encrypt_key', " . sha1(microtime()) . "), ('alert_type', 'status'), ('log_status', '1'), ('log_email', '1'), @@ -227,6 +228,8 @@ class Installer { `warning_threshold` mediumint(1) unsigned NOT NULL DEFAULT '1', `warning_threshold_counter` mediumint(1) unsigned NOT NULL DEFAULT '0', `timeout` smallint(1) unsigned NULL DEFAULT NULL, + `website_username` varchar(255) DEFAULT NULL, + `website_password` varchar(255) DEFAULT NULL, PRIMARY KEY (`server_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;", PSM_DB_PREFIX . 'servers_uptime' => "CREATE TABLE IF NOT EXISTS `" . PSM_DB_PREFIX . "servers_uptime` ( @@ -398,6 +401,9 @@ class Installer { $this->execSQL("ALTER TABLE `".PSM_DB_PREFIX."users` DROP `server_id`;"); } + /** + * Upgrade for v3.1.0 release + */ protected function upgrade310() { $queries = array(); psm_update_conf('log_retention_period', '365'); @@ -423,10 +429,15 @@ class Installer { $this->execSQL($queries); } + /** + * Upgrade for v3.2.0 release + */ protected function upgrade320() { $queries = array(); + psm_update_conf('password_encrypt_key', sha1(microtime())); $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` CHANGE `ip` `ip` VARCHAR(500) NOT NULL;"; + $queries[] = "ALTER TABLE `" . PSM_DB_PREFIX . "servers` ADD `website_username` varchar(255) NULL, ADD `website_password` varchar(255) NULL AFTER `website_username`;"; $this->execSQL($queries); } diff --git a/src/psm/Util/Server/Updater/StatusUpdater.php b/src/psm/Util/Server/Updater/StatusUpdater.php index 395afc43..a8aed70d 100644 --- a/src/psm/Util/Server/Updater/StatusUpdater.php +++ b/src/psm/Util/Server/Updater/StatusUpdater.php @@ -82,7 +82,8 @@ class StatusUpdater { $this->server = $this->db->selectRow(PSM_DB_PREFIX . 'servers', array( 'server_id' => $server_id, ), array( - 'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'active', 'warning_threshold', 'warning_threshold_counter', 'timeout', + 'server_id', 'ip', 'port', 'label', 'type', 'pattern', 'status', 'active', 'warning_threshold', + 'warning_threshold_counter', 'timeout', 'website_username', 'website_password' )); if(empty($this->server)) { return false; @@ -176,7 +177,10 @@ class StatusUpdater { $this->server['ip'], true, ($this->server['pattern'] == '' ? false : true), - $this->server['timeout'] + $this->server['timeout'], + true, + $this->server['website_username'], + psm_password_decrypt($this->server['website_password']) ); $this->rtime = (microtime(true) - $starttime); diff --git a/src/templates/default/module/config/config.tpl.html b/src/templates/default/module/config/config.tpl.html index aafb3125..d7d55ca2 100644 --- a/src/templates/default/module/config/config.tpl.html +++ b/src/templates/default/module/config/config.tpl.html @@ -31,7 +31,17 @@  {{ label_seconds }} - +
+ +
+ +
+
+
{{ label_settings_notification }}
diff --git a/src/templates/default/module/server/server/update.tpl.html b/src/templates/default/module/server/server/update.tpl.html index 016ec667..9b416694 100644 --- a/src/templates/default/module/server/server/update.tpl.html +++ b/src/templates/default/module/server/server/update.tpl.html @@ -19,12 +19,13 @@
-
+
-
+
-
+
-
+
-
+
s
+
+ +
+ {{ label_authentication_settings}} +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ {{ label_fieldset_monitoring }}
@@ -116,6 +137,10 @@
+
+ +
+ {{ label_fieldset_permissions }}
diff --git a/src/templates/default/module/server/server/view.tpl.html b/src/templates/default/module/server/server/view.tpl.html index 8b95c7f5..a2a4e27b 100644 --- a/src/templates/default/module/server/server/view.tpl.html +++ b/src/templates/default/module/server/server/view.tpl.html @@ -73,6 +73,14 @@ {{ label_timeout }}: {{ timeout }} s + + {{ label_website_username }}: + {{ website_username }} + + + {{ label_website_password }}: + ****** + {% if has_admin_actions %}   diff --git a/static/js/scripts.js b/static/js/scripts.js index e1de60d3..fb29cb63 100755 --- a/static/js/scripts.js +++ b/static/js/scripts.js @@ -56,7 +56,6 @@ $().ready(function() { if (portInput != '') { var findPopularPorts = $('#popularPorts').find('option[value=' + portInput + ']'); - if(findPopularPorts.length) { $(findPopularPorts).attr("selected", "selected"); } else { @@ -66,16 +65,54 @@ $().ready(function() { } $('#popularPorts').change(function () { - var popularPorts = $(this).val(); + changePopularPorts($(this).val(), false, $('#type').val()); + }); + // server type + $('.types').hide(); + changeTypeSwitch($('#type').val()); + + $('#type').change(function () { + changeTypeSwitch($('#type').val()); + changePopularPorts($('#popularPorts').val(), true, $('#type').val()); + }); +}); + +function changeTypeSwitch(typeInput) { + switch (typeInput) { + case 'service': + $('.types').slideUp(); + $('.typeService').slideDown(); + break; + + case 'website': + $('.types').slideUp(); + $('.typeWebsite').slideDown(); + break; + + default: + $('.types').hide(); + } +} + +function changePopularPorts(popularPorts, changeType, typeInput) { + if (changeType === true) { + if (typeInput == 'service') { + if (popularPorts == 'custom') { + $('.portGroup').slideDown(); + } else { + $('.portGroup').hide(); + } + } + } else { if (popularPorts == 'custom') { $('.portGroup').slideDown(); } else { $('#port').val(popularPorts); $('.portGroup').slideUp(); } - }); -}); + } +} function psm_xhr(mod, params, method, on_complete, options) { method = (typeof method == 'undefined') ? 'GET' : method;