Skip to content

Commit

Permalink
feature: ACL (Access Control List)
Browse files Browse the repository at this point in the history
This adds a new feature called ACL that offers the ability to control what
IP addresses are allowed to access the Login Page(s). This adds a new
textfield to the System Settings to add a comma separated list of IPs. This
also adds a checkbox called "Apply To Backend Only" that, if enabled, will
only apply the ACL to the Agent Login Page. Lastly, this adds a validator
for a simple comma-separated list of IP addresses. (eg. `111.111.111.111,
222.222.222.222, 333.333.333.333`)

If the requester's IP is not in the ACL the system will show an "Access
Denied" page. If the requester's IP is in the ACL they will be able to
access the Login Page(s) as usual. If the ACL field is left blank anyone
will be able to access the User/Agent Login Pages.
  • Loading branch information
JediKev committed Apr 10, 2019
1 parent dcd94b2 commit 8608697
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include/class.config.php
Expand Up @@ -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');
}
Expand Down Expand Up @@ -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'));
Expand Down Expand Up @@ -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,
));
}

Expand Down
10 changes: 10 additions & 0 deletions include/class.validator.php
Expand Up @@ -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;
}
}
?>
9 changes: 9 additions & 0 deletions include/i18n/en_US/help/tips/settings.system.yaml
Expand Up @@ -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
Expand Down
13 changes: 13 additions & 0 deletions include/staff/settings-system.inc.php
Expand Up @@ -138,6 +138,19 @@
<i class="help-tip icon-question-sign" href="#allow_iframes"></i>
</td>
</tr>
<tr>
<td><?php echo __('ACL'); ?>:</td>
<td><input type="text" size="40" name="acl" value="<?php echo $config['acl']; ?>">
&nbsp;<font class="error">&nbsp;<?php echo $errors['acl']; ?></font>
<label class="inline checkbox">
<input type="checkbox" name="acl_backend" <?php
if ($config['acl_backend']) echo 'checked="checked"';
?> />
<?php echo __('Apply To Backend Only'); ?>
</label>
<i class="help-tip icon-question-sign" href="#acl"></i>
</td>
</tr>
<tr>
<th colspan="2">
<em><b><?php echo __('Date and Time Options'); ?></b>&nbsp;
Expand Down
12 changes: 12 additions & 0 deletions login.php
Expand Up @@ -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');

Expand Down
10 changes: 10 additions & 0 deletions scp/login.php
Expand Up @@ -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');

Expand Down

0 comments on commit 8608697

Please sign in to comment.