Sec: Fix security login mutualized function.

This commit is contained in:
Laurent Destailleur 2011-09-23 11:46:16 +00:00
parent e7565a265f
commit 540ccab025
5 changed files with 145 additions and 106 deletions

View File

@ -30,10 +30,10 @@ class Auth
var $reponse;
var $sqlQuery;
/**
* Enter description here ...
*
*
* @param unknown_type $DB
*/
function Auth($DB)
@ -46,7 +46,7 @@ class Auth
/**
* Enter description here ...
*
*
* @param unknown_type $aLogin
*/
function login($aLogin)
@ -55,10 +55,10 @@ class Auth
$this->login = $aLogin;
}
/**
* Enter description here ...
*
*
* @param unknown_type $aPasswd
*/
function passwd($aPasswd)
@ -68,10 +68,10 @@ class Auth
}
/**
* Enter description here ...
*
*
* @param unknown_type $aReponse
*/
function reponse($aReponse)
@ -82,24 +82,26 @@ class Auth
}
/**
* Enter description here ...
*
* @param unknown_type $aLogin
* @param unknown_type $aPasswd
* Validate login/pass
*
* @param string $aLogin Login
* @param string $aPasswd Password
*/
function verif($aLogin, $aPasswd)
{
global $conf,$dolibarr_main_authentication,$langs;
global $conf,$langs;
global $dolibarr_main_authentication,$dolibarr_auto_user;
$ret=-1;
$login='';
$test=true;
// Authentication mode
if (empty($dolibarr_main_authentication)) $dolibarr_main_authentication='http,dolibarr';
// Authentication mode: forceuser
if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) $dolibarr_auto_user='auto';
// Set authmode
$authmode=explode(',',$dolibarr_main_authentication);
@ -111,16 +113,9 @@ class Auth
exit;
}
$test=true;
// Validation of third party module login method
if (is_array($conf->login_method_modules) && !empty($conf->login_method_modules))
{
include_once(DOL_DOCUMENT_ROOT . "/lib/security.lib.php");
$login = getLoginMethod($_POST["username"],$_POST["password"],$_POST["entity"]);
if ($login) $test=false;
}
$usertotest=$aLogin;
$passwordtotest=$aPasswd;
$entitytotest=$conf->entity;
// Validation tests user / password
// If ok, the variable will be initialized login
@ -131,34 +126,16 @@ class Auth
if ($test && $goontestloop)
{
foreach($authmode as $mode)
$login = checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmode);
if ($login)
{
if ($test && $mode && ! $login)
{
$authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php';
$result=include_once($authfile);
if ($result)
{
$this->login($aLogin);
$this->passwd($aPasswd);
$entitytotest=$conf->entity;
$function='check_user_password_'.$mode;
$login=$function($aLogin,$aPasswd,$entitytotest);
if ($login) // Login is successfull
{
$test=false;
$dol_authmode=$mode; // This properties is defined only when logged to say what mode was successfully used
$ret=0;
}
}
else
{
dol_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR);
sleep(1);
$ret=-1;
}
}
$this->login($aLogin);
$this->passwd($aPasswd);
$ret=0;
}
else
{
$ret=-1;
}
}

View File

@ -57,7 +57,7 @@ class Conf
var $tabs_modules = array();
var $triggers_modules = array();
var $hooks_modules = array();
var $login_method_modules = array();
public $login_method_modules = array();
var $modules = array();
var $entities = array();

View File

