diff --git a/README.md b/README.md index 5094081..7e26ecf 100644 --- a/README.md +++ b/README.md @@ -82,8 +82,10 @@ Example usage on the command line: Master password feature ------------ - -**NOT for production use** + +**⚠️ NOT for production use, ever. ⚠️** + +This is a low-friction convenience feature meant only for disposable dev/test environments, not for use on production sites. This enables you to: diff --git a/auth.php b/auth.php index 84fd15b..1e21b50 100644 --- a/auth.php +++ b/auth.php @@ -101,25 +101,40 @@ public function loginpage_hook() { $this->log(__FUNCTION__ . " log in as: '{$user->username}'"); } } else { - $user = $DB->get_record('user', array('username' => $username)); + $user = $DB->get_record( + 'user', + ['username' => $username, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id] + ); } if ($user) { + // Reject suspended, deleted or unconfirmed accounts. + if ($user->suspended || $user->deleted || !$user->confirmed) { + $this->log(__FUNCTION__ . ' account suspended, deleted or unconfirmed'); + return; + } - $this->log(__FUNCTION__ . ' found user '.$user->username); + $this->log(__FUNCTION__ . ' found user ' . $user->username); $whitelistips = $CFG->auth_basic_whitelist_ips ?? null; - if (empty($whitelistips) || remoteip_in_list($whitelistips) ) { + if (empty($whitelistips) || remoteip_in_list($whitelistips)) { + if (login_is_lockedout($user)) { + $this->log(__FUNCTION__ . ' account locked out: ' . $user->username); + return; + } + if ( $masterpassword || ($user->auth == 'basic' || $this->config->onlybasic == '0') && ( validate_internal_user_password($user, $pass) ) ) { $this->log(__FUNCTION__ . ' password good'); + login_attempt_valid($user); complete_user_login($user); if (isset($SESSION->wantsurl) && !empty($SESSION->wantsurl)) { $urltogo = $SESSION->wantsurl; - } else if (isset($_GET['wantsurl'])) { - $urltogo = $_GET['wantsurl']; + } else if ($wantsurl = optional_param('wantsurl', null, PARAM_LOCALURL)) { + // PARAM_LOCALURL only accepts URLs local to this site. + $urltogo = $wantsurl; } else { $urltogo = $CFG->wwwroot; } @@ -136,6 +151,7 @@ public function loginpage_hook() { $this->log(__FUNCTION__ . " continuing onto " . qualified_me() ); } } else { + login_attempt_failed($user); $this->log(__FUNCTION__ . ' password bad'); } } else { diff --git a/masterpassword.php b/masterpassword.php index b77ca77..cce23b5 100644 --- a/masterpassword.php +++ b/masterpassword.php @@ -54,7 +54,7 @@ } // Save Password Form. -$password = time().uniqid(); +$password = complex_random_string(40); $mform = new savepassword(null, array('password' => $password)); if ($formdata = $mform->get_data()) { diff --git a/version.php b/version.php index 609bc46..87fbac6 100644 --- a/version.php +++ b/version.php @@ -24,8 +24,8 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2022031600; // The current plugin version (Date: YYYYMMDDXX). -$plugin->release = 2022031600; // Match release exactly to version. +$plugin->version = 2022031601; // The current plugin version (Date: YYYYMMDDXX). +$plugin->release = 2022031601; // Match release exactly to version. $plugin->requires = 2020110910; // Requires 3.10 as minimum. $plugin->component = 'auth_basic'; // Full name of the plugin (used for diagnostics). $plugin->maturity = MATURITY_STABLE;