Dovecot/Coverting MD5 to SSHA256 passwords

< Dovecot
Version vom 19. Oktober 2012, 23:16 Uhr von Jonathan (Diskussion | Beiträge) (x)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

done in dovecot via PostLoginScript, see and

add a new field newpw in our database


service imap {
  # tell imap to do post-login lookup using a socket called "imap-postlogin"
  executable = imap imap-postlogin

# The service name below doesn't actually matter.
service imap-postlogin {
  # all post-login scripts are executed via script-login binary
  executable = script-login /etc/dovecot/

  # the script process runs as the user specified here (v2.0.14+):
  user = $default_internal_user
  # this UNIX socket listener must use the same name as given to imap executable
  unix_listener imap-postlogin {


# insert these lines so dovecot uses our scripts
service pop3 {
  executable = pop3 pop3-postlogin
service pop3-postlogin {
  executable = script-login /etc/dovecot/
  user = $default_internal_user
  unix_listener pop3-postlogin {
# end insert

increase limit or you will get errors like "auth-worker: Error: must be installed for pthread_cancel to work"

default_vsz_limit = 512M

# update your password_query so it will look at the new field
# AND add a %w field in the queury so we have the plain password in our Enviroment
password_query = /* dovecot-sql.conf password_query */ \
        SELECT '/srv/vmail/%d/%n' AS userdb_home, 'maildir:~/Maildir' AS userdb_mail, 112 AS userdb_uid, 119 AS userdb_gid, \
        CONCAT('*:bytes=', CAST(m.quota AS CHAR)) AS userdb_quota_rule, \
        CONCAT(m.local_part, '@', AS user,'%w' as userdb_plain_pass, m.password AS password \
        FROM mailboxes AS m LEFT JOIN domains AS d ON m.domain_id = \
        WHERE m.local_part = '%n' AND = '%d' AND m.is_active AND d.is_active

As of now each user which connects through POP/IMAP will convert their password to SSHA256.

If you look at the database you will see for example {SSHA256}fb0e7f39c88c1d7017169f7f6b9cd69xxxxx49382b90da4a390a31e81bab3cdced8 instead off {CRYPT}$1$.gvrgDqc$Sxxxx5zkpVmmJAxi.0k1

When every record is updated you can update dovecot.conf (remove the extra lines), and dovecot-sql (remove the %w-part).



/etc/dovecot/convertpw.php $USER $PLAIN_PASS
exec "$@"


#debug file, must exist
$filename = '/tmp/test2.txt';

if (!$handle = fopen($filename, "a")) {
    print "Kann die Datei $filename nicht öffnen";

$mysqlhost = "localhost";
$mysqluser = "vboxadm";
// username which is used to connect to the database

$mysqlpass = "xxx";
// password which is used to connect to the database

$mysqldb = "vboxadm";
// databasename where the passwords are stored

$mysqltable = "mailboxes";
// table where the passwords are stored

$passfield = "newpw";
// fieldname where the passwords is stored

$usr = explode("@",$argv[1]);
#fwrite($handle, "Checking User ".$argv[1]."\n");

#plain pass
$ruw = $argv[2];

function ssha256($pw) {
        #if(strlen($salt) < 1) {
                $salt = make_salt();
        return "{SSHA256}" . base64_encode( hash('sha256', $pw . $salt, TRUE ) . $salt );

function make_salt() {
        $len   = 4;
        $bytes = array();
        for ($i = 0; $i < $len; $i++ ) {
                $bytes[] = rand(1,255);
        $salt_str = '';
        foreach ($bytes as $b) {
                $salt_str .= pack('C', $b);
        return $salt_str;

$link = mysql_connect ("$mysqlhost", "$mysqluser", "$mysqlpass") or die ("Could not connect");
@mysql_select_db("$mysqldb") or die( "Unable to select database");
$result = mysql_query("SELECT $passfield FROM $mysqltable AS m LEFT JOIN domains AS d ON m.domain_id = WHERE m.local_part = '".$usr[
0]."' AND = '$usr[1]' AND $passfield like '{SSHA%'");

#fwrite($handle, "\n".mysql_num_rows($result)."\n");

if (mysql_num_rows($result)==0){
        $newq= "UPDATE $mysqltable,domains SET $mysqltable.$passfield='".ssha256($ruw)."' where $mysqltable.domain_id = and $m
ysqltable.local_part = '".$usr[0]."' AND = '".$usr[1]."'"; 
        $res2 = mysql_query($newq);
        fwrite($handle, "SQL: $newq\n");
 exit; ?>