diff --git a/include/class.config.php b/include/class.config.php index 7fc9715b81..04f4653aaf 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -424,6 +424,17 @@ function getAllowIframes() { return str_replace(array(', ', ','), array(' ', ' '), $this->get('allow_iframes')) ?: 'self'; } + function getACL() { + if (!($acl = $this->get('acl'))) + return null; + + return explode(',', str_replace(' ', '', $acl)); + } + + function isACLBackendOnly() { + return $this->get('acl_backend') ?: 0; + } + function isAvatarsEnabled() { return $this->get('enable_avatars'); } @@ -1125,6 +1136,7 @@ function updateSystemSettings($vars, &$errors) { $f['default_dept_id']=array('type'=>'int', 'required'=>1, 'error'=>__('Default Department is required')); $f['autolock_minutes']=array('type'=>'int', 'required'=>1, 'error'=>__('Enter lock time in minutes')); $f['allow_iframes']=array('type'=>'cs-domain', 'required'=>0, 'error'=>__('Enter comma separated list of domains')); + $f['acl']=array('type'=>'ipaddr', 'required'=>0, 'error'=>__('Enter comma separated list of IP addresses')); //Date & Time Options $f['time_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Time format is required')); $f['date_format']=array('type'=>'string', 'required'=>1, 'error'=>__('Date format is required')); @@ -1184,6 +1196,8 @@ function updateSystemSettings($vars, &$errors) { 'enable_richtext' => isset($vars['enable_richtext']) ? 1 : 0, 'files_req_auth' => isset($vars['files_req_auth']) ? 1 : 0, 'allow_iframes' => Format::sanitize($vars['allow_iframes']), + 'acl' => Format::sanitize($vars['acl']), + 'acl_backend' => isset($vars['acl_backend']) ? 1 : 0, )); } diff --git a/include/class.validator.php b/include/class.validator.php index 583b25b65c..20661ac390 100644 --- a/include/class.validator.php +++ b/include/class.validator.php @@ -307,5 +307,15 @@ function process($fields,$vars,&$errors){ return (!$errors); } + + function check_acl($ip, $acl) { + if (!$ip || !$acl) + return false; + + if (!in_array($ip, $acl)) + return false; + + return true; + } } ?> diff --git a/include/i18n/en_US/help/tips/settings.system.yaml b/include/i18n/en_US/help/tips/settings.system.yaml index 3b972da6d4..97adb3a7fd 100644 --- a/include/i18n/en_US/help/tips/settings.system.yaml +++ b/include/i18n/en_US/help/tips/settings.system.yaml @@ -106,6 +106,15 @@ allow_iframes: - title: Syntax Information (host-source) href: "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors#Sources" +acl: + title: ACL (Access Control List) + content: > + Enter a comma separated list of IP addresses to allow access to the system. + If left empty, anyone will be able to access the system with the appropriate + credentials. If "Apply To Backend Only" is checked the system will apply the + ACL to Agent/Admin Panels only. If left unchecked however, it will apply + to the User Portal and Agent/Admin Panels. + # Date and time options date_time_options: title: Date & Time Options diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php index 37370df97e..610f84706e 100644 --- a/include/staff/settings-system.inc.php +++ b/include/staff/settings-system.inc.php @@ -138,6 +138,19 @@ + + : + +    + + + +   diff --git a/login.php b/login.php index 5c4a713124..7ef7e8cbb2 100644 --- a/login.php +++ b/login.php @@ -21,6 +21,18 @@ define('CLIENTINC_DIR',INCLUDE_DIR.'client/'); define('OSTCLIENTINC',TRUE); //make includes happy +// Enforce ACL (if applicable) +if (!$cfg->isACLBackendOnly() + && ($acl = $cfg->getACL()) + && !empty($acl)) { + $ip = osTicket::get_client_ip(); + if (!$ip) + die('No Valid IP Address'); + + if (!Validator::check_acl($ip, $acl)) + die('Access Denied'); +} + require_once(INCLUDE_DIR.'class.client.php'); require_once(INCLUDE_DIR.'class.ticket.php'); diff --git a/scp/login.php b/scp/login.php index 4853f7e31f..95eaa3da4e 100644 --- a/scp/login.php +++ b/scp/login.php @@ -20,6 +20,16 @@ // system or browser default TextDomain::configureForUser(); +// Enforce ACL (if applicable) +if (($acl = $cfg->getACL()) && !empty($acl)) { + $ip = osTicket::get_client_ip(); + if (!$ip) + die('No Valid IP Address'); + + if (!Validator::check_acl($ip, $acl)) + die('Access Denied'); +} + require_once(INCLUDE_DIR.'class.staff.php'); require_once(INCLUDE_DIR.'class.csrf.php');