Squirrel Mail - Change Password Plugin - Wicked Simple Version

It's a long sad story as to why I set up an email server. Mostly long. Arguably not sad, since it is collecting email.

However, lacking the usual accessories provided by a hosting company and having issued a collection of awful (secure) passwords, it was abundantly clear a password reset mechanism would be required.

This isn't really suitable for password recovery, because it relies on the person being able to log into Squirrel Mail to change their password. If they have already forgotten it - they're toast.

Thus - one must encourage the users to set the password to something they have a chance at typing correctly and maybe remembering.

Please note I'm not implying the users are incapable of handling a password. I issued passwords which would be difficult to type and virtually impossible to remember.

Here's the code ...


include_once(SM_PATH 'include/validate.php');
// Make sure plugin is activated!
global $plugins;
if (!in_array('change_password'$plugins))
global $color;
sqgetGlobalVar('username',   $username,     SQ_SESSION);
$error $message null;
$dbConn pg_connect('dbname=mail user=somebody password=supersecret');
if ($dbConn !== false) {
    if (!empty($_POST['current-password'])) {
        $currentPassword preg_replace('/[^a-z0-9\_\@\#\$\%\^\&\*\(\)\+\?\>\<\;\:]/i','',$_POST['current-password']);
        $query 'SELECT password FROM users WHERE userid = $1';
        $result pg_query_params($query,[$username]);
        if (pg_affected_rows($result) === 1) {
            $row pg_fetch_assoc($result);
            $passwordPieces explode('$',$row['password']);
            $encryptedCheck '{SHA512-CRYPT}' crypt($currentPassword'$6$'.$passwordPieces[2].'$');
            if ($encryptedCheck !== $row['password']) {
                $error 'Current password mismatch';
        } else {
            $error 'Current user mismatch';
    if ($error === null && isset($_POST['new-password'],$_POST['confirm-password'])) {
        $newPassword trim($_POST['new-password']);
        $confirmPassword trim($_POST['confirm-password']);
        if (strlen($newPassword) < MIN_PASSWORD) {
            $error 'Password must be at least '.MIN_PASSWORD.' characters';
        } else {
            if ($newPassword !== $confirmPassword) {
                $error 'Passwords must match';
            } else {
                $checkForUppercase preg_match('/[A-Z]/',$newPassword);
                $checkForLowercase preg_match('/[a-z]/',$newPassword);
                $checkForDigit preg_match('/\d/',$newPassword);
                $checkForSymbol preg_match('/[\_\!\@\#\$\%\^\&\*\(\)\+\?\>\<\;\:]/',$newPassword);
                if ($checkForUppercase && $checkForLowercase && $checkForDigit && $checkForSymbol) {
                    $random str_shuffle(md5(rand(-1000,1000)));
                                        $encrypted '{SHA512-CRYPT}' crypt($newPassword'$6$'.$random.'$');
                    $query 'UPDATE users SET password = $1 WHERE userid = $2';
                    $result pg_query_params($query,[$encrypted,$username]);
                    if (pg_affected_rows($result) === 1) {
                        $message 'Success';
                    } else {
                        $error 'Unable to update the password';
                } else {
                    $error 'Password must contain at least one uppercase letter, one lowercase letter, one digit, and one symbol';
} else {
    $error 'Unable to update the password';
<?php if ($error !== null) : ?>
<div id="error" style="background-color:#fff;color:#000;padding:5px;margin:5px;">
<p><?= $error ?></p>
<?php endif ?>
<?php if ($message !== null) : ?>
<div id="message" style="background-color:#fff;color:#000;padding:5px;margin:5px;">
<p><?= $message ?></p>
<?php endif ?>
<form action="change_password.php" method="post">
<div class="block">
<p><label for="current-password">Current Password</label><br /><input type="password" name="current-password" id="current-password" /></p>
<div class="block">
<p><label for="new-password">New Password</label><br /><input type="password" name="new-password" id="new-password" /></p>
<div class="block">
<p><label for="confirm-password">Confirm Password</label><br /><input type="password" name="confirm-password" id="confirm-password" /></p>
<p><br /><br />
<button type="submit">Submit</button><br />
<button type="reset">Reset</button></p>

The rest of the files to make the plugin work and the internationalization are left to you dear reader. This is just the stuff you need to make it work.


The blog code formatter modified my HTML. That's okay - what I'm really sharing is the PHP.