Skip to content
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

Override policy rules if password shorter than a certain value #302

Open
wants to merge 1 commit 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
15 changes: 15 additions & 0 deletions conf/config.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,21 @@
$pwd_complexity = 0;
# use pwnedpasswords api v2 to securely check if the password has been on a leak
$use_pwnedpasswords = false;
# override policy if password is shorter than a certain value
# Example:
# $pwd_min_length = 12;
# $pwd_override_by_length = array(
# array(
# 'valid_if_shorter_than' => 12,
# 'rules' => array(
# 'pwd_min_length' => 8,
# 'pwd_min_lower' => 1,
# 'pwd_min_upper' => 1,
# 'pwd_min_digit' => 1,
# 'pwd_min_special' => 1
# )
# )
#);
# Show policy constraints message:
# always
# never
Expand Down
4 changes: 3 additions & 1 deletion index.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
if (!isset($ldap_login_attribute)) { $ldap_login_attribute = "uid"; }
if (!isset($ldap_fullname_attribute)) { $ldap_fullname_attribute = "cn"; }
if (!isset($pwd_forbidden_chars)) { $pwd_forbidden_chars = ""; }
if (!isset($pwd_override_by_length)) { $pwd_override_by_length = array(); }
if (!isset($hash_options)) { $hash_options = array(); }
if (!isset($samba_options)) { $samba_options = array(); }
if (!isset($ldap_starttls)) { $ldap_starttls = false; }
Expand All @@ -141,7 +142,8 @@
"pwd_diff_login" => $pwd_diff_login,
"pwd_complexity" => $pwd_complexity,
"use_pwnedpasswords" => $use_pwnedpasswords,
"pwd_no_special_at_ends" => $pwd_no_special_at_ends
"pwd_no_special_at_ends" => $pwd_no_special_at_ends,
"pwd_override_by_length" => $pwd_override_by_length,
);

if (!isset($pwd_show_policy_pos)) { $pwd_show_policy_pos = "above"; }
Expand Down
1 change: 1 addition & 0 deletions lang/ca.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/cn.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/cs.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/de.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Ihr Passwort enthält das einzige Sonderzeichen am Anfang oder am Ende";
$messages['policyspecialatends'] = "Ein Sonderzeichen, wenn es nur ein einziges gibt, darf nicht am Anfang oder am Ende stehen";
$messages['overriding_policy_by_length'] = "Wenn das Passwort kürzer als %d Zeichen ist, gelten folgende Regeln:";
1 change: 1 addition & 0 deletions lang/ee.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/el.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/en.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/es.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@
$messages['policypwned'] = "Su contraseña no puede haber sido publicada previamente en ninguna lista de contraseñas filtradas accesible al publico de ningun sitio";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/fr.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/hu.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/it.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/ja.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/nb-NO.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Ditt nye passord er ikke publisert på kjente passord-leak siter";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/nl.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/pl.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/pt-BR.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Parece que sua nova senha não foi publicada como vazada de qualquer site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/pt-PT.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/ru.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/sk.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/sl.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/sv.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/tr.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/uk.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/zh-CN.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
1 change: 1 addition & 0 deletions lang/zh-TW.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,4 @@
$messages['policypwned'] = "Your new password may not be published on any previous public password leak from any site";
$messages['specialatends'] = "Your new password has its only special character at the beginning or end";
$messages['policyspecialatends'] = "Your new password may not have its only special character at the beginning or end";
$messages['overriding_policy_by_length'] = "If the password is shorter than %d characters, the following rules apply:";
35 changes: 34 additions & 1 deletion lib/functions.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,17 @@ function show_policy( $messages, $pwd_policy_config, $result ) {
# Display bloc
echo "<div class=\"help alert alert-warning\">\n";
echo "<p>".$messages["policy"]."</p>\n";
output_policy_list($messages, $pwd_policy_config);
usort($pwd_override_by_length, function($a, $b) { return $b['valid_if_shorter_than'] - $a['valid_if_shorter_than']; });
foreach($pwd_override_by_length as $override) {
echo "<p>".sprintf($messages["overriding_policy_by_length"], $override['valid_if_shorter_than']) . "</p>\n";
output_policy_list($messages, $override['rules']);
}
echo "</div>\n";
}

