Commit e9151dd8 authored by Eugene Venter's avatar Eugene Venter
Browse files

admin/users; auth/internal/lib.php; lib/db/upgrade.php (bug #662424)


* encrypt passwords on user add, edit and imports
* upgrade to encrypt and add salt to all existing cleartext passwords
* update validate_password to prevent successful validation of cleartext passwords with no salt
Signed-off-by: default avatarEugene Venter <eugene@catalyst.net.nz>
parent 50c961ec
...@@ -324,6 +324,19 @@ function adduser_submit(Pieform $form, $values) { ...@@ -324,6 +324,19 @@ function adduser_submit(Pieform $form, $values) {
} }
} }
// Add salt and encrypt the pw, if the auth instance allows for it
$userobj = new User();
$userobj = $userobj->find_by_id($user->id);
$authobj = AuthFactory::create($user->authinstance);
if (method_exists($authobj, 'change_password')) {
$authobj->change_password($userobj, $user->password);
} else {
$userobj->password = '';
$userobj->salt = auth_get_random_salt();
$userobj->commit();
}
unset($userobj, $authobj);
$SESSION->add_ok_msg(get_string('newusercreated', 'admin')); $SESSION->add_ok_msg(get_string('newusercreated', 'admin'));
redirect('/admin/users/edit.php?id=' . $user->id); redirect('/admin/users/edit.php?id=' . $user->id);
} }
......
...@@ -367,6 +367,20 @@ function finish_import() { ...@@ -367,6 +367,20 @@ function finish_import() {
} }
} }
foreach ($ADDEDUSERS as $user) {
// Add salt and encrypt the pw, if the auth instance allows for it
$userobj = new User();
$userobj = $userobj->find_by_id($user->id);
$authobj = AuthFactory::create($user->authinstance);
if (method_exists($authobj, 'change_password')) {
$authobj->change_password($userobj, $user->password);
} else {
$userobj->password = '';
$userobj->salt = auth_get_random_salt();
$userobj->commit();
}
}
if (!empty($FAILEDUSERS)) { if (!empty($FAILEDUSERS)) {
$message = get_string('importfailedfornusers', 'admin', count($FAILEDUSERS), $totalusers) . "\n<ul>\n"; $message = get_string('importfailedfornusers', 'admin', count($FAILEDUSERS), $totalusers) . "\n<ul>\n";
foreach ($FAILEDUSERS as $username => $error) { foreach ($FAILEDUSERS as $username => $error) {
......
...@@ -38,6 +38,7 @@ require_once('activity.php'); ...@@ -38,6 +38,7 @@ require_once('activity.php');
$id = param_integer('id'); $id = param_integer('id');
$user = new User; $user = new User;
$user->find_by_id($id); $user->find_by_id($id);
$authobj = AuthFactory::create($user->authinstance);
if (!$USER->is_admin_for_user($user)) { if (!$USER->is_admin_for_user($user)) {
$SESSION->add_error_msg(get_string('youcannotadministerthisuser', 'admin')); $SESSION->add_error_msg(get_string('youcannotadministerthisuser', 'admin'));
...@@ -53,17 +54,22 @@ $elements['id'] = array( ...@@ -53,17 +54,22 @@ $elements['id'] = array(
'rules' => array('integer' => true), 'rules' => array('integer' => true),
'value' => $id, 'value' => $id,
); );
$elements['password'] = array(
'type' => 'text', if (method_exists($authobj, 'change_password')) {
'title' => get_string('resetpassword','admin'), // Only show the password options if the plugin allows for the functionality
'description' => get_string('resetpassworddescription','admin'), $elements['password'] = array(
); 'type' => 'text',
$elements['passwordchange'] = array( 'title' => get_string('resetpassword','admin'),
'type' => 'checkbox', 'description' => get_string('resetpassworddescription','admin'),
'title' => get_string('forcepasswordchange','admin'), );
'description' => get_string('forcepasswordchangedescription','admin'),
'defaultvalue' => $user->passwordchange, $elements['passwordchange'] = array(
); 'type' => 'checkbox',
'title' => get_string('forcepasswordchange','admin'),
'description' => get_string('forcepasswordchangedescription','admin'),
'defaultvalue' => $user->passwordchange,
);
}
if ($USER->get('admin')) { if ($USER->get('admin')) {
$elements['staff'] = array( $elements['staff'] = array(
'type' => 'checkbox', 'type' => 'checkbox',
...@@ -193,10 +199,6 @@ function edituser_site_submit(Pieform $form, $values) { ...@@ -193,10 +199,6 @@ function edituser_site_submit(Pieform $form, $values) {
return false; return false;
} }
if (isset($values['password']) && $values['password'] !== '') {
$user->password = $values['password'];
$user->salt = '';
}
$user->passwordchange = (int) ($values['passwordchange'] == 'on'); $user->passwordchange = (int) ($values['passwordchange'] == 'on');
$user->quota = $values['quota']; $user->quota = $values['quota'];
$user->expiry = db_format_timestamp($values['expiry']); $user->expiry = db_format_timestamp($values['expiry']);
...@@ -256,6 +258,23 @@ function edituser_site_submit(Pieform $form, $values) { ...@@ -256,6 +258,23 @@ function edituser_site_submit(Pieform $form, $values) {
$user->authinstance = $values['authinstance']; $user->authinstance = $values['authinstance'];
} }
} }
if (isset($values['password']) && $values['password'] !== '') {
$userobj = new User();
$userobj = $userobj->find_by_id($user->id);
$authobj = AuthFactory::create($user->authinstance);
if (method_exists($authobj, 'change_password')) {
// Only change the pw if the new auth instance allows for it
$user->password = $authobj->change_password($userobj, $values['password']);
$user->salt = $userobj->salt;
} else {
// Set empty pw with salt
$user->password = '';
$user->salt = auth_get_random_salt();
}
unset($userobj, $authobj);
}
update_record('usr', $user); update_record('usr', $user);
......
...@@ -329,6 +329,21 @@ function uploadcsv_submit(Pieform $form, $values) { ...@@ -329,6 +329,21 @@ function uploadcsv_submit(Pieform $form, $values) {
} }
} }
foreach ($addedusers as $user) {
// Add salt and encrypt the pw, if the auth instance allows for it
$userobj = new User();
$userobj = $userobj->find_by_id($user->id);
$authobj_tmp = AuthFactory::create($user->authinstance);
if (method_exists($authobj_tmp, 'change_password')) {
$authobj_tmp->change_password($userobj, $user->password);
} else {
$userobj->password = '';
$userobj->salt = auth_get_random_salt();
$userobj->commit();
}
}
unset($authobj_tmp, $userobj);
log_info('Inserted ' . count($CSVDATA) . ' records'); log_info('Inserted ' . count($CSVDATA) . ' records');
$SESSION->add_ok_msg(get_string('uploadcsvusersaddedsuccessfully', 'admin')); $SESSION->add_ok_msg(get_string('uploadcsvusersaddedsuccessfully', 'admin'));
......
...@@ -167,15 +167,6 @@ class AuthInternal extends Auth { ...@@ -167,15 +167,6 @@ class AuthInternal extends Auth {
*/ */
private function validate_password($theysent, $wehave, $salt) { private function validate_password($theysent, $wehave, $salt) {
$this->must_be_ready(); $this->must_be_ready();
if ($salt == null) {
// This allows "plaintext" passwords, which are eaiser for an admin to
// create by hacking in the database directly. The application does not
// create passwords in this form.
// We don't allow empty passwords here to prevent anyone logging in to
// user accounts that were created by some other passwordless auth
// method and subsequently changed to internal.
return $wehave != '' && $theysent == $wehave;
}
if ($salt == '*') { if ($salt == '*') {
// This is a special salt that means this user simply CAN'T log in. // This is a special salt that means this user simply CAN'T log in.
......
...@@ -1628,6 +1628,10 @@ function password_validate(Pieform $form, $values, $user) { ...@@ -1628,6 +1628,10 @@ function password_validate(Pieform $form, $values, $user) {
} }
function auth_get_random_salt() {
return substr(md5(rand(1000000, 9999999)), 2, 8);
}
class PluginAuth extends Plugin { class PluginAuth extends Plugin {
public static function get_event_subscriptions() { public static function get_event_subscriptions() {
......
...@@ -2207,5 +2207,18 @@ function xmldb_core_upgrade($oldversion=0) { ...@@ -2207,5 +2207,18 @@ function xmldb_core_upgrade($oldversion=0) {
} }
} }
if ($oldversion < 2010110800) {
// Encrypt all passwords with no set salt values
$sql = "SELECT * FROM {usr}
WHERE salt IS NULL OR salt = ''";
$passwords = get_records_sql_array($sql);
foreach ($passwords as $p) {
$p->salt = substr(md5(rand(1000000, 9999999)), 2, 8);
$p->password = sha1($p->salt . $p->password);
update_record('usr', $p);
}
}
return $status; return $status;
} }
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
defined('INTERNAL') || die(); defined('INTERNAL') || die();
$config = new StdClass; $config = new StdClass;
$config->version = 2010100702; $config->version = 2010110800;
$config->release = '1.4.0dev'; $config->release = '1.4.0dev';
$config->minupgradefrom = 2008040200; $config->minupgradefrom = 2008040200;
$config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)'; $config->minupgraderelease = '1.0.0 (release tag 1.0.0_RELEASE)';
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment