From 355bd271ac8173345aab93ffab79cb7c6312a567 Mon Sep 17 00:00:00 2001 From: martinlanghoff Date: Wed, 14 Nov 2007 22:11:35 +0000 Subject: [PATCH] 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 --- auth/ldap/auth.php | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/auth/ldap/auth.php b/auth/ldap/auth.php index be5c4cfc24..f761d28a18 100644 --- a/auth/ldap/auth.php +++ b/auth/ldap/auth.php @@ -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'; -- 2.39.5