From: skodak Date: Wed, 25 Apr 2007 19:36:47 +0000 (+0000) Subject: MDL-8031 Enforce password complexity for user authentication - original patch by... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=83022298df71b684c0fbdb659039d89cb9829a98;p=moodle.git MDL-8031 Enforce password complexity for user authentication - original patch by IƱaki Arenaza --- diff --git a/admin/settings/security.php b/admin/settings/security.php index e6c9e76271..7a476d32dd 100644 --- a/admin/settings/security.php +++ b/admin/settings/security.php @@ -41,6 +41,12 @@ $temp->add(new admin_setting_configselect('bloglevel', get_string('bloglevel', ' $temp->add(new admin_setting_configcheckbox('cronclionly', get_string('cronclionly', 'admin'), get_string('configcronclionly', 'admin'), 0)); $temp->add(new admin_setting_configtext('cronremotepassword', get_string('cronremotepassword', 'admin'), get_string('configcronremotepassword', 'admin'), '', PARAM_RAW)); +$temp->add(new admin_setting_configcheckbox('passwordpolicy', get_string('passwordpolicy', 'admin'), get_string('configpasswordpolicy', 'admin'), 0)); +$temp->add(new admin_setting_configtext('minpasswordlength', get_string('minpasswordlength', 'admin'), get_string('configminpasswordlength', 'admin'), 8, PARAM_INT)); +$temp->add(new admin_setting_configtext('minpassworddigits', get_string('minpassworddigits', 'admin'), get_string('configminpassworddigits', 'admin'), 1, PARAM_INT)); +$temp->add(new admin_setting_configtext('minpasswordlower', get_string('minpasswordlower', 'admin'), get_string('configminpasswordlower', 'admin'), 1, PARAM_INT)); +$temp->add(new admin_setting_configtext('minpasswordupper', get_string('minpasswordupper', 'admin'), get_string('configminpasswordupper', 'admin'), 1, PARAM_INT)); +$temp->add(new admin_setting_configtext('minpasswordnonalphanum', get_string('minpasswordnonalphanum', 'admin'), get_string('configminpasswordnonalphanum', 'admin'), 1, PARAM_INT)); $ADMIN->add('security', $temp); diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php index d75adb3ca6..43cce10893 100644 --- a/lang/en_utf8/admin.php +++ b/lang/en_utf8/admin.php @@ -135,12 +135,18 @@ $string['configmaxevents'] = 'Events to Lookahead'; $string['configmemcachedhosts'] = 'For memcached. Comma-separated list of hosts that are running the memcached daemon. Use IP addresses to avoid DNS latency. memcached does not behave well if you add/remove hosts on a running setup.'; $string['configmemcachedpconn'] = 'For memcached. Use persistent connections. Use carefully -- it can make Apache/PHP crash after a restart of the memcached daemon.'; $string['configmessaging'] = 'Should the messaging system between site users be enabled?'; +$string['configminpassworddigits'] = 'Passwords must have at least these many digits.'; +$string['configminpasswordlength'] = 'Passwords must be at least these many characters long.'; +$string['configminpasswordlower'] = 'Passwords must have at least these many lower case letters.'; +$string['configminpasswordnonalphanum'] = 'Passwords must have at least these many non-alphanumeric characters.'; +$string['configminpasswordupper'] = 'Passwords must have at least these many upper case letters.'; $string['configmymoodleredirect'] = 'This setting forces redirects to /my on login for non-admins and replaces the top level site breadcrumb with /my'; $string['confignonmetacoursesyncroleids'] = 'By default all enrolments from child courses are synchronised to metacourses. Roles that are selected here will not be included in the synchronisation process.'; $string['confignoreplyaddress'] = 'Emails are sometimes sent out on behalf of a user (eg forum posts). The email address you specify here will be used as the \"From\" address in those cases when the recipients should not be able to reply directly to the user (eg when a user chooses to keep their address private).'; $string['confignotifyloginfailures'] = 'If login failures have been recorded, email notifications can be sent out. Who should see these notifications?'; $string['confignotifyloginthreshold'] = 'If notifications about failed logins are active, how many failed login attempts by one user or one IP address is it worth notifying about?'; $string['confignotloggedinroleid'] = 'Users who are not logged in to the site will be treated as if they have this role granted to them at the site context. Guest is almost always what you want here, but you might want to create roles that are less or more restrictive. Things like creating posts still require the user to log in properly.'; +$string['configpasswordpolicy'] = 'Turning this on will make Moodle check user passwords agains a valid password policy. Use the settings below to specify your policy (they will be ignored if you set this to \'No\').'; $string['configopentogoogle'] = 'If you enable this setting, then Google will be allowed to enter your site as a Guest. In addition, people coming in to your site via a Google search will automatically be logged in as a Guest. Note that this only provides transparent access to courses that already allow guest access.'; $string['configpathtoclam'] = 'Path to clam AV. Probably something like /usr/bin/clamscan or /usr/bin/clamdscan. You need this in order for clam AV to run.'; $string['configpathtodu'] = 'Path to du. Probably something like /usr/bin/du. If you enter this, pages that display directory contents will run much faster for directories with a lot of files.'; @@ -381,6 +387,11 @@ $string['mediapluginwmv'] = 'Enable .wmv filter'; $string['memcachedhosts'] = 'memcached hosts'; $string['memcachedpconn'] = 'memcached use persistent connections'; $string['messaging'] = 'Enable messaging system'; +$string['minpasswordlength'] = 'Password Length'; +$string['minpassworddigits'] = 'Digits'; +$string['minpasswordlower'] = 'Lowercase letters'; +$string['minpasswordnonalphanum'] = 'Non-alphanumeric characters'; +$string['minpasswordupper'] = 'Uppercase letters'; $string['misc'] = 'Miscellaneous'; $string['mnetrestore_extusers'] = 'Note: This backup file contains remote Moodle Network user accounts which will be restored as part of the process.'; $string['mnetrestore_extusers_mismatch'] = 'Note: This backup file apparently originates from a different Moodle installation and contains remote Moodle Network user accounts that may fail to restore. This operation is unsupported. If you are certain that it was created on this Moodle installation, or you can ensure that all the needed Moodle Network Hosts are configured, you may want to still try the restore.'; @@ -412,6 +423,7 @@ $string['order1'] = 'First'; $string['order2'] = 'Second'; $string['order3'] = 'Third'; $string['order4'] = 'Fourth'; +$string['passwordpolicy'] = 'Password Policy'; $string['pathconvert'] = 'Path of convert binary'; $string['pathdvips'] = 'Path of dvips binary'; $string['pathlatex'] = 'Path of latex binary'; diff --git a/lang/en_utf8/auth.php b/lang/en_utf8/auth.php index 21a555d8eb..7a394f7ec3 100644 --- a/lang/en_utf8/auth.php +++ b/lang/en_utf8/auth.php @@ -309,6 +309,11 @@ $string['changepasswordhelp'] = 'Here you can specify a location at which your u $string['chooseauthmethod'] = 'Choose an authentication method'; $string['createpasswordifneeded'] = 'Create password if needed'; $string['errorpasswordupdate'] = 'Error updating password, password not changed'; +$string['errorminpasswordlength'] = 'Passwords must be at least $a characters long.'; +$string['errorminpassworddigits'] = 'Passwords must have at least $a digit(s).'; +$string['errorminpasswordlower'] = 'Passwords must have at least $a lower case letter(s).'; +$string['errorminpasswordnonalphanum'] = 'Passwords must have at least $a non-alphanumeric character(s).'; +$string['errorminpasswordupper'] = 'Passwords must have at least $a upper case letter(s).'; $string['infilefield'] = 'Field required in file'; $string['forcechangepassword'] = 'Force change password'; $string['forcechangepassword_help'] = 'Force users to change password on their next login to Moodle.'; diff --git a/lib/moodlelib.php b/lib/moodlelib.php index c66c250d1f..3df079b095 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -2852,9 +2852,49 @@ function get_complete_user_data($field, $value, $mnethostid=null) { return $user; } +/** + * @uses $CFG + * @param string $password the password to be checked agains the password policy + * @param string $errmsg the error message to display when the password doesn't comply with the policy. + * @return bool true if the password is valid according to the policy. false otherwise. + */ +function check_password_policy($password, &$errmsg) { + global $CFG; + if (empty($CFG->passwordpolicy)) { + return true; + } -/* + $textlib = new textlib(); + $errmsg = ''; + if ($textlib->strlen($password) < $CFG->minpasswordlength) { + $errmsg = get_string('errorminpasswordlength', 'auth', $CFG->minpasswordlength); + + } else if (preg_match_all('/[[:digit:]]/u', $password, $matches) < $CFG->minpassworddigits) { + $errmsg = get_string('errorminpassworddigits', 'auth', $CFG->minpassworddigits); + + } else if (preg_match_all('/[[:lower:]]/u', $password, $matches) < $CFG->minpasswordlower) { + $errmsg = get_string('errorminpasswordlower', 'auth', $CFG->minpasswordlower); + + } else if (preg_match_all('/[[:upper:]]/u', $password, $matches) < $CFG->minpasswordupper) { + $errmsg = get_string('errorminpasswordupper', 'auth', $CFG->minpasswordupper); + + } else if (preg_match_all('/[^[:upper:][:lower:][:digit:]]/u', $password, $matches) < $CFG->minpasswordnonalphanum) { + $errmsg = get_string('errorminpasswordnonalphanum', 'auth', $CFG->minpasswordnonalphanum); + + } else if ($password == 'admin' or $password == 'password') { + $errmsg = get_string('unsafepassword'); + } + + if ($errmsg == '') { + return true; + } else { + return false; + } +} + + +/** * When logging in, this function is run to set certain preferences * for the current SESSION */ diff --git a/login/change_password_form.php b/login/change_password_form.php index fb41c12a6d..d0338f213a 100644 --- a/login/change_password_form.php +++ b/login/change_password_form.php @@ -66,6 +66,12 @@ class login_change_password_form extends moodleform { return $errors; } + $errmsg = '';//prevents eclipse warnings + if (!check_password_policy($data['newpassword1'], $errmsg)) { + $errors['newpassword1'] = $errmsg; + $errors['newpassword2'] = $errmsg; + } + return true; } } diff --git a/login/signup_form.php b/login/signup_form.php index 8a978bb0c2..c8b9e80b19 100644 --- a/login/signup_form.php +++ b/login/signup_form.php @@ -110,6 +110,9 @@ class login_signup_form extends moodleform { } + if (!check_password_policy($data['password'], $errmsg)) { + $errors['password'] = $errmsg; + } if (0 == count($errors)){ return true; diff --git a/user/editadvanced_form.php b/user/editadvanced_form.php index 31140933fd..7165ea8d29 100644 --- a/user/editadvanced_form.php +++ b/user/editadvanced_form.php @@ -109,6 +109,13 @@ class user_editadvanced_form extends moodleform { $user = get_record('user', 'id', $usernew->id); $err = array(); + if (!empty($usernew->newpassword)) { + $errmsg = '';//prevent eclipse warning + if (!check_password_policy($usernew->newpassword, $errmsg)) { + $err['newpassword'] = $errmsg; + } + } + if (empty($usernew->username)) { //might be only whitespace $err['username'] = get_string('required');