From d6ac29b69bf4c7a0815b6bc13f0e750802d5c3dd Mon Sep 17 00:00:00 2001 From: Florian Schaal Date: Wed, 13 Dec 2017 15:15:45 +0100 Subject: [PATCH] Option to limit access for remote-user to specified IP(s) / hostname(s) (#4881) --- .../sql/incremental/upd_dev_collection.sql | 2 + install/sql/ispconfig3.sql | 2 + interface/lib/classes/remoting.inc.php | 35 +++++++++++ .../lib/classes/validate_remote_user.inc.php | 59 +++++++++++++++++++ .../web/admin/form/remote_user.tform.php | 21 +++++++ .../web/admin/lib/lang/de_remote_user.lng | 3 + .../web/admin/lib/lang/en_remote_user.lng | 3 + .../web/admin/templates/remote_user_edit.htm | 6 ++ 8 files changed, 131 insertions(+) create mode 100755 interface/lib/classes/validate_remote_user.inc.php diff --git a/install/sql/incremental/upd_dev_collection.sql b/install/sql/incremental/upd_dev_collection.sql index 2458724d2e..f73a20b057 100644 --- a/install/sql/incremental/upd_dev_collection.sql +++ b/install/sql/incremental/upd_dev_collection.sql @@ -1 +1,3 @@ ALTER TABLE `web_domain` ADD COLUMN `ssl_letsencrypt_exclude` enum('n','y') NOT NULL DEFAULT 'n' AFTER `ssl_letsencrypt`; +ALTER TABLE `remote_user` ADD `remote_access` ENUM('y','n') NOT NULL DEFAULT 'y' AFTER `remote_password`; +ALTER TABLE `remote_user` ADD `remote_ips` TEXT AFTER `remote_access`; diff --git a/install/sql/ispconfig3.sql b/install/sql/ispconfig3.sql index 11755a34b9..9aa91701bc 100644 --- a/install/sql/ispconfig3.sql +++ b/install/sql/ispconfig3.sql @@ -1246,6 +1246,8 @@ CREATE TABLE `remote_user` ( `sys_perm_other` varchar(5) default NULL, `remote_username` varchar(64) NOT NULL DEFAULT '', `remote_password` varchar(64) NOT NULL DEFAULT '', + `remote_access` enum('y','n') NOT NULL DEFAULT 'y', + `remote_ips` TEXT, `remote_functions` text, PRIMARY KEY (`remote_userid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; diff --git a/interface/lib/classes/remoting.inc.php b/interface/lib/classes/remoting.inc.php index 87072d32b6..a3bb192d91 100644 --- a/interface/lib/classes/remoting.inc.php +++ b/interface/lib/classes/remoting.inc.php @@ -144,6 +144,41 @@ class remoting { $sql = "SELECT * FROM remote_user WHERE remote_username = ? and remote_password = md5(?)"; $remote_user = $app->db->queryOneRecord($sql, $username, $password); if($remote_user['remote_userid'] > 0) { + $allowed_ips = explode(',',$remote_user['remote_ips']); + foreach($allowed_ips as $i => $allowed) { + if(!filter_var($allowed, FILTER_VALIDATE_IP)) { + // get the ip for a hostname + unset($allowed_ips[$i]); + $temp=dns_get_record($allowed, DNS_A+DNS_AAAA); + foreach($temp as $t) { + if(isset($t['ip'])) $allowed_ips[] = $t['ip']; + if(isset($t['ipv6'])) $allowed_ips[] = $t['ipv6']; + } + unset($temp); + } + } + $allowed_ips[] = '127.0.0.1'; + $allowed_ips[] = '::1'; + $allowed_ips=array_unique($allowed_ips); + $ip = $_SERVER['REMOTE_ADDR']; + $remote_allowed = @($ip == '::1' || $ip == '127.0.0.1')?true:false; + if(!$remote_allowed && $remote_user['remote_access'] == 'y') { + if(trim($remote_user['remote_ips']) == '') { + $remote_allowed=true; + } else { + $ip = inet_pton($_SERVER['REMOTE_ADDR']); + foreach($allowed_ips as $allowed) { + if($ip == inet_pton(trim($allowed))) { + $remote_allowed=true; + break; + } + } + } + } + if(!$remote_allowed) { + throw new SoapFault('login_failed', 'The login is not allowed from '.$_SERVER['REMOTE_ADDR']); + return false; + } //* Create a remote user session //srand ((double)microtime()*1000000); $remote_session = md5(mt_rand().uniqid('ispco')); diff --git a/interface/lib/classes/validate_remote_user.inc.php b/interface/lib/classes/validate_remote_user.inc.php new file mode 100755 index 0000000000..1b941f04c5 --- /dev/null +++ b/interface/lib/classes/validate_remote_user.inc.php @@ -0,0 +1,59 @@ +\r\n"; + + if($valid == false) { + $errmsg = $validator['errmsg']; + if(isset($app->tform->wordbook[$errmsg])) { + return $app->tform->wordbook[$errmsg]."
\r\n"; + } else { + return $errmsg."
\r\n"; + } + } + } + } + +} diff --git a/interface/web/admin/form/remote_user.tform.php b/interface/web/admin/form/remote_user.tform.php index 1ab2b0e0d5..895d9418a9 100644 --- a/interface/web/admin/form/remote_user.tform.php +++ b/interface/web/admin/form/remote_user.tform.php @@ -115,6 +115,27 @@ $form["tabs"]['remote_user'] = array ( 'width' => '30', 'maxlength' => '255' ), + 'remote_access' => array ( + 'datatype' => 'VARCHAR', + 'formtype' => 'CHECKBOX', + 'default' => 'n', + 'value' => array(0 => 'n', 1 => 'y') + ), + 'remote_ips' => array ( + 'datatype' => 'TEXT', + 'formtype' => 'TEXT', + 'validators' => array ( + 0 => array ( + 'type' => 'CUSTOM', + 'class' => 'validate_remote_user', + 'function' => 'valid_remote_ip', + 'errmsg' => 'remote_user_error_ips'), + ), + 'default' => '', + 'value' => '', + 'width' => '60', + 'searchable' => 2 + ), 'remote_functions' => array ( 'datatype' => 'TEXT', 'formtype' => 'CHECKBOXARRAY', diff --git a/interface/web/admin/lib/lang/de_remote_user.lng b/interface/web/admin/lib/lang/de_remote_user.lng index 1458d22ee5..164a0fb81a 100644 --- a/interface/web/admin/lib/lang/de_remote_user.lng +++ b/interface/web/admin/lib/lang/de_remote_user.lng @@ -44,4 +44,7 @@ $wb['generate_password_txt'] = 'Passwort erzeugen'; $wb['repeat_password_txt'] = 'Passwort wiederholen'; $wb['password_mismatch_txt'] = 'Die Passwörter stimmen nicht überein.'; $wb['password_match_txt'] = 'Die Passwörter stimmen überein.'; +$wb['remote_user_error_ips'] = 'Mindestens eine eingegebene IP-Adresse oder ein Hostname ist ungueltig.'; +$wb['remote_access_txt'] = 'Entfernter Zugriff'; +$wb['remote_ips_txt'] = 'Entfernter Zugriff IP / Hostname (Mehrere mit Komma trennen, keine Angabe für alle)'; ?> diff --git a/interface/web/admin/lib/lang/en_remote_user.lng b/interface/web/admin/lib/lang/en_remote_user.lng index 4868e39bdb..2fc633b555 100644 --- a/interface/web/admin/lib/lang/en_remote_user.lng +++ b/interface/web/admin/lib/lang/en_remote_user.lng @@ -44,4 +44,7 @@ $wb['generate_password_txt'] = 'Generate Password'; $wb['repeat_password_txt'] = 'Repeat Password'; $wb['password_mismatch_txt'] = 'The passwords do not match.'; $wb['password_match_txt'] = 'The passwords do match.'; +$wb['remote_access_txt'] = 'Remote Access'; +$wb['remote_ips_txt'] = 'Remote Access IPs / Hostnames (separate by , and leave blank for any)'; +$wb['remote_user_error_ips'] = 'At least one of the entered ip addresses or hostnames is invalid.'; ?> diff --git a/interface/web/admin/templates/remote_user_edit.htm b/interface/web/admin/templates/remote_user_edit.htm index dcfea7929d..099af58eb5 100644 --- a/interface/web/admin/templates/remote_user_edit.htm +++ b/interface/web/admin/templates/remote_user_edit.htm @@ -36,6 +36,12 @@ +
+ +
{tmpl_var name='remote_access'}
+
+ +
-- GitLab