I had some issues on my forum with admins picking horrible passwords, so I set out to find a way to force them to use good ones. After some messing around I figured out how to add cracklib[1] functionality to FUDforum.
Requirements:
PHP 4.0+ compiled with the '--with-crack' option
Cracklib 2.7 or greater
A cracklib dictionary
Cracklib comes with most Linux distros, so I won't go over how to install it. You can make a dictionary from just about any text file, although cracklib comes with a pretty good one. It's typically stored in a directory like /usr/share/cracklib and will consist of three files, pw_dict.hwm, pw_dict.pwd, and pw_dict.pwi. They might be located in a different place or named something different on your computer.
Now, you need to open the file rpasswd.php.t in the FUDforum/src directory in a text editor, ideally one that doesn't use word wrap. From the command line I use nano -w.
Scroll through and find the section that looks like this:
if (isset($_POST['btn_submit'], $_POST['passwd1'], $_POST['cpasswd']) && is_string($_POST['passwd1'])) {
if (__fud_real_user__ != q_singleval("SELECT id FROM {SQL_TABLE_PREFIX}users WHERE login='".addslashes($usr->login)."' AND passwd='".md5((string)$_POST['cpasswd'])."'")) {
$rpasswd_error_msg = '{TEMPLATE: rpasswd_invalid_passwd}';
} else if ($_POST['passwd1'] !== $_POST['passwd2']) {
$rpasswd_error_msg = '{TEMPLATE: rpasswd_passwd_nomatch}';
} else if (strlen($_POST['passwd1']) < 6 ) {
$rpasswd_error_msg = '{TEMPLATE: rpasswd_passwd_length}';
} else {
q("UPDATE {SQL_TABLE_PREFIX}users SET passwd='".md5($_POST['passwd1'])."' WHERE id=".__fud_real_user__);
logaction(__fud_real_user__, 'CHANGE_PASSWD', 0, get_ip());
exit('<html><script>window.close();</script></html>');
}
$rpasswd_error = '{TEMPLATE: rpasswd_error}';
} else {
$rpasswd_error = '';
}
You need to change it so it looks like this (you might want to edit this to make it work how you want):
if (isset($_POST['btn_submit'], $_POST['passwd1'], $_POST['cpasswd']) && is_string($_POST['passwd1'])) {
if (__fud_real_user__ != q_singleval("SELECT id FROM fud26_users WHERE login='".addslashes($usr->login)."' AND passwd='".md5((string)$_POST['cpasswd'])."'")) {
$rpasswd_error_msg = 'Invalid Password';
}
else
{
$temppass = $_POST['passwd1'];
$dictionary = crack_opendict('/usr/share/cracklib/pw_dict') or die('Unable to open CrackLib dictionary');
$check = crack_check($dictionary, "$temppass");
$diag = crack_getlastmessage();
if ($diag != "strong password")
{
$rpasswd_error_msg = "Password error: $diag";
}
else if ($_POST['passwd1'] !== $_POST['passwd2']) {
$rpasswd_error_msg = 'Passwords do not match';
} else if (strlen($_POST['passwd1']) < 6 ) {
$rpasswd_error_msg = 'Password must be at least 6 characters long';
} else {
q("UPDATE fud26_users SET passwd='".md5($_POST['passwd1'])."' WHERE id=".__fud_real_user__);
logaction(__fud_real_user__, 'CHANGE_PASSWD', 0, get_ip());
exit('<html><script>window.close();</script></html>');
}
$rpasswd_error = '<tr><td class="rpasswdE" colspan=2>'.$rpasswd_error_msg.'</td></tr>';
}
}
else {
$rpasswd_error = '';
}
That'll make it so that current users will need to pick good passwords when changing their passwords. The following will make it so new users must also pick good passwords.
Edit register.php.t and find this section:
$_POST['reg_plaintext_passwd'] = trim($_POST['reg_plaintext_passwd']);
if (strlen($_POST['reg_plaintext_passwd']) < 6) {
set_err('reg_plaintext_passwd', '{TEMPLATE: register_err_shortpasswd}');
}
$_POST['reg_plaintext_passwd_conf'] = trim($_POST['reg_plaintext_passwd_conf']);
if ($_POST['reg_plaintext_passwd'] !== $_POST['reg_plaintext_passwd_conf']) {
set_err('reg_plaintext_passwd', '{TEMPLATE: register_err_passwdnomatch}');
}
You'll need to change it to this (or whatever works for you):
$_POST['reg_plaintext_passwd'] = trim($_POST['reg_plaintext_passwd']);
if (strlen($_POST['reg_plaintext_passwd']) < 6) {
set_err('reg_plaintext_passwd', '{TEMPLATE: register_err_shortpasswd}');
}
$temppass = $_POST['reg_plaintext_passwd'];
$dictionary = crack_opendict('/usr/share/cracklib/pw_dict') or die('Unable to open CrackLib dictionary');
$check = crack_check($dictionary, "$temppass");
$diag = crack_getlastmessage();
if ($diag != "strong password")
{
set_err('reg_plaintext_passwd', "Password error: $diag");
}
$_POST['reg_plaintext_passwd_conf'] = trim($_POST['reg_plaintext_passwd_conf']);
if ($_POST['reg_plaintext_passwd'] !== $_POST['reg_plaintext_passwd_conf']) {
set_err('reg_plaintext_passwd', '{TEMPLATE: register_err_passwdnomatch}');
}
Really, with Cracklib there's no need to even have the built-in length restrictions, but I just tried to mess with the original code as little as possible. Let me know what you all think of this.
1: Cracklib: A C library used to check the strength of passwords. It's used by most Linux/UNIX systems that support Pluggable Access Modules.
[Updated on: Sat, 03 September 2005 09:25]
Report message to a moderator