From c8149606847de40da48f77df36364a38321dbd19 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 27 Jan 2017 14:27:58 +0100 Subject: [PATCH] * Admin: fix bulk password reset to pick only passwords having required strength --- admin/inc/class.admin_passwordreset.inc.php | 23 +++++++++++++++++---- api/src/Auth.php | 23 +++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/admin/inc/class.admin_passwordreset.inc.php b/admin/inc/class.admin_passwordreset.inc.php index 73ac36e5d2..e0343d1bfb 100644 --- a/admin/inc/class.admin_passwordreset.inc.php +++ b/admin/inc/class.admin_passwordreset.inc.php @@ -115,7 +115,16 @@ class admin_passwordreset //_debug_array($account); //break; if ($content['random_pw']) { - $password = Api\Auth::randomstring(8); + if (($minlength=$GLOBALS['egw_info']['server']['force_pwd_length']) < 8) + { + $minlength = 8; + } + $n = 0; + do { + $password = Api\Auth::randomstring($minlength, + $GLOBALS['egw_info']['server']['force_pwd_strength'] >= 4); + error_log(__METHOD__."() minlength=$minlength, n=$n, password=$password"); + } while (++$n < 100 && Api\Auth::crackcheck($password, null, null, null, $account)); $old_password = null; } elseif ($change_pw && !preg_match('/^{plain}/i',$account['account_pwd']) && @@ -129,9 +138,15 @@ class admin_passwordreset $old_password = $password = preg_replace('/^{plain}/i','',$account['account_pwd']); } // change password, if requested - if ($change_pw && !$GLOBALS['egw']->auth->change_password($old_password,$password,$account_id)) - { - $msg .= lang('Failed to change password for account "%1"!',$account['account_lid'])."\n"; + try { + if ($change_pw && !$GLOBALS['egw']->auth->change_password($old_password,$password,$account_id)) + { + $msg .= lang('Failed to change password for account "%1"!',$account['account_lid'])."\n"; + continue; + } + } + catch(Exception $e) { + $msg .= lang('Failed to change password for account "%1"!',$account['account_lid']).' '.$e->getMessage()."\n"; continue; } // force password change on next login diff --git a/api/src/Auth.php b/api/src/Auth.php index 2ecb5a5fd6..1610549002 100644 --- a/api/src/Auth.php +++ b/api/src/Auth.php @@ -45,6 +45,11 @@ class Auth */ private $backend; + /** + * Specialchars as considered by crackcheck method + */ + const SPECIALCHARS = '~!@#$%^&*_-+=`|\(){}[]:;"\'<>,.?/'; + /** * Constructor * @@ -272,19 +277,25 @@ class Auth * * @param $size int-size of random string to return */ - static function randomstring($size) + static function randomstring($size, $use_specialchars=false) { - static $random_char = array( + $random_char = array( '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L', 'M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' ); - $s = ''; - for ($i=0; $i<$size; $i++) + // we need special chars + if ($use_specialchars) { - $s .= $random_char[mt_rand(1,61)]; + $random_char = array_merge($random_char, str_split(str_replace('\\', '', self::SPECIALCHARS)), $random_char); + } + + $s = ''; + for ($i=0; $i < $size; $i++) + { + $s .= $random_char[mt_rand(0, count($random_char)-1)]; } return $s; } @@ -680,7 +691,7 @@ class Auth { $missing[] = lang('lowercase letters'); } - if (!preg_match('/['.preg_quote('~!@#$%^&*_-+=`|\(){}[]:;"\'<>,.?/', '/').']/', $passwd)) + if (!preg_match('/['.preg_quote(self::SPECIALCHARS, '/').']/', $passwd)) { $missing[] = lang('special characters'); }