mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-02-21 21:02:02 +01:00
* Mail: automatic migrate old mcrypt tripledes passwords to openssl AES on successful login
This commit is contained in:
parent
ea200604fb
commit
26ccede602
@ -235,6 +235,13 @@ class Account implements \ArrayAccess
|
||||
'accountStatus', 'deliveryMode', 'quotaLimit', 'quotaUsed',
|
||||
);
|
||||
|
||||
/**
|
||||
* Callable to run on successful login to eg. run Credentials::migrate
|
||||
*
|
||||
* @var array with callable and further arguments
|
||||
*/
|
||||
protected $on_login;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -248,7 +255,7 @@ class Account implements \ArrayAccess
|
||||
/*protected*/ function __construct(array $params, $called_for=null)
|
||||
{
|
||||
// read credentials from database
|
||||
$params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for);
|
||||
$params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for, $this->on_login);
|
||||
|
||||
if (!isset($params['notify_folders']))
|
||||
{
|
||||
@ -365,6 +372,14 @@ class Account implements \ArrayAccess
|
||||
|
||||
$class = $this->params['acc_imap_type'];
|
||||
$this->imapServer = new $class($this->params, $_adminConnection, $_timeout);
|
||||
|
||||
// if Credentials class told us to run something on successful login, tell it to Imap class
|
||||
if ($this->on_login)
|
||||
{
|
||||
$func = array_shift($this->on_login);
|
||||
$this->imapServer->runOnLogin($func, $this->on_login);
|
||||
unset($this->on_login);
|
||||
}
|
||||
}
|
||||
return $this->imapServer;
|
||||
}
|
||||
|
@ -144,9 +144,11 @@ class Credentials
|
||||
* @param int $acc_id
|
||||
* @param int $type =null default return all credentials
|
||||
* @param int|array $account_id =null default use current user or all (in that order)
|
||||
* @param array& $on_login =null on return array with callable and further arguments
|
||||
* to run on successful login to trigger password migration
|
||||
* @return array with values for (imap|smtp|admin)_(username|password|cred_id)
|
||||
*/
|
||||
public static function read($acc_id, $type=null, $account_id=null)
|
||||
public static function read($acc_id, $type=null, $account_id=null, &$on_login=null)
|
||||
{
|
||||
if (is_null($type)) $type = self::ALL;
|
||||
if (is_null($account_id))
|
||||
@ -176,6 +178,7 @@ class Credentials
|
||||
$rows = call_user_func_array('array_merge', $rows);
|
||||
//error_log(__METHOD__."($acc_id, $type, ".array2string($account_id).") read from cache ".array2string($rows));
|
||||
}
|
||||
$on_login = null;
|
||||
$results = array();
|
||||
foreach($rows as $row)
|
||||
{
|
||||
@ -184,6 +187,11 @@ class Credentials
|
||||
{
|
||||
self::$cache[$acc_id][$row['account_id']][$row['cred_type']] = $row;
|
||||
//error_log(__METHOD__."($acc_id, $type, ".array2string($account_id).") stored to cache ".array2string($row));
|
||||
|
||||
if (!isset($on_login) && self::needMigration($row['cred_pw_enc']))
|
||||
{
|
||||
$on_login = array(__CLASS__.'::migrate', $acc_id);
|
||||
}
|
||||
}
|
||||
$password = self::decrypt($row);
|
||||
|
||||
@ -632,6 +640,43 @@ class Credentials
|
||||
self::AES_METHOD, $aes_key, OPENSSL_RAW_DATA, $salt), "\0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if credentials need migration to AES
|
||||
*
|
||||
* @param string $pw_enc
|
||||
* @return boolean
|
||||
*/
|
||||
static public function needMigration($pw_enc)
|
||||
{
|
||||
return $pw_enc == self::USER || $pw_enc == self::SYSTEM || $pw_enc == self::CLEARTEXT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run password migration for credentials of given account
|
||||
*
|
||||
* @param int $acc_id
|
||||
*/
|
||||
static function migrate($acc_id)
|
||||
{
|
||||
try {
|
||||
foreach((array)self::$cache[$acc_id] as $account_id => &$rows)
|
||||
{
|
||||
foreach($rows as $cred_type => &$row)
|
||||
{
|
||||
if (self::needMigration($row['cred_pw_enc']) && ($row['cred_pw_enc'] != self::USER ||
|
||||
$row['cred_pw_enc'] == self::USER && $account_id == $GLOBALS['egw_info']['user']['account_id']))
|
||||
{
|
||||
self::write($acc_id, $row['cred_username'], self::decrypt($row), $cred_type, $account_id, $row['cred_id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e) {
|
||||
// do not stall regular use, if password migration fails
|
||||
_egw_log_exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook called when user changes his password, to re-encode his credentials with his new password
|
||||
*
|
||||
|
@ -238,6 +238,41 @@ class Imap extends Horde_Imap_Client_Socket implements Imap\Iface
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Methods to run on successful login
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $run_on_login=array();
|
||||
|
||||
/**
|
||||
* Run given function on successful login
|
||||
*
|
||||
* @param callable $func
|
||||
* @param array $params =array()
|
||||
*/
|
||||
public function runOnLogin($func, array $params=array())
|
||||
{
|
||||
$this->run_on_login[] = array($func, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to the IMAP server.
|
||||
*
|
||||
* @throws Horde_Imap_Client_Exception
|
||||
*/
|
||||
public function login()
|
||||
{
|
||||
parent::login();
|
||||
|
||||
foreach($this->run_on_login as $key => $data)
|
||||
{
|
||||
call_user_func_array($data[0], $data[1]);
|
||||
|
||||
unset($this->run_on_login[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow read access to former public attributes
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user