Projects
Kolab:3.4
roundcubemail
roundcubemail-1.1-collated.patch
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File roundcubemail-1.1-collated.patch of Package roundcubemail (Revision 54)
Currently displaying revision
54
,
Show latest
diff -ur roundcubemail-1.1.orig/config/defaults.inc.php roundcubemail-1.1/config/defaults.inc.php --- roundcubemail-1.1.orig/config/defaults.inc.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/config/defaults.inc.php 2014-11-05 12:46:36.186520550 +0100 @@ -430,7 +430,7 @@ // Password charset. // Use it if your authentication backend doesn't support UTF-8. // Defaults to ISO-8859-1 for backward compatibility -$config['password_charset'] = 'ISO-8859-1'; +$config['password_charset'] = 'UTF-8'; // How many seconds must pass between emails sent by a user $config['sendmail_delay'] = 0; @@ -532,6 +532,23 @@ // Note: useful when SMTP server stores sent mail in user mailbox $config['no_save_sent_messages'] = false; +// Improve system security by using special URL with security token. +// This can be set to a number defining token length. Default: 16. +// Warning: This requires http server configuration. Sample: +// RewriteRule ^/roundcubemail/[a-f0-9]{16}/(.*) /roundcubemail/$1 [PT] +// Alias /roundcubemail /var/www/roundcubemail/ +// Note: Use assets_path to not prevent the browser from caching assets +$config['use_secure_urls'] = true; + +// Allows to define separate server/path for image/js/css files +// Warning: If the domain is different cross-domain access to some +// resources need to be allowed +// Sample: +// <FilesMatch ".(eot|ttf|woff)"> +// Header set Access-Control-Allow-Origin "*" +// </FilesMatch> +$config['assets_path'] = '/roundcubemail/assets/'; + // ---------------------------------- // PLUGINS // ---------------------------------- @@ -625,7 +642,7 @@ // Since Google shut down their public spell checking service, the default settings // connect to http://spell.roundcube.net which is a hosted service provided by Roundcube. // You can connect to any other googie-compliant service by setting 'spellcheck_uri' accordingly. -$config['spellcheck_engine'] = 'googie'; +$config['spellcheck_engine'] = 'pspell'; // For locally installed Nox Spell Server or After the Deadline services, // please specify the URI to call it. @@ -1008,7 +1025,7 @@ $config['display_next'] = true; // Default messages listing mode. One of 'threads' or 'list'. -$config['default_list_mode'] = 'list'; +$config['default_list_mode'] = 'threads'; // 0 - Do not expand threads // 1 - Expand all threads automatically Only in roundcubemail-1.1/config: defaults.inc.php.orig diff -ur roundcubemail-1.1.orig/.htaccess roundcubemail-1.1/.htaccess --- roundcubemail-1.1.orig/.htaccess 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/.htaccess 2014-11-05 12:46:36.166520529 +0100 @@ -30,7 +30,7 @@ # security rules: # - deny access to files not containing a dot or starting with a dot # in all locations except installer directory -RewriteRule ^(?!installer)(\.?[^\.]+)$ - [F] +RewriteRule ^(?!installer|[a-f0-9]{16})(\.?[^\.]+)$ - [F] # - deny access to some locations RewriteRule ^/?(\.git|\.tx|SQL|bin|config|logs|temp|tests|program\/(include|lib|localization|steps)) - [F] # - deny access to some documentation files diff -ur roundcubemail-1.1.orig/index.php roundcubemail-1.1/index.php --- roundcubemail-1.1.orig/index.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/index.php 2014-11-05 12:46:36.167520530 +0100 @@ -90,9 +90,9 @@ // try to log in if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') { - $request_valid = $_SESSION['temp'] && $RCMAIL->check_request(rcube_utils::INPUT_POST, 'login'); + $request_valid = $_SESSION['temp'] && $RCMAIL->check_request(); - // purge the session in case of new login when a session already exists + // purge the session in case of new login when a session already exists $RCMAIL->kill_session(); $auth = $RCMAIL->plugins->exec_hook('authenticate', array( @@ -140,7 +140,7 @@ unset($redir['abort'], $redir['_err']); // send redirect - $OUTPUT->redirect($redir); + $OUTPUT->redirect($redir, 0, true); } else { if (!$auth['valid']) { @@ -171,10 +171,10 @@ } } -// end session (after optional referer check) -else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id']) - && (!$RCMAIL->config->get('referer_check') || rcube_utils::check_referer()) -) { +// end session +else if ($RCMAIL->task == 'logout' && isset($_SESSION['user_id'])) { + $RCMAIL->request_security_check($mode = rcube_utils::INPUT_GET); + $userdata = array( 'user' => $_SESSION['username'], 'host' => $_SESSION['storage_host'], @@ -234,32 +234,9 @@ $OUTPUT->send($plugin['task']); } -// CSRF prevention else { - // don't check for valid request tokens in these actions - $request_check_whitelist = array('login'=>1, 'spell'=>1, 'spell_html'=>1); - - if (!$request_check_whitelist[$RCMAIL->action]) { - // check client X-header to verify request origin - if ($OUTPUT->ajax_call) { - if (rcube_utils::request_header('X-Roundcube-Request') != $RCMAIL->get_request_token()) { - header('HTTP/1.1 403 Forbidden'); - die("Invalid Request"); - } - } - // check request token in POST form submissions - else if (!empty($_POST) && !$RCMAIL->check_request()) { - $OUTPUT->show_message('invalidrequest', 'error'); - $OUTPUT->send($RCMAIL->task); - } - - // check referer if configured - if ($RCMAIL->config->get('referer_check') && !rcube_utils::check_referer()) { - raise_error(array( - 'code' => 403, 'type' => 'php', - 'message' => "Referer check failed"), true, true); - } - } + // CSRF prevention + $RCMAIL->request_security_check(); // check access to disabled actions $disabled_actions = (array) $RCMAIL->config->get('disabled_actions'); diff -ur roundcubemail-1.1.orig/plugins/acl/acl.js roundcubemail-1.1/plugins/acl/acl.js --- roundcubemail-1.1.orig/plugins/acl/acl.js 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/plugins/acl/acl.js 2014-11-05 12:46:36.168520531 +0100 @@ -58,8 +58,11 @@ var users = this.acl_get_usernames(); if (users && users.length && confirm(this.get_label('acl.deleteconfirm'))) { - this.http_request('settings/plugin.acl', '_act=delete&_user='+urlencode(users.join(',')) - + '&_mbox='+urlencode(this.env.mailbox), + this.http_post('settings/plugin.acl', { + _act: 'delete', + _user: users.join(','), + _mbox: this.env.mailbox + }, this.set_busy(true, 'acl.deleting')); } } @@ -67,7 +70,7 @@ // Save ACL data rcube_webmail.prototype.acl_save = function() { - var user = $('#acluser', this.acl_form).val(), rights = '', type; + var data, type, rights = '', user = $('#acluser', this.acl_form).val(); $((this.env.acl_advanced ? '#advancedrights :checkbox' : '#simplerights :checkbox'), this.acl_form).map(function() { if (this.checked) @@ -88,12 +91,18 @@ return; } - this.http_request('settings/plugin.acl', '_act=save' - + '&_user='+urlencode(user) - + '&_acl=' +rights - + '&_mbox='+urlencode(this.env.mailbox) - + (this.acl_id ? '&_old='+this.acl_id : ''), - this.set_busy(true, 'acl.saving')); + data = { + _act: 'save', + _user: user, + _acl: rights, + _mbox: this.env.mailbox + } + + if (this.acl_id) { + data._old = this.acl_id; + } + + this.http_post('settings/plugin.acl', data, this.set_busy(true, 'acl.saving')); } // Cancel/Hide form diff -ur roundcubemail-1.1.orig/plugins/acl/acl.php roundcubemail-1.1/plugins/acl/acl.php --- roundcubemail-1.1.orig/plugins/acl/acl.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/plugins/acl/acl.php 2014-11-05 12:46:36.169520532 +0100 @@ -454,10 +454,10 @@ */ private function action_save() { - $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)); // UTF7-IMAP - $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_GPC)); - $acl = trim(rcube_utils::get_input_value('_acl', rcube_utils::INPUT_GPC)); - $oldid = trim(rcube_utils::get_input_value('_old', rcube_utils::INPUT_GPC)); + $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true)); // UTF7-IMAP + $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)); + $acl = trim(rcube_utils::get_input_value('_acl', rcube_utils::INPUT_POST)); + $oldid = trim(rcube_utils::get_input_value('_old', rcube_utils::INPUT_POST)); $acl = array_intersect(str_split($acl), $this->rights_supported()); $users = $oldid ? array($user) : explode(',', $user); @@ -510,8 +510,8 @@ */ private function action_delete() { - $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)); //UTF7-IMAP - $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_GPC)); + $mbox = trim(rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true)); //UTF7-IMAP + $user = trim(rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)); $user = explode(',', $user); diff -ur roundcubemail-1.1.orig/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php roundcubemail-1.1/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php --- roundcubemail-1.1.orig/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php 2014-11-05 12:46:36.171520534 +0100 @@ -349,7 +349,7 @@ } } else if ($action == 'setact' && !$error) { - $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); + $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_POST, true); $result = $this->activate_script($script_name); $kep14 = $this->rc->config->get('managesieve_kolab_master'); @@ -363,7 +363,7 @@ } } else if ($action == 'deact' && !$error) { - $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); + $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_POST, true); $result = $this->deactivate_script($script_name); if ($result === true) { @@ -376,7 +376,7 @@ } } else if ($action == 'setdel' && !$error) { - $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true); + $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_POST, true); $result = $this->remove_script($script_name); if ($result === true) { @@ -419,14 +419,14 @@ $this->rc->output->command('managesieve_updatelist', 'list', array('list' => $result)); } else if ($action == 'ruleadd') { - $rid = rcube_utils::get_input_value('_rid', rcube_utils::INPUT_GPC); + $rid = rcube_utils::get_input_value('_rid', rcube_utils::INPUT_POST); $id = $this->genid(); $content = $this->rule_div($fid, $id, false); $this->rc->output->command('managesieve_rulefill', $content, $id, $rid); } else if ($action == 'actionadd') { - $aid = rcube_utils::get_input_value('_aid', rcube_utils::INPUT_GPC); + $aid = rcube_utils::get_input_value('_aid', rcube_utils::INPUT_POST); $id = $this->genid(); $content = $this->action_div($fid, $id, false); diff -ur roundcubemail-1.1.orig/program/include/rcmail_output_html.php roundcubemail-1.1/program/include/rcmail_output_html.php --- roundcubemail-1.1.orig/program/include/rcmail_output_html.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/include/rcmail_output_html.php 2014-11-05 13:56:12.263999725 +0100 @@ -45,6 +45,7 @@ protected $footer = ''; protected $body = ''; protected $base_path = ''; + protected $assets_path; protected $devel_mode = false; // deprecated names of templates used before 0.5 @@ -80,6 +81,8 @@ $this->set_skin($skin); $this->set_env('skin', $skin); + $this->set_assets_path($this->config->get('assets_path')); + if (!empty($_REQUEST['_extwin'])) $this->set_env('extwin', 1); if ($this->framed || $framed) @@ -145,6 +148,51 @@ } /** + * Parse and set assets path + * + * @param string Assets path (relative or absolute URL) + */ + public function set_assets_path($path) + { + if (empty($path)) { + return; + } + + $path = rtrim($path, '/') . '/'; + + // convert to absolute URL + if (!preg_match('|^https?://|', $path)) { + if ($path[0] != '/') { + $base = preg_replace('/[?#&].*$/', '', $_SERVER['REQUEST_URI']); + $base = rtrim($base, '/'); + } + + // remove url token if exists + if ($len = intval($this->config->get('use_secure_urls'))) { + $_base = explode('/', $base); + $length = $len > 1 ? $len : 16; // as in rcube::get_secure_url_token() + + // we can't use real token here because it + // does not exists in unauthenticated state, + // hope this will not produce false-positive matches + foreach ($_base as $idx => $token) { + if (preg_match('/^[a-f0-9]{' . $length . '}$/', $token)) { + unset($_base[$idx]); + break; + } + } + + $base = implode('/', $_base); + } + $path = (rcube_utils::https_check() ? 'https' : 'http') . '://' + . $_SERVER['HTTP_HOST'] . rtrim($base, '/') . '/' . ltrim($path, '/'); + } + + $this->assets_path = $path; + $this->set_env('assets_path', $path); + } + + /** * Getter for the current page title * * @return string The page title @@ -261,10 +309,27 @@ } foreach ($skin_paths as $skin_path) { - $path = realpath($skin_path . $file); + $path = $skin_path . $file; + if (is_file($path)) { return $skin_path . $file; } + + $path = rtrim(RCUBE_INSTALL_PATH, '/'); + $path .= '/' . 'public_html/assets/'; + $path .= rtrim($skin_path, '/') . '/' . $file; + + if (is_file($path)) { + return $skin_path . $file; + } + + $path = rtrim(RCUBE_INSTALL_PATH, '/'); + $path .= '/' . $skin_path . $file; + $path = realpath($path); + + if ($skin_path[0] != '/' && is_file($path)) { + return $path; + } } return false; @@ -369,14 +434,15 @@ /** * Redirect to a certain url * - * @param mixed $p Either a string with the action or url parameters as key-value pairs - * @param int $delay Delay in seconds + * @param mixed $p Either a string with the action or url parameters as key-value pairs + * @param int $delay Delay in seconds + * @param bool $secure Redirect to secure location (see rcmail::url()) */ - public function redirect($p = array(), $delay = 1) + public function redirect($p = array(), $delay = 1, $secure = false) { if ($this->env['extwin']) $p['extwin'] = 1; - $location = $this->app->url($p); + $location = $this->app->url($p, false, false, $secure); header('Location: ' . $location); exit; } @@ -494,9 +560,10 @@ // fallback to deprecated template names if (!is_readable($path) && $this->deprecated_templates[$realname]) { - $path = "$skin_path/templates/" . $this->deprecated_templates[$realname] . ".html"; + // Try an old path + $tpath = "$skin_path/templates/" . $this->deprecated_templates[$realname] . ".html"; - if (is_readable($path)) { + if (is_readable($tpath)) { rcube::raise_error(array( 'code' => 502, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, @@ -506,6 +573,10 @@ } } + if (!is_readable($path) && $path[0] != '/' && is_readable(rtrim(RCUBE_INSTALL_PATH, '/') . '/' . $path)) { + $path = rtrim(RCUBE_INSTALL_PATH, '/') . '/' . $path; + } + if (is_readable($path)) { $this->config->set('skin_path', $skin_path); $this->base_path = preg_replace('!plugins/\w+/!', '', $skin_path); // set base_path to core skin directory (not plugin's skin) @@ -667,6 +738,24 @@ exit; } + /** + * Modify path by adding URL prefix if configured + */ + public function asset_url($path) + { + // iframe content can't be in a different domain + // @TODO: check if assests are on a different domain + if (!$this->assets_path || $path == $this->env['blankpage']) { + return $path; + } + + if ($path[0] == '.' && $path[1] == '/') { + $path = substr($path, 2); + } + + return $this->assets_path . $path; + } + /***** Template parsing methods *****/ @@ -723,6 +812,8 @@ $file = $this->file_mod($file); } + $file = $this->asset_url($file); + return $matches[1] . '=' . $matches[2] . $file . $matches[4]; } @@ -1337,6 +1428,7 @@ { if (!preg_match('|^https?://|i', $file) && $file[0] != '/') { $file = $this->file_mod($this->scripts_path . $file); + $file = $this->asset_url($file); } if (!is_array($this->script_files[$position])) { @@ -1549,7 +1641,7 @@ } $attrib['name'] = $attrib['id']; - $attrib['src'] = $attrib['src'] ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif'; + $attrib['src'] = $this->asset_url($attrib['src'] ? $this->abs_url($attrib['src'], true) : 'program/resources/blank.gif'); // register as 'contentframe' object if ($is_contentframe || $attrib['contentframe']) { @@ -1766,9 +1858,11 @@ { $images = preg_split('/[\s\t\n,]+/', $attrib['images'], -1, PREG_SPLIT_NO_EMPTY); $images = array_map(array($this, 'abs_url'), $images); + $images = array_map(array($this, 'asset_url'), $images); - if (empty($images) || $this->app->task == 'logout') + if (empty($images) || $_REQUEST['_task'] == 'logout') { return; + } $this->add_script('var images = ' . self::json_serialize($images) .'; for (var i=0; i<images.length; i++) { diff -ur roundcubemail-1.1.orig/program/include/rcmail_output_json.php roundcubemail-1.1/program/include/rcmail_output_json.php --- roundcubemail-1.1.orig/program/include/rcmail_output_json.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/include/rcmail_output_json.php 2014-11-05 12:46:36.174520537 +0100 @@ -181,6 +181,11 @@ */ public function raise_error($code, $message) { + if ($code == 403) { + header('HTTP/1.1 403 Forbidden'); + die("Invalid Request"); + } + $this->show_message("Application Error ($code): $message", 'error'); $this->remote_response(); exit; diff -ur roundcubemail-1.1.orig/program/include/rcmail.php roundcubemail-1.1/program/include/rcmail.php --- roundcubemail-1.1.orig/program/include/rcmail.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/include/rcmail.php 2014-11-05 12:46:36.175520538 +0100 @@ -760,49 +760,16 @@ } /** - * Generate a unique token to be used in a form request - * - * @return string The request token - */ - public function get_request_token() - { - $sess_id = $_COOKIE[ini_get('session.name')]; - - if (!$sess_id) { - $sess_id = session_id(); - } - - $plugin = $this->plugins->exec_hook('request_token', array( - 'value' => md5('RT' . $this->get_user_id() . $this->config->get('des_key') . $sess_id))); - - return $plugin['value']; - } - - /** - * Check if the current request contains a valid token - * - * @param int Request method - * - * @return boolean True if request token is valid false if not - */ - public function check_request($mode = rcube_utils::INPUT_POST) - { - $token = rcube_utils::get_input_value('_token', $mode); - $sess_id = $_COOKIE[ini_get('session.name')]; - - return !empty($sess_id) && $token == $this->get_request_token(); - } - - /** * Build a valid URL to this instance of Roundcube * * @param mixed Either a string with the action or url parameters as key-value pairs * @param boolean Build an URL absolute to document root * @param boolean Create fully qualified URL including http(s):// and hostname + * @param bool Return absolute URL in secure location * * @return string Valid application URL */ - public function url($p, $absolute = false, $full = false) + public function url($p, $absolute = false, $full = false, $secure = false) { if (!is_array($p)) { if (strpos($p, 'http') === 0) { @@ -828,9 +795,21 @@ } } + $base_path = preg_replace('![^/]+$!', '', strval($_SERVER['SCRIPT_NAME'])); + + if ($secure && ($token = $this->get_secure_url_token(true))) { + // add token to the url + $url = $token . '/' . $url; + + // remove old token from the path + $base_path = preg_replace('/\/[a-f0-9]{' . strlen($token) . '}$/', '', $base_path); + + // this need to be full url to make redirects work + $absolute = true; + } + if ($absolute || $full) { // add base path to this Roundcube installation - $base_path = preg_replace('![^/]+$!', '', strval($_SERVER['SCRIPT_NAME'])); if ($base_path == '') $base_path = '/'; $prefix = $base_path; @@ -879,6 +858,36 @@ } } + /** + * CSRF attack prevention code + * + * @param int Request mode + */ + public function request_security_check($mode = rcube_utils::INPUT_POST) + { + // don't check for valid request tokens in these actions + // @TODO: get rid of this + $request_check_whitelist = array('spell'=>1, 'spell_html'=>1); + + if ($request_check_whitelist[$this->action]) { + return; + } + + // check request token + if (!$this->check_request($mode)) { + self::raise_error(array( + 'code' => 403, 'type' => 'php', + 'message' => "Request security check failed"), false, true); + } + + // check referer if configured + if ($this->config->get('referer_check') && !rcube_utils::check_referer()) { + self::raise_error(array( + 'code' => 403, 'type' => 'php', + 'message' => "Referer check failed"), true, true); + } + } + /** * Registers action aliases for current task * diff -ur roundcubemail-1.1.orig/program/js/app.js roundcubemail-1.1/program/js/app.js --- roundcubemail-1.1.orig/program/js/app.js 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/js/app.js 2014-11-05 12:46:36.179520543 +0100 @@ -58,7 +58,6 @@ request_timeout: 180, // seconds draft_autosave: 0, // seconds comm_path: './', - blankpage: 'program/resources/blank.gif', recipients_separator: ',', recipients_delimiter: ', ', popup_width: 1150, @@ -163,6 +162,10 @@ return; } + if (!this.env.blankpage) + this.env.blankpage = (this.env.assets_path ? this.env.assets_path : '') + 'program/resources/blank.gif'; + + // find all registered gui containers for (n in this.gui_containers) this.gui_containers[n] = $('#'+this.gui_containers[n]); @@ -1405,8 +1408,10 @@ if (task == 'mail') url += '&_mbox=INBOX'; - else if (task == 'logout' && !this.env.server_error) + else if (task == 'logout' && !this.env.server_error) { + url += '&_token=' + this.env.request_token; this.clear_compose_data(); + } this.redirect(url); }; @@ -1416,7 +1421,10 @@ if (!url) url = this.env.comm_path; - return url.replace(/_task=[a-z0-9_-]+/i, '_task='+task); + if (url.match(/[?&]_task=[a-zA-Z0-9_-]+/)) + return url.replace(/_task=[a-zA-Z0-9_-]+/, '_task=' + task); + else + return url.replace(/\?.*$/, '') + '?_task=' + task; }; this.reload = function(delay) @@ -7982,7 +7990,7 @@ img.onload = function() { ref.env.browser_capabilities.tif = 1; }; img.onerror = function() { ref.env.browser_capabilities.tif = 0; }; - img.src = 'program/resources/blank.tif'; + img.src = (this.env.assets_path ? this.env.assets_path : '') + 'program/resources/blank.tif'; }; this.pdf_support_check = function() diff -ur roundcubemail-1.1.orig/program/js/editor.js roundcubemail-1.1/program/js/editor.js --- roundcubemail-1.1.orig/program/js/editor.js 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/js/editor.js 2014-11-05 12:46:36.181520545 +0100 @@ -36,11 +36,12 @@ function rcube_text_editor(config, id) { var ref = this, + abs_url = location.href.replace(/[?#].*$/, '').replace(/\/$/, ''), conf = { selector: '#' + ($('#' + id).is('.mce_editor') ? id : 'fake-editor-id'), theme: 'modern', language: config.lang, - content_css: 'program/js/tinymce/roundcube/content.css?v2', + content_css: (rcmail.env.assets_path || '') + 'program/js/tinymce/roundcube/content.css?v2', menubar: false, statusbar: false, toolbar_items_size: 'small', @@ -82,7 +83,7 @@ toolbar: 'bold italic underline | alignleft aligncenter alignright alignjustify' + ' | bullist numlist outdent indent ltr rtl blockquote | forecolor backcolor | fontselect fontsizeselect' + ' | link unlink table | emoticons charmap image media | code searchreplace undo redo', - spellchecker_rpc_url: '../../../../../?_task=utils&_action=spell_html&_remote=1', + spellchecker_rpc_url: abs_url + '/?_task=utils&_action=spell_html&_remote=1', spellchecker_language: rcmail.env.spell_lang, accessibility_focus: false, file_browser_callback: function(name, url, type, win) { ref.file_browser_callback(name, url, type); }, diff -ur roundcubemail-1.1.orig/program/lib/Roundcube/rcube_ldap.php roundcubemail-1.1/program/lib/Roundcube/rcube_ldap.php --- roundcubemail-1.1.orig/program/lib/Roundcube/rcube_ldap.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/lib/Roundcube/rcube_ldap.php 2014-11-05 12:46:19.849500765 +0100 @@ -853,7 +853,7 @@ // add general filter to query if (!empty($this->prop['filter'])) - $filter = '(&(' . preg_replace('/^\(|\)$/', '', $this->prop['filter']) . ')' . $filter . ')'; + $filter = '(&(' . preg_replace('/^\(|\)$/', '', array_key_exists('adv_filter', $this->prop) ? $this->prop['adv_filter'] : $this->prop['filter']) . ')' . $filter . ')'; // set filter string and execute search $this->set_search_set($filter); Only in roundcubemail-1.1/program/lib/Roundcube: rcube_ldap.php.orig diff -ur roundcubemail-1.1.orig/program/lib/Roundcube/rcube.php roundcubemail-1.1/program/lib/Roundcube/rcube.php --- roundcubemail-1.1.orig/program/lib/Roundcube/rcube.php 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/lib/Roundcube/rcube.php 2014-11-05 12:46:36.182520546 +0100 @@ -28,9 +28,15 @@ */ class rcube { - const INIT_WITH_DB = 1; + // Init options + const INIT_WITH_DB = 1; const INIT_WITH_PLUGINS = 2; + // Request status + const REQUEST_VALID = 0; + const REQUEST_ERROR_URL = 1; + const REQUEST_ERROR_TOKEN = 2; + /** * Singleton instace of rcube * @@ -101,6 +107,12 @@ */ public $user; + /** + * Request status + * + * @var int + */ + public $request_status = 0; /* private/protected vars */ protected $texts; @@ -978,6 +990,104 @@ /** + * Returns session token for secure URLs + * + * @param bool $generate Generate token if not exists in session yet + * + * @return string|bool Token string, False when disabled + */ + public function get_secure_url_token($generate = false) + { + if ($len = $this->config->get('use_secure_urls')) { + if (empty($_SESSION['secure_token']) && $generate) { + // generate x characters long token + $length = $len > 1 ? $len : 16; + $token = openssl_random_pseudo_bytes($length / 2); + $token = bin2hex($token); + + $plugin = $this->plugins->exec_hook('secure_token', + array('value' => $token, 'length' => $length)); + + $_SESSION['secure_token'] = $plugin['value']; + } + + return $_SESSION['secure_token']; + } + + return false; + } + + + /** + * Generate a unique token to be used in a form request + * + * @return string The request token + */ + public function get_request_token() + { + $sess_id = $_COOKIE[ini_get('session.name')]; + if (!$sess_id) { + $sess_id = session_id(); + } + + $plugin = $this->plugins->exec_hook('request_token', array( + 'value' => md5('RT' . $this->get_user_id() . $this->config->get('des_key') . $sess_id))); + + return $plugin['value']; + } + + + /** + * Check if the current request contains a valid token. + * Empty requests aren't checked until use_secure_urls is set. + * + * @param int Request method + * + * @return boolean True if request token is valid false if not + */ + public function check_request($mode = rcube_utils::INPUT_POST) + { + // check secure token in URL if enabled + if ($token = $this->get_secure_url_token()) { + foreach (explode('/', preg_replace('/[?#&].*$/', '', $_SERVER['REQUEST_URI'])) as $tok) { + if ($tok == $token) { + return true; + } + } + + $this->request_status = self::REQUEST_ERROR_URL; + + return false; + } + + $sess_tok = $this->get_request_token(); + + // ajax requests + if (rcube_utils::request_header('X-Roundcube-Request') == $sess_tok) { + return true; + } + + // skip empty requests + if (($mode == rcube_utils::INPUT_POST && empty($_POST)) + || ($mode == rcube_utils::INPUT_GET && empty($_GET)) + ) { + return true; + } + + // default method of securing requests + $token = rcube_utils::get_input_value('_token', $mode); + $sess_id = $_COOKIE[ini_get('session.name')]; + + if (empty($sess_id) || $token != $sess_tok) { + $this->request_status = self::REQUEST_ERROR_TOKEN; + return false; + } + + return true; + } + + + /** * Build a valid URL to this instance of Roundcube * * @param mixed Either a string with the action or url parameters as key-value pairs @@ -1265,7 +1375,7 @@ $cli = php_sapi_name() == 'cli'; - if (($log || $terminate) && !$cli && $arg['message']) { + if ($log && !$cli && $arg['message']) { $arg['fatal'] = $terminate; self::log_bug($arg); } diff -ur roundcubemail-1.1.orig/program/steps/addressbook/delete.inc roundcubemail-1.1/program/steps/addressbook/delete.inc --- roundcubemail-1.1.orig/program/steps/addressbook/delete.inc 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/steps/addressbook/delete.inc 2014-11-05 12:46:36.183520547 +0100 @@ -20,10 +20,11 @@ */ // process ajax requests only -if (!$OUTPUT->ajax_call) +if (!$OUTPUT->ajax_call) { return; +} -$cids = rcmail_get_cids(); +$cids = rcmail_get_cids(null, rcube_utils::INPUT_POST); $delcnt = 0; // remove previous deletes diff -ur roundcubemail-1.1.orig/program/steps/addressbook/func.inc roundcubemail-1.1/program/steps/addressbook/func.inc --- roundcubemail-1.1.orig/program/steps/addressbook/func.inc 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/steps/addressbook/func.inc 2014-11-05 12:46:36.184520548 +0100 @@ -896,13 +896,13 @@ * * @return array List of contact IDs per-source */ -function rcmail_get_cids($filter = null) +function rcmail_get_cids($filter = null, $request_type = rcube_utils::INPUT_GPC) { // contact ID (or comma-separated list of IDs) is provided in two // forms. If _source is an empty string then the ID is a string // containing contact ID and source name in form: <ID>-<SOURCE> - $cid = rcube_utils::get_input_value('_cid', rcube_utils::INPUT_GPC); + $cid = rcube_utils::get_input_value('_cid', $request_type); $source = (string) rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); if (is_array($cid)) { diff -ur roundcubemail-1.1.orig/program/steps/mail/show.inc roundcubemail-1.1/program/steps/mail/show.inc --- roundcubemail-1.1.orig/program/steps/mail/show.inc 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/steps/mail/show.inc 2014-11-05 12:46:36.184520548 +0100 @@ -351,10 +351,10 @@ '_alt' => $placeholder, )); - $attrib['onerror'] = "this.src = '" . ($placeholder ? $placeholder : 'program/resources/blank.gif') . "'"; + $attrib['onerror'] = "this.src = '" . $RCMAIL->output->asset_url(($placeholder ? $placeholder : 'program/resources/blank.gif')) . "'"; } else { - $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif'; + $photo_img = ($placeholder ? $placeholder : $RCMAIL->output->asset_url('program/resources/blank.gif')); } return html::img(array('src' => $photo_img, 'alt' => $RCMAIL->gettext('contactphoto')) + $attrib); diff -ur roundcubemail-1.1.orig/program/steps/utils/error.inc roundcubemail-1.1/program/steps/utils/error.inc --- roundcubemail-1.1.orig/program/steps/utils/error.inc 2014-11-04 15:28:27.000000000 +0100 +++ roundcubemail-1.1/program/steps/utils/error.inc 2014-11-05 12:46:36.185520549 +0100 @@ -50,9 +50,17 @@ // forbidden due to request check else if ($ERROR_CODE == 403) { + if ($_SERVER['REQUEST_METHOD'] == 'GET' && $rcmail->request_status == rcube::REQUEST_ERROR_URL) { + parse_str($_SERVER['QUERY_STRING'], $url); + $url = $rcmail->url($url, true, false, true); + $add = "<br /><a href=\"$url\">Click here to try again.<a/>"; + } + else { + $add = "Please contact your server-administrator."; + } + $__error_title = "REQUEST CHECK FAILED"; - $__error_text = "Access to this service was denied due to failing security checks!<br />\n" - . "Please contact your server-administrator."; + $__error_text = "Access to this service was denied due to failing security checks!<br />\n$add"; } // failed request (wrong step in URL)
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.