This documentation is for Dovecot v2.x, see wiki1 for v1.x documentation.
Differences between revisions 1 and 15 (spanning 14 versions)
Revision 1 as of 2011-04-14 11:02:53
Size: 3625
Editor: d54C144EF
Comment:
Revision 15 as of 2015-09-15 05:03:34
Size: 6840
Editor: ip-62-143-0-245
Comment:
Deletions are marked like this. Additions are marked like this.
Line 5: Line 5:
Line 7: Line 6:
Through the years computers are being faster and faster, and so with it the encryption of passwords have to more secure.
In this example we convert passwords stored in MySQL with basic CRYPT-encryption to SSHA256-encryption (Salted SHA256).
Through the years computers are being faster and faster, and so with it the encryption of passwords have to more secure. In this example we convert passwords stored in MySQL with basic CRYPT-encryption to SSHA256-encryption (Salted SHA256).
Line 15: Line 13:
 * Copy the CRYPT-passwords to a new field (newpw) but with the prefix {{{ {CRYPT} }}}  * Copy the CRYPT-passwords to a new field (newpw) but with the prefix {{{ {CRYPT} }}}. This might start you off in the right direction for mysql: {{{UPDATE `your_table` SET field_name = CONCAT('{CRYPT}', field_name)}}}
Line 17: Line 15:
Line 25: Line 24:
}}}
# Alternatively, here is another config that worked for me (note: uncomment the lines relevant for your setup):
#
# driver = mysql
# connect = host=127.0.0.1 user=mailauth password=secret dbname=postfixadmin
# default_pass_scheme = SHA512-CRYPT
# password_query = SELECT username AS user, password, CONCAT('/var/mail/vdomains/', maildir) as userdb_home, 'vmail' as userdb_uid, 'vmail' as userdb_gid, '%w' as userdb_plain_pass FROM mailbox WHERE username = '%u'
# user_query = SELECT CONCAT('/var/mail/vdomains/', maildir) AS home, 'vmail' AS uid, 'vmail' AS gid, password FROM mailbox WHERE username = '%u' AND active = 1

}}}
 * Make sure you configured

