diff options
Diffstat (limited to 'plugins/password/drivers')
-rw-r--r-- | plugins/password/drivers/chpasswd.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/cpanel.php | 110 | ||||
-rw-r--r-- | plugins/password/drivers/dbmail.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/directadmin.php | 3 | ||||
-rw-r--r-- | plugins/password/drivers/domainfactory.php | 117 | ||||
-rw-r--r-- | plugins/password/drivers/expect.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/hmail.php | 12 | ||||
-rw-r--r-- | plugins/password/drivers/ldap.php | 169 | ||||
-rw-r--r-- | plugins/password/drivers/ldap_simple.php | 228 | ||||
-rw-r--r-- | plugins/password/drivers/pam.php | 4 | ||||
-rw-r--r-- | plugins/password/drivers/pw_usermod.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/sasl.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/smb.php | 14 | ||||
-rw-r--r-- | plugins/password/drivers/sql.php | 19 | ||||
-rw-r--r-- | plugins/password/drivers/virtualmin.php | 2 | ||||
-rw-r--r-- | plugins/password/drivers/xmail.php | 16 |
16 files changed, 401 insertions, 303 deletions
diff --git a/plugins/password/drivers/chpasswd.php b/plugins/password/drivers/chpasswd.php index 137275e69..3ea10159c 100644 --- a/plugins/password/drivers/chpasswd.php +++ b/plugins/password/drivers/chpasswd.php @@ -26,7 +26,7 @@ class rcube_chpasswd_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/cpanel.php b/plugins/password/drivers/cpanel.php index b71c33ec1..79887109b 100644 --- a/plugins/password/drivers/cpanel.php +++ b/plugins/password/drivers/cpanel.php @@ -4,43 +4,95 @@ * cPanel Password Driver * * Driver that adds functionality to change the users cPanel password. - * Originally written by Fulvio Venturelli <fulvio@venturelli.org> + * The cPanel PHP API code has been taken from: http://www.phpclasses.org/browse/package/3534.html * - * Completely rewritten using the cPanel API2 call Email::passwdpop - * as opposed to the original coding against the UI, which is a fragile method that - * makes the driver to always return a failure message for any language other than English - * see http://trac.roundcube.net/ticket/1487015 + * This driver has been tested with Hostmonster hosting and seems to work fine. * - * This driver has been tested with o2switch hosting and seems to work fine. - * - * @version 3.0 - * @author Christian Chech <christian@chech.fr> + * @version 2.0 + * @author Fulvio Venturelli <fulvio@venturelli.org> */ class rcube_cpanel_password { public function save($curpas, $newpass) { - require_once 'xmlapi.php'; - $rcmail = rcmail::get_instance(); - $this->cuser = $rcmail->config->get('password_cpanel_username'); - - // Setup the xmlapi connection - $this->xmlapi = new xmlapi($rcmail->config->get('password_cpanel_host')); - $this->xmlapi->set_port($rcmail->config->get('password_cpanel_port')); - $this->xmlapi->password_auth($this->cuser, $rcmail->config->get('password_cpanel_password')); - $this->xmlapi->set_output('json'); - $this->xmlapi->set_debug(0); + // Create a cPanel email object + $cPanel = new emailAccount($rcmail->config->get('password_cpanel_host'), + $rcmail->config->get('password_cpanel_username'), + $rcmail->config->get('password_cpanel_password'), + $rcmail->config->get('password_cpanel_port'), + $rcmail->config->get('password_cpanel_ssl'), + $rcmail->config->get('password_cpanel_theme'), + $_SESSION['username'] ); - if ($this->setPassword($_SESSION['username'], $newpass)) { + if ($cPanel->setPassword($newpass)) { return PASSWORD_SUCCESS; } else { return PASSWORD_ERROR; } } +} + + +class HTTP +{ + function HTTP($host, $username, $password, $port, $ssl, $theme) + { + $this->ssl = $ssl ? 'ssl://' : ''; + $this->username = $username; + $this->password = $password; + $this->theme = $theme; + $this->auth = base64_encode($username . ':' . $password); + $this->port = $port; + $this->host = $host; + $this->path = '/frontend/' . $theme . '/'; + } + + function getData($url, $data = '') + { + $url = $this->path . $url; + if (is_array($data)) { + $url = $url . '?'; + foreach ($data as $key => $value) { + $url .= urlencode($key) . '=' . urlencode($value) . '&'; + } + $url = substr($url, 0, -1); + } + + $response = ''; + $fp = fsockopen($this->ssl . $this->host, $this->port); + if (!$fp) { + return false; + } + + $out = 'GET ' . $url . ' HTTP/1.0' . "\r\n"; + $out .= 'Authorization: Basic ' . $this->auth . "\r\n"; + $out .= 'Connection: Close' . "\r\n\r\n"; + fwrite($fp, $out); + while (!feof($fp)) { + $response .= @fgets($fp); + } + fclose($fp); + return $response; + } +} + + +class emailAccount +{ + function emailAccount($host, $username, $password, $port, $ssl, $theme, $address) + { + $this->HTTP = new HTTP($host, $username, $password, $port, $ssl, $theme); + if (strpos($address, '@')) { + list($this->email, $this->domain) = explode('@', $address); + } + else { + list($this->email, $this->domain) = array($address, ''); + } + } /** * Change email account password @@ -49,24 +101,16 @@ class rcube_cpanel_password * @param string $password email account password * @return bool */ - function setPassword($address, $password) + function setPassword($password) { - if (strpos($address, '@')) { - list($data['email'], $data['domain']) = explode('@', $address); - } - else { - list($data['email'], $data['domain']) = array($address, ''); - } - + $data['email'] = $this->email; + $data['domain'] = $this->domain; $data['password'] = $password; + $response = $this->HTTP->getData('mail/dopasswdpop.html', $data); - $query = $this->xmlapi->api2_query($this->cuser, 'Email', 'passwdpop', $data); - $query = json_decode($query, true); - - if ($query['cpanelresult']['data'][0]['result'] == 1) { + if (strpos($response, 'success') && !strpos($response, 'failure')) { return true; } - return false; } } diff --git a/plugins/password/drivers/dbmail.php b/plugins/password/drivers/dbmail.php index 529027b8d..e4c0d52e3 100644 --- a/plugins/password/drivers/dbmail.php +++ b/plugins/password/drivers/dbmail.php @@ -29,7 +29,7 @@ class rcube_dbmail_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/directadmin.php b/plugins/password/drivers/directadmin.php index 44ecea406..fb156cea9 100644 --- a/plugins/password/drivers/directadmin.php +++ b/plugins/password/drivers/directadmin.php @@ -43,7 +43,7 @@ class rcube_directadmin_password $response = $Socket->fetch_parsed_body(); //DEBUG - //rcube::console("Password Plugin: [USER: $da_user] [HOST: $da_host] - Response: [SOCKET: ".$Socket->result_status_code."] [DA ERROR: ".strip_tags($response['error'])."] [TEXT: ".$response[text]."]"); + //console("Password Plugin: [USER: $da_user] [HOST: $da_host] - Response: [SOCKET: ".$Socket->result_status_code."] [DA ERROR: ".strip_tags($response['error'])."] [TEXT: ".$response[text]."]"); if($Socket->result_status_code != 200) return array('code' => PASSWORD_CONNECT_ERROR, 'message' => $Socket->error[0]); @@ -297,6 +297,7 @@ class HTTPSocket { $status = socket_get_status($socket); $startTime = time(); $length = 0; + $prevSecond = 0; while ( !feof($socket) && !$status['timed_out'] ) { $chunk = fgets($socket,1024); diff --git a/plugins/password/drivers/domainfactory.php b/plugins/password/drivers/domainfactory.php index 9128720c9..7f6b8860e 100644 --- a/plugins/password/drivers/domainfactory.php +++ b/plugins/password/drivers/domainfactory.php @@ -4,9 +4,9 @@ * domainFACTORY Password Driver * * Driver to change passwords with the hosting provider domainFACTORY. - * http://www.df.eu/ + * See: http://www.df.eu/ * - * @version 2.1 + * @version 2.0 * @author Till Krüss <me@tillkruess.com> * @link http://tillkruess.com/projects/roundcube/ * @@ -14,76 +14,57 @@ class rcube_domainfactory_password { - function save($curpass, $passwd) - { - $rcmail = rcmail::get_instance(); + function save($curpass, $passwd) + { + $rcmail = rcmail::get_instance(); - if (is_null($curpass)) { - $curpass = $rcmail->decrypt($_SESSION['password']); - } + if (is_null($curpass)) { + $curpass = $rcmail->decrypt($_SESSION['password']); + } - if ($ch = curl_init()) { + if ($ch = curl_init()) { + // initial login + curl_setopt_array($ch, array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_URL => 'https://ssl.df.eu/chmail.php', + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => array( + 'login' => $rcmail->user->get_username(), + 'pwd' => $curpass, + 'action' => 'change' + ) + )); - // initial login - curl_setopt_array($ch, array( - CURLOPT_RETURNTRANSFER => true, - CURLOPT_URL => 'https://ssl.df.eu/chmail.php', - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => array( - 'login' => $rcmail->user->get_username(), - 'pwd' => $curpass, - 'action' => 'change' - ) - )); + if ($result = curl_exec($ch)) { + // login successful, get token! + $postfields = array( + 'pwd1' => $passwd, + 'pwd2' => $passwd, + 'action[update]' => 'Speichern' + ); - if ($result = curl_exec($ch)) { - // login successful, get token! - $postfields = array( - 'pwd1' => $passwd, - 'pwd2' => $passwd, - 'action[update]' => 'Speichern' - ); + preg_match_all('~<input name="(.+?)" type="hidden" value="(.+?)">~i', $result, $fields); + foreach ($fields[1] as $field_key => $field_name) { + $postfields[$field_name] = $fields[2][$field_key]; + } - preg_match_all('~<input name="(.+?)" type="hidden" value="(.+?)">~i', $result, $fields); - foreach ($fields[1] as $field_key => $field_name) { - $postfields[$field_name] = $fields[2][$field_key]; - } + // change password + $ch = curl_copy_handle($ch); + curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); + if ($result = curl_exec($ch)) { + if (strpos($result, 'Einstellungen erfolgreich') !== false) { + return PASSWORD_SUCCESS; + } + } else { + return PASSWORD_CONNECT_ERROR; + } + } else { + return PASSWORD_CONNECT_ERROR; + } + } else { + return PASSWORD_CONNECT_ERROR; + } - // change password - $ch = curl_copy_handle($ch); - curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); - if ($result = curl_exec($ch)) { - - // has the password been changed? - if (strpos($result, 'Einstellungen erfolgreich') !== false) { - return PASSWORD_SUCCESS; - } - - // show error message(s) if possible - if (strpos($result, '<div class="d-msg-text">') !== false) { - preg_match_all('#<div class="d-msg-text">(.*?)</div>#s', $result, $errors); - if (isset($errors[1])) { - $error_message = ''; - foreach ( $errors[1] as $error ) { - $error_message .= trim(mb_convert_encoding( $error, 'UTF-8', 'ISO-8859-15' )).' '; - } - return array('code' => PASSWORD_ERROR, 'message' => $error_message); - } - } - - - } else { - return PASSWORD_CONNECT_ERROR; - } - - } else { - return PASSWORD_CONNECT_ERROR; - } - - } else { - return PASSWORD_CONNECT_ERROR; - } - - return PASSWORD_ERROR; - } + return PASSWORD_ERROR; + } } diff --git a/plugins/password/drivers/expect.php b/plugins/password/drivers/expect.php index 1f68924df..7a191e254 100644 --- a/plugins/password/drivers/expect.php +++ b/plugins/password/drivers/expect.php @@ -45,7 +45,7 @@ class rcube_expect_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/hmail.php b/plugins/password/drivers/hmail.php index 650434617..104c851ae 100644 --- a/plugins/password/drivers/hmail.php +++ b/plugins/password/drivers/hmail.php @@ -5,6 +5,7 @@ * * @version 2.0 * @author Roland 'rosali' Liebl <myroundcube@mail4us.net> + * */ class rcube_hmail_password @@ -25,8 +26,8 @@ class rcube_hmail_password $obApp = new COM("hMailServer.Application"); } catch (Exception $e) { - rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage()))); - rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set."); + write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage()))); + write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set."); return PASSWORD_ERROR; } @@ -38,7 +39,8 @@ class rcube_hmail_password else { $domain = $rcmail->config->get('username_domain',false); if (!$domain) { - rcube::write_log('errors','Plugin password (hmail driver): $config[\'username_domain\'] is not defined.'); + write_log('errors','Plugin password (hmail driver): $rcmail_config[\'username_domain\'] is not defined.'); + write_log('errors','Plugin password (hmail driver): Hint: Use hmail_login plugin (http://myroundcube.googlecode.com'); return PASSWORD_ERROR; } $username = $username . "@" . $domain; @@ -53,8 +55,8 @@ class rcube_hmail_password return PASSWORD_SUCCESS; } catch (Exception $e) { - rcube::write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage()))); - rcube::write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set."); + write_log('errors', "Plugin password (hmail driver): " . trim(strip_tags($e->getMessage()))); + write_log('errors', "Plugin password (hmail driver): This problem is often caused by DCOM permissions not being set."); return PASSWORD_ERROR; } } diff --git a/plugins/password/drivers/ldap.php b/plugins/password/drivers/ldap.php index 739958ad7..f773335ac 100644 --- a/plugins/password/drivers/ldap.php +++ b/plugins/password/drivers/ldap.php @@ -23,7 +23,7 @@ class rcube_ldap_password // Building user DN if ($userDN = $rcmail->config->get('password_ldap_userDN_mask')) { - $userDN = self::substitute_vars($userDN); + $userDN = $this->substitute_vars($userDN); } else { $userDN = $this->search_userdn($rcmail); } @@ -64,7 +64,7 @@ class rcube_ldap_password return PASSWORD_CONNECT_ERROR; } - $crypted_pass = self::hash_password($passwd, $rcmail->config->get('password_ldap_encodage')); + $crypted_pass = $this->hashPassword($passwd, $rcmail->config->get('password_ldap_encodage')); $force = $rcmail->config->get('password_ldap_force_replace'); $pwattr = $rcmail->config->get('password_ldap_pwattr'); $lchattr = $rcmail->config->get('password_ldap_lchattr'); @@ -84,7 +84,7 @@ class rcube_ldap_password } // Crypt new samba password - if ($smbpwattr && !($samba_pass = self::hash_password($passwd, 'samba'))) { + if ($smbpwattr && !($samba_pass = $this->hashPassword($passwd, 'samba'))) { return PASSWORD_CRYPT_ERROR; } @@ -146,8 +146,8 @@ class rcube_ldap_password return ''; } - $base = self::substitute_vars($rcmail->config->get('password_ldap_search_base')); - $filter = self::substitute_vars($rcmail->config->get('password_ldap_search_filter')); + $base = $rcmail->config->get('password_ldap_search_base'); + $filter = $this->substitute_vars($rcmail->config->get('password_ldap_search_filter')); $options = array ( 'scope' => 'sub', 'attributes' => array(), @@ -163,25 +163,27 @@ class rcube_ldap_password } /** - * Substitute %login, %name, %domain, %dc in $str - * See plugin config for details + * Substitute %login, %name, %domain, %dc in $str. + * See plugin config for details. */ - static function substitute_vars($str) + function substitute_vars($str) { - $str = str_replace('%login', $_SESSION['username'], $str); - $str = str_replace('%l', $_SESSION['username'], $str); - - $parts = explode('@', $_SESSION['username']); - - if (count($parts) == 2) { - $dc = 'dc='.strtr($parts[1], array('.' => ',dc=')); // hierarchal domain string - - $str = str_replace('%name', $parts[0], $str); - $str = str_replace('%n', $parts[0], $str); - $str = str_replace('%dc', $dc, $str); - $str = str_replace('%domain', $parts[1], $str); - $str = str_replace('%d', $parts[1], $str); - } + $rcmail = rcmail::get_instance(); + $domain = $rcmail->user->get_username('domain'); + $dc = 'dc='.strtr($domain, array('.' => ',dc=')); // hierarchal domain string + + $str = str_replace(array( + '%login', + '%name', + '%domain', + '%dc', + ), array( + $_SESSION['username'], + $rcmail->user->get_username('local'), + $domain, + $dc, + ), $str + ); return $str; } @@ -190,109 +192,128 @@ class rcube_ldap_password * Code originaly from the phpLDAPadmin development team * http://phpldapadmin.sourceforge.net/ * - * Hashes a password and returns the hash based on the specified enc_type + * Hashes a password and returns the hash based on the specified enc_type. + * + * @param string $passwordClear The password to hash in clear text. + * @param string $encodageType Standard LDAP encryption type which must be one of + * crypt, ext_des, md5crypt, blowfish, md5, sha, smd5, ssha, or clear. + * @return string The hashed password. + * */ - static function hash_password($password_clear, $encodage_type) + function hashPassword( $passwordClear, $encodageType ) { - $encodage_type = strtolower($encodage_type); - switch ($encodage_type) { + $encodageType = strtolower( $encodageType ); + switch( $encodageType ) { case 'crypt': - $crypted_password = '{CRYPT}' . crypt($password_clear, self::random_salt(2)); + $cryptedPassword = '{CRYPT}' . crypt($passwordClear, $this->randomSalt(2)); break; + case 'ext_des': - /* Extended DES crypt. see OpenBSD crypt man page */ - if (!defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) { - /* Your system crypt library does not support extended DES encryption */ - return false; + // extended des crypt. see OpenBSD crypt man page. + if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) { + // Your system crypt library does not support extended DES encryption. + return FALSE; } - $crypted_password = '{CRYPT}' . crypt($password_clear, '_' . self::random_salt(8)); + $cryptedPassword = '{CRYPT}' . crypt( $passwordClear, '_' . $this->randomSalt(8) ); break; + case 'md5crypt': - if (!defined('CRYPT_MD5') || CRYPT_MD5 == 0) { - /* Your system crypt library does not support md5crypt encryption */ - return false; + if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) { + // Your system crypt library does not support md5crypt encryption. + return FALSE; } - $crypted_password = '{CRYPT}' . crypt($password_clear, '$1$' . self::random_salt(9)); + $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$1$' . $this->randomSalt(9) ); break; + case 'blowfish': - if (!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) { - /* Your system crypt library does not support blowfish encryption */ - return false; + if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) { + // Your system crypt library does not support blowfish encryption. + return FALSE; } - /* Hardcoded to second blowfish version and set number of rounds */ - $crypted_password = '{CRYPT}' . crypt($password_clear, '$2a$12$' . self::random_salt(13)); + // hardcoded to second blowfish version and set number of rounds + $cryptedPassword = '{CRYPT}' . crypt( $passwordClear , '$2a$12$' . $this->randomSalt(13) ); break; + case 'md5': - $crypted_password = '{MD5}' . base64_encode(pack('H*', md5($password_clear))); + $cryptedPassword = '{MD5}' . base64_encode( pack( 'H*' , md5( $passwordClear) ) ); break; + case 'sha': - if (function_exists('sha1')) { - /* Use PHP 4.3.0+ sha1 function, if it is available */ - $crypted_password = '{SHA}' . base64_encode(pack('H*', sha1($password_clear))); - } else if (function_exists('mhash')) { - $crypted_password = '{SHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear)); + if( function_exists('sha1') ) { + // use php 4.3.0+ sha1 function, if it is available. + $cryptedPassword = '{SHA}' . base64_encode( pack( 'H*' , sha1( $passwordClear) ) ); + } elseif( function_exists( 'mhash' ) ) { + $cryptedPassword = '{SHA}' . base64_encode( mhash( MHASH_SHA1, $passwordClear) ); } else { - /* Your PHP install does not have the mhash() function */ - return false; + return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes. } break; + case 'ssha': - if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { - mt_srand((double) microtime() * 1000000 ); - $salt = mhash_keygen_s2k(MHASH_SHA1, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4); - $crypted_password = '{SSHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear . $salt) . $salt); + if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) { + mt_srand( (double) microtime() * 1000000 ); + $salt = mhash_keygen_s2k( MHASH_SHA1, $passwordClear, substr( pack( 'h*', md5( mt_rand() ) ), 0, 8 ), 4 ); + $cryptedPassword = '{SSHA}'.base64_encode( mhash( MHASH_SHA1, $passwordClear.$salt ).$salt ); } else { - /* Your PHP install does not have the mhash() function */ - return false; + return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes. } break; + case 'smd5': - if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { - mt_srand((double) microtime() * 1000000 ); - $salt = mhash_keygen_s2k(MHASH_MD5, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4); - $crypted_password = '{SMD5}' . base64_encode(mhash(MHASH_MD5, $password_clear . $salt) . $salt); + if( function_exists( 'mhash' ) && function_exists( 'mhash_keygen_s2k' ) ) { + mt_srand( (double) microtime() * 1000000 ); + $salt = mhash_keygen_s2k( MHASH_MD5, $passwordClear, substr( pack( 'h*', md5( mt_rand() ) ), 0, 8 ), 4 ); + $cryptedPassword = '{SMD5}'.base64_encode( mhash( MHASH_MD5, $passwordClear.$salt ).$salt ); } else { - /* Your PHP install does not have the mhash() function */ - return false; + return FALSE; //Your PHP install does not have the mhash() function. Cannot do SHA hashes. } break; + case 'samba': if (function_exists('hash')) { - $crypted_password = hash('md4', rcube_charset::convert($password_clear, RCUBE_CHARSET, 'UTF-16LE')); - $crypted_password = strtoupper($crypted_password); + $cryptedPassword = hash('md4', rcube_charset_convert($passwordClear, RCMAIL_CHARSET, 'UTF-16LE')); + $cryptedPassword = strtoupper($cryptedPassword); } else { /* Your PHP install does not have the hash() function */ return false; } break; - case 'ad': - $crypted_password = rcube_charset::convert('"' . $password_clear . '"', RCUBE_CHARSET, 'UTF-16LE'); - break; + case 'clear': default: - $crypted_password = $password_clear; + $cryptedPassword = $passwordClear; } - return $crypted_password; + return $cryptedPassword; } /** * Code originaly from the phpLDAPadmin development team * http://phpldapadmin.sourceforge.net/ * - * Used to generate a random salt for crypt-style passwords + * Used to generate a random salt for crypt-style passwords. Salt strings are used + * to make pre-built hash cracking dictionaries difficult to use as the hash algorithm uses + * not only the user's password but also a randomly generated string. The string is + * stored as the first N characters of the hash for reference of hashing algorithms later. + * + * --- added 20021125 by bayu irawan <bayuir@divnet.telkom.co.id> --- + * --- ammended 20030625 by S C Rigler <srigler@houston.rr.com> --- + * + * @param int $length The length of the salt string to generate. + * @return string The generated salt string. */ - static function random_salt($length) + function randomSalt( $length ) { - $possible = '0123456789' . 'abcdefghijklmnopqrstuvwxyz' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . './'; + $possible = '0123456789'. + 'abcdefghijklmnopqrstuvwxyz'. + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. + './'; $str = ''; // mt_srand((double)microtime() * 1000000); - while (strlen($str) < $length) { + while (strlen($str) < $length) $str .= substr($possible, (rand() % strlen($possible)), 1); - } return $str; } - } diff --git a/plugins/password/drivers/ldap_simple.php b/plugins/password/drivers/ldap_simple.php index 47e3b07de..01385f2d0 100644 --- a/plugins/password/drivers/ldap_simple.php +++ b/plugins/password/drivers/ldap_simple.php @@ -13,37 +13,21 @@ class rcube_ldap_simple_password { - private $debug = false; - function save($curpass, $passwd) { $rcmail = rcmail::get_instance(); - $this->debug = $rcmail->config->get('ldap_debug'); - - $ldap_host = $rcmail->config->get('password_ldap_host'); - $ldap_port = $rcmail->config->get('password_ldap_port'); - - $this->_debug("C: Connect to $ldap_host:$ldap_port"); - // Connect - if (!$ds = ldap_connect($ldap_host, $ldap_port)) { - $this->_debug("S: NOT OK"); - - rcube::raise_error(array( - 'code' => 100, 'type' => 'ldap', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not connect to LDAP server" - ), - true); - + if (!$ds = ldap_connect($rcmail->config->get('password_ldap_host'), $rcmail->config->get('password_ldap_port'))) { + ldap_unbind($ds); return PASSWORD_CONNECT_ERROR; } - $this->_debug("S: OK"); - // Set protocol version - ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $rcmail->config->get('password_ldap_version')); + if (!ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $rcmail->config->get('password_ldap_version'))) { + ldap_unbind($ds); + return PASSWORD_CONNECT_ERROR; + } // Start TLS if ($rcmail->config->get('password_ldap_starttls')) { @@ -53,19 +37,9 @@ class rcube_ldap_simple_password } } - // include 'ldap' driver, we share some static methods with it - require_once INSTALL_PATH . 'plugins/password/drivers/ldap.php'; - - // other plugins might want to modify user DN - $plugin = $rcmail->plugins->exec_hook('password_ldap_bind', array( - 'user_dn' => '', 'conn' => $ds)); - // Build user DN - if (!empty($plugin['user_dn'])) { - $user_dn = $plugin['user_dn']; - } - else if ($user_dn = $rcmail->config->get('password_ldap_userDN_mask')) { - $user_dn = rcube_ldap_password::substitute_vars($user_dn); + if ($user_dn = $rcmail->config->get('password_ldap_userDN_mask')) { + $user_dn = $this->substitute_vars($user_dn); } else { $user_dn = $this->search_userdn($rcmail, $ds); @@ -89,13 +63,12 @@ class rcube_ldap_simple_password break; } + $crypted_pass = $this->hash_password($passwd, $rcmail->config->get('password_ldap_encodage')); $lchattr = $rcmail->config->get('password_ldap_lchattr'); $pwattr = $rcmail->config->get('password_ldap_pwattr'); $smbpwattr = $rcmail->config->get('password_ldap_samba_pwattr'); $smblchattr = $rcmail->config->get('password_ldap_samba_lchattr'); $samba = $rcmail->config->get('password_ldap_samba'); - $pass_mode = $rcmail->config->get('password_ldap_encodage'); - $crypted_pass = rcube_ldap_password::hash_password($passwd, $pass_mode); // Support password_ldap_samba option for backward compat. if ($samba && !$smbpwattr) { @@ -109,55 +82,40 @@ class rcube_ldap_simple_password } // Crypt new Samba password - if ($smbpwattr && !($samba_pass = rcube_ldap_password::hash_password($passwd, 'samba'))) { + if ($smbpwattr && !($samba_pass = $this->hash_password($passwd, 'samba'))) { return PASSWORD_CRYPT_ERROR; } - $this->_debug("C: Bind $binddn [pass: $bindpw]"); - // Bind if (!ldap_bind($ds, $binddn, $bindpw)) { - $this->_debug("S: ".ldap_error($ds)); - ldap_unbind($ds); - return PASSWORD_CONNECT_ERROR; } - $this->_debug("S: OK"); - - $entry[$pwattr] = $crypted_pass; + $entree[$pwattr] = $crypted_pass; // Update PasswordLastChange Attribute if desired if ($lchattr) { - $entry[$lchattr] = (int)(time() / 86400); + $entree[$lchattr] = (int)(time() / 86400); } // Update Samba password if ($smbpwattr) { - $entry[$smbpwattr] = $samba_pass; + $entree[$smbpwattr] = $samba_pass; } // Update Samba password last change if ($smblchattr) { - $entry[$smblchattr] = time(); + $entree[$smblchattr] = time(); } - $this->_debug("C: Modify $user_dn: " . print_r($entry, true)); - - if (!ldap_modify($ds, $user_dn, $entry)) { - $this->_debug("S: ".ldap_error($ds)); - + if (!ldap_modify($ds, $user_dn, $entree)) { ldap_unbind($ds); - return PASSWORD_CONNECT_ERROR; } - $this->_debug("S: OK"); - // All done, no error ldap_unbind($ds); - return PASSWORD_SUCCESS; } @@ -168,57 +126,151 @@ class rcube_ldap_simple_password */ function search_userdn($rcmail, $ds) { - $search_user = $rcmail->config->get('password_ldap_searchDN'); - $search_pass = $rcmail->config->get('password_ldap_searchPW'); - - if (empty($search_user)) { - return null; + /* Bind */ + if (!ldap_bind($ds, $rcmail->config->get('password_ldap_searchDN'), $rcmail->config->get('password_ldap_searchPW'))) { + return false; } - $this->_debug("C: Bind $search_user [pass: $search_pass]"); + /* Search for the DN */ + if (!$sr = ldap_search($ds, $rcmail->config->get('password_ldap_search_base'), $this->substitute_vars($rcmail->config->get('password_ldap_search_filter')))) { + return false; + } - // Bind - if (!ldap_bind($ds, $search_user, $search_pass)) { - $this->_debug("S: ".ldap_error($ds)); + /* If no or more entries were found, return false */ + if (ldap_count_entries($ds, $sr) != 1) { return false; } - $this->_debug("S: OK"); + return ldap_get_dn($ds, ldap_first_entry($ds, $sr)); + } - $search_base = $rcmail->config->get('password_ldap_search_base'); - $search_filter = $rcmail->config->get('password_ldap_search_filter'); + /** + * Substitute %login, %name, %domain, %dc in $str + * See plugin config for details + */ + function substitute_vars($str) + { + $str = str_replace('%login', $_SESSION['username'], $str); + $str = str_replace('%l', $_SESSION['username'], $str); - $search_base = rcube_ldap_password::substitute_vars($search_base); - $search_filter = rcube_ldap_password::substitute_vars($search_filter); + $parts = explode('@', $_SESSION['username']); - $this->_debug("C: Search $search_base for $search_filter"); + if (count($parts) == 2) { + $dc = 'dc='.strtr($parts[1], array('.' => ',dc=')); // hierarchal domain string - // Search for the DN - if (!$sr = ldap_search($ds, $search_base, $search_filter)) { - $this->_debug("S: ".ldap_error($ds)); - return false; + $str = str_replace('%name', $parts[0], $str); + $str = str_replace('%n', $parts[0], $str); + $str = str_replace('%dc', $dc, $str); + $str = str_replace('%domain', $parts[1], $str); + $str = str_replace('%d', $parts[1], $str); } - $found = ldap_count_entries($ds, $sr); - - $this->_debug("S: OK [found $found records]"); + return $str; + } - // If no or more entries were found, return false - if ($found != 1) { - return false; + /** + * Code originaly from the phpLDAPadmin development team + * http://phpldapadmin.sourceforge.net/ + * + * Hashes a password and returns the hash based on the specified enc_type + */ + function hash_password($password_clear, $encodage_type) + { + $encodage_type = strtolower($encodage_type); + switch ($encodage_type) { + case 'crypt': + $crypted_password = '{CRYPT}' . crypt($password_clear, $this->random_salt(2)); + break; + case 'ext_des': + /* Extended DES crypt. see OpenBSD crypt man page */ + if (!defined('CRYPT_EXT_DES') || CRYPT_EXT_DES == 0) { + /* Your system crypt library does not support extended DES encryption */ + return false; + } + $crypted_password = '{CRYPT}' . crypt($password_clear, '_' . $this->random_salt(8)); + break; + case 'md5crypt': + if (!defined('CRYPT_MD5') || CRYPT_MD5 == 0) { + /* Your system crypt library does not support md5crypt encryption */ + return false; + } + $crypted_password = '{CRYPT}' . crypt($password_clear, '$1$' . $this->random_salt(9)); + break; + case 'blowfish': + if (!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH == 0) { + /* Your system crypt library does not support blowfish encryption */ + return false; + } + /* Hardcoded to second blowfish version and set number of rounds */ + $crypted_password = '{CRYPT}' . crypt($password_clear, '$2a$12$' . $this->random_salt(13)); + break; + case 'md5': + $crypted_password = '{MD5}' . base64_encode(pack('H*', md5($password_clear))); + break; + case 'sha': + if (function_exists('sha1')) { + /* Use PHP 4.3.0+ sha1 function, if it is available */ + $crypted_password = '{SHA}' . base64_encode(pack('H*', sha1($password_clear))); + } else if (function_exists('mhash')) { + $crypted_password = '{SHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear)); + } else { + /* Your PHP install does not have the mhash() function */ + return false; + } + break; + case 'ssha': + if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { + mt_srand((double) microtime() * 1000000 ); + $salt = mhash_keygen_s2k(MHASH_SHA1, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4); + $crypted_password = '{SSHA}' . base64_encode(mhash(MHASH_SHA1, $password_clear . $salt) . $salt); + } else { + /* Your PHP install does not have the mhash() function */ + return false; + } + break; + case 'smd5': + if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { + mt_srand((double) microtime() * 1000000 ); + $salt = mhash_keygen_s2k(MHASH_MD5, $password_clear, substr(pack('h*', md5(mt_rand())), 0, 8), 4); + $crypted_password = '{SMD5}' . base64_encode(mhash(MHASH_MD5, $password_clear . $salt) . $salt); + } else { + /* Your PHP install does not have the mhash() function */ + return false; + } + break; + case 'samba': + if (function_exists('hash')) { + $crypted_password = hash('md4', rcube_charset_convert($password_clear, RCMAIL_CHARSET, 'UTF-16LE')); + $crypted_password = strtoupper($crypted_password); + } else { + /* Your PHP install does not have the hash() function */ + return false; + } + break; + case 'clear': + default: + $crypted_password = $password_clear; } - return ldap_get_dn($ds, ldap_first_entry($ds, $sr)); + return $crypted_password; } /** - * Prints debug info to the log + * Code originaly from the phpLDAPadmin development team + * http://phpldapadmin.sourceforge.net/ + * + * Used to generate a random salt for crypt-style passwords */ - private function _debug($str) + function random_salt($length) { - if ($this->debug) { - rcube::write_log('ldap', $str); + $possible = '0123456789' . 'abcdefghijklmnopqrstuvwxyz' . 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . './'; + $str = ''; + // mt_srand((double)microtime() * 1000000); + + while (strlen($str) < $length) { + $str .= substr($possible, (rand() % strlen($possible)), 1); } - } + return $str; + } } diff --git a/plugins/password/drivers/pam.php b/plugins/password/drivers/pam.php index 4d0ba1656..15a802c74 100644 --- a/plugins/password/drivers/pam.php +++ b/plugins/password/drivers/pam.php @@ -21,7 +21,7 @@ class rcube_pam_password } } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, @@ -30,7 +30,7 @@ class rcube_pam_password } } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/pw_usermod.php b/plugins/password/drivers/pw_usermod.php index 237e275a7..5b92fcbfb 100644 --- a/plugins/password/drivers/pw_usermod.php +++ b/plugins/password/drivers/pw_usermod.php @@ -28,7 +28,7 @@ class rcube_pw_usermod_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/sasl.php b/plugins/password/drivers/sasl.php index 8776eff2e..9380cf838 100644 --- a/plugins/password/drivers/sasl.php +++ b/plugins/password/drivers/sasl.php @@ -32,7 +32,7 @@ class rcube_sasl_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/smb.php b/plugins/password/drivers/smb.php index 9f2b96afa..88021156f 100644 --- a/plugins/password/drivers/smb.php +++ b/plugins/password/drivers/smb.php @@ -26,15 +26,13 @@ class rcube_smb_password public function save($currpass, $newpass) { - $host = rcmail::get_instance()->config->get('password_smb_host','localhost'); - $bin = rcmail::get_instance()->config->get('password_smb_cmd','/usr/bin/smbpasswd'); + $host = rcmail::get_instance()->config->get('password_smb_host','localhost'); + $bin = rcmail::get_instance()->config->get('password_smb_cmd','/usr/bin/smbpasswd'); $username = $_SESSION['username']; - $host = rcube_utils::parse_host($host); - $tmpfile = tempnam(sys_get_temp_dir(),'smb'); - $cmd = $bin . ' -r ' . $host . ' -s -U "' . $username . '" > ' . $tmpfile . ' 2>&1'; - $handle = @popen($cmd, 'w'); - + $tmpfile = tempnam(sys_get_temp_dir(),'smb'); + $cmd = $bin . ' -r ' . $host . ' -s -U "' . $username . '" > ' . $tmpfile . ' 2>&1'; + $handle = @popen($cmd, 'w'); fputs($handle, $currpass."\n"); fputs($handle, $newpass."\n"); fputs($handle, $newpass."\n"); @@ -46,7 +44,7 @@ class rcube_smb_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/sql.php b/plugins/password/drivers/sql.php index 7a51dfe44..8c8dc87b5 100644 --- a/plugins/password/drivers/sql.php +++ b/plugins/password/drivers/sql.php @@ -34,9 +34,8 @@ class rcube_sql_password $db = $rcmail->get_dbh(); } - if ($db->is_error()) { + if ($err = $db->is_error()) return PASSWORD_ERROR; - } // crypted password if (strpos($sql, '%c') !== FALSE) { @@ -118,7 +117,7 @@ class rcube_sql_password // hashed passwords if (preg_match('/%[n|q]/', $sql)) { if (!extension_loaded('hash')) { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, @@ -165,14 +164,14 @@ class rcube_sql_password // convert domains to/from punnycode if ($rcmail->config->get('password_idn_ascii')) { - $domain_part = rcube_utils::idn_to_ascii($domain_part); - $username = rcube_utils::idn_to_ascii($username); - $host = rcube_utils::idn_to_ascii($host); + $domain_part = rcube_idn_to_ascii($domain_part); + $username = rcube_idn_to_ascii($username); + $host = rcube_idn_to_ascii($host); } else { - $domain_part = rcube_utils::idn_to_utf8($domain_part); - $username = rcube_utils::idn_to_utf8($username); - $host = rcube_utils::idn_to_utf8($host); + $domain_part = rcube_idn_to_utf8($domain_part); + $username = rcube_idn_to_utf8($username); + $host = rcube_idn_to_utf8($host); } // at least we should always have the local part @@ -185,7 +184,7 @@ class rcube_sql_password if (!$db->is_error()) { if (strtolower(substr(trim($sql),0,6)) == 'select') { - if ($db->fetch_array($res)) + if ($result = $db->fetch_array($res)) return PASSWORD_SUCCESS; } else { // This is the good case: 1 row updated diff --git a/plugins/password/drivers/virtualmin.php b/plugins/password/drivers/virtualmin.php index 36c54664b..40f5c2529 100644 --- a/plugins/password/drivers/virtualmin.php +++ b/plugins/password/drivers/virtualmin.php @@ -66,7 +66,7 @@ class rcube_virtualmin_password return PASSWORD_SUCCESS; } else { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, diff --git a/plugins/password/drivers/xmail.php b/plugins/password/drivers/xmail.php index 47beb2178..33a49ffe3 100644 --- a/plugins/password/drivers/xmail.php +++ b/plugins/password/drivers/xmail.php @@ -10,10 +10,10 @@ * Setup xmail_host, xmail_user, xmail_pass and xmail_port into * config.inc.php of password plugin as follows: * - * $config['xmail_host'] = 'localhost'; - * $config['xmail_user'] = 'YourXmailControlUser'; - * $config['xmail_pass'] = 'YourXmailControlPass'; - * $config['xmail_port'] = 6017; + * $rcmail_config['xmail_host'] = 'localhost'; + * $rcmail_config['xmail_user'] = 'YourXmailControlUser'; + * $rcmail_config['xmail_pass'] = 'YourXmailControlPass'; + * $rcmail_config['xmail_port'] = 6017; * */ @@ -32,7 +32,7 @@ class rcube_xmail_password $xmail->port = $rcmail->config->get('xmail_port'); if (!$xmail->connect()) { - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, @@ -42,7 +42,7 @@ class rcube_xmail_password } else if (!$xmail->send("userpasswd\t".$domain."\t".$user."\t".$newpass."\n")) { $xmail->close(); - rcube::raise_error(array( + raise_error(array( 'code' => 600, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, @@ -67,7 +67,7 @@ class XMail { function send($msg) { socket_write($this->socket,$msg); - if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") { + if (substr($in = socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") { return false; } return true; @@ -85,7 +85,7 @@ class XMail { return false; } - if (substr(socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") { + if (substr($in = socket_read($this->socket, 512, PHP_BINARY_READ),0,1) != "+") { socket_close($this->socket); return false; } |