* * See the inclosed NOTICE file for conditions of use and distribution. */ /** * Class SmartSieve contains the generic SmartSieve functions * used throughout the application. * * @author Stephen Grier * @version $Revision: 1.59 $ */ class SmartSieve { /** * Check the authentication state of this session. If a session exists * try to authenticate. If not, check for submitted login credentials, set * a session and try to authenticate. If all else fails, redirect to the * login page. * * @return void Sends a 302 redirect on failure */ function checkAuthentication() { if (isset($_SESSION['smartsieve']) && is_array($_SESSION['smartsieve'])) { if (SmartSieve::authenticate() !== true) { SmartSieve::destroy(); header('Location: ' . SmartSieve::setUrl('login.php')); exit; } } elseif (($details = SmartSieve::getLoginDetails()) !== false) { $ret = SmartSieve::login($details); if ($ret !== true) { header('Location: ' . SmartSieve::setUrl('login.php?reason=failure')); exit; } } else { // No existing session or login attempt. Redirect to login page. header('Location: ' . SmartSieve::setUrl('login.php')); exit; } } /** * Get the login details from the login page, or some other source. * * @return mixed array of login details on success, boolean false if not */ function getLoginDetails() { $details = array(); /* If user has submitted login page, get details from POST request. */ if (isset($_POST['auth']) && isset($_POST['passwd'])) { $details['auth'] = SmartSieve::getFormValue('auth'); $details['passwd'] = SmartSieve::getFormValue('passwd'); $details['authz'] = SmartSieve::getFormValue('authz'); $details['server'] = SmartSieve::getFormValue('server'); } /* Try an alternative source. */ elseif (($func = SmartSieve::getConf('get_login_details_hook')) !== null && function_exists($func)) { $details = call_user_func($func); } return (!empty($details) && is_array($details)) ? $details : false; } /** * Handle a login event. Set session environment and authenticate. * * @param array Login credentials (auth, passwd, authz, server) * @return boolean true on success, false if not */ function login($credentials) { if (empty($credentials) || !is_array($credentials)) { return false; } // Make sure we have a clean session. SmartSieve::destroy(); session_start(); if (SmartSieve::getConf('auto_select_server', false)) { $server = SmartSieve::getServer($credentials['auth']); if ($server) $credentials['server'] = $server; } if (($ret = SmartSieve::setSession($credentials['auth'], $credentials['passwd'], $credentials['authz'], $credentials['server'])) === true && ($ret = SmartSieve::authenticate()) === true) { $smartsieve = &$_SESSION['smartsieve']; $ret = SmartSieve::writeToLog(sprintf('login: %s%s [%s] {%s:%s}', ($smartsieve['auth'] != $smartsieve['authz']) ? sprintf('%s as ', $smartsieve['auth']) : '', $smartsieve['authz'], $_SERVER['REMOTE_ADDR'], $smartsieve['server'], $smartsieve['sieveport']), LOG_INFO); if ($ret !== true) { SmartSieve::setError($ret); } // Set the array of script objects in the PHP session. $_SESSION['scripts'] = array(); // Set which script to edit first. SmartSieve::setWorkingScript(SmartSieve::getFormValue('scriptfile')); if (isset($_POST['lang'])) { $_SESSION['smartsieve_lang'] = SmartSieve::getFormValue('lang'); } return true; } SmartSieve::writeToLog(sprintf('FAILED LOGIN: %s%s [%s] {%s}: %s', $credentials['auth'], (!empty($credentials['authz']) && $credentials['authz'] != $credentials['auth']) ? sprintf(' as %s', $credentials['authz']) : '', $_SERVER['REMOTE_ADDR'], $credentials['server'], $ret), LOG_ERR); SmartSieve::destroy(); return false; } function getServer($auth) { $db_host = SmartSieve::getConf('auto_select_db_host'); $db_name = SmartSieve::getConf('auto_select_db_name'); $db_user = SmartSieve::getConf('auto_select_db_user'); $db_password = SmartSieve::getConf('auto_select_db_password'); $conn = pg_connect("dbname='$db_name' host='$db_host' user='$db_user' password='$db_password'"); if (!$conn) return false; $db_table = SmartSieve::getConf('auto_select_db_table'); $db_uname_column = SmartSieve::getConf('auto_select_db_uname_column'); $db_mail_column = SmartSieve::getConf('auto_select_db_mail_column'); $query = "SELECT $db_mail_column FROM $db_table WHERE $db_uname_column='$auth'"; $res = pg_query($query); if (!$res) { pg_close($conn); return false; } if (pg_num_rows($res) != 1) { pg_free_result($res); pg_close($conn); return false; } $row = pg_fetch_assoc($res); $mail = $row['mail']; # will come back as foo@bar.baz.com, we want everything after @ $mail_pieces = preg_split("/@/", $mail, 2); if (count($mail_pieces) == 1) $server = $mail_pieces[0]; else $server = $mail_pieces[1]; pg_free_result($res); pg_close($conn); return $server; } /** * Destroy the current PHP session. * * @return void */ function destroy() { if (isset($_SESSION['smartsieve'])) { $_SESSION['smartsieve'] = null; unset($_SESSION['smartsieve']); } if (isset($_SESSION['scripts'])) { $_SESSION['scripts'] = null; unset($_SESSION['scripts']); } @session_destroy(); } /** * Handle a logout event. * * @return void Possibly a 302 redirect */ function logout() { if (isset($_SESSION['smartsieve']) && is_array($_SESSION['smartsieve'])) { SmartSieve::writeToLog(sprintf('logout: %s', $_SESSION['smartsieve']['authz']), LOG_INFO); SmartSieve::destroy(); if (($uri = SmartSieve::getConf('logout_redirect')) !== null) { header(sprintf('Location: %s', $uri)); exit; } } } /** * Set up the SmartSieve session. This should only be called when * a user logs in. * * @param auth string authentication user * @param passwd string authentication password * @param authz string authorization user * @param server string server * @return mixed boolean true on success, string error if not */ function setSession($auth, $passwd, $authz='', $server) { global $default, $servers; if (empty($auth)) { return 'setSession: no auth name supplied'; } if (empty($passwd)) { return 'setSession: no password supplied'; } if (empty($server)) { return 'setSession: no server supplied'; } $smartsieve = array(); include_once SmartSieve::getConf('config_dir') . "/servers.php"; if (!array_key_exists($server, $servers) || !is_array($servers[$server])) { $srvkeys = array_keys($servers); $server = (!empty($srvkeys)) ? $srvkeys[0] : ''; } $smartsieve['server'] = SmartSieve::getServerValue($server, 'server'); $smartsieve['server_display'] = SmartSieve::getServerValue($server, 'display', $smartsieve['server']); $smartsieve['sieveport'] = SmartSieve::getServerValue($server, 'sieveport', '2000'); $smartsieve['imapport'] = SmartSieve::getServerValue($server, 'imapport', '143'); $smartsieve['alt_namespace'] = SmartSieve::getServerValue($server, 'alt_namespace', false); $smartsieve['namespace_user_prefix'] = SmartSieve::getServerValue($server, 'namespace_user_prefix', ''); $smartsieve['namespace_shared_prefix'] = SmartSieve::getServerValue($server, 'namespace_shared_prefix', ''); $smartsieve['maildomain'] = SmartSieve::getServerValue($server, 'maildomain'); $smartsieve['use_starttls'] = SmartSieve::getServerValue($server, 'use_starttls', true); $smartsieve['auth'] = $auth; $auth_domain = SmartSieve::getServerValue($server, 'auth_domain'); if (!empty($auth_domain) && strpos($auth,'@') === false) { $smartsieve['auth'] .= '@' . $auth_domain; } $smartsieve['authz'] = $authz; if ($authz == '') { $smartsieve['authz'] = $auth; } if (!empty($auth_domain) && strpos($authz,'@') === false) { $smartsieve['authz'] .= '@' . $auth_domain; } $key = SmartSieve::generateKey(); $smartsieve['passwd'] = SmartSieve::encrypt($passwd, $key); $_SESSION['smartsieve'] = $smartsieve; return true; } /** * Login to the managesieve server. * * @return mixed true on success, string error if not */ function authenticate() { global $default; if (!isset($_SESSION['smartsieve']) || !is_array($_SESSION['smartsieve'])) { return 'authenticate: no session started'; } $smartsieve = $_SESSION['smartsieve']; $key = SmartSieve::retrieveKey(); $passwd = SmartSieve::decrypt($smartsieve['passwd'], $key); $managesieve = new Managesieve(); $ret = $managesieve->open($smartsieve['server'], $smartsieve['sieveport']); if ($ret !== true) { $err = $managesieve->getError(); $managesieve->close(); return $err; } if (in_array('starttls', $managesieve->_capabilities) && function_exists('stream_socket_enable_crypto') && $smartsieve['use_starttls'] !== false) { $ret = $managesieve->starttls(); if ($ret !== true) { $err = $managesieve->getError(); $managesieve->close(); return $err; } } $ret = $managesieve->authenticate($smartsieve['auth'], $passwd, $smartsieve['authz'], SmartSieve::getConf('sasl_mech')); if ($ret !== true) { $err = $managesieve->getError(); $managesieve->close(); return $err; } $GLOBALS['managesieve'] = $managesieve; register_shutdown_function(array('SmartSieve', 'close')); return true; } /** * Close the managesieve connection and destroy the managesieve object. * * @return boolean true */ function close() { if (isset($GLOBALS['managesieve']) && is_object($GLOBALS['managesieve'])) { $GLOBALS['managesieve']->close(); unset($GLOBALS['managesieve']); } return true; } /* * return correct mailbox name. apply alternative namespacing if * necessary. */ function getMailboxName($mbox) { if ($_SESSION['smartsieve']['alt_namespace']){ if (preg_match("/^INBOX$/i", $mbox)){ # do nothing. } elseif (preg_match("/^INBOX\..+/i", $mbox)){ $mbox = substr($mbox, 6); } elseif (preg_match("/^user\./i", $mbox)){ $tmp = substr($mbox, 4); $mbox = $_SESSION['smartsieve']['namespace_user_prefix'] . $tmp; } elseif (preg_match("/^shared\./i", $mbox)){ $tmp = substr($mbox, 6); $mbox = $_SESSION['smartsieve']['namespace_shared_prefix'] . $tmp; } } return $mbox; } /* * This function takes a string $string and returns it, translated * into the language set for this session if possible. When calling * this function the $string argument should always be a raw string * and not a variable, ie. ::text('string') not ::text($string). */ function text($string = '', $args = array()) { global $default; static $lang, $phrase; if (!isset($lang)) { $lang = SmartSieve::getLang(); } if (!isset($phrase)) { @include "$default->lang_dir/$lang/strings.php"; } if (!empty($phrase[$string])) { $string = $phrase[$string]; } return vsprintf($string, $args); } /* * Return the charset to use to display each page. Different * languages might use different charsets. */ function getCharset() { static $charset; if (!isset($charset)) { $lang = SmartSieve::getLang(); include SmartSieve::getConf('config_dir') . '/locales.php'; if (isset($locales[$lang]['charset'])) { $charset = $locales[$lang]['charset']; } else { $charset = SmartSieve::getConf('charset', 'ISO-8859-1'); } } return $charset; } /* * Return the language to use for this SmartSieve session. */ function getLang() { global $default; /* get lang if login form submitted. */ if (isset($_POST['lang'])) return SmartSieve::getFormValue('lang'); /* check if user has changed language on login page. */ if (isset($_GET['login_lang'])) return SmartSieve::getFormValue('login_lang'); /* check if language is set in the session. */ if (isset($_SESSION['smartsieve_lang'])) return $_SESSION['smartsieve_lang']; /* if none of the above, use the default. */ return $default->language; } /* * Convert a modified UTF-7 encoded mailbox name (RFC-2060) into the * charset for the current language. */ function mutf7Decode($string) { $charset = SmartSieve::getCharset(); /* if we're using the ISO-8859-1 charset, we can just use imap_utf7_decode(). */ if (strtolower($charset) == 'iso-8859-1' || strtolower($charset) == 'us-ascii') { if (extension_loaded('imap')) { return imap_utf7_decode($string); } } /* try mbstring if available. */ if (extension_loaded('mbstring')) { $decoded = @mb_convert_encoding($string, $charset, 'UTF7-IMAP'); if ($decoded) { return $decoded; } } /* try iconv if available. use transliterations to avoid warnings about * incompatible characters. also, add extra ascii char to avoid iconv bug. */ if (extension_loaded('iconv')) { /* convert the modified UTF-7 string to UTF-7. */ $utf7 = SmartSieve::modifiedToPlainUTF7($string); $decoded = @iconv('UTF-7', $charset . '//TRANSLIT', $utf7 . "\0"); if ($decoded) { return $decoded; } } /* if all else fails, use imap_utf7_decode(). If mailbox name includes * non-ISO-8859-1 characters, they will not be decoded correctly. */ if (extension_loaded('imap')) { return imap_utf7_decode($string); } return $string; } /* * Convert a modified UTF-7 encoded string to unmodified UTF-7. * See: RFC-2060. */ function modifiedToPlainUTF7($string) { $utf7 = ''; $base64 = false; for ($i = 0; $i < strlen($string); $i++) { if ($string[$i] == "&") { /* Convert the shift char '&' to '+'. Literal '&' will be encoded as '&-'. */ if ($string[$i+1] == "-") { $utf7 .= "&"; // '&-' -> '&' $i++; } else { $utf7 .= "+"; // '&' -> '+' $base64 = true; } } elseif ($string[$i] == "-" && $base64) { /* shift back to us-ascii. */ $base64 = false; } else { if ($base64 && $string[$i] == ",") { $utf7 .= "/"; // ',' -> '/' } elseif (!$base64 && $string[$i] == "+") { $utf7 .= "+-"; // '+' -> '+-' } else { $utf7 .= $string[$i]; } } } return $utf7; } /** * Get the value of a config option. Returns the value of the setting * or null if not set, thereby avoiding Undefined variable warnings. * * @param option string config option to get * @param def string default value * @return mixed config value, possibly null */ function getConf($option, $def=null) { require_once "conf/config.php"; global $default; if (isset($default->$option)) { return $default->$option; } return $def; } /** * Get a value for a server set in servers.php * * @param skey string servers array index * @param val string server value * @param def string default value * @return mixed server value, possibly null */ function getServerValue($skey, $val, $def=null) { require_once "conf/servers.php"; global $servers; if (isset($servers[$skey]) && isset($servers[$skey][$val])) { return $servers[$skey][$val]; } return $def; } /** * Write a message to the log. * * @param msg string message to write to log * @param level integer one of the LOG_* constants * @return mixed boolean true on success, string error if not */ function writeToLog($msg, $level=LOG_DEBUG) { static $log; if (SmartSieve::getConf('logging') == false) { return true; } if ($level > SmartSieve::getConf('logging_level')) { return true; } if (!is_object($log)) { include_once SmartSieve::getConf('lib_dir') . "/Log.php"; if (SmartSieve::getConf('logging_method') === null || SmartSieve::getConf('logging_facility') === null || SmartSieve::getConf('logging_ident') === null) { return 'writeToLog: logging not configured correctly'; } $log = new Log(SmartSieve::getConf('logging_method'), SmartSieve::getConf('logging_facility'), SmartSieve::getConf('logging_ident')); if ($log->errstr){ return $log->errstr; } if (!is_object($log)){ return 'writeToLog: failed to create log object'; } } return ($log->writetoLog($msg, $level)) ? true : $log->errstr; } /** * Set an error notice message. If called without the msg parameter * this will return the current set of error messages. * * @param msg string the error message to set * @return mixed boolean true or array of string messages */ function setError($msg=null) { if (!isset($_SESSION['errors']) || !is_array($_SESSION['errors'])) { $_SESSION['errors'] = array(); } if ($msg === null) { $errors = $_SESSION['errors']; unset($_SESSION['errors']); return $errors; } $_SESSION['errors'][] = $msg; return true; } /** * Set a notice message. If called without the msg parameter * this will return the current set of notices. * * @param msg string the message to set * @return mixed boolean true or array of string messages */ function setNotice($msg=null) { if (!isset($_SESSION['notices']) || !is_array($_SESSION['notices'])) { $_SESSION['notices'] = array(); } if ($msg === null) { $notices = $_SESSION['notices']; unset($_SESSION['notices']); return $notices; } $_SESSION['notices'][] = $msg; return true; } /** * Get the list of Sieve scripts on the server for the current user. * * @return mixed array of scripts if success, or string error if not */ function getScriptList() { if (!isset($GLOBALS['managesieve']) || !is_object($GLOBALS['managesieve'])) { $ret = SmartSieve::authenticate(); if ($ret !== true) { return $ret; } } global $managesieve; $slist = $managesieve->listScripts(); if ($slist === false) { $resp = $managesieve->getLastResponse(); if ($resp['state'] === F_BYE) { SmartSieve::handleReferral(); return Smartsieve::getScriptList(); } return $managesieve->getError(); } return $slist; } /** * Get the name of the active script. * * @return mixed string name of active script, or null if none active */ function getActiveScript() { $slist = SmartSieve::getScriptList(); if (!is_array($slist)) { return "getActiveScript: $slist"; } return array_search(true, $slist, true); } /** * Check if script exists on the server. * * @param name string name of script * @return boolean true if script exists on server, false if not */ function scriptExists($name) { $slist = array_keys(SmartSieve::getScriptList()); return in_array($name, $slist, true); } /** * Handle managesieve referrals. * * @return boolean true on success, or void redirect if not */ function handleReferral() { global $managesieve; $resp = $managesieve->getLastResponse(); if ($resp['state'] === F_BYE && $resp['code'] === RC_REFERRAL) { $rserver = $resp['code_args']; // With Cyrus 2.2.x the host value will look like "sieve://host". if (substr($rserver, 0, 8) == 'sieve://') { $rserver = substr($rserver, 8); } $managesieve->close(); $ret = $managesieve->open($rserver, $_SESSION['smartsieve']['sieveport']); if ($ret === true) { $key = SmartSieve::retrieveKey(); $passwd = SmartSieve::decrypt($_SESSION['smartsieve']['passwd'], $key); $ret = $managesieve->authenticate($_SESSION['smartsieve']['auth'], $passwd, $_SESSION['smartsieve']['authz'], SmartSieve::getConf('sasl_mech')); if ($ret === true) { SmartSieve::setNotice(SmartSieve::text('Referred to server "%s"', $rserver)); $_SESSION['smartsieve']['server'] = $rserver; return true; } } SmartSieve::writeToLog('handleReferral: ' . $managesieve->getError(), LOG_ERR); SmartSieve::close(); header('Location: ' . SmartSieve::setUrl('login.php?reason=failure'),true); exit; } return true; } /** * Set the script to edit. Select a script and set the script object for it. * If allow_multi_scripts if false this will always set the default script. * Otherwise, if passed the script parameter this will set that as the working * script. If not, it will set the currently active script or the first from the * current script list, or the default script name if none exist on the server. * * @param script string the script to edit * @return void */ function setWorkingScript($script=null) { // If not allowing multiple scripts select the default. if (SmartSieve::getConf('allow_multi_scripts') === false) { $script = SmartSieve::getConf('scriptfile', 'smartsieve'); } if (empty($script)) { $slist = SmartSieve::getScriptList(); if (is_array($slist)) { $active = array_search(true, $slist, true); $slist = array_keys($slist); // If a script is active, select that. if ($active !== null && $active !== false) { $script = $active; } elseif (count($slist) > 0) { // Select the first from the list. $script = $slist[0]; } } else { SmartSieve::setError(SmartSieve::text('Failed reading script list: %s', $slist)); SmartSieve::writeToLog("setWorkingScript: failed reading script list: $slist", LOG_ERR); } } // If all else fails, select the default. if (empty($script)) { $script = SmartSieve::getConf('scriptfile', 'smartsieve'); } $_SESSION['smartsieve']['workingScript'] = $script; // Set the script object if not already set. if (!isset($_SESSION['scripts'][$script]) || !is_object($_SESSION['scripts'][$script])) { $_SESSION['scripts'][$script] = new Script($script); } $s = &$_SESSION['scripts'][$script]; $ret = $s->retrieveRules(); if ($ret === false) { SmartSieve::setError(SmartSieve::text('ERROR: ') . $s->errstr); $logmsg = sprintf('failed reading rules from script "%s" for %s: %s', $s->name, $_SESSION['smartsieve']['authz'], $s->errstr); SmartSieve::writeToLog($logmsg, LOG_ERR); } } /** * Get the list of mailboxes for the current user. * * @return mixed An array of mUTF7 encoded mailbox names, or string error on failure */ function getMailboxList() { require_once SmartSieve::getConf('lib_dir') . "/Crypt.php"; $connstr = sprintf('{%s:%s}INBOX', $_SESSION['smartsieve']['server'], $_SESSION['smartsieve']['imapport']); // get encrypted passwd. $key = SmartSieve::retrieveKey(); $passwd = SmartSieve::decrypt($_SESSION['smartsieve']['passwd'], $key); $conn = imap_open($connstr, $_SESSION['smartsieve']['auth'], $passwd, OP_HALFOPEN); if (!$conn){ return 'getMailboxList: imap_open failed: ' . imap_last_error(); } $mboxlist = array(); $mboxes = array(); $connstr = sprintf('{%s:%s}', $_SESSION['smartsieve']['server'], $_SESSION['smartsieve']['imapport']); $mboxes = imap_listmailbox($conn,$connstr,"*"); if (!is_array($mboxes) || count($mboxes) == 0) { return 'getMailboxList: imap_listmailbox failed: ' . imap_last_error(); } foreach ($mboxes as $mbox) { $label = str_replace($connstr, '', $mbox); $mboxlist[] = $label; } imap_close($conn); return $mboxlist; } /** * Return a formatted url. Prepend the webroot if requested. * Set the session id as a parameter if the browser is not * accepting cookies. * * @param uri string resourse to format * @param prependRoot boolean prepend the webroot * @return string formatted url */ function setUrl($uri, $prependRoot=true) { $url = ''; if ($prependRoot) { $baseurl = SmartSieve::getConf('baseurl', ''); if (substr($baseurl, -1) != '/') { $baseurl .= '/'; } $url = $baseurl . $uri; } if (!isset($_COOKIE[session_name()])) { // Add session_id as url parameter. if (strstr($url, '?') === false) { $url .= '?'; } else { $url .= '&'; } $url .= urlencode(session_name()) . '=' . session_id(); } return $url; } /** * Get a POST or GET value. Strip backslashes if magic_quotes.gpc is on. * * @param var string value to get * @param def string default * @return mixed form value if set, or default if not */ function getFormValue($var, $def=null) { if (isset($_POST[$var])) { $val = $_POST[$var]; } elseif (isset($_GET[$var])) { $val = $_GET[$var]; } else { $val = $def; } static $magicquotes; if (!isset($magicquotes)) { $magicquotes = get_magic_quotes_gpc(); } if ($val !== null) { if ($magicquotes) { if (is_array($val)) { $newval = array(); foreach ($val as $v) { $newval[] = stripslashes($v); } $val = $newval; } else { $val = stripslashes($val); } } } return $val; } /** * Generate a secret key. * * Generate a secret key to use in encryption/decryption. If browser is * accepting cookies, generate a 32 bit key using a Mersenne Twister * style random number generator and store this in a cookie. If not, * return a less random key based on session_id. * * @return string A 32 bit secret key */ function generateKey() { static $srand; if (isset($_COOKIE) && isset($_COOKIE[session_name()])) { // Seed the generator. Should only happen once. if (!isset($srand)) { mt_srand((double)microtime() * 1000000); $srand = true; } $key = md5(uniqid(mt_rand(),1)); $_COOKIE['smartsieve_key'] = $key; setcookie('smartsieve_key', $key, 0, SmartSieve::getConf('cookie_path', ''), SmartSieve::getConf('cookie_domain', ''), 0); } else { // Can't store random key in cookie, so we have to use a standard one. $key = md5(session_id()); } return $key; } /** * Retrieve the key from the cookie if it exists, or the less random one * based on session_id if not. * * @return string The 32 bit secret key */ function retrieveKey() { if (isset($_COOKIE['smartsieve_key'])) { return $_COOKIE['smartsieve_key']; } return md5(session_id()); } /** * Encrypt a string with a secret key. * * @param string $string The text to encrypt * @param string $key The secret key * @return string An encrypted string */ function encrypt($string, $key) { static $crypt; if (!isset($crypt) || !is_object($crypt)) { $lib = SmartSieve::getCryptLib(); $args = SmartSieve::getConf('crypt_args', array()); $args['key'] = $key; require_once SmartSieve::getConf('lib_dir') . '/Crypt.php'; $crypt = SmartSieveCrypt::factory($lib, $args); } return $crypt->encrypt($string); } /** * Decrypt a string encrypted with SmartSieve::encrypt(). * * @param string $data The string to decrypt * @param string $key The secret key used to encrypt * @return string The unencrypted string */ function decrypt($data,$key) { static $crypt; if (!isset($crypt) || !is_object($crypt)) { $lib = SmartSieve::getCryptLib(); $args = SmartSieve::getConf('crypt_args', array()); $args['key'] = $key; require_once SmartSieve::getConf('lib_dir') . '/Crypt.php'; $crypt = SmartSieveCrypt::factory($lib, $args); } return $crypt->decrypt($data); } /** * Select which encryption library to use. Use the lib specified in the * config file if set. If not, check for mcrypt, PEAR's Rc4, and PEAR's * HCEMD5, in that order. Function mcrypt_module_open is only found in * libmcrypt 2.4.x and above. * * @return string The encryption library to use */ function getCryptLib() { $libs = array(); if (extension_loaded('mcrypt') && function_exists('mcrypt_module_open')) { $libs[] = 'mcrypt'; } if (@include_once('Crypt/Rc4.php')) { $libs[] = 'rc4'; } if (@include_once('Crypt/HCEMD5.php')) { $libs[] = 'hcemd5'; } // Bail if we can't find a cryptography library. if (empty($libs)) { SmartSieve::writeToLog('cannot find a usable cryptography library.', LOG_ERR); echo 'ERROR: Cannot find a usable cryptography library. ' . 'Please read the INSTALL file for info on this.'; exit; } $lib = $libs[0]; if (SmartSieve::getConf('crypt_lib') && in_array(SmartSieve::getConf('crypt_lib'), $libs)) { $lib = SmartSieve::getConf('crypt_lib'); } SmartSieve::writeToLog('getCryptLib: using ' . $lib, LOG_DEBUG); return $lib; } /** * Convert a non-UTF-8 encoded string into UTF-8. We must assume the string is * currently encoded in the charset used for the current language. * * @param string $string The string to convert * @return string UTF-8 encoded string */ function utf8Encode($string) { $charset = SmartSieve::getCharset(); if (strtolower($charset) == 'utf-8') { return $string; } /* Try iconv. */ if (extension_loaded('iconv')) { $recoded = @iconv($charset, 'UTF-8', $string); if ($recoded) { return $recoded; } } /* Try mbstring. */ if (extension_loaded('mbstring')) { $recoded = @mb_convert_encoding($string, 'UTF-8', $charset); if ($recoded) { return $recoded; } } /* If all else fails, use utf8_encode(). If $string contains * non-ISO-8859-1 characters, they will not be encoded correctly. */ return utf8_encode($string); } /** * Convert a UTF-8 encoded string into the charset of the current language. * * @param string $string The UTF-8 string to convert * @return string The decoded string */ function utf8Decode($string) { $charset = SmartSieve::getCharset(); if (strtolower($charset) == 'utf-8') { return $string; } /* Try iconv. */ if (extension_loaded('iconv')) { $recoded = @iconv('UTF-8', $charset . '//TRANSLIT', $string); if ($recoded) { return $recoded; } } /* Try mbstring. */ if (extension_loaded('mbstring')) { $recoded = @mb_convert_encoding($string, $charset, 'UTF-8'); if ($recoded) { return $recoded; } } /* If all else fails, use utf8_decode(). If $string contains * non-ISO-8859-1 characters, they will not be decoded correctly. */ return utf8_decode($string); } } /* end class SmartSieve. */ ?>