@ -24,61 +24,113 @@
/**
* Return a login if login/pass was successfull using an external login method.
* Return a login if login/pass was successfull
*
* @param string $usertotest Login value to test
* @param string $passwordtotest Password value to test
* @param string $entitytotest Instance to test
* @param array $authmode Array list of selected authentication mode ('http', 'dolibarr', 'xxx'...)
* @return string Login or ''
*/
function getLoginMethod($usertotest,$passwordtotest,$entitytotest=1)
function checkLoginPassEntity($usertotest,$passwordtotest,$entitytotest,$authmode)
{
global $conf,$langs;
global $dolauthmode; // To return authentication finally used
// Check parameetrs
if ($entitytotest == '') $entitytotest=1;
dol_syslog("checkLoginPassEntity usertotest=".$usertotest." entitytotest=".$entitytotest." authmode=".join(',',$authmode));
$login = '';
foreach($conf->login_method_modules as $dir)
// Validation of login/pass/entity with a third party login module method
if (is_array($conf->login_method_modules) && !empty($conf->login_method_modules))
{
// Check if directory exists
if (!is_dir($dir)) continue;
foreach($conf->login_method_modules as $dir)
{
$newdir=dol_osencode($dir);
$handle=opendir($dir);
if (is_resource($handle))
{
while (($file = readdir($handle))!==false)
{
if (is_readable($dir.'/'.$file) && preg_match('/^functions_([^_]+)\.php/',$file,$reg))
{
$authfile = $dir.'/'.$file;
$mode = $reg[1];
// Check if directory exists
if (!is_dir($newdir)) continue;
$result=include_once($authfile);
if ($result)
{
// Call function to check user/password
$function='check_user_password_'.$mode;
$login=call_user_func($function,$usertotest,$passwordtotest,$entitytotest);
if ($login)
{
$conf->authmode=$mode; // This properties is defined only when logged
}
}
else
{
dol_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR);
sleep(1); // To slow brut force cracking
$langs->load('main');
$langs->load('other');
$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode);
}
}
}
}
closedir($handle);
$handle=opendir($newdir);
if (is_resource($handle))
{
while (($file = readdir($handle))!==false)
{
if (is_readable($dir.'/'.$file) && preg_match('/^functions_([^_]+)\.php/',$file,$reg))
{
$authfile = $dir.'/'.$file;
$mode = $reg[1];
$result=include_once($authfile);
if ($result)
{
// Call function to check user/password
$function='check_user_password_'.$mode;
$login=call_user_func($function,$usertotest,$passwordtotest,$entitytotest);
if ($login)
{
$conf->authmode=$mode; // This properties is defined only when logged to say what mode was successfully used
}
}
else
{
dol_syslog("Authentification ko - failed to load file '".$authfile."'",LOG_ERR);
sleep(1); // To slow brut force cracking
$langs->load('main');
$langs->load('other');
$_SESSION["dol_loginmesg"]=$langs->trans("ErrorFailedToLoadLoginFileForMode",$mode);
}
}
}
closedir($handle);
}
}
}
// Validation of login/pass/entity with standard modules
if (empty($login))
{
$test=true;
foreach($authmode as $mode)
{
if ($test && $mode && ! $login)
{
$mode=trim($mode);
$authfile=DOL_DOCUMENT_ROOT.'/includes/login/functions_'.$mode.'.php';
$result=include_once($authfile);
if ($result)
{
// Call function to check user/password
$function='check_user_password_'.$mode;
$login=call_user_func($function,$usertotest,$passwordtotest,$entitytotest);
if ($login) // Login is successfull
{
$test=false; // To stop once at first login success
$conf->authmode=$mode; // This properties is defined only when logged to say what mode was successfully used
$dol_tz=$_POST["tz"];
$dol_dst=$_POST["dst"];
$dol_screenwidth=$_POST["screenwidth"];
$dol_screenheight=$_POST["screenheight"];
}
}
else
{
dol_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);
}
}
}
}
return $login;
}
/**
* Show Dolibarr default login page
*

View File

@ -24,6 +24,7 @@
/**
* Check authentication array and set error, errorcode, errorlabel
*
* @param authentication Array
* @param error
* @param errorcode
@ -32,6 +33,7 @@
function check_authentication($authentication,&$error,&$errorcode,&$errorlabel)
{
global $db,$conf,$langs;
global $dolibarr_main_authentication,$dolibarr_auto_user;
$fuser=new User($db);
@ -50,26 +52,34 @@ function check_authentication($authentication,&$error,&$errorcode,&$errorlabel)
if (! $error)
{
$result=$fuser->fetch('',$authentication['login'],'',0);
if ($result <= 0) $error++;
// Validation of login with a third party login module method
if (! $error)
{
if (is_array($conf->login_method_modules) && !empty($conf->login_method_modules))
{
$login = getLoginMethod($authentication['login'],$authentication['password'],$authentication['entity']);
if (empty($login)) $error++;
}
else
{
$errorcode='BAD_LOGIN_METHOD'; $errorlabel='Bad value for login method';
}
}
if ($error)
if ($result < 0)
{
$error++;
$errorcode='ERROR_FETCH_USER'; $errorlabel='A technical error occurs during fetch of user';
}
else if ($result == 0)
{
$error++;
$errorcode='BAD_CREDENTIALS'; $errorlabel='Bad value for login or password';
}
// Validation of login
if (! $error)
{
// Authentication mode
if (empty($dolibarr_main_authentication)) $dolibarr_main_authentication='http,dolibarr';
// Authentication mode: forceuser
if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) $dolibarr_auto_user='auto';
// Set authmode
$authmode=explode(',',$dolibarr_main_authentication);
$login = checkLoginPassEntity($authentication['login'],$authentication['password'],$authentication['entity'],$authmode);
if (empty($login))
{
$error++;
$errorcode='BAD_CREDENTIALS'; $errorlabel='Bad value for login or password';
}
}
}
return $fuser;

View File

@ -17,7 +17,7 @@
*/
/**
* \file test/phpunit/DateLibTest.php
* \file test/phpunit/WebservicesTest.php
* \ingroup test
* \brief PHPUnit test
* \remarks To run this script as CLI: phpunit filename.php