Merge pull request #18 from andrewhancox/master

Add ability to white list IP addresses to ignore iprestrictions
This commit is contained in:
Dmitrii Metelkin 2017-10-23 15:33:53 +11:00 committed by GitHub
commit 19fb0044f0
6 changed files with 100 additions and 2 deletions

View file

@ -57,6 +57,7 @@ class auth_plugin_userkey extends auth_plugin_base {
'mappingfield' => self::DEFAULT_MAPPING_FIELD, 'mappingfield' => self::DEFAULT_MAPPING_FIELD,
'keylifetime' => 60, 'keylifetime' => 60,
'iprestriction' => 0, 'iprestriction' => 0,
'ipwhitelist' => '',
'redirecturl' => '', 'redirecturl' => '',
'ssourl' => '', 'ssourl' => '',
'createuser' => false, 'createuser' => false,

View file

@ -124,8 +124,28 @@ class core_userkey_manager implements userkey_manager_interface {
if ($key->iprestriction) { if ($key->iprestriction) {
$remoteaddr = getremoteaddr(null); $remoteaddr = getremoteaddr(null);
if (empty($remoteaddr) or !address_in_subnet($remoteaddr, $key->iprestriction)) {
print_error('ipmismatch'); if (isset($this->config->ipwhitelist)) {
$whitelist = $this->config->ipwhitelist;
} else {
$whitelist = false;
}
if (empty($remoteaddr) ) {
print_error('noip', 'auth_userkey');
} else if (!empty($whitelist)) {
$ips = explode(';', $whitelist);
$whitelisted = false;
foreach ($ips as $ip) {
if (address_in_subnet($remoteaddr, $ip)) {
$whitelisted = true;
}
}
if (!$whitelisted) {
print_error('ipmismatch', 'error', '', null, "Remote address: $remoteaddr\nKey IP: $key->iprestriction");
}
} else if (!address_in_subnet($remoteaddr, $key->iprestriction)) {
print_error('ipmismatch', 'error', '', null, "Remote address: $remoteaddr\nKey IP: $key->iprestriction");
} }
} }

View file

@ -29,6 +29,10 @@ $string['mappingfield_desc'] = 'This user field will be used to find relevant us
$string['iprestriction'] = 'IP restriction'; $string['iprestriction'] = 'IP restriction';
$string['iprestriction_desc'] = 'If enabled, a web call has to contain "ip" parameter when requesting login URL. $string['iprestriction_desc'] = 'If enabled, a web call has to contain "ip" parameter when requesting login URL.
A user has to have provided IP to be able to use a key to login to LMS.'; A user has to have provided IP to be able to use a key to login to LMS.';
$string['ipwhitelist'] = 'Whitelist IP ranges';
$string['ipwhitelist_desc'] = "Ignore IP restrictions if the IP address the token was issued for or the login attempt comes from falls within any of these ranges.
\nThis can happen when some users reach Moodle or the system issuing login tokens via a private network or DMZ.
\nIf the route to either the system issuing tokens or this Moodle is via a private address range then set this value to 10.0.0.0/8;172.16.0.0/12;192.168.0.0/16";
$string['keylifetime'] = 'User key life time'; $string['keylifetime'] = 'User key life time';
$string['keylifetime_desc'] = 'Life time in seconds of the each user login key.'; $string['keylifetime_desc'] = 'Life time in seconds of the each user login key.';
$string['incorrectkeylifetime'] = 'User key life time should be a number'; $string['incorrectkeylifetime'] = 'User key life time should be a number';

View file

@ -49,6 +49,13 @@ $fields = get_auth_plugin('userkey')->get_allowed_mapping_fields();
<?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?> <?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?>
<?php print_string($field.'_desc', 'auth_userkey')?></td> <?php print_string($field.'_desc', 'auth_userkey')?></td>
</tr> </tr>
<tr valign="top">
<?php $field = 'ipwhitelist' ?>
<td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td>
<td><input type="text" size="60" name="<?php echo $field ?>" value="<?php print $config->$field ?>" placeholder=""><br>
<?php if (isset($err[$field])) { echo $OUTPUT->notification($err[$field], 'notifyfailure'); } ?>
<?php print_string($field.'_desc', 'auth_userkey') ?></td>
</tr>
<tr valign="top"> <tr valign="top">
<?php $field = 'redirecturl' ?> <?php $field = 'redirecturl' ?>
<td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td> <td align="right"><label for="<?php echo $field ?>"><?php print_string($field, 'auth_userkey') ?></label></td>

View file

@ -756,6 +756,7 @@ class auth_plugin_userkey_testcase extends advanced_testcase {
$formconfig->mappingfield = 'email'; $formconfig->mappingfield = 'email';
$formconfig->keylifetime = 100; $formconfig->keylifetime = 100;
$formconfig->iprestriction = 0; $formconfig->iprestriction = 0;
$formconfig->ipwhitelist = '';
$formconfig->redirecturl = 'http://google.com/'; $formconfig->redirecturl = 'http://google.com/';
$formconfig->ssourl = 'http://google.com/'; $formconfig->ssourl = 'http://google.com/';
$formconfig->createuser = false; $formconfig->createuser = false;
@ -842,6 +843,32 @@ class auth_plugin_userkey_testcase extends advanced_testcase {
$this->auth->user_login_userkey(); $this->auth->user_login_userkey();
} }
/**
* Test that IP address mismatch exception gets thrown if incorrect IP and outside whitelist.
*
* @expectedException moodle_exception
* @expectedExceptionMessage Client IP address mismatch
*/
public function test_ipmismatch_exception_thrown_if_ip_is_outside_whitelist() {
global $DB;
set_config('ipwhitelist', '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16', 'auth_userkey');
$key = new stdClass();
$key->value = 'IpmismatchKey';
$key->script = 'auth/userkey';
$key->userid = $this->user->id;
$key->instance = $this->user->id;
$key->iprestriction = '192.161.1.1';
$key->validuntil = time() + 300;
$key->timecreated = time();
$DB->insert_record('user_private_key', $key);
$_POST['key'] = 'IpmismatchKey';
$_SERVER['HTTP_CLIENT_IP'] = '192.161.1.2';
$this->auth->user_login_userkey();
}
/** /**
* Test that IP address mismatch exception gets thrown if user id is incorrect. * Test that IP address mismatch exception gets thrown if user id is incorrect.
* *

View file

@ -149,6 +149,45 @@ class core_userkey_manager_testcase extends advanced_testcase {
$this->assertEquals(time() + 60, $actualkey->validuntil); $this->assertEquals(time() + 60, $actualkey->validuntil);
} }
/**
* Test that IP address mismatch exception gets thrown if incorrect IP and outside whitelist.
*
* @expectedException moodle_exception
* @expectedExceptionMessage Client IP address mismatch
*/
public function test_exception_if_ip_is_outside_whitelist() {
global $DB;
$this->config->iprestriction = true;
$this->config->ipwhitelist = '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16';
$manager = new core_userkey_manager($this->config);
$value = $manager->create_key($this->user->id, '193.168.1.1');
$_SERVER['HTTP_CLIENT_IP'] = '193.168.1.2';
$manager->validate_key($value);
}
/**
* Test that key is accepted if incorrect IP and within whitelist.
*/
public function test_create_correct_key_if_ip_is_whitelisted() {
global $DB;
$this->config->iprestriction = true;
$this->config->ipwhitelist = '10.0.0.0/8;172.16.0.0/12;192.168.0.0/16';
$manager = new core_userkey_manager($this->config);
$value = $manager->create_key($this->user->id, '192.168.1.1');
$_SERVER['HTTP_CLIENT_IP'] = '192.168.1.2';
$key = $manager->validate_key($value);
$this->assertEquals($this->user->id, $key->userid);
}
/** /**
* Test that key gets created correctly if config option iprestriction is set to false and we set allowedips. * Test that key gets created correctly if config option iprestriction is set to false and we set allowedips.
*/ */