From 4c9a9f1a745fffd75760eeef73089b77ed76bada Mon Sep 17 00:00:00 2001 From: Dany wm De Bontridder Date: Wed, 11 Nov 2020 18:08:03 +0100 Subject: [PATCH] Security administration : add a confirmation with generate random string and record it in audit --- include/ajax/ajax_admin.php | 4 +-- include/class/user.class.php | 38 ++++++++++++++++++----- include/constant.php | 2 +- include/dossier.inc.php | 13 +++++--- include/lib/ac_common.php | 32 ++++++++++++++++++++ include/sql/patch/ac-upgrade19.sql | 7 +++++ include/user.inc.php | 2 ++ include/user_detail.inc.php | 48 ++++++++++++++++++++++++++---- 8 files changed, 127 insertions(+), 19 deletions(-) create mode 100644 include/sql/patch/ac-upgrade19.sql diff --git a/include/ajax/ajax_admin.php b/include/ajax/ajax_admin.php index 1d38c98c4..6e958fea3 100644 --- a/include/ajax/ajax_admin.php +++ b/include/ajax/ajax_admin.php @@ -261,8 +261,8 @@ if (in_array($op, array('modele_drop', 'modele_modify', 'folder_modify', 'folder $confirm=new ICheckBox(); $confirm->name="p_confirm"; echo '

'; - echo _('Cochez la case si vous êtes sûr de vouloir effacer ce dossier'); - echo $confirm->input(); + echo _("Tapez le code de confirmation"); + echo confirm_with_string("fld_drop",5); echo '

'; echo '

'; echo HtmlInput::submit('remove', _('Effacer')); diff --git a/include/class/user.class.php b/include/class/user.class.php index 6d43289b6..7ea928d27 100644 --- a/include/class/user.class.php +++ b/include/class/user.class.php @@ -1085,6 +1085,21 @@ class User return $array; } + /** + * Audit action from the administration menu + * @param $p_module description of the action + */ + static function audit_admin($p_module) { + $cn = new Database(); + $sql = "insert into audit_connect (ac_user,ac_ip,ac_module,ac_url,ac_state) values ($1,$2,$3,$4,$5)"; + + $cn->exec_sql($sql, array( + $_SESSION['g_user'], + $_SERVER["REMOTE_ADDR"], + $p_module, + $_SERVER['REQUEST_URI'], + 'ADMIN')); + } function audit($action = 'AUDIT', $p_module = "") { global $audit; @@ -1364,19 +1379,28 @@ class User static function remove_inexistant_user($p_dossier) { $cnx_repo=new Database(); + $name=$cnx_repo->format_name($p_dossier,'dos'); + if ($cnx_repo->exist_database($name) == 0 )return; $cnx_dossier=new Database($p_dossier); - - $a_user=$cnx_dossier->get_array('select user_name from profile_user'); + if ($cnx_dossier->exist_table('profile_user')) + $a_user=$cnx_dossier->get_array('select user_name from profile_user'); + else + return; + if ( ! $a_user ) return; $nb=count($a_user); for ($i=0;$i < $nb;$i++) { if ( $cnx_repo->get_value('select count(*) from ac_users where use_login=$1', array($a_user[$i]['user_name'])) == 0) { - $cnx_dossier->exec_sql("delete from user_sec_jrn where uj_login=$1",array($a_user[$i]['user_name'])); - $cnx_dossier->exec_sql("delete from profile_user where user_name=$1",array($a_user[$i]['user_name'])); - $cnx_dossier->exec_sql("delete from user_sec_act where ua_login=$1",array($a_user[$i]['user_name'])); - $cnx_dossier->exec_sql("delete from user_sec_jrn where uj_login=$1",array($a_user[$i]['user_name'])); - $cnx_dossier->exec_sql("delete from user_active_security where us_login=$1",array($a_user[$i]['user_name'])); + if ($cnx_dossier->exist_table('user_sec_jrn')) + $cnx_dossier->exec_sql("delete from user_sec_jrn where uj_login=$1",array($a_user[$i]['user_name'])); + $cnx_dossier->exec_sql("delete from profile_user where user_name=$1",array($a_user[$i]['user_name'])); + if ($cnx_dossier->exist_table('user_sec_act')) + $cnx_dossier->exec_sql("delete from user_sec_act where ua_login=$1",array($a_user[$i]['user_name'])); + if ($cnx_dossier->exist_table('user_sec_jrn')) + $cnx_dossier->exec_sql("delete from user_sec_jrn where uj_login=$1",array($a_user[$i]['user_name'])); + if ($cnx_dossier->exist_table('user_active_security')) + $cnx_dossier->exec_sql("delete from user_active_security where us_login=$1",array($a_user[$i]['user_name'])); } } } diff --git a/include/constant.php b/include/constant.php index 92046e50d..5aa3a4da6 100644 --- a/include/constant.php +++ b/include/constant.php @@ -109,7 +109,7 @@ if ( ! defined ("SYSINFO_DISPLAY")) { } define ("DBVERSION",151); define ("MONO_DATABASE",25); -define ("DBVERSIONREPO",18); +define ("DBVERSIONREPO",19); define ('NOTFOUND','--not found--'); define ("MAX_COMPTE",4); define ('MAX_ARTICLE',5); diff --git a/include/dossier.inc.php b/include/dossier.inc.php index 25d865934..1ff726bdb 100644 --- a/include/dossier.inc.php +++ b/include/dossier.inc.php @@ -105,6 +105,8 @@ if ( isset ($_POST["DATABASE"]) ) values ($1,$2,$3)",array($dos,$desc,$max_email)); $l_id=$repo->get_current_seq('dossier_id'); $repo->commit(); + + } catch (Exception $e) { @@ -181,7 +183,7 @@ if ( isset ($_POST["DATABASE"]) ) Dossier::synchro_admin($l_id); User::remove_inexistant_user($l_id); - + User::audit_admin(sprintf('CREATE DATABASE %s %s',$l_id,$dos)); } } @@ -204,6 +206,7 @@ if ( isset ($_POST["DATABASE"]) ) echo _("Echec création "); exit; } + User::audit_admin(sprintf('CREATE DATABASE %s %s',$l_id,$dos)); ob_flush(); } @@ -376,10 +379,11 @@ if ( $sa == 'list' ) //--------------------------------------------------------------------------- if ( $sa == 'remove' && isNumber($dossier_id) == 1 && $dossier_id != -1 ) { - - if ( ! isset ($_REQUEST['p_confirm'])) + $ctl=$http->request("fld_drop"); + $ctl_code=$http->request("ctlcode"); + if ( $ctl != $ctl_code) { - echo _('Désolé, vous n\'avez pas coché la case'); + echo _('Désolé, le code est invalide'); echo HtmlInput::button_anchor(_('Retour'),'?action=dossier_mgt'); return; } @@ -423,6 +427,7 @@ if ( $sa == 'remove' && isNumber($dossier_id) == 1 && $dossier_id != -1 ) $cn->exec_sql($sql,array($dossier_id)); print '

'; printf (_("Le dossier %s est effacé").'

',h($name)); + User::audit_admin(sprintf('DROP DATABASE %s %s',$dossier_id,$name)); echo HtmlInput::button_anchor(_('Retour'),'?action=dossier_mgt'); } ?> diff --git a/include/lib/ac_common.php b/include/lib/ac_common.php index ff0f1e8f2..c6c30e7d1 100644 --- a/include/lib/ac_common.php +++ b/include/lib/ac_common.php @@ -1392,3 +1392,35 @@ function remove_divide_zero($p_formula) return $p_formula; } +/** + * Create randomly a string + * @param int $p_length length of the generate string + */ +function generate_random_string($car) +{ + $string=""; + $chaine="abcdefghijklmnpqrstuvwxyABCDEFGHIJKLMNPQRSTUVWXY0123456789*/+-=<>"; + srand((double) microtime()*1020030); + for ($i=0; $i<$car; $i++) + { + $string .= $chaine[rand()%strlen($chaine)]; + } + return $string; +} + +/** + * generate a string of p_car character and a input text with name p_ctl_name + * work like a kind of captcha.The control code for checking is ctlcode. + * You compare the content of the variable p_ctl_name with ctlcode + * @param $p_ctl_name + * @param $p_car + */ +function confirm_with_string($p_ctl_name,$p_car) +{ + $code=generate_random_string($p_car ); + $r = HtmlInput::hidden("ctlcode",$code); + $r.=''. $code.''; + $ctl=new IText($p_ctl_name); + $r.=$ctl->input(); + return $r; +} diff --git a/include/sql/patch/ac-upgrade19.sql b/include/sql/patch/ac-upgrade19.sql new file mode 100644 index 000000000..6fe6bb07c --- /dev/null +++ b/include/sql/patch/ac-upgrade19.sql @@ -0,0 +1,7 @@ +begin; + +ALTER TABLE public.audit_connect DROP CONSTRAINT valid_state ; +ALTER TABLE public.audit_connect ADD CONSTRAINT valid_state CHECK ( ac_state in ('FAIL','SUCCESS','AUDIT','ADMIN')); + +select upgrade_repo(19); +commit; \ No newline at end of file diff --git a/include/user.inc.php b/include/user.inc.php index 3148f2f55..f3248a659 100644 --- a/include/user.inc.php +++ b/include/user.inc.php @@ -57,6 +57,8 @@ if ( isset ($_POST["ADD"]) ) $new_user->insert(); $new_user->load(); $_REQUEST['use_id']=$new_user->id; + User::audit_admin(sprintf('ADD USER %s %s',$new_user->id,$login)); + require_once NOALYSS_INCLUDE.'/user_detail.inc.php'; return; diff --git a/include/user_detail.inc.php b/include/user_detail.inc.php index 8740238c8..c0c72bdb3 100644 --- a/include/user_detail.inc.php +++ b/include/user_detail.inc.php @@ -87,7 +87,16 @@ else if ($sbaction == "delete") // // Delete the user // + // check that the control is correct + $code=$http->post("userdel"); + $ctl_code=$http->post('ctlcode'); + if ( $code != $ctl_code) { + echo _("Code invalide, effacement refusé"); + return; + } $cn = new Database(); + $auser=$cn->get_row('select use_login from ac_users where use_id = $1',[$uid]); + if ( $auser == null) return; $Res = $cn->exec_sql("delete from jnt_use_dos where use_id=$1", array($uid)); $Res = $cn->exec_sql("delete from ac_users where use_id=$1", array($uid)); //------------------------------------ @@ -99,8 +108,10 @@ else if ($sbaction == "delete") for ( $i=0;$i<$nb;$i++) User::remove_inexistant_user($a_dossier[$i]['dos_id']); } - - echo "

Utilisateur " . h($_POST['fname']) . " " . h($_POST['lname']) . " est effacé

"; + User::audit_admin(sprintf('DELETE USER %s %s',$uid,$auser['use_login'])); + echo "

"; + printf (_("Utilisateur %s %s est effacé"),$http->post('fname'),$http->post('lname')) ; + echo "

"; require_once NOALYSS_INCLUDE.'/lib/iselect.class.php'; require_once NOALYSS_INCLUDE.'/user.inc.php'; return; @@ -180,12 +191,39 @@ $it_pass->value=""; - - - + + + + + + + admin == 0 ) : ?>