function output_policy_list($messages, $policy) {
extract($policy);
echo "<ul>\n";
if ( $pwd_min_length ) { echo "<li>".$messages["policyminlength"] ." $pwd_min_length</li>\n"; }
if ( $pwd_max_length ) { echo "<li>".$messages["policymaxlength"] ." $pwd_max_length</li>\n"; }
Expand All @@ -194,7 +205,6 @@ function show_policy( $messages, $pwd_policy_config, $result ) {
if ( $use_pwnedpasswords ) { echo "<li>".$messages["policypwned"] ."\n"; }
if ( $pwd_no_special_at_ends ) { echo "<li>".$messages["policyspecialatends"] ."</li>\n"; }
echo "</ul>\n";
echo "</div>\n";
}

# Check password strength
Expand All @@ -205,6 +215,29 @@ function check_password_strength( $password, $oldpassword, $pwd_policy_config, $
$result = "";

$length = strlen(utf8_decode($password));

usort($pwd_override_by_length, function($a, $b) { return $a['valid_if_shorter_than'] - $b['valid_if_shorter_than']; });
$checked = false;
foreach($pwd_override_by_length as $override) {
if($length < $override['valid_if_shorter_than']) {
$policy = array_merge($pwd_policy_config, $override['rules']);
$result = match_policy($password, $oldpassword, $policy, $login, $length);
$checked = true;
break;
}
}
if(!$checked) {
$result = match_policy($password, $oldpassword, $pwd_policy_config, $login, $length);
}

return $result;
}

function match_policy($password, $oldpassword, $pwd_policy_config, $login, $length) {
extract( $pwd_policy_config );

$result = "";

preg_match_all("/[a-z]/", $password, $lower_res);
$lower = count( $lower_res[0] );
preg_match_all("/[A-Z]/", $password, $upper_res);
Expand Down
29 changes: 29 additions & 0 deletions tests/CheckPasswordTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function testCheckPasswordStrength()
"pwd_complexity" => 0,
"use_pwnedpasswords" => false,
"pwd_no_special_at_ends" => false,
"pwd_override_by_length" => array(),
);

$login = "coudot";
Expand Down Expand Up @@ -59,11 +60,38 @@ public function testCheckPasswordStrength()
"pwd_complexity" => 3,
"use_pwnedpasswords" => false,
"pwd_no_special_at_ends" => true,
"pwd_override_by_length" => array(
array(
'valid_if_shorter_than' => 5,
'rules' => array(
'pwd_min_length' => 4,
'pwd_min_digit' => 1,
'pwd_min_upper' => 1,
'pwd_min_lower' => 1,
'pwd_min_special' => 1,
'pwd_complexity' => 0
)
),
array(
'valid_if_shorter_than' => 4,
'rules' => array(
'pwd_min_length' => 3,
'pwd_min_lower' => 1,
'pwd_min_special' => 2,
'pwd_complexity' => 0
)
)
),
);

$this->assertEquals("notcomplex", check_password_strength( "simple", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("specialatends", check_password_strength( "!simple", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("specialatends", check_password_strength( "simple?", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("minspecial", check_password_strength( "xyZ1", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("minupper", check_password_strength( "xy%1", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("", check_password_strength( "xY%1", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("minspecial", check_password_strength( "x%1", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("", check_password_strength( "x%$", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("", check_password_strength( "C0mplex", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("", check_password_strength( "C0!mplex", $oldpassword, $pwd_policy_config, $login ) );
$this->assertEquals("", check_password_strength( "%C0!mplex", $oldpassword, $pwd_policy_config, $login ) );
Expand Down Expand Up @@ -99,6 +127,7 @@ public function testCheckPasswordStrengthPwnedPasswords()
"pwd_complexity" => 0,
"use_pwnedpasswords" => true,
"pwd_no_special_at_ends" => false,
"pwd_override_by_length" => array(),
);

$this->assertEquals("pwned", check_password_strength( "!1Password", $oldpassword, $pwd_policy_config, $login ) );
Expand Down