I was looking around the forums and couldn't find any solution for using other algorithms with the SQL driver, so I decided to write my own modified version of the driver so it can use any algorithm dovecot can.
I haven't tested it extensively, so it may need adjusting but so far it's 100% compatible with CRAM-MD5. The SQL query syntax is the same as the SQL driver, with the exception that in this driver %c and %n have the same value.
All in all this should be a drop in replacement for the SQL driver... Well, that killed 45 minutes, time for coffee.;D
Important note: DIGEST-MD5 will not work. Also, the query given here is meant for a database setup for use with postfixadmin. Lastly, if SELinux is enabled on your system, this script may not work without additional policies in place.
set driver in (roundcube root)/plugins/password/config.inc.php:
$rcmail_config['password_driver'] = 'dovecotpw-sql';
Add these lines to (roundcube root)/plugins/password/config.inc.php:
// dovecotpw executable, default '/usr/sbin/dovecotpw'(CentOS)
$rcmail_config['password_dovecotpw'] = '/usr/sbin/dovecotpw';
// dovecotpw algorithm, default 'CRAM-MD5', run 'dovecotpw -l' to list possibilities, DIGEST-MD5 will not work
$rcmail_config['password_dovecotpw_algorithm'] = 'CRAM-MD5';
// PEAR database DSN
$rcmail_config['password_dovecotpw_db_dsn'] = 'mysql://db_user:db_pass@unix(/var/lib/mysql/mysql.sock)/database_name';
// SQL Query see SQL Driver for details about syntax
$rcmail_config['password_dovecotpw_query'] = 'UPDATE mailbox SET password = %c, modified=now() WHERE username = %u LIMIT 1;';
Create this file (roundcube root)/plugins/password/drivers/dovecotpw-sql.php
/**
* dovecot-SQL Password Driver
*
* Driver for passwords stored in SQL database encrypted using the dovecotpw utility
*
* @version 0.1
* @author Kaz Walker
* @contributing author Aleksander 'A.L.E.C' Machniak
*
*/
function password_save($curpass, $passwd)
{
$rcmail = rcmail::get_instance();
if (!($sql = $rcmail->config->get('password_dovecotpw_query')))
$sql = 'SELECT update_passwd(%c, %u)';
if ($dsn = $rcmail->config->get('password_dovecotpw_db_dsn')) {
// #1486067: enable new_link option
if (is_array($dsn) && empty($dsn['new_link']))
$dsn['new_link'] = true;
else if (!is_array($dsn) && !preg_match('/\?new_link=true/', $dsn))
$dsn .= '?new_link=true';
$db = new rcube_mdb2($dsn, '', FALSE);
$db->set_debug((bool)$rcmail->config->get('sql_debug'));
$db->db_connect('w');
} else {
$db = $rcmail->get_dbh();
}
if ($err = $db->is_error())
return PASSWORD_ERROR;
if (!($pw_algo = $rcmail->config->get('password_dovecotpw_algorithm')))
$pw_algo = 'CRAM-MD5';
if (!($dovecotpw = $rcmail->config->get('password_dovecotpw')))
$dovecotpw = '/usr/sbin/dovecotpw';
// encrypt password
if (strpos($sql, '%c') !== FALSE) {
$enc_passwd = '';
$safe_passwd = escapeshellarg($passwd);
$dovotpw_com = "$dovecotpw -p $safe_passwd -s $pw_algo";
if ($pw_algo != null && $safe_passwd != null) {
$tmp_passwd = shell_exec($dovotpw_com);
$tmp_passwd = explode("}", $tmp_passwd);
$enc_passwd = trim($tmp_passwd[1]);
} else {
return PASSWORD_CRYPT_ERROR;
}
$sql = str_replace('%c', $db->quote($enc_passwd, 'text'), $sql);
}
if (strpos($sql, '%n') !== FALSE) {
$safe_passwd = escapeshellarg($passwd);
$dovotpw_com = "$dovecotpw -p $safe_passwd -s $pw_algo";
if(strpos($sql, '%c') !== FALSE) {
// Do nothing, $enc_pass is already set correctly
} else if ($pw_algo != null && $safe_passwd != null) {
$enc_passwd = '';
$tmp_passwd = shell_exec($dovotpw_com);
$tmp_passwd = explode("}", $tmp_passwd);
$enc_passwd = trim($tmp_passwd[1]);
} else {
return PASSWORD_CRYPT_ERROR;
}
$sql = str_replace('%n', $db->quote($enc_passwd, 'text'), $sql);
}
if (strpos($sql, '%q') !== FALSE) {
$enc_curpass = '';
$safe_curpass = escapeshellarg($curpass);
$dovotpw_com = "$dovecotpw -p $safe_curpass -s $pw_algo";
if ($pw_algo != null && $safe_curpass != null) {
$tmp_curpass = shell_exec($dovotpw_com);
$tmp_curpass = explode("}", $tmp_curpass);
$enc_curpass = trim($tmp_curpass[1]);
} else {
return PASSWORD_CRYPT_ERROR;
}
$sql = str_replace('%q', $db->quote($enc_curpass, 'text'), $sql);
}
$user_info = explode('@', $_SESSION['username']);
if (count($user_info) >= 2) {
$sql = str_replace('%l', $db->quote($user_info[0], 'text'), $sql);
$sql = str_replace('%d', $db->quote($user_info[1], 'text'), $sql);
}
$sql = str_replace('%u', $db->quote($_SESSION['username'],'text'), $sql);
$sql = str_replace('%h', $db->quote($_SESSION['imap_host'],'text'), $sql);
$sql = str_replace('%p', $db->quote($passwd,'text'), $sql);
$sql = str_replace('%o', $db->quote($curpass,'text'), $sql);
$res = $db->query($sql);
if (!$db->is_error()) {
if (strtolower(substr(trim($query),0,6))=='select') {
if ($result = $db->fetch_array($res))
return PASSWORD_SUCCESS;
} else {
if ($db->affected_rows($res) == 1)
return PASSWORD_SUCCESS; // This is the good case: 1 row updated
}
}
return PASSWORD_ERROR;
}
?>
Quote from: Kaz;27069I was looking around the forums and couldn't find any solution for using other algorithms with the SQL driver, so I decided to write my own modified version of the driver so it can use any algorithm dovecot can.
SWEET!!! Happy to have given this a try and feedback to follow.
Quote from: Kaz;27069I haven't tested it extensively, so it may need adjusting but so far it's 100% compatible with CRAM-MD5. The SQL query syntax is the same as the SQL driver, with the exception that in this driver %c and %n have the same value.
This almost worked. After running "/usr/sbin/dovecotpw -l" I found that my version of dovecot (1.2.11) was happy to support: CRYPT MD5 MD5-CRYPT SHA SHA1 SHA256 SMD5 SSHA SSHA256 PLAIN CLEARTEXT CRAM-MD5 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA.
Of course I require MD5-CRYPT as that's how I've setup postfixadmin and dovecot so I altered the "dovecotpw_algorithm" in (roundcube root)/plugins/password/config.inc.php and the "pw_algo" variable in (roundcube root)/plugins/password/drivers/dovecotpw-sql.php to same. Works a treat. Thanks heaps for doing that. Much appreciated.
:-*
Quote from: VampX;27394This almost worked. After running "/usr/sbin/dovecotpw -l" I found that my version of dovecot (1.2.11) was happy to support: CRYPT MD5 MD5-CRYPT SHA SHA1 SHA256 SMD5 SSHA SSHA256 PLAIN CLEARTEXT CRAM-MD5 HMAC-MD5 DIGEST-MD5 PLAIN-MD4 PLAIN-MD5 LDAP-MD5 LANMAN NTLM OTP SKEY RPA.
Of course I require MD5-CRYPT as that's how I've setup postfixadmin and dovecot so I altered the "dovecotpw_algorithm" in (roundcube root)/plugins/password/config.inc.php and the "pw_algo" variable in (roundcube root)/plugins/password/drivers/dovecotpw-sql.php to same. Works a treat. Thanks heaps for doing that. Much appreciated.
:-*
Thanks, sadly about 2 hours after I wrote this, I realized that the 0.4 beta supports this functionality out of the box, so I switched to that on my server. But it's nice to know that this code lives on being useful somewhere else.:)
Just to let you know, modifying $pw_algo in (roundcube root)/plugins/password/drivers/dovecotpw-sql.php wasn't necessary, it only gets set to CRAM-MD5 is there's no algorithm setting in (roundcube root)/plugins/password/config.inc.php
Quote
Thanks, sadly about 2 hours after I wrote this, I realized that the 0.4 beta supports this functionality out of the box, so I switched to that on my server. But it's nice to know that this code lives on being useful somewhere else.:)
I know this is an old post, but it seems that dovecot functionality in the change password plugin is still missing. I did not understand the quoted part above. What functionality is included in beta 0.4?