diff --git a/htdocs/admin/tools/listevents.php b/htdocs/admin/tools/listevents.php index c5e6065a86555ea1762eee13983af3d48f2fec49..02f052e83da697634da2dd4796da85f12e0cd1f5 100644 --- a/htdocs/admin/tools/listevents.php +++ b/htdocs/admin/tools/listevents.php @@ -17,9 +17,9 @@ */ /** - \file htdocs/compta/clients.php - \ingroup compta - \brief Page accueil des clients + \file htdocs/admin/tools/listevents.php + \ingroup core + \brief List of security events \version $Id$ */ @@ -58,8 +58,8 @@ llxHeader(); $userstatic=new User($db); -$sql = "SELECT e.rowid, e.type, ".$db->pdate("e.dateevent")." as dateevent,"; -$sql.= " e.fk_user, e.label, e.description,"; +$sql = "SELECT e.rowid, e.type, e.ip, ".$db->pdate("e.dateevent")." as dateevent,"; +$sql.= " e.fk_user, e.description,"; $sql.= " u.login"; $sql.= " FROM ".MAIN_DB_PREFIX."events as e"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON u.rowid = e.fk_user"; @@ -77,9 +77,10 @@ if ($result) print '<table class="liste" width="100%">'; print '<tr class="liste_titre">'; print_liste_field_titre($langs->trans("Date"),$_SERVER["PHP_SELF"],"e.dateevent","","",'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Type"),$_SERVER["PHP_SELF"],"e.type","","",'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Code"),$_SERVER["PHP_SELF"],"e.type","","",'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("IP"),$_SERVER["PHP_SELF"],"e.ip","","",'align="left"',$sortfield,$sortorder); print_liste_field_titre($langs->trans("User"),$_SERVER["PHP_SELF"],"u.login","","",'align="left"',$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Label"),$_SERVER["PHP_SELF"],"e.label","","",'align="left"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Description"),$_SERVER["PHP_SELF"],"e.description","","",'align="left"',$sortfield,$sortorder); print '<td> </td>'; print "</tr>\n"; @@ -96,10 +97,6 @@ if ($result) print '<input class="flat" type="text" size="10" name="search_compta" value="'.$_GET["search_user"].'">'; print '</td>'; - print '<td align="left" class="liste_titre">'; - print '<input class="flat" type="text" size="10" name="search_compta" value="'.$_GET["search_label"].'">'; - print '</td>'; - print '<td align="right" class="liste_titre">'; print '<input type="image" class="liste_titre" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/search.png" name="button_search" alt="'.$langs->trans("Search").'">'; print '</td>'; @@ -116,14 +113,32 @@ if ($result) $var=!$var; print "<tr $bc[$var]>"; - print '<td align="left" nowrap="nowrap">'.dolibarr_print_date($obj->dateevent,'dayhour').'</td>'; + + // Date + print '<td align="left" nowrap="nowrap">'.dolibarr_print_date($obj->dateevent,'%Y-%m-%d %H:%M:%S').'</td>'; + + // Code print '<td>'.$obj->type.'</td>'; - $userstatic->id=$obj->fk_user; - $userstatic->login=$obj->login; - print '<td>'.$userstatic->getLoginUrl(1).'</td>'; - print '<td>'.$obj->label.'</td>'; -// print '<td>'.$obj->description.'</td>'; + + // IP + print '<td>'.$obj->ip.'</td>'; + + // Login + print '<td>'; + if ($obj->fk_user) + { + $userstatic->id=$obj->fk_user; + $userstatic->login=$obj->login; + print $userstatic->getLoginUrl(1); + } + else print ' '; + print '</td>'; + + // Description + print '<td>'.$obj->description.'</td>'; + print '<td> </td>'; + print "</tr>\n"; $i++; } diff --git a/htdocs/core/events.class.php b/htdocs/core/events.class.php index c43dd7db134b87a11bfc7f83c265771aa648b943..7f35d11f66db50cacec2911eddb5ad3020a288cf 100644 --- a/htdocs/core/events.class.php +++ b/htdocs/core/events.class.php @@ -49,7 +49,6 @@ class Events // extends CommonObject var $tms; var $type; var $dateevent; - var $label; var $description; @@ -78,30 +77,28 @@ class Events // extends CommonObject // Clean parameters $this->id=trim($this->id); $this->fk_action=trim($this->fk_action); - $this->label=trim($this->label); $this->description=trim($this->description); // Check parameters - if (! $user->id) { $this->error='ErrorBadValueForParameter'; return -1; } + if (! $this->description) { $this->error='ErrorBadValueForParameter'; return -1; } // Insert request $sql = "INSERT INTO ".MAIN_DB_PREFIX."events("; $sql.= "type,"; + $sql.= "ip,"; $sql.= "dateevent,"; $sql.= "fk_user,"; - $sql.= "label,"; $sql.= "description"; $sql.= ") VALUES ("; $sql.= " '".$this->type."',"; + $sql.= " '".$_SERVER['REMOTE_ADDR']."',"; $sql.= " ".$this->db->idate($this->dateevent).","; - $sql.= " '".$user->id."',"; - $sql.= " '".$this->label."',"; + $sql.= " ".($user->id?"'".$user->id."'":'NULL').","; $sql.= " '".$this->description."'"; - $sql.= ")"; dolibarr_syslog("Events::create sql=".$sql, LOG_DEBUG); @@ -134,7 +131,6 @@ class Events // extends CommonObject $this->id=trim($this->id); $this->type=trim($this->type); - $this->label=trim($this->label); $this->description=trim($this->description); @@ -147,7 +143,6 @@ class Events // extends CommonObject $sql.= " type='".$this->type."',"; $sql.= " dateevent=".$this->db->idate($this->dateevent).","; - $sql.= " label='".addslashes($this->label)."',"; $sql.= " description='".addslashes($this->description)."'"; $sql.= " WHERE rowid=".$this->id; @@ -180,7 +175,6 @@ class Events // extends CommonObject $sql.= " ".$this->db->pdate('t.tms').","; $sql.= " t.type,"; $sql.= " ".$this->db->pdate('t.dateevent').","; - $sql.= " t.label,"; $sql.= " t.description"; @@ -200,7 +194,6 @@ class Events // extends CommonObject $this->tms = $obj->tms; $this->type = $obj->type; $this->dateevent = $obj->dateevent; - $this->label = $obj->label; $this->description = $obj->description; @@ -254,7 +247,6 @@ class Events // extends CommonObject $this->tms=time(); $this->type=''; $this->dateevent=time(); - $this->label='Speciment event'; $this->description='This is a specimen event'; } diff --git a/htdocs/includes/login/functions_dolibarr.php b/htdocs/includes/login/functions_dolibarr.php index 91b6a1ebe92d52c89d9edf5c8dcb1f04b3c8e5ec..aa56cf80aab0a19d0e66fa780d5633b8aeeaf4d0 100644 --- a/htdocs/includes/login/functions_dolibarr.php +++ b/htdocs/includes/login/functions_dolibarr.php @@ -1,5 +1,5 @@ <?php -/* Copyright (C) 2007 Laurent Destailleur <eldy@users.sourceforge.net> +/* Copyright (C) 2007-2008 Laurent Destailleur <eldy@users.sourceforge.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,14 +14,13 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * $Id$ */ /** \file htdocs/includes/login/functions_dolibarr.php \ingroup core \brief Authentication functions for Dolibarr mode + \version $Id$ */ diff --git a/htdocs/includes/triggers/interface_all_Logevents.class.php b/htdocs/includes/triggers/interface_all_Logevents.class.php index 5055183156777cb00da0d57005ec034bb3f690ed..d2b107bc9e8b107540670438f3d612c761bc2197 100644 --- a/htdocs/includes/triggers/interface_all_Logevents.class.php +++ b/htdocs/includes/triggers/interface_all_Logevents.class.php @@ -49,7 +49,7 @@ class InterfaceLogevents $this->name = "Logevents"; $this->family = "core"; - $this->description = "Les triggers de ce composant permettent de logguer les evenements Dolibarr (modification status des objets)."; + $this->description = "Les triggers de ce composant permettent de logguer les evenements de securite Dolibarr."; $this->version = 'dolibarr'; // 'experimental' or 'dolibarr' or version } @@ -116,6 +116,17 @@ class InterfaceLogevents $this->texte=$langs->transnoentities("UserLogged",$object->login); $this->desc=$langs->transnoentities("UserLogged",$object->login); } + if ($action == 'USER_LOGIN_FAILED') + { + dolibarr_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + $langs->load("users"); + + // Initialisation donnees (date,duree,texte,desc) + $this->date=time(); + $this->duree=0; + $this->texte=$object->trigger_mesg; // Message direct + $this->desc=$object->trigger_mesg; // Message direct + } if ($action == 'USER_CREATE') { dolibarr_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -496,10 +507,10 @@ class InterfaceLogevents } else { - $error ="Failed to insert : ".$webcal->error." "; + $error ="Failed to insert security event: ".$event->error; $this->error=$error; - //dolibarr_syslog("interface_webcal.class.php: ".$this->error); + dolibarr_syslog("interface_all_Logevents.class.php: ".$this->error); return -1; } } diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 2c886e701bcb8d6d5080ac3b75e5cdd871d175bf..6bffe53c02b0f1863d41f726140f41addd02c8b0 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -111,7 +111,6 @@ if ($conf->main_force_https) } // Chargement des includes complementaire de presentation - if (! defined('NOREQUIREMENU')) require_once(DOL_DOCUMENT_ROOT ."/menu.class.php"); // Need 11ko memory (11ko in 2.2) if (! defined('NOREQUIREHTML')) require_once(DOL_DOCUMENT_ROOT ."/html.form.class.php"); // Need 690ko memory (800ko in 2.2) if (! defined('NOREQUIREAJAX') && $conf->use_javascript_ajax) require_once(DOL_DOCUMENT_ROOT.'/lib/ajax.lib.php'); // Need 20ko memory @@ -123,9 +122,6 @@ session_name($sessionname); session_start(); dolibarr_syslog("Session name=".$sessionname." Session id()=".session_id().", _SESSION['dol_login']=".$_SESSION["dol_login"]); -$bc[0]="class=\"impair\""; -$bc[1]="class=\"pair\""; - /* * Phase identification */ @@ -177,40 +173,70 @@ if (! isset($_SESSION["dol_login"])) dolibarr_syslog('Bad value for code, connexion refused'); $langs->load('main'); $langs->load('other'); + + $user->trigger_mesg='ErrorBadValueForCode - login='.$_POST["username"]; $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadValueForCode"); $test=false; + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf); + if ($result < 0) { $error++; } + // Fin appel triggers } } // Tests de validation user/mot de passe // Si ok, la variable login doit avoir ete initialisee // Si erreur, on a place message erreur dans session sous le nom dol_loginmesg - foreach($authmode as $mode) + if ($test) { - if ($test && $mode && ! $login) + foreach($authmode as $mode) { - $authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php'; - $result=include_once($authfile); - if ($result) - { - // Call function to check user/password - $usertotest=$_POST["username"]; - $passwordtotest=$_POST["password"]; - $function='check_user_password_'.$mode; - $login=$function($usertotest,$passwordtotest); - if ($login) $test=false; - } - else + if ($test && $mode && ! $login) { - dolibarr_syslog("Authentification ko - failed to load file '".$authfile."'"); - sleep(1); - $langs->load('main'); - $langs->load('other'); - $_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode); + $authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php'; + $result=include_once($authfile); + if ($result) + { + // Call function to check user/password + $usertotest=$_POST["username"]; + $passwordtotest=$_POST["password"]; + $function='check_user_password_'.$mode; + $login=$function($usertotest,$passwordtotest); + if ($login) $test=false; + } + else + { + dolibarr_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR); + sleep(1); + $langs->load('main'); + $langs->load('other'); + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode); + } } } - } + if (! $login) + { + dolibarr_syslog('Bad password, connexion refused',LOG_DEBUG); + $langs->load('main'); + $langs->load('other'); + + // Bad password. No authmode has found a good password. + $user->trigger_mesg=$langs->trans("ErrorBadLoginPassword").' - login='.$_POST["username"]; + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorBadLoginPassword"); + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf); + if ($result < 0) { $error++; } + // Fin appel triggers + } + } + // Fin des tests de login/passwords if (! $login) { @@ -228,8 +254,27 @@ if (! isset($_SESSION["dol_login"])) session_start(); $langs->load('main'); - if ($resultFetchUser == 0) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login); - if ($resultFetchUser < 0) $_SESSION["dol_loginmesg"]=$user->error; + if ($resultFetchUser == 0) + { + $langs->load('main'); + $langs->load('other'); + + $user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login; + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login); + } + if ($resultFetchUser < 0) + { + $user->trigger_mesg=$user->error; + $_SESSION["dol_loginmesg"]=$user->error; + } + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf); + if ($result < 0) { $error++; } + // Fin appel triggers + header('Location: '.DOL_URL_ROOT.'/index.php'); exit; } @@ -250,8 +295,27 @@ else session_start(); $langs->load('main'); - if ($resultFetchUser == 0) $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login); - if ($resultFetchUser < 0) $_SESSION["dol_loginmesg"]=$user->error; + if ($resultFetchUser == 0) + { + $langs->load('main'); + $langs->load('other'); + + $user->trigger_mesg='ErrorCantLoadUserFromDolibarrDatabase - login='.$login; + $_SESSION["dol_loginmesg"]=$langs->trans("ErrorCantLoadUserFromDolibarrDatabase",$login); + } + if ($resultFetchUser < 0) + { + $user->trigger_mesg=$user->error; + $_SESSION["dol_loginmesg"]=$user->error; + } + + // Appel des triggers + include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); + $interface=new Interfaces($db); + $result=$interface->run_triggers('USER_LOGIN_FAILED',$user,$user,$langs,$conf); + if ($result < 0) { $error++; } + // Fin appel triggers + header('Location: '.DOL_URL_ROOT.'/index.php'); exit; } @@ -273,13 +337,15 @@ if (! isset($_SESSION["dol_login"])) include_once(DOL_DOCUMENT_ROOT . "/interfaces.class.php"); $interface=new Interfaces($db); $result=$interface->run_triggers('USER_LOGIN',$user,$user,$langs,$conf); - if ($result < 0) { $error++; $this->errors=$interface->errors; } + if ($result < 0) { $error++; } // Fin appel triggers if ($error) { - dolibarr_print_errors($db,$this->errors); $db->rollback(); + session_destroy(); + dolibarr_print_error($db,'Error in some triggers on action USER_LOGIN',LOG_ERR); + exit; } else { diff --git a/mysql/migration/2.2.0-2.4.0.sql b/mysql/migration/2.2.0-2.4.0.sql index 8facc488e1b5c9da945a5c940bae6eb5419dd4a0..ac40c7d5bb5d1ad179e24507becb265ffb3b1ae4 100644 --- a/mysql/migration/2.2.0-2.4.0.sql +++ b/mysql/migration/2.2.0-2.4.0.sql @@ -192,8 +192,8 @@ create table llx_events type varchar(32) NOT NULL, dateevent datetime, fk_user integer, - label varchar(50) NOT NULL, - description varchar(200) NOT NULL, + description varchar(250) NOT NULL, + ip varchar(32) NOT NULL, fk_object integer ) type=innodb; diff --git a/mysql/tables/llx_events.sql b/mysql/tables/llx_events.sql index 48d59f5827a4dbbd46e67d08136e4feae2782368..2798cb356f59d18b98d7a90dedc8bdb0c896f708 100644 --- a/mysql/tables/llx_events.sql +++ b/mysql/tables/llx_events.sql @@ -17,8 +17,9 @@ -- -- $Id$ -- ======================================================================== --- This table logs all dolibarr events --- Content of this table is not managed by users but by Dolibarr triggers. +-- This table logs all dolibarr security events +-- Content of this table is not managed by users but by Dolibarr +-- trigger interface_all_LogEvent. -- ======================================================================== create table llx_events @@ -28,8 +29,8 @@ create table llx_events type varchar(32) NOT NULL, -- action type dateevent datetime, -- date event fk_user integer, -- id user - label varchar(50) NOT NULL, -- label of action - description varchar(200) NOT NULL, -- full description of action + description varchar(250) NOT NULL, -- full description of action + ip varchar(32) NOT NULL, -- ip fk_object integer -- id of related object ) type=innodb;