{{{
 userdb {
  driver = prefetch
}
}}}
Line 28: Line 43:
{{{
{{{#!highlight bash
Line 33: Line 49:

{{{
# Here is an alterate version that I used (note: uncomment the lines relevant for your setup including the ones I added for debugging purposes if needed):
# #!/usr/local/bin/bash
# echo "USER: $USER" >> /tmp/log
# echo "PLAIN-PASS: $PLAIN_PASS" >> /tmp/log
# DOVECOTPW=$(/usr/local/bin/doveadm pw -s SHA512-CRYPT -p "$PLAIN_PASS")
# echo $DOVECOTPW >> /tmp/log
# /usr/local/etc/convertpw.php $USER $DOVECOTPW
# exec "$@"
#

}}}
Line 34: Line 63:
{{{
{{{#!highlight php
Line 36: Line 66:
<? <?php
Line 42: Line 72:
$idfield = "id"; // fieldname where the userlogin is stored  $idfield = "id"; // fieldname where the userlogin is stored
Line 56: Line 86:
$link = mysql_connect ("$mysqlhost", "$mysqluse", "$mysqlpass") or die ("Could not connect"); $link = mysql_connect ("$mysqlhost", "$mysqluser", "$mysqlpass") or die ("Could not connect");
Line 60: Line 90:
 $salt=substr(sha1(uniqid()),18,8);
 $salt_ascii = hexToAscii($salt);
 $newq= "UPDATE $mysqltable SET $passfield='{SSHA256.hex}".hash('sha256',$ruw.$salt_ascii).$salt."' WHERE $idfield='".$usr."'";
 $res2 = mysql_query($newq);
        $salt=substr(sha1(uniqid()),18,8);
        $salt_ascii = hexToAscii($salt);
        $newq= "UPDATE $mysqltable SET $passfield='{SSHA256.hex}".hash('sha256',$ruw.$salt_ascii).$salt."' WHERE $idfield='".$usr."'";
        $res2 = mysql_query($newq);
Line 69: Line 99:
Line 80: Line 111:
# end insert  # end insert
Line 82: Line 113:
 * now reload dovecot.   * now reload dovecot.
Line 84: Line 115:
As of now each user which connects through POP will convert their password to SSHA256.
If you look at the database you will see for example {SSHA256.hex}fb0e7f39c88c1d7017169f7f6b9cd6977d1e3291149382b90da4a390a31e81bab3cdced8 instead off {CRYPT}$1$.gvrgDqc$Slvoapz5zkpVmmJAxi.0k1
As of now each user which connects through POP will convert their password to SSHA256. If you look at the database you will see for example {SSHA256.hex}fb0e7f39c88c1d7017169f7f6b9cd6977d1e3291149382b90da4a390a31e81bab3cdced8 instead off {CRYPT}$1$.gvrgDqc$Slvoapz5zkpVmmJAxi.0k1
Line 88: Line 118:

= SHA512-CRYPT =
To use SHA512-CRYPT passwords use {{{/usr/local/etc/popafter.sh}}}

{{{#!highlight bash
#!/bin/sh
DOVECOTPW=$(doveadm pw -s SHA512-CRYPT -p $PLAIN_PASS)
/usr/local/etc/convertpw.php $USER $DOVECOTPW
exec "$@"
}}}
{{{/usr/local/etc/convertpw.php}}}

{{{#!highlight php
#!/usr/bin/php
<?php
$mysqlhost = "127.0.0.1";
$mysqluser = "postfix"; // username which is used to connect to the database
$mysqlpass = "password"; // password which is used to connect to the database
$mysqldb = "postfix"; // databasename where the passwords are stored
$mysqltable = "mailbox"; // table where the passwords are stored
$idfield = "username"; // fieldname where the userlogin is stored
$passfield = "password"; // fieldname where the passwords is stored

$usr = $argv[1];
$dov = $argv[2];
function hexToAscii($hex){
    $strLength = strlen($hex);
    $returnVal = '';
    for($i=0; $i<$strLength; $i += 2) {
        $dec_val = hexdec(substr($hex, $i, 2));
        $returnVal .= chr($dec_val);
    }
    return $returnVal;
}
$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 WHERE $idfield = '$usr' AND $passfield like '{SHA%'");
if (mysql_num_rows($result)==0){
        $salt=substr(sha1(uniqid()),18,8);
        $salt_ascii = hexToAscii($salt);
        $newq= "UPDATE $mysqltable SET $passfield='".$dov."' WHERE $idfield='".$usr."'";
        $res2 = mysql_query($newq);
}
exit;
?>
}}}
= selinux =
{{{#!highlight bash
chcon -u system_u /usr/local/etc/convertpw.php
chcon -t bin_t /usr/local/etc/convertpw.php
chcon -u system_u /usr/local/etc/popafter.sh
chcon -t bin_t /usr/local/etc/popafter.sh
}}}

Introduction

Through the years computers are being faster and faster, and so with it the encryption of passwords have to more secure. In this example we convert passwords stored in MySQL with basic CRYPT-encryption to SSHA256-encryption (Salted SHA256).

See Authentication/PasswordSchemes for a list of supported password schemes.

We used php to generate the new passwords, but you can use any language you want

Example

  • Copy the CRYPT-passwords to a new field (newpw) but with the prefix  {CRYPT} . This might start you off in the right direction for mysql: UPDATE `your_table` SET field_name = CONCAT('{CRYPT}', field_name)

  • Change dovecot-sql.conf, so it will look at the new fields

# Comment default_pass_scheme so dovecot will look at the prefix
# default_pass_scheme = CRYPT

# 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 = SELECT id as user, newpw as password, home as userdb_home, \
uid as userdb_uid, gid as userdb_gid, '%w' as userdb_plain_pass FROM users WHERE id = '%u'

# Alternatively, here is another config that worked for me (note: uncomment the lines relevant for your setup):
#
# driver = mysql
# connect = host=127.0.0.1 user=mailauth password=secret dbname=postfixadmin
# default_pass_scheme = SHA512-CRYPT
# password_query = SELECT username AS user, password, CONCAT('/var/mail/vdomains/', maildir) as userdb_home, 'vmail' as userdb_uid, 'vmail' as userdb_gid, '%w' as userdb_plain_pass FROM mailbox WHERE username = '%u'
# user_query = SELECT CONCAT('/var/mail/vdomains/', maildir) AS home, 'vmail' AS uid, 'vmail' AS gid, password FROM mailbox WHERE username = '%u' AND active = 1
  • Make sure you configured

 userdb {
  driver = prefetch
}
  • Now reload dovecot, and see everything is still working
  • Make the postlogin-script (which is executed after login) and save it as /usr/local/etc/popafter.sh

   1 #!/bin/sh
   2 /usr/local/etc/convertpw.php $USER $PLAIN_PASS
   3 exec "$@"

# Here is an alterate version that I used (note: uncomment the lines relevant for your setup including the ones I added for debugging purposes if needed):
# #!/usr/local/bin/bash
# echo "USER: $USER" >> /tmp/log
# echo "PLAIN-PASS: $PLAIN_PASS" >> /tmp/log
# DOVECOTPW=$(/usr/local/bin/doveadm pw -s SHA512-CRYPT -p "$PLAIN_PASS")
# echo $DOVECOTPW >> /tmp/log
# /usr/local/etc/convertpw.php $USER $DOVECOTPW
# exec "$@"
#
  • Make the php-script which updates the password and save it as /usr/local/etc/convertpw.php

   1 #!/usr/local/bin/php
   2 <?php
   3 $mysqlhost  = "localhost";
   4 $mysqluser  = "mysqlusername"; // username which is used to connect to the database
   5 $mysqlpass  = "mysqlpassword"; // password which is used to connect to the database
   6 $mysqldb    = "databasename";  // databasename where the passwords are stored
   7 $mysqltable = "users";         // table where the passwords are stored
   8 $idfield    = "id";            // fieldname where the userlogin is stored
   9 $passfield  = "newpw";         // fieldname where the passwords is stored
  10 
  11 $usr = $argv[1];
  12 $ruw = $argv[2];
  13 function hexToAscii($hex){
  14     $strLength = strlen($hex);
  15     $returnVal = '';
  16     for($i=0; $i<$strLength; $i += 2) {
  17         $dec_val = hexdec(substr($hex, $i, 2));
  18         $returnVal .= chr($dec_val);
  19     }
  20     return $returnVal;
  21 }
  22 $link = mysql_connect ("$mysqlhost", "$mysqluser", "$mysqlpass")  or die ("Could not connect");
  23 @mysql_select_db("$mysqldb") or die( "Unable to select database");
  24 $result = mysql_query("SELECT $passfield FROM $mysqltable WHERE $idfield = '$usr' AND $passfield like '{SSHA%'");
  25 if (mysql_num_rows($result)==0){
  26         $salt=substr(sha1(uniqid()),18,8);
  27         $salt_ascii = hexToAscii($salt);
  28         $newq= "UPDATE $mysqltable SET $passfield='{SSHA256.hex}".hash('sha256',$ruw.$salt_ascii).$salt."' WHERE $idfield='".$usr."'";
  29         $res2 = mysql_query($newq);
  30 }
  31 exit;
  32 ?>
  • update your dovecot.conf so it will use the scripts we just made

# insert these lines so dovecot uses our scripts
service pop3 {
  executable = pop3 pop3-postlogin
}
service pop3-postlogin {
  executable = script-login /usr/local/etc/popafter.sh
  user = $default_internal_user
  unix_listener pop3-postlogin {
  }
}
# end insert
  • now reload dovecot.

As of now each user which connects through POP will convert their password to SSHA256. If you look at the database you will see for example {SSHA256.hex}fb0e7f39c88c1d7017169f7f6b9cd6977d1e3291149382b90da4a390a31e81bab3cdced8 instead off {CRYPT}$1$.gvrgDqc$Slvoapz5zkpVmmJAxi.0k1

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

SHA512-CRYPT

To use SHA512-CRYPT passwords use /usr/local/etc/popafter.sh

   1 #!/bin/sh
   2 DOVECOTPW=$(doveadm pw -s SHA512-CRYPT -p $PLAIN_PASS)
   3 /usr/local/etc/convertpw.php $USER $DOVECOTPW
   4 exec "$@"

/usr/local/etc/convertpw.php

   1 #!/usr/bin/php
   2 <?php
   3 $mysqlhost  = "127.0.0.1";
   4 $mysqluser  = "postfix"; // username which is used to connect to the database
   5 $mysqlpass  = "password"; // password which is used to connect to the database
   6 $mysqldb    = "postfix";  // databasename where the passwords are stored
   7 $mysqltable = "mailbox";         // table where the passwords are stored
   8 $idfield    = "username";            // fieldname where the userlogin is stored
   9 $passfield  = "password";         // fieldname where the passwords is stored
  10 
  11 $usr = $argv[1];
  12 $dov = $argv[2];
  13 function hexToAscii($hex){
  14     $strLength = strlen($hex);
  15     $returnVal = '';
  16     for($i=0; $i<$strLength; $i += 2) {
  17         $dec_val = hexdec(substr($hex, $i, 2));
  18         $returnVal .= chr($dec_val);
  19     }
  20     return $returnVal;
  21 }
  22 $link = mysql_connect ("$mysqlhost", "$mysqluser", "$mysqlpass")  or die ("Could not connect");
  23 @mysql_select_db("$mysqldb") or die( "Unable to select database");
  24 $result = mysql_query("SELECT $passfield FROM $mysqltable WHERE $idfield = '$usr' AND $passfield like '{SHA%'");
  25 if (mysql_num_rows($result)==0){
  26         $salt=substr(sha1(uniqid()),18,8);
  27         $salt_ascii = hexToAscii($salt);
  28         $newq= "UPDATE $mysqltable SET $passfield='".$dov."' WHERE $idfield='".$usr."'";
  29         $res2 = mysql_query($newq);
  30 }
  31 exit;
  32 ?>

selinux

   1 chcon -u system_u /usr/local/etc/convertpw.php
   2 chcon -t bin_t /usr/local/etc/convertpw.php
   3 chcon -u system_u /usr/local/etc/popafter.sh
   4 chcon -t bin_t /usr/local/etc/popafter.sh

None: HowTo/ConvertPasswordSchemes (last edited 2018-12-09 20:31:10 by p54A9A6E3)