From e6ad65387e774d7146662f686cf567da1ef7bf92 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Sat, 7 May 2016 16:55:15 +0000 Subject: [PATCH] mask out passwords in admin queue --- admin/inc/class.admin_cmd.inc.php | 40 ++++++++++++++++++++++++++++++- admin/setup/setup.inc.php | 2 +- admin/setup/tables_update.inc.php | 27 +++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/admin/inc/class.admin_cmd.inc.php b/admin/inc/class.admin_cmd.inc.php index 4d4544baa4..8331c05599 100644 --- a/admin/inc/class.admin_cmd.inc.php +++ b/admin/inc/class.admin_cmd.inc.php @@ -25,6 +25,13 @@ abstract class admin_cmd const pending = 4; const queued = 5; // command waits to be fetched from remote + /** + * Status which stil need passwords available + * + * @var array + */ + static $require_pw_stati = array(self::scheduled,self::pending,self::queued); + /** * The status of the command, one of either scheduled, successful, failed or deleted * @@ -309,7 +316,10 @@ abstract class admin_cmd $vars[$name] = $this->$name; } } - $vars['data'] = json_encode($this->data); // data is stored serialized + // data is stored serialized + // paswords are masked / removed, if we dont need them anymore + $vars['data'] = in_array($this->status, self::$require_pw_stati) ? + json_encode($this->data) : self::mask_passwords($this->data); admin_cmd::$sql->init($vars); if (admin_cmd::$sql->save() != 0) @@ -334,6 +344,33 @@ abstract class admin_cmd return true; } + /** + * Mask / remove passwords in $data + * + * @param string|array $data json or php-encoded string or array + * @param boolean $return_serialized =true true: return json serialized string, false: return array + * @return string|array see $return_serialized + */ + static function mask_passwords($data, $return_serialized=true) + { + if (!is_array($data)) + { + $data = json_php_unserialize($data); + } + foreach($data as $key => &$value) + { + if (is_array($value)) + { + $value = self::mask_passwords($value, false); + } + elseif (preg_match('/(pw|passwd_?\d*|(? admin_cmd::failed, 'error' => lang('Unknown command %1!',$job['type']), 'errno' => 0, + 'data' => self::mask_passwords($job['data']), )); } } diff --git a/admin/setup/setup.inc.php b/admin/setup/setup.inc.php index 5ab254d4c9..58105aff54 100755 --- a/admin/setup/setup.inc.php +++ b/admin/setup/setup.inc.php @@ -10,7 +10,7 @@ */ $setup_info['admin']['name'] = 'admin'; -$setup_info['admin']['version'] = '14.3'; +$setup_info['admin']['version'] = '16.1'; $setup_info['admin']['app_order'] = 1; $setup_info['admin']['tables'] = array('egw_admin_queue','egw_admin_remote'); $setup_info['admin']['enable'] = 1; diff --git a/admin/setup/tables_update.inc.php b/admin/setup/tables_update.inc.php index c8134632c7..b9265d8c59 100644 --- a/admin/setup/tables_update.inc.php +++ b/admin/setup/tables_update.inc.php @@ -151,3 +151,30 @@ function admin_upgrade14_2_001() return $GLOBALS['setup_info']['admin']['currentver'] = '14.3'; } +/** + * Remove cleartext passwords from egw_admin_queue + * + * @return string + */ +function admin_upgrade14_3() +{ + // asuming everythings not MySQL uses PostgreSQL regular expression syntax + $regexp = substr($GLOBALS['egw_setup']->db->Type, 0, 5) == 'mysql' ? 'REGEXP' : '~*'; + + foreach($GLOBALS['egw_setup']->db->select('egw_admin_queue', 'cmd_id,cmd_data', + 'cmd_status NOT IN ('.implode(',', admin_cmd::$require_pw_stati).") AND cmd_data $regexp '(pw|passwd\\_?\\d*|password|db\\_pass)\\?\"'", + __LINE__, __FILE__, false, '', 'admin') as $row) + { + if (($masked = admin_cmd::mask_passwords($row['cmd_data'])) != $row['cmd']) + { + $GLOBALS['egw_setup']->db->update('egw_admin_queue', array('cmd_data' => $masked), + array('cmd_id' => $row['cmd_id']), __LINE__, __FILE__, 'admin'); + } + } + return $GLOBALS['setup_info']['admin']['currentver'] = '14.3.001'; +} + +function admin_upgrade14_3_001() +{ + return $GLOBALS['setup_info']['admin']['currentver'] = '16.1'; +} \ No newline at end of file