Some bugfixes, security issues + minor improvements
| | |
| | | CHANGELOG RoundCube Webmail |
| | | --------------------------- |
| | | |
| | | 2007/08/09 (thomasb) |
| | | ---------- |
| | | - Identify mailboxes case-sensitive |
| | | - Sort mailbox list case-insensitive (closes #1484338) |
| | | - Fix display of multipart messages from Apple Mail (closes #1484027) |
| | | - Protect AJAX request from being fetched by a foreign site (XSS) |
| | | - Make autocomplete for loginform configurable by the skin template |
| | | |
| | | |
| | | 2007/07/09 (richs) |
| | | ---------- |
| | | - Fixed bug with buttons not dimming/enabling properly after switching folders |
| | |
| | | - Increased "mailboxcontrols" mail.css width from 160 to 170px to fix non-english languages |
| | | - Fixed empty-message sending with TinyMCE plain-text mode, or if it's not installed |
| | | |
| | | |
| | | 2007/07/03 (thomasb) |
| | | ---------- |
| | | - Added Macedonian (Slavic FYROM) localization |
| | |
| | | /* |
| | | +-----------------------------------------------------------------------+ |
| | | | RoundCube Webmail IMAP Client | |
| | | | Version 0.1-20070518 | |
| | | | Version 0.1-20070809 | |
| | | | | |
| | | | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland | |
| | | | Licensed under the GNU GPL | |
| | |
| | | */ |
| | | |
| | | // application constants |
| | | define('RCMAIL_VERSION', '0.1-20070517'); |
| | | define('RCMAIL_VERSION', '0.1-20070809'); |
| | | define('RCMAIL_CHARSET', 'UTF-8'); |
| | | define('JS_OBJECT_NAME', 'rcmail'); |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | // check client X-header to verify request origin |
| | | if ($OUTPUT->ajax_call) |
| | | { |
| | | $hdrs = getallheaders(); |
| | | if (empty($hdrs['X-RoundCube-Referer']) && empty($CONFIG['devel_mode'])) |
| | | { |
| | | header('HTTP/1.1 404 Not Found'); |
| | | die("Invalid Request"); |
| | | } |
| | | } |
| | | |
| | | |
| | | // set task and action to client |
| | | $OUTPUT->set_env('task', $_task); |
| | |
| | | // check session filetime |
| | | if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED) && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time()) |
| | | $valid = false; |
| | | |
| | | if (!$valid) |
| | | write_log('timeouts', $_SESSION + array('SESS_CLIENT_IP' => $SESS_CLIENT_IP, 'SESS_CHANGED' => $SESS_CHANGED, 'COOKIE' => $_COOKIE)); |
| | | |
| | | return $valid; |
| | | } |
| | |
| | | $labels['pass'] = rcube_label('password'); |
| | | $labels['host'] = rcube_label('server'); |
| | | |
| | | $input_user = new textfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30, 'autocomplete' => 'off')); |
| | | $input_pass = new passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30)); |
| | | $input_user = new textfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30) + $attrib); |
| | | $input_pass = new passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30) + $attrib); |
| | | $input_action = new hiddenfield(array('name' => '_action', 'value' => 'login')); |
| | | |
| | | $fields = array(); |
| | |
| | | // make sure mailbox exists |
| | | if (!in_array($to_mbox, $this->_list_mailboxes())) |
| | | { |
| | | if (in_array(strtolower($to_mbox), $this->default_folders)) |
| | | if (in_array($to_mbox, $this->default_folders)) |
| | | $this->create_mailbox($to_mbox, TRUE); |
| | | else |
| | | return FALSE; |
| | |
| | | $abs_name = $this->_mod_mailbox($name); |
| | | $a_mailbox_cache = $this->get_cache('mailboxes'); |
| | | |
| | | if (strlen($abs_name) && (!is_array($a_mailbox_cache) || !in_array_nocase($abs_name, $a_mailbox_cache))) |
| | | if (strlen($abs_name) && (!is_array($a_mailbox_cache) || !in_array($abs_name, $a_mailbox_cache))) |
| | | $result = iil_C_CreateFolder($this->conn, $abs_name); |
| | | |
| | | // try to subscribe it |
| | | if ($subscribe) |
| | | if ($result && $subscribe) |
| | | $this->subscribe($name); |
| | | |
| | | return $result ? $name : FALSE; |
| | |
| | | foreach ($this->default_folders as $folder) |
| | | { |
| | | $abs_name = $this->_mod_mailbox($folder); |
| | | if (!in_array_nocase($abs_name, $a_subscribed)) |
| | | { |
| | | if (!in_array_nocase($abs_name, $a_folders)) |
| | | $this->create_mailbox($folder, TRUE); |
| | | else |
| | | $this->subscribe($folder); |
| | | } |
| | | else if (!in_array_nocase($abs_name, $a_folders)) |
| | | { |
| | | $this->create_mailbox($folder, FALSE); |
| | | } |
| | | if (!in_array_nocase($abs_name, $a_folders)) |
| | | $this->create_mailbox($folder, TRUE); |
| | | else if (!in_array_nocase($abs_name, $a_subscribed)) |
| | | $this->subscribe($folder); |
| | | } |
| | | } |
| | | |
| | |
| | | $a_out[] = $folder; |
| | | } |
| | | |
| | | sort($a_out); |
| | | natcasesort($a_out); |
| | | ksort($a_defaults); |
| | | |
| | | return array_merge($a_defaults, $a_out); |
| | |
| | | break; |
| | | |
| | | case 'logout': |
| | | this.goto_url('logout'); |
| | | this.goto_url('logout', true); |
| | | break; |
| | | |
| | | // commands to switch task |
| | |
| | | |
| | | this.redirect = function(url, lock) |
| | | { |
| | | if (lock || lock == NULL) |
| | | if (lock || lock === null) |
| | | this.set_busy(true); |
| | | |
| | | if (this.env.framed && window.parent) |
| | |
| | | return false; |
| | | } |
| | | |
| | | var ref = this; |
| | | var _ref = this; |
| | | this.url = url; |
| | | this.busy = true; |
| | | |
| | | this.xmlhttp.onreadystatechange = function(){ ref.xmlhttp_onreadystatechange(); }; |
| | | this.xmlhttp.onreadystatechange = function(){ _ref.xmlhttp_onreadystatechange(); }; |
| | | this.xmlhttp.open('GET', url); |
| | | this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('sessid')); |
| | | this.xmlhttp.send(null); |
| | | }; |
| | | |
| | |
| | | this.xmlhttp.onreadystatechange = function() { ref.xmlhttp_onreadystatechange(); }; |
| | | this.xmlhttp.open('POST', url, true); |
| | | this.xmlhttp.setRequestHeader('Content-Type', contentType); |
| | | this.xmlhttp.setRequestHeader('X-RoundCube-Referer', bw.get_cookie('sessid')); |
| | | this.xmlhttp.send(req_body); |
| | | }; |
| | | |
| | |
| | | |
| | | foreach ($structure->parts as $p => $sub_part) |
| | | { |
| | | $rel_parts = $attachmnts = null; |
| | | $sub_ctype_primary = strtolower($sub_part->ctype_primary); |
| | | $sub_ctype_secondary = strtolower($sub_part->ctype_secondary); |
| | | |
| | |
| | | $html_part = $p; |
| | | else if ($sub_ctype_primary=='text' && $sub_ctype_secondary=='enriched') |
| | | $enriched_part = $p; |
| | | else if ($sub_ctype_primary=='multipart' && $sub_ctype_secondary=='related') |
| | | else if ($sub_ctype_primary=='multipart' && ($sub_ctype_secondary=='related' || $sub_ctype_secondary=='mixed')) |
| | | $related_part = $p; |
| | | } |
| | | |
| | | |
| | | // parse related part (alternative part could be in here) |
| | | if ($related_part!==NULL && $prefer_html) |
| | | { |
| | | list($parts, $attachmnts) = rcmail_parse_message($structure->parts[$related_part], $arg, TRUE); |
| | | $a_return_parts = array_merge($a_return_parts, $parts); |
| | | if ($related_part!==NULL) |
| | | { |
| | | list($rel_parts, $attachmnts) = rcmail_parse_message($structure->parts[$related_part], $arg, TRUE); |
| | | $a_attachments = array_merge($a_attachments, $attachmnts); |
| | | } |
| | | } |
| | | |
| | | // merge related parts if any |
| | | if ($rel_parts && $prefer_html && !$html_part) |
| | | $a_return_parts = array_merge($a_return_parts, $rel_parts); |
| | | |
| | | // print html/plain part |
| | | // choose html/plain part to print |
| | | else if ($html_part!==NULL && $prefer_html) |
| | | $print_part = &$structure->parts[$html_part]; |
| | | else if ($enriched_part!==NULL) |
| | |
| | | $a_return_parts[] = $print_part; |
| | | } |
| | | // show plaintext warning |
| | | else if ($html_part!==NULL) |
| | | else if ($html_part!==NULL && empty($a_return_parts)) |
| | | { |
| | | $c = new stdClass; |
| | | $c->type = 'content'; |
| | |
| | | $ctype_secondary = strtolower($MESSAGE['structure']->ctype_secondary); |
| | | |
| | | // list images after mail body |
| | | if (get_boolean($attrib['showimages']) && $ctype_primary=='multipart' && $ctype_secondary=='mixed' && |
| | | sizeof($MESSAGE['attachments']) && !strstr($message_body, '<html') && strlen($GET_URL)) |
| | | if (get_boolean($attrib['showimages']) && $ctype_primary=='multipart' && |
| | | !empty($MESSAGE['attachments']) && !strstr($message_body, '<html') && strlen($GET_URL)) |
| | | { |
| | | foreach ($MESSAGE['attachments'] as $attach_prop) |
| | | { |
| | |
| | | $part = $MESSAGE['parts'][$_GET['_part']]; |
| | | $ctype_primary = strtolower($part->ctype_primary); |
| | | |
| | | $attrib['src'] = './?'.str_replace('_frame=', ($ctype_primary=='text' ? '_show=' : '_preload='), $_SERVER['QUERY_STRING']); |
| | | $attrib['src'] = Q('./?'.str_replace('_frame=', ($ctype_primary=='text' ? '_show=' : '_preload='), $_SERVER['QUERY_STRING'])); |
| | | |
| | | $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style', 'src', 'width', 'height')); |
| | | $out = '<iframe '. $attrib_str . "></iframe>"; |
| | |
| | | $message = rcube_label('loadingdata'); |
| | | |
| | | print "<html>\n<head>\n" . |
| | | '<meta http-equiv="refresh" content="0; url='.htmlspecialchars($url).'">' . |
| | | '<meta http-equiv="refresh" content="0; url='.Q($url).'">' . |
| | | "\n</head>\n<body>" . |
| | | $message . |
| | | "\n</body>\n</html>"; |
| | |
| | | else |
| | | { |
| | | header(sprintf('Content-Disposition: %s; filename="%s";', |
| | | $part->disposition ? $part->disposition : 'attachment', |
| | | $_GET['_download'] ? 'attachment' : 'inline', |
| | | $part->filename ? $part->filename : "roundcube.$ctype_secondary")); |
| | | |
| | | // turn off output buffering and print part content |
| | |
| | | // allow caching, unless remote images are present |
| | | if ((bool)get_input_value('_safe', RCUBE_INPUT_GET)) |
| | | send_nocacheing_headers(); |
| | | else |
| | | else if (empty($CONFIG['devel_mode'])) |
| | | send_modified_header($_SESSION['login_time'], $etag); |
| | | |
| | | $MESSAGE['subject'] = rcube_imap::decode_mime_string($MESSAGE['headers']->subject, $MESSAGE['headers']->charset); |
| | |
| | | if ($_action=='subscribe') |
| | | { |
| | | if ($mboxes = get_input_value('_mboxes', RCUBE_INPUT_POST)) |
| | | $IMAP->subscribe(array($mboxes)); |
| | | $IMAP->subscribe($mboxes); |
| | | |
| | | if ($OUTPUT->ajax_call) |
| | | $OUTPUT->remote_response('// subscribed'); |
| | |
| | | else if ($_action=='unsubscribe') |
| | | { |
| | | if ($mboxes = get_input_value('_mboxes', RCUBE_INPUT_POST)) |
| | | $IMAP->unsubscribe(array($mboxes)); |
| | | $IMAP->unsubscribe($mboxes); |
| | | |
| | | if ($OUTPUT->ajax_call) |
| | | $OUTPUT->remote_response('// unsubscribed'); |