29require
'../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.
'/core/lib/admin.lib.php';
40require_once DOL_DOCUMENT_ROOT.
'/core/lib/security2.lib.php';
42$action =
GETPOST(
'action',
'aZ09');
45$langs->loadLangs(array(
"users",
"admin",
"other"));
52$allow_disable_encryption =
false;
59if ($action ==
'setgeneraterule') {
60 $value =
GETPOST(
"value",
"alphanohtml");
63 setEventMessages($langs->trans(
"PasswordGenerationNoneDisabled"),
null,
'errors');
69if ($action ==
'activate_encrypt') {
78 dolibarr_set_const($db,
"DATABASE_PWD_ENCRYPTED",
"1",
'chaine', 0,
'', $entityforall);
80 $sql =
"SELECT u.rowid, u.pass, u.pass_crypted";
81 $sql .=
" FROM ".MAIN_DB_PREFIX.
"user as u";
82 $sql .=
" WHERE u.pass IS NOT NULL AND LENGTH(u.pass) < 32";
84 $resql = $db->query($sql);
86 $numrows = $db->num_rows($resql);
88 while ($i < $numrows) {
89 $obj = $db->fetch_object($resql);
91 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"user";
92 $sql .=
" SET pass_crypted = '".dol_hash($obj->pass).
"', pass = NULL";
93 $sql .=
" WHERE rowid=".((int) $obj->rowid);
96 $resql2 = $db->query($sql);
107 dol_print_error($db);
116 dol_print_error($db,
'');
118} elseif ($action ==
'disable_encrypt') {
121 if ($allow_disable_encryption) {
127if ($action ==
'activate_encryptdbpassconf') {
134 header(
"Location: security.php");
137 setEventMessages($langs->trans(
'InstrucToEncodePass',
dolEncrypt($dolibarr_main_db_pass)),
null,
'warnings');
139} elseif ($action ==
'disable_encryptdbpassconf') {
146 header(
"Location: security.php");
150 setEventMessages($langs->trans(
'InstrucToClearPass', $langs->transnoentitiesnoconv(
"DatabasePassword")),
null,
'warnings');
154if ($action ==
'activate_MAIN_SECURITY_DISABLEFORGETPASSLINK') {
156} elseif ($action ==
'disable_MAIN_SECURITY_DISABLEFORGETPASSLINK') {
160if ($action ==
'updatepattern') {
161 $pattern =
GETPOST(
"pattern",
"alpha");
162 $explodePattern = explode(
';', $pattern);
164 $patternInError =
false;
165 if ((
int) $explodePattern[0] < 1 || (
int) $explodePattern[4] < 0) {
166 $patternInError =
true;
169 if ((
int) $explodePattern[0] < (
int) $explodePattern[1] + (
int) $explodePattern[2] + (
int) $explodePattern[3]) {
170 $patternInError =
true;
174 if ((
int) $explodePattern[0] < $minlengthallowed) {
177 $patternInError =
true;
178 setEventMessages($langs->trans(
"PasswordPatternMinLengthRestricted", $minlengthallowed),
null,
'errors');
181 if (!$patternInError) {
183 setEventMessages($langs->trans(
"SetupSaved"),
null,
'mesgs');
184 header(
"Location: security.php");
195$form =
new Form($db);
197$wikihelp =
'EN:Setup_Security|FR:Paramétrage_Sécurité|ES:Configuración_Seguridad';
198llxHeader(
'', $langs->trans(
"Passwords"), $wikihelp,
'', 0, 0,
'',
'',
'',
'mod-admin page-security');
202print
'<div class="info">'.$langs->trans(
"GeneratedPasswordDesc").
"</div>\n";
212print
'<form action="'.$_SERVER[
"PHP_SELF"].
'" method="POST" spellcheck="false">';
213print
'<input type="hidden" name="token" value="'.newToken().
'">';
214print
'<input type="hidden" name="action" value="update">';
215print
'<input type="hidden" name="constname" value="USER_PASSWORD_GENERATED">';
216print
'<input type="hidden" name="consttype" value="yesno">';
222$dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
223$arrayhandler = array();
224foreach ($dirmodels as $reldir) {
225 $dir =
dol_buildpath($reldir.
'core/modules/security/generate/');
227 $handle = @opendir($dir);
228 if (is_resource($handle)) {
229 while (($file = readdir($handle)) !==
false) {
231 if (preg_match(
'/(modGeneratePass[a-z]+)\.class\.php$/i', $file, $reg)) {
233 $classname = $reg[1];
234 if (!class_exists($classname)) {
235 require_once $dir.$file;
237 if (class_exists($classname)) {
238 $obj =
new $classname($db,
$conf, $langs, $user);
239 '@phan-var-force ModeleGenPassword $obj';
240 $arrayhandler[$obj->id] = $obj;
249print
'<div class="div-table-responsive-no-min">';
250print
'<table class="noborder centpercent">';
251print
'<tr class="liste_titre">';
252print
'<td colspan="2">'.$langs->trans(
"RuleForGeneratedPasswords").
'</td>';
253print
'<td>'.$langs->trans(
"Example").
'</td>';
254print
'<td class="center">'.$langs->trans(
"Activated").
'</td>';
259foreach ($arrayhandler as $key =>
$module) {
269 print
'<tr class="oddeven"><td class="nowraponall">';
270 print img_picto(
'',
$module->picto,
'class="width25 size15x marginrightonly"').
' ';
271 print
'<div class="refid inline-block">'.ucfirst($key).
'</span>';
273 print
$module->getDescription().
'<br>';
274 print $langs->trans(
"MinLength").
': <span class="opacitymedium">'.
$module->length.
'</span>';
278 print
'<td class="nowraponall">';
280 if (preg_match(
'/^Error/', $tmp)) {
281 $langs->load(
"errors");
282 print
'<div class="error">'.$langs->trans($tmp).
'</div>';
283 } elseif ($tmp ==
'NotConfigured') {
284 print
'<span class="opacitymedium">'.$langs->trans($tmp).
'</span>';
286 print
'<span class="opacitymedium">'.$tmp.
'</span>';
290 print
'<td class="center">';
293 print img_picto($langs->trans(
"Enabled"),
'switch_on');
295 print
'<a href="'.$_SERVER[
'PHP_SELF'].
'?action=setgeneraterule&token='.
newToken().
'&value='.$key.
'">';
297 print img_picto($langs->trans(
"Disabled"),
'switch_off');
300 print
"</td></tr>\n";
313 print
'<div class="div-table-responsive-no-min">';
314 print
'<table class="noborder centpercent">';
315 print
'<tr class="liste_titre">';
316 print
'<td colspan="2"> '.$langs->trans(
"PasswordPatternDesc").
'</td>';
321 print
'<tr class="oddeven">';
322 print
'<td>'.$langs->trans(
"MinLength");
323 if ($minlengthallowed > 1) {
324 print
' <span class="opacitymedium">('.$langs->trans(
"PasswordPatternMinLengthRestricted", $minlengthallowed).
')</span>';
327 print
'<td><input type="number" class="width50 right" value="'.$tabConf[0].
'" id="minlength" min="'.$minlengthallowed.
'"></td>';
331 print
'<tr class="oddeven">';
332 print
'<td>'.$langs->trans(
"NbMajMin").
"</td>";
333 print
'<td><input type="number" class="width50 right" value="'.$tabConf[1].
'" id="NbMajMin" min="0"></td>';
337 print
'<tr class="oddeven">';
338 print
'<td>'.$langs->trans(
"NbNumMin").
"</td>";
339 print
'<td><input type="number" class="width50 right" value="'.$tabConf[2].
'" id="NbNumMin" min="0"></td>';
343 print
'<tr class="oddeven">';
344 print
'<td>'.$langs->trans(
"NbSpeMin").
"</td>";
345 print
'<td><input type="number" class="width50 right" value="'.$tabConf[3].
'" id="NbSpeMin" min="0"></td>';
349 print
'<tr class="oddeven">';
350 print
'<td>'.$langs->trans(
"NbIteConsecutive").
"</td>";
351 print
'<td><input type="number" class="width50 right" value="'.$tabConf[4].
'" id="NbIteConsecutive" min="0"></td>';
355 print
'<tr class="oddeven">';
356 print
'<td>'.$langs->trans(
"NoAmbiCaracAutoGeneration").
"</td>";
357 print
'<td><input type="checkbox" id="NoAmbiCaracAutoGeneration" '.($tabConf[5] ?
"checked" :
"").
' min="0"> <label for="NoAmbiCaracAutoGeneration" id="textcheckbox">'.($tabConf[5] ? $langs->trans(
"Activated") : $langs->trans(
"Disabled")).
'</label></td>';
362 print
'<div class="center">';
363 print
'<a class="button button-save" id="linkChangePattern">'.$langs->trans(
"Save").
'</a>';
368 print
'<script type="text/javascript">';
369 print
' function getStringArg(){';
370 print
' var pattern = "";';
371 print
' pattern += $("#minlength").val() + ";";';
372 print
' pattern += $("#NbMajMin").val() + ";";';
373 print
' pattern += $("#NbNumMin").val() + ";";';
374 print
' pattern += $("#NbSpeMin").val() + ";";';
375 print
' pattern += $("#NbIteConsecutive").val() + ";";';
376 print
' pattern += $("#NoAmbiCaracAutoGeneration")[0].checked ? "1" : "0";';
377 print
' return pattern;';
380 print
' function valuePossible(){';
381 print
' var fields = ["#minlength", "#NbMajMin", "#NbNumMin", "#NbSpeMin", "#NbIteConsecutive"];';
382 print
' for(var i = 0 ; i < fields.length ; i++){';
383 print
' if($(fields[i]).val() < $(fields[i]).attr("min")){';
384 print
' return false;';
388 print
' var length = parseInt($("#minlength").val());';
389 print
' var length_mini = parseInt($("#NbMajMin").val()) + parseInt($("#NbNumMin").val()) + parseInt($("#NbSpeMin").val());';
390 print
' return length >= length_mini;';
393 print
' function generatelink(){';
394 print
' return "security.php?action=updatepattern&token='.newToken().
'&pattern="+getStringArg();';
397 print
' function valuePatternChange(){';
398 print
' console.log("valuePatternChange");';
399 print
' var lang_save = "'.$langs->trans(
"Save").
'";';
400 print
' var lang_error = "'.$langs->trans(
"Error").
'";';
401 print
' var lang_Disabled = "'.$langs->trans(
"Disabled").
'";';
402 print
' var lang_Activated = "'.$langs->trans(
"Activated").
'";';
403 print
' $("#textcheckbox").html($("#NoAmbiCaracAutoGeneration")[0].checked ? unescape(lang_Activated) : unescape(lang_Disabled));';
404 print
' if(valuePossible()){';
405 print
' $("#linkChangePattern").attr("href",generatelink()).text(lang_save);';
408 print
' $("#linkChangePattern").attr("href", null).text(lang_error);';
412 print
' $("#minlength").change(function(){valuePatternChange();});';
413 print
' $("#NbMajMin").change(function(){valuePatternChange();});';
414 print
' $("#NbNumMin").change(function(){valuePatternChange();});';
415 print
' $("#NbSpeMin").change(function(){valuePatternChange();});';
416 print
' $("#NbIteConsecutive").change(function(){valuePatternChange();});';
417 print
' $("#NoAmbiCaracAutoGeneration").change(function(){valuePatternChange();});';
426print
'<form method="post" action="'.dolBuildUrl($_SERVER[
"PHP_SELF"]).
'" spellcheck="false">';
427print
'<input type="hidden" name="token" value="'.newToken().
'">';
428print
'<input type="hidden" name="action" value="encrypt">';
430print
'<table class="noborder centpercent">';
431print
'<tr class="liste_titre">';
432print
'<td colspan="3">'.$langs->trans(
"Parameters").
'</td>';
433print
'<td class="center">'.$langs->trans(
"Activated").
'</td>';
434print
'<td class="center"></td>';
438print
'<tr class="oddeven">';
439print
'<td colspan="3">'.$langs->trans(
"DoNotStoreClearPassword").
'</td>';
440print
'<td class="center" width="60">';
442 print img_picto($langs->trans(
"Active"),
'tick');
446 print
'<td class="center" width="100">';
447 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=activate_encrypt&token='.
newToken().
'">'.$langs->trans(
"Activate").
'</a>';
450 print
'<td class="center" width="100">';
451 if ($allow_disable_encryption) {
453 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=disable_encrypt&token='.
newToken().
'">'.$langs->trans(
"Disable").
'</a>';
455 print
'<span class="opacitymedium">'.$langs->trans(
"Always").
'</span>';
465print
'<tr class="oddeven">';
466print
'<td colspan="3">'.$langs->trans(
"MainDbPasswordFileConfEncrypted").
'</td>';
467print
'<td align="center" width="60">';
468if (preg_match(
'/(crypted|dolcrypt):/i', $dolibarr_main_db_pass) || !empty($dolibarr_main_db_encrypted_pass)) {
469 print img_picto($langs->trans(
"Active"),
'tick');
474print
'<td class="center" width="100">';
475if (empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) {
476 $langs->load(
"errors");
477 print img_warning($langs->trans(
"WarningPassIsEmpty"));
479 if (empty($dolibarr_main_db_encrypted_pass)) {
480 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=activate_encryptdbpassconf&token='.
newToken().
'">'.$langs->trans(
"Activate").
'</a>';
482 if (!empty($dolibarr_main_db_encrypted_pass)) {
483 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=disable_encryptdbpassconf&token='.
newToken().
'">'.$langs->trans(
"Disable").
'</a>';
494print
'<tr class="oddeven">';
495print
'<td colspan="3">'.$langs->trans(
"DisableForgetPasswordLinkOnLogonPage").
'</td>';
496print
'<td class="center" width="60">';
498 print img_picto($langs->trans(
"Active"),
'tick');
502 print
'<td class="center" width="100">';
503 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=activate_MAIN_SECURITY_DISABLEFORGETPASSLINK&token='.
newToken().
'">'.$langs->trans(
"Activate").
'</a>';
507 print
'<td class="center" width="100">';
508 print
'<a class="reposition" href="'.$_SERVER[
"PHP_SELF"].
'?action=disable_MAIN_SECURITY_DISABLEFORGETPASSLINK&token='.
newToken().
'">'.$langs->trans(
"Disable").
'</a>';
522 if (function_exists(
'password_hash')) {
523 print $langs->trans(
"Note: The function password_hash exists on your PHP").
"<br>\n";
525 print $langs->trans(
"Note: The function password_hash does not exist on your PHP").
"<br>\n";
527 print
'MAIN_SECURITY_HASH_ALGO = '.getDolGlobalString(
'MAIN_SECURITY_HASH_ALGO').
"<br>\n";
528 print
'MAIN_SECURITY_SALT = '.getDolGlobalString(
'MAIN_SECURITY_SALT').
"<br>\n";
security_prepare_head()
Prepare array with list of tabs.
dolibarr_set_const($db, $name, $value, $type='chaine', $visible=0, $note='', $entity=1)
Insert a parameter (key,value) into database (delete old key then insert it again).
dolibarr_del_const($db, $name, $entity=1)
Delete a constant.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
if(! $sortfield) if(! $sortorder) $module
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getPasswordPatternMinLength()
Return the lowest value allowed for the minimum length (first field of USER_PASSWORD_PATTERN) of the ...
encodedecode_dbpassconf($level=0)
Encode or decode database password in config file.
isPasswordGenerationNoneForbidden()
Return if the 'none' password generation model (the one that applies no rule at all) is forbidden on ...
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
dol_hash($chain, $type='0', $nosalt=0, $mode=0)
Returns a hash (non reversible encryption) of a string.
dolEncrypt($chain, $key='', $ciphering='', $forceseed='', $obfuscationmode='dolcrypt')
Encode a string with a symmetric encryption.