Skip to content

Additional password checks #1067

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion htdocs/change.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,4 @@
error_log("Error while sending change email to $mail (user $login)");
}
}
}
}
6 changes: 4 additions & 2 deletions htdocs/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,11 @@
"use_pwnedpasswords" => $use_pwnedpasswords,
"pwd_no_special_at_ends" => $pwd_no_special_at_ends,
"pwd_forbidden_words" => $pwd_forbidden_words,
"pwd_forbidden_ldap_fields" => $pwd_forbidden_ldap_fields,
"pwd_forbidden_ldap_fields" => !empty($pwd_forbidden_ldap_fields),
"pwd_display_entropy" => $pwd_display_entropy,
"pwd_check_entropy" => $pwd_check_entropy,
"pwd_min_entropy" => $pwd_min_entropy
"pwd_min_entropy" => $pwd_min_entropy,
"use_restapi" => $use_restapi,
);

if (!isset($pwd_show_policy_pos)) { $pwd_show_policy_pos = "above"; }
Expand Down Expand Up @@ -285,6 +286,7 @@
$smarty->assign('use_questions', $use_questions);
$smarty->assign('use_tokens', $use_tokens);
$smarty->assign('use_sms', $use_sms);
$smarty->assign('use_restapi', $use_restapi);
$smarty->assign('change_sshkey', $change_sshkey);
if(empty($change_custompwdfield)) {
$smarty->assign('change_custompwdfield', false);
Expand Down
2 changes: 1 addition & 1 deletion lang/en.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
$messages['forbiddenwords'] = "Your passwords contains forbidden words or strings";
$messages['policyforbiddenwords'] = "Your password must not contain:";
$messages['forbiddenldapfields'] = "Your password contains values from your LDAP entry";
$messages['policyforbiddenldapfields'] = "Your password may not contain values from the following LDAP fields:";
$messages['policyforbiddenldapfields'] = "Your password may not contain personal informations";
$messages['policyentropy'] = "Password strength";
$messages['ldap_cn'] = "common name";
$messages['ldap_givenName'] = "given name";
Expand Down
2 changes: 1 addition & 1 deletion lang/fr.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
$messages['forbiddenwords'] = "Votre mot de passe contient des mots interdits";
$messages['policyforbiddenwords'] = "Votre mot de passe ne doit pas contenir ::";
$messages['forbiddenldapfields'] = "Votre mot de passe contient des valeurs de votre entrée LDAP";
$messages['policyforbiddenldapfields'] = "Votre mot de passe ne doit pas contenir la valeur des attributs de votre entrée :";
$messages['policyforbiddenldapfields'] = "Votre mot de passe ne doit pas contenir d'informations personnelles";
$messages['policyentropy'] = "Force du mot de passe";
$messages['ldap_cn'] = "nom complet";
$messages['ldap_givenName'] = "prénom";
Expand Down
3 changes: 1 addition & 2 deletions rest/v1/include.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?php

#==============================================================================
# Configuration
#==============================================================================
Expand Down Expand Up @@ -31,7 +30,7 @@
}
closedir($handle);
}
$lang = \Ltb\Language::detectLanguage($lang, $languages);
$lang = \Ltb\Language::detect_language($lang, $languages);
require_once("../../lang/$lang.inc.php");
if (file_exists("../../conf/$lang.inc.php")) {
require_once("../../conf/$lang.inc.php");
Expand Down
107 changes: 107 additions & 0 deletions rest/v1/validatepassword.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

use Symfony\Component\Cache\Adapter\FilesystemAdapter;

global $ldapInstance, $ldaphost, $ldap_base, $pwd_forbidden_ldap_fields;

require_once("./include.php");

#==============================================================================
# Action
#==============================================================================
$return = Array();
$login = "";
$password = "";

if (
isset($_POST["login"]) && $_POST["login"] &&
isset($_POST["password"]) && $_POST["password"]
) {
$login = $_POST["login"];
$password = $_POST["password"];
} else {
$return['message'] = "Login and password required.";
http_response_code(400);
echo json_encode($return);
return;
}

$attributes = $pwd_forbidden_ldap_fields;

#==============================================================================
# Load data from cache or LDAP
#==============================================================================
$userData = [];

$cache = new FilesystemAdapter(
namespace: 'ldap_forbiddenvalidation_cache',
defaultLifetime: 300,
directory: dirname(__DIR__, 2) . '/cache'
);

$cacheKey = 'ldap_user_' . md5($login);
$cachedItem = $cache->getItem($cacheKey);

if ($cachedItem->isHit()) {
$userData = $cachedItem->get();
}
else {
$filter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=" . $login . "))";

// Connect to LDAP
$ldap_connection = $ldapInstance->connect();
$ldap = $ldap_connection[0];

// Assert successful LDAP connection
if (!$ldap_connection) {
$return['message'] = "Could not connect to {$ldaphost}.";
http_response_code(500);
echo json_encode($return);
return;
}

// Search LDAP using filter, get the entries, and set count.
$search = ldap_search($ldap, $ldap_base, $filter, $attributes, 0, 0);

$userData = ldap_get_entries($ldap, $search);
$cachedItem->set($userData);
if (!$cache->save($cachedItem)) {
error_log("Error while trying to write cache");
}
}

#==============================================================================
# Process data
#==============================================================================
if ($userData["count"] === 0) {
http_response_code(404);
$return['message'] = "User not found.";
echo json_encode($return);
return;
}

$upperPwd = strtoupper($password);

foreach ($attributes as $attribute) {
$lowerAttribute = strtolower($attribute);
if(!isset($userData[0][$lowerAttribute][0])) {
continue;
}

$upperValue = strtoupper($userData[0][$lowerAttribute][0]);

if(str_contains($upperPwd, $upperValue)) {
$return['message'] = "User found.";
$return['isValid'] = false;

http_response_code(200);
echo json_encode($return);

return;
}
}

$return['message'] = "User found.";
$return['isValid'] = true;
http_response_code(200);
echo json_encode($return);