Skip to content

Commit 7b93884

Browse files
author
Marius Cramer
committed
Added system option to configure minimum password strength and length
1 parent b5b6136 commit 7b93884

24 files changed

+295
-2
lines changed

install/tpl/system.ini.master

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ customer_no_start=1
5151
customer_no_counter=0
5252
session_timeout=0
5353
session_allow_endless=0
54+
min_password_length=5
55+
min_password_strength=0
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?php
2+
3+
/*
4+
Copyright (c) 2007, Till Brehm, projektfarm Gmbh
5+
Copyright (c) 2014, Marius Cramer, pixcept KG
6+
All rights reserved.
7+
8+
Redistribution and use in source and binary forms, with or without modification,
9+
are permitted provided that the following conditions are met:
10+
11+
* Redistributions of source code must retain the above copyright notice,
12+
this list of conditions and the following disclaimer.
13+
* Redistributions in binary form must reproduce the above copyright notice,
14+
this list of conditions and the following disclaimer in the documentation
15+
and/or other materials provided with the distribution.
16+
* Neither the name of ISPConfig nor the names of its contributors
17+
may be used to endorse or promote products derived from this software without
18+
specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23+
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
class validate_password {
33+
34+
private function _get_password_strength($password) {
35+
$length = strlen($password);
36+
$points = 0;
37+
if ($length < 5) {
38+
return 1;
39+
}
40+
41+
if (preg_match('/[ABCDEFGHIJKLNMOPQRSTUVWXYZ]/', $password)) {
42+
$points += 1;
43+
}
44+
45+
if (preg_match('/[0123456789]/', $password)) {
46+
$points += 1;
47+
}
48+
49+
if (preg_match('/[`~!@#$%^&*()_+|\\=-[]}{\';:\/?.>,<" ]/', $password)) {
50+
$points += 1;
51+
}
52+
53+
if ($points == 0) {
54+
if ($length >= 5 && $length <= 6) {
55+
return 1;
56+
} else if ($length >= 7 && $length <= 8) {
57+
return 2;
58+
} else {
59+
return 3;
60+
}
61+
} else if ($points == 1) {
62+
if ($length >= 5 && $length <= 6) {
63+
return 2;
64+
} else if (length >= 7 && length <=10) {
65+
return 3;
66+
} else {
67+
return 4;
68+
}
69+
} else if ($points == 2) {
70+
if ($length >= 5 && $length <= 8) {
71+
return 3;
72+
} else if ($length >= 9 && $length <= 10) {
73+
return 4;
74+
} else {
75+
return 5;
76+
}
77+
} else if ($points == 3) {
78+
if ($length >= 5 && $length <= 6) {
79+
return 3;
80+
} else if ($length >= 7 && $length <= 8) {
81+
return 4;
82+
} else {
83+
return 5;
84+
}
85+
} else if ($points >= 4) {
86+
if ($length >= 5 && $length <= 6) {
87+
return 4;
88+
} else {
89+
return 5;
90+
}
91+
}
92+
93+
}
94+
95+
/* Validator function */
96+
function password_check($field_name, $field_value, $validator) {
97+
global $app;
98+
99+
$app->uses('ini_parser,getconf');
100+
$server_config_array = $app->getconf->get_global_config();
101+
102+
$min_password_strength = 0;
103+
$min_password_length = 5;
104+
if(isset($server_config_array['misc']['min_password_length'])) $min_password_length = $server_config_array['misc']['min_password_length'];
105+
if(isset($server_config_array['misc']['min_password_strength'])) $min_password_strength = $server_config_array['misc']['min_password_strength'];
106+
107+
if($min_password_strength > 0) {
108+
$lng_text = $app->lng('weak_password_txt');
109+
$lng_text = str_replace(array('{chars}', '{strength}'), array($min_password_length, $app->lng('strength_' . $min_password_strength)), $lng_text);
110+
} else {
111+
$lng_text = $app->lng('weak_password_length_txt');
112+
$lng_text = str_replace('{chars}', $min_password_length, $lng_text);
113+
}
114+
if(!$lng_text) $lng_text = 'weak_password_txt'; // always return a string, even if language is missing - otherwise validator is NOT MATCHING!
115+
116+
if(strlen($field_value) < $min_password_length) return $lng_text;
117+
if($this->_get_password_strength($field_value) < $min_password_strength) return $lng_text;
118+
119+
return false;
120+
}
121+
}

interface/lib/lang/de.lng

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,12 @@ $wb['gender_f_txt'] = 'Frau';
139139
$wb['client_cannot_be_deleted_because_of_billing_module_txt'] = 'Für den Kunden existieren Einträge im Billing-Modul, daher kann er nicht gelöscht werden.';
140140
$wb['yes_txt'] = 'Ja';
141141
$wb['no_txt'] = 'Nein';
142+
$wb['None'] = 'Keine';
143+
$wb['strength_1'] = 'Leicht';
144+
$wb['strength_2'] = 'Mittel';
145+
$wb['strength_3'] = 'Gut';
146+
$wb['strength_4'] = 'Stark';
147+
$wb['strength_5'] = 'Sehr stark';
148+
$wb['weak_password_txt'] = 'Das gewählte Passwort erfüllt die Sicherheitsanforderungen nicht. Es muss mindestens {chars} Zeichen lang sein und die Stärke "{strength}" besitzen.';
149+
$wb['weak_password_length_txt'] = 'Das gewählte Passwort erfüllt die Sicherheitsanforderungen nicht. Es muss mindestens {chars} Zeichen lang sein.';
142150
?>

