From 7b938845cf265114c6cb2b02228ff9d10b676016 Mon Sep 17 00:00:00 2001 From: Marius Cramer <m.cramer@pixcept.de> Date: Mon, 10 Mar 2014 06:18:26 -0400 Subject: [PATCH] Added system option to configure minimum password strength and length --- interface/web/admin/lib/lang/en_system_config.lng | 2 interface/web/sites/form/ftp_user.tform.php | 8 + interface/web/sites/form/web_vhost_subdomain.tform.php | 8 + install/tpl/system.ini.master | 2 interface/web/client/form/client.tform.php | 8 + interface/web/sites/form/database_user.tform.php | 8 + interface/web/admin/form/users.tform.php | 8 + interface/web/admin/lib/lang/de_system_config.lng | 2 interface/web/sites/form/webdav_user.tform.php | 8 + interface/web/admin/form/system_config.tform.php | 14 ++ interface/web/mailuser/form/mail_user_password.tform.php | 8 + interface/web/admin/form/remote_user.tform.php | 8 + interface/web/tools/form/user_settings.tform.php | 8 + interface/web/mail/form/mail_user.tform.php | 8 + interface/lib/classes/validate_password.inc.php | 121 ++++++++++++++++++++++++ interface/lib/lang/en.lng | 9 + interface/web/mail/form/mail_mailinglist.tform.php | 8 + interface/lib/lang/de.lng | 8 + interface/web/sites/form/web_folder_user.tform.php | 8 + interface/web/client/form/reseller.tform.php | 8 + interface/web/sites/form/shell_user.tform.php | 8 + interface/web/sites/form/web_domain.tform.php | 8 + interface/web/admin/templates/system_config_misc_edit.htm | 10 ++ interface/web/js/scrigo.js.php | 9 + 24 files changed, 295 insertions(+), 2 deletions(-) diff --git a/install/tpl/system.ini.master b/install/tpl/system.ini.master index 1f305dd..2b1a6d7 100644 --- a/install/tpl/system.ini.master +++ b/install/tpl/system.ini.master @@ -51,3 +51,5 @@ customer_no_counter=0 session_timeout=0 session_allow_endless=0 +min_password_length=5 +min_password_strength=0 diff --git a/interface/lib/classes/validate_password.inc.php b/interface/lib/classes/validate_password.inc.php new file mode 100644 index 0000000..9619637 --- /dev/null +++ b/interface/lib/classes/validate_password.inc.php @@ -0,0 +1,121 @@ +<?php + +/* +Copyright (c) 2007, Till Brehm, projektfarm Gmbh +Copyright (c) 2014, Marius Cramer, pixcept KG +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of ISPConfig nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +class validate_password { + + private function _get_password_strength($password) { + $length = strlen($password); + $points = 0; + if ($length < 5) { + return 1; + } + + if (preg_match('/[ABCDEFGHIJKLNMOPQRSTUVWXYZ]/', $password)) { + $points += 1; + } + + if (preg_match('/[0123456789]/', $password)) { + $points += 1; + } + + if (preg_match('/[`~!@#$%^&*()_+|\\=-[]}{\';:\/?.>,<" ]/', $password)) { + $points += 1; + } + + if ($points == 0) { + if ($length >= 5 && $length <= 6) { + return 1; + } else if ($length >= 7 && $length <= 8) { + return 2; + } else { + return 3; + } + } else if ($points == 1) { + if ($length >= 5 && $length <= 6) { + return 2; + } else if (length >= 7 && length <=10) { + return 3; + } else { + return 4; + } + } else if ($points == 2) { + if ($length >= 5 && $length <= 8) { + return 3; + } else if ($length >= 9 && $length <= 10) { + return 4; + } else { + return 5; + } + } else if ($points == 3) { + if ($length >= 5 && $length <= 6) { + return 3; + } else if ($length >= 7 && $length <= 8) { + return 4; + } else { + return 5; + } + } else if ($points >= 4) { + if ($length >= 5 && $length <= 6) { + return 4; + } else { + return 5; + } + } + + } + + /* Validator function */ + function password_check($field_name, $field_value, $validator) { + global $app; + + $app->uses('ini_parser,getconf'); + $server_config_array = $app->getconf->get_global_config(); + + $min_password_strength = 0; + $min_password_length = 5; + if(isset($server_config_array['misc']['min_password_length'])) $min_password_length = $server_config_array['misc']['min_password_length']; + if(isset($server_config_array['misc']['min_password_strength'])) $min_password_strength = $server_config_array['misc']['min_password_strength']; + + if($min_password_strength > 0) { + $lng_text = $app->lng('weak_password_txt'); + $lng_text = str_replace(array('{chars}', '{strength}'), array($min_password_length, $app->lng('strength_' . $min_password_strength)), $lng_text); + } else { + $lng_text = $app->lng('weak_password_length_txt'); + $lng_text = str_replace('{chars}', $min_password_length, $lng_text); + } + if(!$lng_text) $lng_text = 'weak_password_txt'; // always return a string, even if language is missing - otherwise validator is NOT MATCHING! + + if(strlen($field_value) < $min_password_length) return $lng_text; + if($this->_get_password_strength($field_value) < $min_password_strength) return $lng_text; + + return false; + } +} diff --git a/interface/lib/lang/de.lng b/interface/lib/lang/de.lng index 91300ea..920e2ce 100644 --- a/interface/lib/lang/de.lng +++ b/interface/lib/lang/de.lng @@ -139,4 +139,12 @@ $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.'; $wb['yes_txt'] = 'Ja'; $wb['no_txt'] = 'Nein'; +$wb['None'] = 'Keine'; +$wb['strength_1'] = 'Leicht'; +$wb['strength_2'] = 'Mittel'; +$wb['strength_3'] = 'Gut'; +$wb['strength_4'] = 'Stark'; +$wb['strength_5'] = 'Sehr stark'; +$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.'; +$wb['weak_password_length_txt'] = 'Das gewählte Passwort erfüllt die Sicherheitsanforderungen nicht. Es muss mindestens {chars} Zeichen lang sein.'; ?> \ No newline at end of file diff --git a/interface/lib/lang/en.lng b/interface/lib/lang/en.lng index a8939b9..ec309d9 100644 --- a/interface/lib/lang/en.lng +++ b/interface/lib/lang/en.lng @@ -141,4 +141,13 @@ $wb['client_cannot_be_deleted_because_of_billing_module_txt'] = 'This client has records in the billing module, therefore he cannot be deleted.'; $wb['yes_txt'] = 'Yes'; $wb['no_txt'] = 'No'; +$wb['None'] = 'None'; +$wb['strength_1'] = 'Weak'; +$wb['strength_2'] = 'Fair'; +$wb['strength_3'] = 'Good'; +$wb['strength_4'] = 'Strong'; +$wb['strength_5'] = 'Very Strong'; +$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}".'; +$wb['weak_password_length_txt'] = 'The chosen password does not match the security guidelines. It has to be at least {chars} chars in length.'; + ?> diff --git a/interface/web/admin/form/remote_user.tform.php b/interface/web/admin/form/remote_user.tform.php index fd765ce..1ab2b0e 100644 --- a/interface/web/admin/form/remote_user.tform.php +++ b/interface/web/admin/form/remote_user.tform.php @@ -101,6 +101,14 @@ 'remote_password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'MD5', 'default' => '', 'value' => '', diff --git a/interface/web/admin/form/system_config.tform.php b/interface/web/admin/form/system_config.tform.php index 8d7008f..6054534 100644 --- a/interface/web/admin/form/system_config.tform.php +++ b/interface/web/admin/form/system_config.tform.php @@ -487,6 +487,20 @@ 'default' => 'n', 'value' => array(0 => 'n', 1 => 'y') ), + 'min_password_length' => array( + 'datatype' => 'INTEGER', + 'formtype' => 'TEXT', + 'default' => '5', + 'value' => '', + 'width' => '30', + 'maxlength' => '255' + ), + 'min_password_strength' => array( + 'datatype' => 'VARCHAR', + 'formtype' => 'SELECT', + 'default' => '', + 'value' => array('' => 'None', '1' => 'strength_1', '2' => 'strength_2', '3' => 'strength_3', '4' => 'strength_4', '5' => 'strength_5') + ) //################################# // ENDE Datatable fields //################################# diff --git a/interface/web/admin/form/users.tform.php b/interface/web/admin/form/users.tform.php index 06f07c0..9ee2970 100644 --- a/interface/web/admin/form/users.tform.php +++ b/interface/web/admin/form/users.tform.php @@ -164,6 +164,14 @@ 'passwort' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'regex' => '', 'errmsg' => '', diff --git a/interface/web/admin/lib/lang/de_system_config.lng b/interface/web/admin/lib/lang/de_system_config.lng index f4103d5..9c97821 100644 --- a/interface/web/admin/lib/lang/de_system_config.lng +++ b/interface/web/admin/lib/lang/de_system_config.lng @@ -66,4 +66,6 @@ $wb['session_timeout_txt'] = 'Session-Timeout (Minuten)'; $wb['session_allow_endless_txt'] = '"Eingeloggt bleiben" aktivieren'; $wb['No'] = 'Nein'; +$wb['min_password_length_txt'] = 'Minimale Passwortlänge'; +$wb['min_password_strength_txt'] = 'Minimale Passwortstärke'; ?> \ No newline at end of file diff --git a/interface/web/admin/lib/lang/en_system_config.lng b/interface/web/admin/lib/lang/en_system_config.lng index d78478e..f0e0193 100644 --- a/interface/web/admin/lib/lang/en_system_config.lng +++ b/interface/web/admin/lib/lang/en_system_config.lng @@ -66,4 +66,6 @@ $wb['session_timeout_txt'] = 'Session timeout (minutes)'; $wb['session_allow_endless_txt'] = 'Enable "stay logged in"'; $wb['No'] = 'No'; +$wb['min_password_length_txt'] = 'Minimum password length'; +$wb['min_password_strength_txt'] = 'Minimum password strength'; ?> diff --git a/interface/web/admin/templates/system_config_misc_edit.htm b/interface/web/admin/templates/system_config_misc_edit.htm index ea9844e..2fd6eef 100644 --- a/interface/web/admin/templates/system_config_misc_edit.htm +++ b/interface/web/admin/templates/system_config_misc_edit.htm @@ -91,6 +91,16 @@ {tmpl_var name='session_allow_endless'} </div> </div> + <div class="ctrlHolder"> + <label for="min_password_length">{tmpl_var name='min_password_length_txt'}</label> + <input name="min_password_length" id="min_password_length" value="{tmpl_var name='min_password_length'}" size="30" maxlength="255" type="text" class="textInput" /> + </div> + <div class="ctrlHolder"> + <label for="min_password_strength">{tmpl_var name='min_password_strength_txt'}</label> + <select name="min_password_strength" id="min_password_strength" class="selectInput formLengthHalf"> + {tmpl_var name='min_password_strength'} + </select> + </div> <div class="ctrlHolder"> <p class="label">{tmpl_var name='maintenance_mode_txt'}</p> <div class="multiField"> diff --git a/interface/web/client/form/client.tform.php b/interface/web/client/form/client.tform.php index 41e49b6..623f92e 100644 --- a/interface/web/client/form/client.tform.php +++ b/interface/web/client/form/client.tform.php @@ -166,6 +166,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption'=> 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/client/form/reseller.tform.php b/interface/web/client/form/reseller.tform.php index a372109..99e7c6e 100644 --- a/interface/web/client/form/reseller.tform.php +++ b/interface/web/client/form/reseller.tform.php @@ -166,6 +166,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption'=> 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/js/scrigo.js.php b/interface/web/js/scrigo.js.php index ec7cdb9..be5d44f 100644 --- a/interface/web/js/scrigo.js.php +++ b/interface/web/js/scrigo.js.php @@ -522,8 +522,13 @@ } - -var pass_minimum_length = 5; +<?php +$min_password_length = 5; +if(isset($server_config_array['misc']['min_password_length'])) { + $min_password_length = $app->functions->intval($server_config_array['misc']['min_password_length']); +} +?> +var pass_minimum_length = <?php echo $min_password_length; ?>; var pass_messages = new Array(); var pass_message = new Array(); diff --git a/interface/web/mail/form/mail_mailinglist.tform.php b/interface/web/mail/form/mail_mailinglist.tform.php index dbd7c0e..24c4f00 100644 --- a/interface/web/mail/form/mail_mailinglist.tform.php +++ b/interface/web/mail/form/mail_mailinglist.tform.php @@ -132,6 +132,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption'=> 'CLEARTEXT', 'default' => '', 'value' => '', diff --git a/interface/web/mail/form/mail_user.tform.php b/interface/web/mail/form/mail_user.tform.php index 66bc8e3..fdfd6a6 100644 --- a/interface/web/mail/form/mail_user.tform.php +++ b/interface/web/mail/form/mail_user.tform.php @@ -120,6 +120,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption'=> 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/mailuser/form/mail_user_password.tform.php b/interface/web/mailuser/form/mail_user_password.tform.php index 65cf076..a11982e 100644 --- a/interface/web/mailuser/form/mail_user_password.tform.php +++ b/interface/web/mailuser/form/mail_user_password.tform.php @@ -61,6 +61,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/database_user.tform.php b/interface/web/sites/form/database_user.tform.php index a270fb1..6afb34b 100644 --- a/interface/web/sites/form/database_user.tform.php +++ b/interface/web/sites/form/database_user.tform.php @@ -102,6 +102,14 @@ 'database_password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'MYSQL', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/ftp_user.tform.php b/interface/web/sites/form/ftp_user.tform.php index b540ec0..20e4565 100644 --- a/interface/web/sites/form/ftp_user.tform.php +++ b/interface/web/sites/form/ftp_user.tform.php @@ -110,6 +110,14 @@ ), 'password' => array ( 'datatype' => 'VARCHAR', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'formtype' => 'PASSWORD', 'encryption' => 'CRYPT', 'default' => '', diff --git a/interface/web/sites/form/shell_user.tform.php b/interface/web/sites/form/shell_user.tform.php index d9928e6..ab7cef1 100644 --- a/interface/web/sites/form/shell_user.tform.php +++ b/interface/web/sites/form/shell_user.tform.php @@ -111,6 +111,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/web_domain.tform.php b/interface/web/sites/form/web_domain.tform.php index 59f38b5..651b643 100644 --- a/interface/web/sites/form/web_domain.tform.php +++ b/interface/web/sites/form/web_domain.tform.php @@ -478,6 +478,14 @@ 'stats_password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/web_folder_user.tform.php b/interface/web/sites/form/web_folder_user.tform.php index 19ca71c..c3386a5 100644 --- a/interface/web/sites/form/web_folder_user.tform.php +++ b/interface/web/sites/form/web_folder_user.tform.php @@ -98,6 +98,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/web_vhost_subdomain.tform.php b/interface/web/sites/form/web_vhost_subdomain.tform.php index 1448a64..e4ca6a2 100644 --- a/interface/web/sites/form/web_vhost_subdomain.tform.php +++ b/interface/web/sites/form/web_vhost_subdomain.tform.php @@ -468,6 +468,14 @@ 'stats_password' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption' => 'CRYPT', 'default' => '', 'value' => '', diff --git a/interface/web/sites/form/webdav_user.tform.php b/interface/web/sites/form/webdav_user.tform.php index d17f3ed..a1bfd30 100644 --- a/interface/web/sites/form/webdav_user.tform.php +++ b/interface/web/sites/form/webdav_user.tform.php @@ -104,6 +104,14 @@ 'password' => array ( 'datatype' => 'VARCHAR', 'encryption' => 'CLEARTEXT', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'formtype' => 'PASSWORD', 'default' => '', 'value' => '', diff --git a/interface/web/tools/form/user_settings.tform.php b/interface/web/tools/form/user_settings.tform.php index 4ceda58..f3ad5a2 100644 --- a/interface/web/tools/form/user_settings.tform.php +++ b/interface/web/tools/form/user_settings.tform.php @@ -104,6 +104,14 @@ 'passwort' => array ( 'datatype' => 'VARCHAR', 'formtype' => 'PASSWORD', + 'validators' => array( + 0 => array( + 'type' => 'CUSTOM', + 'class' => 'validate_password', + 'function' => 'password_check', + 'errmsg' => 'weak_password_txt' + ) + ), 'encryption'=> 'CRYPT', 'regex' => '', 'errmsg' => '', -- Gitblit v1.9.1