From bac7d1742d45f256ded98656482ec9995e1c330a Mon Sep 17 00:00:00 2001 From: thomascube Date: Tue, 18 Jul 2006 21:02:43 +0000 Subject: [PATCH] Fixed bugs #1364122, #1468895, ticket #1483811 and other minor bugs --- .htaccess | 2 ++ CHANGELOG | 9 +++++ config/main.inc.php.dist | 5 +++ index.php | 28 ++++++++------- program/include/main.inc | 59 ++++++++++++++++++++++++-------- program/include/rcube_imap.inc | 4 +-- program/include/rcube_shared.inc | 17 ++++++++- program/steps/mail/func.inc | 6 ++-- 8 files changed, 98 insertions(+), 32 deletions(-) diff --git a/.htaccess b/.htaccess index 31495a4c6..9474105de 100644 --- a/.htaccess +++ b/.htaccess @@ -1,5 +1,7 @@ # AddDefaultCharset UTF-8 php_flag display_errors Off +php_flag log_errors On +php_value error_log logs/errors php_value upload_max_filesize 2M diff --git a/CHANGELOG b/CHANGELOG index 0e0b36059..18349ad11 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,15 @@ CHANGELOG RoundCube Webmail --------------------------- +2006/07/18 +---------- +- Fixed password with spaces issue (Bug #1364122) +- Replaced _auth hash with second cookie (Ticket #1483811) +- Don't use get_input_value() for passwords (Bug #1468895) +- Made password encryption key configurable +- Minor bugfixes with charset encoding + + 2006/07/07 ---------- - Fixed INSTALL_PATH bug #1425663 diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index ce05d80a0..f679d1014 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -99,6 +99,11 @@ $rcmail_config['session_lifetime'] = 10; // check client IP in session athorization $rcmail_config['ip_check'] = TRUE; +// this key is used to encrypt the users imap password which is stored +// in the session record (and the client cookie if remember password is enabled). +// please provide a string of exactly 24 chars. +$rcmail_config['des_key'] = 'rcmail-!24ByteDESkey*Str'; + // the default locale setting $rcmail_config['locale_string'] = 'en'; diff --git a/index.php b/index.php index 33f28c081..9668d52fa 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,7 @@ /* +-----------------------------------------------------------------------+ | RoundCube Webmail IMAP Client | - | Version 0.1-20060505 | + | Version 0.1-20060718 | | | | Copyright (C) 2005, RoundCube Dev. - Switzerland | | Licensed under the GNU GPL | @@ -40,7 +40,7 @@ */ -define('RCMAIL_VERSION', '0.1-20060707'); +define('RCMAIL_VERSION', '0.1-20060718'); // define global vars $CHARSET = 'UTF-8'; @@ -53,7 +53,13 @@ if (empty($INSTALL_PATH)) $INSTALL_PATH = './'; else $INSTALL_PATH .= '/'; - + + +// make sure path_separator is defined +if (!defined('PATH_SEPARATOR')) + define('PATH_SEPARATOR', (eregi('win', PHP_OS) ? ';' : ':')); + + // RC include folders MUST be included FIRST to avoid other // possible not compatible libraries (i.e PEAR) to be included // instead the ones provided by RC @@ -89,7 +95,7 @@ else // catch some url/post parameters -$_auth = get_input_value('_auth', RCUBE_INPUT_GPC); +//$_auth = get_input_value('_auth', RCUBE_INPUT_GPC); $_task = get_input_value('_task', RCUBE_INPUT_GPC); $_action = get_input_value('_action', RCUBE_INPUT_GPC); $_framed = (!empty($_GET['_framed']) || !empty($_POST['_framed'])); @@ -104,8 +110,8 @@ if (!empty($_GET['_remote'])) rcmail_startup($_task); // set session related variables -$COMM_PATH = sprintf('./?_auth=%s&_task=%s', $sess_auth, $_task); -$SESS_HIDDEN_FIELD = sprintf('', $sess_auth); +$COMM_PATH = sprintf('./?_task=%s', $_task); +$SESS_HIDDEN_FIELD = ''; // add framed parameter @@ -146,9 +152,7 @@ if ($_action=='login' && $_task=='mail') show_message("cookiesdisabled", 'warning'); } else if (isset($_POST['_user']) && isset($_POST['_pass']) && - rcmail_login(get_input_value('_user', RCUBE_INPUT_POST), - get_input_value('_pass', RCUBE_INPUT_POST), - $host)) + rcmail_login(get_input_value('_user', RCUBE_INPUT_POST), $_POST['_pass'], $host)) { // send redirect header("Location: $COMM_PATH"); @@ -168,10 +172,10 @@ else if ($_action=='logout' && isset($_SESSION['user_id'])) rcmail_kill_session(); } -// check session cookie and auth string -else if ($_action!='login' && $sess_auth && $_SESSION['user_id']) +// check session and auth cookie +else if ($_action!='login' && $_SESSION['user_id']) { - if ($_auth !== $sess_auth || $_auth != rcmail_auth_hash($_SESSION['client_id'], $_SESSION['auth_time']) || + if (!rcmail_authenticate_session() || ($CONFIG['session_lifetime'] && isset($SESS_CHANGED) && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < mktime())) { $message = show_message('sessionerror', 'error'); diff --git a/program/include/main.inc b/program/include/main.inc index cc019af67..34e21c2a1 100644 --- a/program/include/main.inc +++ b/program/include/main.inc @@ -46,7 +46,7 @@ function rcmail_startup($task='mail') // load host-specific configuration rcmail_load_host_config($CONFIG); - $CONFIG['skin_path'] = $CONFIG['skin_path'] ? preg_replace('/\/$/', '', $CONFIG['skin_path']) : 'skins/default'; + $CONFIG['skin_path'] = $CONFIG['skin_path'] ? unslashify($CONFIG['skin_path']) : 'skins/default'; // load db conf include_once('config/db.inc.php'); @@ -55,7 +55,7 @@ function rcmail_startup($task='mail') if (empty($CONFIG['log_dir'])) $CONFIG['log_dir'] = $INSTALL_PATH.'logs'; else - $CONFIG['log_dir'] = ereg_replace('\/$', '', $CONFIG['log_dir']); + $CONFIG['log_dir'] = unslashify($CONFIG['log_dir']); // set PHP error logging according to config if ($CONFIG['debug_level'] & 1) @@ -67,7 +67,8 @@ function rcmail_startup($task='mail') ini_set('display_errors', 1); else ini_set('display_errors', 0); - + + // set session garbage collecting time according to session_lifetime if (!empty($CONFIG['session_lifetime'])) ini_set('session.gc_maxlifetime', ($CONFIG['session_lifetime']+2)*60); @@ -81,7 +82,6 @@ function rcmail_startup($task='mail') $DB->db_connect('w'); // we can use the database for storing session data - // session queries do not work with MDB2 if (!$DB->is_error()) include_once('include/session.inc'); @@ -90,17 +90,14 @@ function rcmail_startup($task='mail') $sess_id = session_id(); // create session and set session vars - if (!$_SESSION['client_id']) + if (!isset($_SESSION['auth_time'])) { - $_SESSION['client_id'] = $sess_id; $_SESSION['user_lang'] = rcube_language_prop($CONFIG['locale_string']); $_SESSION['auth_time'] = mktime(); - $_SESSION['auth'] = rcmail_auth_hash($sess_id, $_SESSION['auth_time']); - unset($GLOBALS['_auth']); + setcookie('sessauth', rcmail_auth_hash($sess_id, $_SESSION['auth_time'])); } // set session vars global - $sess_auth = $_SESSION['auth']; $sess_user_lang = rcube_language_prop($_SESSION['user_lang']); @@ -148,7 +145,7 @@ function rcmail_load_host_config(&$config) $config = array_merge($config, $rcmail_config); } } - + // create authorization hash function rcmail_auth_hash($sess_id, $ts) @@ -168,6 +165,22 @@ function rcmail_auth_hash($sess_id, $ts) } +// compare the auth hash sent by the client with the local session credentials +function rcmail_authenticate_session() + { + $now = mktime(); + $valid = ($_COOKIE['sessauth'] == rcmail_auth_hash(session_id(), $_SESSION['auth_time'])); + + // renew auth cookie every 5 minutes + if (!$valid || ($now-$_SESSION['auth_time'] > 300)) + { + $_SESSION['auth_time'] = $now; + setcookie('sessauth', rcmail_auth_hash(session_id(), $now)); + } + + return $valid; + } + // create IMAP object and connect to server function rcmail_imap_init($connect=FALSE) @@ -718,17 +731,35 @@ function console($msg, $type=1) } +// encrypt IMAP password using DES encryption function encrypt_passwd($pass) { - $cypher = des('rcmail?24BitPwDkeyF**ECB', $pass, 1, 0, NULL); + $cypher = des(get_des_key(), $pass, 1, 0, NULL); return base64_encode($cypher); } +// decrypt IMAP password using DES encryption function decrypt_passwd($cypher) { - $pass = des('rcmail?24BitPwDkeyF**ECB', base64_decode($cypher), 0, 0, NULL); - return trim($pass); + $pass = des(get_des_key(), base64_decode($cypher), 0, 0, NULL); + return preg_replace('/\x00/', '', $pass); + } + + +// return a 24 byte key for the DES encryption +function get_des_key() + { + $key = !empty($GLOBALS['CONFIG']['des_key']) ? $GLOBALS['CONFIG']['des_key'] : 'rcmail?24BitPwDkeyF**ECB'; + $len = strlen($key); + + // make sure the key is exactly 24 chars long + if ($len<24) + $key .= str_repeat('_', 24-$len); + else if ($len>24) + substr($key, 0, 24); + + return $key; } @@ -802,7 +833,7 @@ function rcmail_clear_session_temp($sess_id) { global $CONFIG; - $temp_dir = $CONFIG['temp_dir'].(!eregi('\/$', $CONFIG['temp_dir']) ? '/' : ''); + $temp_dir = slashify($CONFIG['temp_dir']); $cache_dir = $temp_dir.$sess_id; if (is_dir($cache_dir)) diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc index bb3146466..bc12eac06 100644 --- a/program/include/rcube_imap.inc +++ b/program/include/rcube_imap.inc @@ -1732,7 +1732,7 @@ class rcube_imap * * @access static */ - function decode_mime_string($input) + function decode_mime_string($input, $recursive=false) { $out = ''; @@ -1753,7 +1753,7 @@ class rcube_imap return $out; } - + // no encoding information, defaults to what is specified in the class header return rcube_charset_convert($input, 'ISO-8859-1'); } diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc index fe1a560a3..8f4efdb07 100644 --- a/program/include/rcube_shared.inc +++ b/program/include/rcube_shared.inc @@ -1334,7 +1334,8 @@ function make_absolute_url($path, $base_url) } - +// replace the middle part of a string with ... +// if it is longer than the allowed length function abbrevate_string($str, $maxlength, $place_holder='...') { $length = strlen($str); @@ -1350,6 +1351,20 @@ function abbrevate_string($str, $maxlength, $place_holder='...') } +// make sure the string ends with a slash +function slashify($str) + { + return unslashify($str).'/'; + } + + +// remove slash at the end of the string +function unslashify($str) + { + return preg_replace('/\/$/', '', $str); + } + + // delete all files within a folder function clear_directory($dir_path) { diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 261cbdd25..376c0bf93 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -214,7 +214,7 @@ function rcmail_render_folder_tree_html(&$arrFolders, &$special, &$mbox_name, $m else if ($folder['id']==$CONFIG['junk_mbox']) $class_name = 'junk'; - $out .= sprintf('
  • %s', $folder_css, @@ -437,7 +437,7 @@ function rcmail_message_list($attrib) { $cont = rep_specialchars_output($IMAP->decode_header($header->$col), 'html', 'all'); // firefox/mozilla temporary workaround to pad subject with content so that whitespace in rows responds to drag+drop - $cont .= sprintf('', $skin_path, "/images/cleardot.png"); + $cont .= ''; } else if ($col=='size') $cont = show_bytes($header->$col); @@ -1017,7 +1017,7 @@ function rcmail_message_headers($attrib, $headers=NULL) if ($hkey=='date' && !empty($headers[$hkey])) $header_value = format_date(strtotime($headers[$hkey])); else if (in_array($hkey, array('from', 'to', 'cc', 'bcc', 'reply-to'))) - $header_value = rep_specialchars_output(rcmail_address_string($IMAP->decode_header($headers[$hkey]), NULL, $attrib['addicon'])); + $header_value = rep_specialchars_output(rcmail_address_string($headers[$hkey], NULL, $attrib['addicon'])); else $header_value = rep_specialchars_output($IMAP->decode_header($headers[$hkey]), '', 'all');