thomascube
2007-08-10 719a257f0c8fd750a4984ed56273dc653565729e
Some bugfixes, security issues + minor improvements

10 files modified
103 ■■■■■ changed files
CHANGELOG 10 ●●●●● patch | view | raw | blame | history
index.php 15 ●●●● patch | view | raw | blame | history
program/include/main.inc 3 ●●●●● patch | view | raw | blame | history
program/include/rcmail_template.inc 4 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.inc 23 ●●●●● patch | view | raw | blame | history
program/js/app.js 10 ●●●●● patch | view | raw | blame | history
program/steps/mail/func.inc 28 ●●●●● patch | view | raw | blame | history
program/steps/mail/get.inc 4 ●●●● patch | view | raw | blame | history
program/steps/mail/show.inc 2 ●●● patch | view | raw | blame | history
program/steps/settings/manage_folders.inc 4 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -1,6 +1,15 @@
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
@@ -13,6 +22,7 @@
- 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
index.php
@@ -2,7 +2,7 @@
/*
 +-----------------------------------------------------------------------+
 | RoundCube Webmail IMAP Client                                         |
 | Version 0.1-20070518                                                  |
 | Version 0.1-20070809                                                  |
 |                                                                       |
 | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
@@ -41,7 +41,7 @@
*/
// application constants
define('RCMAIL_VERSION', '0.1-20070517');
define('RCMAIL_VERSION', '0.1-20070809');
define('RCMAIL_CHARSET', 'UTF-8');
define('JS_OBJECT_NAME', 'rcmail');
@@ -218,6 +218,17 @@
}
// 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);
program/include/main.inc
@@ -234,6 +234,9 @@
  // 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;
  }
program/include/rcmail_template.inc
@@ -745,8 +745,8 @@
  $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();
program/include/rcube_imap.inc
@@ -1374,7 +1374,7 @@
    // 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;
@@ -1658,11 +1658,11 @@
    $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;
@@ -1768,17 +1768,10 @@
    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);
      }
    }
@@ -2433,7 +2426,7 @@
        $a_out[] = $folder;
      }
    sort($a_out);
    natcasesort($a_out);
    ksort($a_defaults);
    
    return array_merge($a_defaults, $a_out);
program/js/app.js
@@ -463,7 +463,7 @@
        break;
      case 'logout':
        this.goto_url('logout');
        this.goto_url('logout', true);
        break;      
      // commands to switch task
@@ -3195,7 +3195,7 @@
  this.redirect = function(url, lock)
    {
    if (lock || lock == NULL)
    if (lock || lock === null)
      this.set_busy(true);
    if (this.env.framed && window.parent)
@@ -3498,12 +3498,13 @@
      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);
    };
@@ -3537,6 +3538,7 @@
    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);
    };
program/steps/mail/func.inc
@@ -646,6 +646,7 @@
    
    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);
@@ -656,19 +657,22 @@
        $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)
@@ -683,7 +687,7 @@
      $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';
@@ -913,8 +917,8 @@
  $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)
      {
@@ -1239,7 +1243,7 @@
  $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>";
program/steps/mail/get.inc
@@ -29,7 +29,7 @@
  $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>";
@@ -107,7 +107,7 @@
    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
program/steps/mail/show.inc
@@ -48,7 +48,7 @@
  // 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);
program/steps/settings/manage_folders.inc
@@ -27,7 +27,7 @@
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');
@@ -37,7 +37,7 @@
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');