interface/lib/lang/en.lng

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,13 @@ $wb['gender_f_txt'] = 'Ms.';
141141
$wb['client_cannot_be_deleted_because_of_billing_module_txt'] = 'This client has records in the billing module, therefore he cannot be deleted.';
142142
$wb['yes_txt'] = 'Yes';
143143
$wb['no_txt'] = 'No';
144+
$wb['None'] = 'None';
145+
$wb['strength_1'] = 'Weak';
146+
$wb['strength_2'] = 'Fair';
147+
$wb['strength_3'] = 'Good';
148+
$wb['strength_4'] = 'Strong';
149+
$wb['strength_5'] = 'Very Strong';
150+
$wb['weak_password_txt'] = 'The chosen password does not match the security guidelines. It has to be at least {chars} chars in length and have a strength of "{strength}".';
151+
$wb['weak_password_length_txt'] = 'The chosen password does not match the security guidelines. It has to be at least {chars} chars in length.';
152+
144153
?>

interface/web/admin/form/remote_user.tform.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,14 @@
101101
'remote_password' => array (
102102
'datatype' => 'VARCHAR',
103103
'formtype' => 'PASSWORD',
104+
'validators' => array(
105+
0 => array(
106+
'type' => 'CUSTOM',
107+
'class' => 'validate_password',
108+
'function' => 'password_check',
109+
'errmsg' => 'weak_password_txt'
110+
)
111+
),
104112
'encryption' => 'MD5',
105113
'default' => '',
106114
'value' => '',

interface/web/admin/form/system_config.tform.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,20 @@
487487
'default' => 'n',
488488
'value' => array(0 => 'n', 1 => 'y')
489489
),
490+
'min_password_length' => array(
491+
'datatype' => 'INTEGER',
492+
'formtype' => 'TEXT',
493+
'default' => '5',
494+
'value' => '',
495+
'width' => '30',
496+
'maxlength' => '255'
497+
),
498+
'min_password_strength' => array(
499+
'datatype' => 'VARCHAR',
500+
'formtype' => 'SELECT',
501+
'default' => '',
502+
'value' => array('' => 'None', '1' => 'strength_1', '2' => 'strength_2', '3' => 'strength_3', '4' => 'strength_4', '5' => 'strength_5')
503+
)
490504
//#################################
491505
// ENDE Datatable fields
492506
//#################################

interface/web/admin/form/users.tform.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,14 @@
164164
'passwort' => array (
165165
'datatype' => 'VARCHAR',
166166
'formtype' => 'PASSWORD',
167+
'validators' => array(
168+
0 => array(
169+
'type' => 'CUSTOM',
170+
'class' => 'validate_password',
171+
'function' => 'password_check',
172+
'errmsg' => 'weak_password_txt'
173+
)
174+
),
167175
'encryption' => 'CRYPT',
168176
'regex' => '',
169177
'errmsg' => '',

interface/web/admin/lib/lang/de_system_config.lng

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ $wb['customer_no_counter_txt'] = 'Kundennummer Zähler';
6666
$wb['session_timeout_txt'] = 'Session-Timeout (Minuten)';
6767
$wb['session_allow_endless_txt'] = '"Eingeloggt bleiben" aktivieren';
6868
$wb['No'] = 'Nein';
69+
$wb['min_password_length_txt'] = 'Minimale Passwortlänge';
70+
$wb['min_password_strength_txt'] = 'Minimale Passwortstärke';
6971
?>

interface/web/admin/lib/lang/en_system_config.lng

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,6 @@ $wb['customer_no_counter_txt'] = 'Customer No. counter';
6666
$wb['session_timeout_txt'] = 'Session timeout (minutes)';
6767
$wb['session_allow_endless_txt'] = 'Enable "stay logged in"';
6868
$wb['No'] = 'No';
69+
$wb['min_password_length_txt'] = 'Minimum password length';
70+
$wb['min_password_strength_txt'] = 'Minimum password strength';
6971
?>

interface/web/admin/templates/system_config_misc_edit.htm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ <h2><tmpl_var name="list_head_txt"></h2>
9090
<div class="multiField">
9191
{tmpl_var name='session_allow_endless'}
9292
</div>
93+
</div>
94+
<div class="ctrlHolder">
95+
<label for="min_password_length">{tmpl_var name='min_password_length_txt'}</label>
96+
<input name="min_password_length" id="min_password_length" value="{tmpl_var name='min_password_length'}" size="30" maxlength="255" type="text" class="textInput" />
97+
</div>
98+
<div class="ctrlHolder">
99+
<label for="min_password_strength">{tmpl_var name='min_password_strength_txt'}</label>
100+
<select name="min_password_strength" id="min_password_strength" class="selectInput formLengthHalf">
101+
{tmpl_var name='min_password_strength'}
102+
</select>
93103
</div>
94104
<div class="ctrlHolder">
95105
<p class="label">{tmpl_var name='maintenance_mode_txt'}</p>

0 commit comments

Comments
 (0)