Rewrite generate password and check password - requires composer update

- Added ircmaxell/random-lib lib to improve security.
- Add 'password_requirements' setting see BT#12571 to customize min
requirements.
pull/2487/head
jmontoyaa 9 years ago
parent 9105ea5cf7
commit 807cf5697b
  1. 3
      composer.json
  2. 119
      main/inc/lib/api.lib.php
  3. 3
      main/inc/lib/internationalization.lib.php
  4. 11
      main/install/configuration.dist.php

@ -104,7 +104,8 @@
"kigkonsult/icalcreator" : "0.1.0",
"essence/essence": "2.6.1",
"pclzip/pclzip": "2.8.2",
"chamilo/chash": "dev-master"
"chamilo/chash": "dev-master",
"ircmaxell/random-lib": "^1.2"
},
"require-dev": {
"behat/behat": "@stable",

@ -1953,22 +1953,49 @@ function api_format_course_array($course_data)
*/
function api_generate_password($length = 8)
{
$characters = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$numbers = '23456789';
if ($length < 2) {
$length = 2;
}
$charactersLowerCase = 'abcdefghijkmnopqrstuvwxyz';
$charactersUpperCase = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
$minNumbers = 2;
$length = $length - $minNumbers;
$minLowerCase = round($length/2);
$minUpperCase = $length - $minLowerCase;
$password = '';
for ($i = 0; $i < $length; $i ++) {
$password .= $characters[rand() % strlen($characters)];
$passwordRequirements = api_get_configuration_value('password_requirements');
$factory = new RandomLib\Factory();
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));
if (!empty($passwordRequirements)) {
$length = $passwordRequirements['min']['length'];
$minNumbers = $passwordRequirements['min']['numeric'];
$minLowerCase = $passwordRequirements['min']['lowercase'];
$minUpperCase = $passwordRequirements['min']['uppercase'];
$rest = $length - $minNumbers - $minLowerCase - $minUpperCase;
// Add the rest to fill the length requirement
if ($rest > 0) {
$password .= $generator->generateString($rest, $charactersLowerCase.$charactersUpperCase);
}
}
// At least 2 digits
for ($i = 0; $i < 2; $i ++) {
$password .= $numbers[rand() % strlen($numbers)];
// Min digits default 2
for ($i = 0; $i < $minNumbers; $i ++) {
$password .= $generator->generateInt(2, 9);
}
// Min lowercase
$password .= $generator->generateString($minLowerCase, $charactersLowerCase);
// Min uppercase
$password .= $generator->generateString($minUpperCase, $charactersUpperCase);
$password = str_shuffle($password);
return $password;
}
@ -1982,37 +2009,57 @@ function api_generate_password($length = 8)
* 3. The password should contain at least 3 letters.
* 4. It should contain at least 2 digits.
* 5. It should not contain 3 or more consequent (according to ASCII table) characters.
*/
function api_check_password($password) {
$password_length = api_strlen($password);
if ($password_length < 5) {
* Settings will change if the configuration value is set: password_requirements
*/
function api_check_password($password)
{
$passwordRequirements = api_get_configuration_value('password_requirements');
$minLength = 5;
$minLetters = 3;
$minNumbers = 2;
$minLowerCase = 0; // Is only use if password_requirements is set
$minUpperCase = 0; // Is only use if password_requirements is set
if (!empty($passwordRequirements)) {
$minLength = $passwordRequirements['min']['length'];
$minNumbers = $passwordRequirements['min']['numeric'];
$minLowerCase = $passwordRequirements['min']['lowercase'];
$minUpperCase = $passwordRequirements['min']['uppercase'];
$minLetters = $minLowerCase + $minUpperCase;
}
$passwordLength = api_strlen($password);
if ($passwordLength < $minLength) {
return false;
}
$password = api_strtolower($password);
$letters = 0;
$digits = 0;
$consequent_characters = 0;
$previous_character_code = 0;
for ($i = 0; $i < $password_length; $i ++) {
$current_character_code = api_ord(api_substr($password, $i, 1));
if ($i && abs($current_character_code - $previous_character_code) <= 1) {
$consequent_characters ++;
if ($consequent_characters == 3) {
return false;
}
} else {
$consequent_characters = 1;
$lowerCase = 0;
$upperCase = 0;
for ($i = 0; $i < $passwordLength; $i++) {
$currentCharacterCode = api_ord(api_substr($password, $i, 1));
if ($currentCharacterCode >= 65 && $currentCharacterCode <= 90) {
$upperCase++;
}
if ($current_character_code >= 97 && $current_character_code <= 122) {
$letters ++;
} elseif ($current_character_code >= 48 && $current_character_code <= 57) {
$digits ++;
} else {
return false;
if ($currentCharacterCode >= 97 && $currentCharacterCode <= 122) {
$lowerCase++;
}
if ($currentCharacterCode >= 48 && $currentCharacterCode <= 57) {
$digits++;
}
$previous_character_code = $current_character_code;
}
return ($letters >= 3 && $digits >= 2);
$letters = $upperCase + $lowerCase;
if (!empty($passwordRequirements)) {
return (
$upperCase >= $minUpperCase &&
$lowerCase >= $minLowerCase &&
$digits >= $minNumbers
);
}
return $letters >= $minLetters && $digits >= $minNumbers;
}
/**
@ -2040,7 +2087,8 @@ function api_clear_anonymous($db_check = false)
* @author Noel Dieschburg
* @param the int status code
*/
function get_status_from_code($status_code) {
function get_status_from_code($status_code)
{
switch ($status_code) {
case STUDENT:
return get_lang('Student', '');
@ -2062,7 +2110,8 @@ function get_status_from_code($status_code) {
* time we get on a course homepage or on a neutral page (index, admin, my space)
* @return bool true if set user as anonymous, false if user was already logged in or anonymous id could not be found
*/
function api_set_anonymous() {
function api_set_anonymous()
{
global $_user;
if (!empty($_user['user_id'])) {

@ -1092,7 +1092,8 @@ function api_transliterate($string, $unknown = '?', $from_encoding = null)
* @link http://php.net/manual/en/function.ord.php
* Note the difference with the original funtion ord(): ord('') returns 0, api_ord('') returns 0xFFFD (unknown character).
*/
function api_ord($character, $encoding = null) {
function api_ord($character, $encoding = 'UTF-8')
{
return Utf8::ord(api_utf8_encode($character, $encoding));
}

@ -309,4 +309,13 @@ $_configuration['system_stable'] = NEW_VERSION_STABLE;
// Hide LP time in reports.
// $_configuration['hide_lp_time'] = false;
// Hide rating elements in pages ("Courses catalog" & "Most Popular courses")
// $_configuration['hide_course_rating'] = false;
// $_configuration['hide_course_rating'] = false;
// Customize password generation and verification
/*$_configuration['password_requirements'] = [
'min' => [
'lowercase' => 2,
'uppercase' => 2,
'numeric' => 2,
'length' => 8
]
];*/

Loading…
Cancel
Save