MDL-9399 auth/ldap: NTLM SSO - use sesskey and other tidyups
Several tidyups: - use moodle_strtolower() for utf-8 correctness - use sesskey as the key instead of IP addr to support proxied users - clean the sesskey after success! - pull timeout out to a constant: AUTH_NTLMTIMEOUT
This commit is contained in:
+24
-16
@@ -23,6 +23,10 @@ if (!defined('AUTH_AD_ACCOUNTDISABLE')) {
|
||||
if (!defined('AUTH_AD_NORMAL_ACCOUNT')) {
|
||||
define('AUTH_AD_NORMAL_ACCOUNT', 0x0200);
|
||||
}
|
||||
if (!defined('AUTH_NTLMTIMEOUT')) { // timewindow for the NTLM SSO process, in secs...
|
||||
define('AUTH_NTLMTIMEOUT', 10);
|
||||
}
|
||||
|
||||
|
||||
require_once($CFG->libdir.'/authlib.php');
|
||||
|
||||
@@ -83,19 +87,18 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
|
||||
//
|
||||
// Before we connect to LDAP, check if this is an AD SSO login
|
||||
// if we succeed in this block, we'll return success early.
|
||||
//
|
||||
if (!empty($this->config->ntlmsso_enabled)) {
|
||||
$key = $_SERVER['REMOTE_ADDR'];
|
||||
$key = sesskey();
|
||||
if ($cookie = get_config('auth/ldap/ntlmsess', $key)) {
|
||||
// These checks match the work done
|
||||
if (preg_match('/^(\d+):(.{10}):(.+)$/',$cookie,$matches)) {
|
||||
if (preg_match('/^(\d+):(.+)$/',$cookie,$matches)) {
|
||||
// $matches[0] is the whole matched string...
|
||||
$time = $matches[1];
|
||||
$sesskey = $matches[2];
|
||||
$sessusername = $matches[3];
|
||||
if (((time() - ((int)$time)) < 6) // timewindow for the process, in secs...
|
||||
&& $sesskey === sesskey()
|
||||
&& $sesskey === $password
|
||||
$sessusername = $matches[2];
|
||||
if (((time() - ((int)$time)) < AUTH_NTLMTIMEOUT)
|
||||
&& $key === $password
|
||||
&& $sessusername === $username) {
|
||||
|
||||
unset($cookie);
|
||||
@@ -114,11 +117,13 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
}
|
||||
ldap_close($ldapconnection);
|
||||
}
|
||||
|
||||
// Shortcut here - SSO confirmed
|
||||
return $validuser;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // End SSO processing
|
||||
|
||||
|
||||
$textlib = textlib_get_instance();
|
||||
@@ -1789,9 +1794,9 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
if (isset($_SERVER['REMOTE_USER']) && !empty($_SERVER['REMOTE_USER'])) {
|
||||
$username = $_SERVER['REMOTE_USER'];
|
||||
$username = substr(strrchr($username, '\\'), 1); //strip domain info
|
||||
$username = strtolower($username); //compatibility hack
|
||||
$key = $_SERVER['REMOTE_ADDR']; // add sesskey?
|
||||
$value = time() . ':' . $sesskey . ':' . $username;
|
||||
$username = moodle_strtolower($username); //compatibility hack
|
||||
$key = $sesskey;
|
||||
$value = time() . ':' . $username;
|
||||
return set_config($key, $value, 'auth/ldap/ntlmsess');
|
||||
}
|
||||
return false;
|
||||
@@ -1810,14 +1815,13 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
function ntlmsso_finish() {
|
||||
global $CFG, $USER;
|
||||
|
||||
$key = $_SERVER['REMOTE_ADDR']; // add sesskey?
|
||||
$key = sesskey();
|
||||
if ($cookie = get_config('auth/ldap/ntlmsess', $key)) {
|
||||
if (preg_match('/^(\d+):(.{10}):(.+)$/',$cookie,$matches)) {
|
||||
if (preg_match('/^(\d+):(.+)$/',$cookie,$matches)) {
|
||||
// $matches[0] is the whole matched string...
|
||||
$time = $matches[1];
|
||||
$sesskey = $matches[2];
|
||||
$username = $matches[3];
|
||||
if (((time() - ((int)$time)) < 6) // timewindow for the process, in secs...
|
||||
$username = $matches[2];
|
||||
if (((time() - ((int)$time)) < AUTH_NTLMTIMEOUT) // timewindow for the process, in secs...
|
||||
&& $sesskey === sesskey()) {
|
||||
// Here we want to trigger the whole authentication machinery
|
||||
// to make sure no step is bypassed...
|
||||
@@ -1827,6 +1831,10 @@ class auth_plugin_ldap extends auth_plugin_base {
|
||||
$user->id, 0, $user->id);
|
||||
$USER = complete_user_login($user);
|
||||
|
||||
// Cleanup the key to prevent reuse...
|
||||
// and to allow re-logins with normal credentials
|
||||
set_config($key, NULL, 'auth/ldap/ntlmsess');
|
||||
|
||||
/// Redirection
|
||||
if (user_not_fully_set_up($USER)) {
|
||||
$urltogo = $CFG->wwwroot.'/user/edit.php';
|
||||
|
||||
Reference in New Issue
Block a user