From 48a04205c8513fdc4f923fef556e3db8cc17d9f9 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Fri, 17 Aug 2012 09:02:18 -0400 Subject: [PATCH] Fix bug where domain name was converted to lower-case even with login_lc=false (#1488593) --- program/include/rcmail.php | 192 ++++++++++++++++++++++++----------------------- 1 files changed, 98 insertions(+), 94 deletions(-) diff --git a/program/include/rcmail.php b/program/include/rcmail.php index 3d5915e..44a6016 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -129,6 +129,12 @@ private $caches = array(); private $action_map = array(); private $shutdown_functions = array(); + private $expunge_cache = false; + + const ERROR_STORAGE = -2; + const ERROR_INVALID_REQUEST = 1; + const ERROR_INVALID_HOST = 2; + const ERROR_COOKIES_DISABLED = 3; /** @@ -338,15 +344,20 @@ $this->memcache = new Memcache; $this->mc_available = 0; - - // add alll configured hosts to pool + + // add all configured hosts to pool $pconnect = $this->config->get('memcache_pconnect', true); foreach ($this->config->get('memcache_hosts', array()) as $host) { - list($host, $port) = explode(':', $host); - if (!$port) $port = 11211; + if (substr($host, 0, 7) != 'unix://') { + list($host, $port) = explode(':', $host); + if (!$port) $port = 11211; + } + else { + $port = 0; + } $this->mc_available += intval($this->memcache->addServer($host, $port, $pconnect, 1, 1, 15, false, array($this, 'memcache_failure'))); } - + // test connection and failover (will result in $this->mc_available == 0 on complete failure) $this->memcache->increment('__CONNECTIONTEST__', 1); // NOP if key doesn't exist @@ -356,14 +367,14 @@ return $this->memcache; } - + /** * Callback for memcache failure */ public function memcache_failure($host, $port) { static $seen = array(); - + // only report once if (!$seen["$host:$port"]++) { $this->mc_available--; @@ -555,7 +566,7 @@ $this->output->set_charset(RCMAIL_CHARSET); // add some basic labels to client - $this->output->add_label('loading', 'servererror'); + $this->output->add_label('loading', 'servererror', 'requesttimedout'); return $this->output; } @@ -727,11 +738,10 @@ } else { $this->set_storage_prop(); - return $storage->is_connected(); } } - return false; + return $storage->is_connected(); } @@ -767,8 +777,7 @@ $this->session = new rcube_session($this->get_dbh(), $this->config); $this->session->register_gc_handler('rcmail_temp_gc'); - if ($this->config->get('enable_caching')) - $this->session->register_gc_handler('rcmail_cache_gc'); + $this->session->register_gc_handler(array($this, 'cache_gc')); // start PHP session (if not in CLI mode) if ($_SERVER['REMOTE_ADDR']) @@ -777,6 +786,10 @@ // set initial session vars if (!$_SESSION['user_id']) $_SESSION['temp'] = true; + + // restore skin selection after logout + if ($_SESSION['temp'] && !empty($_SESSION['skin'])) + $this->config->set('skin', $_SESSION['skin']); } @@ -799,7 +812,7 @@ $this->session->set_keep_alive($keep_alive); } - $this->session->set_secret($this->config->get('des_key') . $_SERVER['HTTP_USER_AGENT']); + $this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME'])); $this->session->set_ip_check($this->config->get('ip_check')); } @@ -811,12 +824,20 @@ * @param string Mail storage (IMAP) user name * @param string Mail storage (IMAP) password * @param string Mail storage (IMAP) host + * @param bool Enables cookie check * * @return boolean True on success, False on failure */ - function login($username, $pass, $host=NULL) + function login($username, $pass, $host = null, $cookiecheck = false) { + $this->login_error = null; + if (empty($username)) { + return false; + } + + if ($cookiecheck && empty($_COOKIE)) { + $this->login_error = self::ERROR_COOKIES_DISABLED; return false; } @@ -836,11 +857,18 @@ break; } } - if (!$allowed) - return false; + if (!$allowed) { + $host = null; } - else if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host'])) + } + else if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host'])) { + $host = null; + } + + if (!$host) { + $this->login_error = self::ERROR_INVALID_HOST; return false; + } // parse $host URL $a_host = parse_url($host); @@ -871,7 +899,14 @@ // Convert username to lowercase. If storage backend // is case-insensitive we need to store always the same username (#1487113) if ($config['login_lc']) { - $username = mb_strtolower($username); + if ($config['login_lc'] == 2 || $config['login_lc'] === true) { + $username = mb_strtolower($username); + } + else if (strpos($username, '@')) { + // lowercase domain name + list($local, $domain) = explode('@', $username); + $username = $local . '@' . mb_strtolower($domain); + } } // try to resolve email address from virtuser table @@ -881,17 +916,13 @@ // Here we need IDNA ASCII // Only rcube_contacts class is using domain names in Unicode - $host = rcube_idn_to_ascii($host); - if (strpos($username, '@')) { - // lowercase domain name - list($local, $domain) = explode('@', $username); - $username = $local . '@' . mb_strtolower($domain); - $username = rcube_idn_to_ascii($username); - } + $host = rcube_idn_to_ascii($host); + $username = rcube_idn_to_ascii($username); // user already registered -> overwrite username - if ($user = rcube_user::query($username, $host)) + if ($user = rcube_user::query($username, $host)) { $username = $user->data['username']; + } if (!$this->storage) $this->storage_init(); @@ -963,7 +994,7 @@ $_SESSION['storage_port'] = $port; $_SESSION['storage_ssl'] = $ssl; $_SESSION['password'] = $this->encrypt($pass); - $_SESSION['login_time'] = mktime(); + $_SESSION['login_time'] = time(); if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_') $_SESSION['timezone'] = floatval($_REQUEST['_timezone']); @@ -978,6 +1009,23 @@ return false; } + + + /** + * Returns error code of last login operation + * + * @return int Error code + */ + public function login_error() + { + if ($this->login_error) { + return $this->login_error; + } + + if ($this->storage && $this->storage->get_error_code() < -1) { + return self::ERROR_STORAGE; + } + } /** @@ -1014,15 +1062,16 @@ if (is_array($default_host)) { $post_host = get_input_value('_host', RCUBE_INPUT_POST); + $post_user = get_input_value('_user', RCUBE_INPUT_POST); + + list($user, $domain) = explode('@', $post_user); // direct match in default_host array - if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) { + if ($default_host[$post_host] || in_array($post_host, $default_host)) { $host = $post_host; } - // try to select host by mail domain - list($user, $domain) = explode('@', get_input_value('_user', RCUBE_INPUT_POST)); - if (!empty($domain)) { + else if (!empty($domain)) { foreach ($default_host as $storage_host => $mail_domains) { if (is_array($mail_domains) && in_array_nocase($domain, $mail_domains)) { $host = $storage_host; @@ -1164,7 +1213,7 @@ $this->texts = array_merge($this->texts, $messages); // include user language files - if ($lang != 'en' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { + if ($lang != 'en' && $lang != 'en_US' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) { include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc'); include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc'); @@ -1221,7 +1270,7 @@ $this->plugins->exec_hook('session_destroy'); $this->session->kill(); - $_SESSION = array('language' => $this->user->language, 'temp' => true); + $_SESSION = array('language' => $this->user->language, 'temp' => true, 'skin' => $this->config->get('skin')); $this->user->reset(); } @@ -1278,8 +1327,11 @@ $cache->close(); } - if (is_object($this->storage)) + if (is_object($this->storage)) { + if ($this->expunge_cache) + $this->storage->expunge_cache(); $this->storage->close(); + } // before closing the database connection, write session data if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) { @@ -1312,6 +1364,18 @@ public function add_shutdown_function($function) { $this->shutdown_functions[] = $function; + } + + + /** + * Garbage collector for cache entries. + * Set flag to expunge caches on shutdown + */ + function cache_gc() + { + // because this gc function is called before storage is initialized, + // we just set a flag to expunge storage cache on shutdown. + $this->expunge_cache = true; } @@ -1514,66 +1578,6 @@ } } return $url; - } - - - /** - * Use imagemagick or GD lib to read image properties - * - * @param string Absolute file path - * @return mixed Hash array with image props like type, width, height or False on error - */ - public static function imageprops($filepath) - { - $rcmail = rcmail::get_instance(); - if ($cmd = $rcmail->config->get('im_identify_path', false)) { - list(, $type, $size) = explode(' ', strtolower(rcmail::exec($cmd. ' 2>/dev/null {in}', array('in' => $filepath)))); - if ($size) - list($width, $height) = explode('x', $size); - } - else if (function_exists('getimagesize')) { - $imsize = @getimagesize($filepath); - $width = $imsize[0]; - $height = $imsize[1]; - $type = preg_replace('!image/!', '', $imsize['mime']); - } - - return $type ? array('type' => $type, 'width' => $width, 'height' => $height) : false; - } - - - /** - * Convert an image to a given size and type using imagemagick (ensures input is an image) - * - * @param $p['in'] Input filename (mandatory) - * @param $p['out'] Output filename (mandatory) - * @param $p['size'] Width x height of resulting image, e.g. "160x60" - * @param $p['type'] Output file type, e.g. "jpg" - * @param $p['-opts'] Custom command line options to ImageMagick convert - * @return Success of convert as true/false - */ - public static function imageconvert($p) - { - $result = false; - $rcmail = rcmail::get_instance(); - $convert = $rcmail->config->get('im_convert_path', false); - $identify = $rcmail->config->get('im_identify_path', false); - - // imagemagick is required for this - if (!$convert) - return false; - - if (!(($imagetype = @exif_imagetype($p['in'])) && ($type = image_type_to_extension($imagetype, false)))) - list(, $type) = explode(' ', strtolower(rcmail::exec($identify . ' 2>/dev/null {in}', $p))); # for things like eps - - $type = strtr($type, array("jpeg" => "jpg", "tiff" => "tif", "ps" => "eps", "ept" => "eps")); - $p += array('type' => $type, 'types' => "bmp,eps,gif,jp2,jpg,png,svg,tif", 'quality' => 75); - $p['-opts'] = array('-resize' => $p['size'].'>') + (array)$p['-opts']; - - if (in_array($type, explode(',', $p['types']))) # Valid type? - $result = rcmail::exec($convert . ' 2>&1 -flatten -auto-orient -colorspace RGB -quality {quality} {-opts} {in} {type}:{out}', $p) === ""; - - return $result; } -- Gitblit v1.9.1