alecpl
2010-11-30 e17553d9548d4870a4579a86c6e425a7f32aecf5
program/include/rcmail.php
@@ -28,19 +28,88 @@
 */
class rcmail
{
  /**
   * Main tasks.
   *
   * @var array
   */
  static public $main_tasks = array('mail','settings','addressbook','login','logout','utils','dummy');
  /**
   * Singleton instace of rcmail
   *
   * @var rcmail
   */
  static private $instance;
  /**
   * Stores instance of rcube_config.
   *
   * @var rcube_config
   */
  public $config;
  /**
   * Stores rcube_user instance.
   *
   * @var rcube_user
   */
  public $user;
  /**
   * Instace of database class.
   *
   * @var rcube_mdb2
   */
  public $db;
  /**
   * Instace of rcube_session class.
   *
   * @var rcube_session
   */
  public $session;
  /**
   * Instance of rcube_smtp class.
   *
   * @var rcube_smtp
   */
  public $smtp;
  /**
   * Instance of rcube_imap class.
   *
   * @var rcube_imap
   */
  public $imap;
  /**
   * Instance of rcube_template class.
   *
   * @var rcube_template
   */
  public $output;
  /**
   * Instance of rcube_plugin_api.
   *
   * @var rcube_plugin_api
   */
  public $plugins;
  /**
   * Current task.
   *
   * @var string
   */
  public $task;
  /**
   * Current action.
   *
   * @var string
   */
  public $action = '';
  public $comm_path = './';
@@ -51,7 +120,7 @@
  /**
   * This implements the 'singleton' design pattern
   *
   * @return object rcmail The one and only instance
   * @return rcmail The one and only instance
   */
  static function get_instance()
  {
@@ -154,7 +223,7 @@
  /**
   * Setter for system user object
   *
   * @param object rcube_user Current user instance
   * @param rcube_user Current user instance
   */
  public function set_user($user)
  {
@@ -226,7 +295,7 @@
  /**
   * Get the current database connection
   *
   * @return object rcube_mdb2  Database connection object
   * @return rcube_mdb2  Database connection object
   */
  public function get_dbh()
  {
@@ -247,7 +316,7 @@
   *
   * @param string  Address book identifier
   * @param boolean True if the address book needs to be writeable
   * @return object rcube_contacts Address book object
   * @return rcube_contacts Address book object
   */
  public function get_address_book($id, $writeable = false)
  {
@@ -346,7 +415,7 @@
   * environment vars according to the current session and configuration
   *
   * @param boolean True if this request is loaded in a (i)frame
   * @return object rcube_template Reference to HTML output object
   * @return rcube_template Reference to HTML output object
   */
  public function load_gui($framed = false)
  {
@@ -379,7 +448,7 @@
  /**
   * Create an output object for JSON responses
   *
   * @return object rcube_json_output Reference to JSON output object
   * @return rcube_json_output Reference to JSON output object
   */
  public function json_init()
  {
@@ -432,8 +501,8 @@
    // can save time detecting them using NAMESPACE and LIST
    $options = array(
      'auth_method' => $this->config->get('imap_auth_type', 'check'),
      'delimiter'   => isset($_SESSION['imap_delimiter']) ? $_SESSION['imap_delimiter'] : $this->config->get('imap_delimiter'),
      'rootdir'     => isset($_SESSION['imap_root']) ? $_SESSION['imap_root'] : $this->config->get('imap_root'),
      'auth_cid'    => $this->config->get('imap_auth_cid'),
      'auth_pw'     => $this->config->get('imap_auth_pw'),
      'debug_mode'  => (bool) $this->config->get('imap_debug', 0),
      'force_caps'  => (bool) $this->config->get('imap_force_caps'),
      'timeout'     => (int) $this->config->get('imap_timeout', 0),
@@ -451,8 +520,11 @@
    // support this parameter for backward compatibility but log warning
    if ($connect) {
      $this->imap_connect();
      raise_error(array('code' => 800, 'type' => 'imap', 'file' => __FILE__,
        'message' => "rcube::imap_init(true) is deprecated, use rcube::imap_connect() instead"), true, false);
      raise_error(array(
        'code' => 800, 'type' => 'imap',
        'file' => __FILE__, 'line' => __LINE__,
        'message' => "rcube::imap_init(true) is deprecated, use rcube::imap_connect() instead"),
        true, false);
    }
  }
@@ -470,7 +542,7 @@
    if ($_SESSION['imap_host'] && !$this->imap->conn->connected()) {
      if (!$this->imap->connect($_SESSION['imap_host'], $_SESSION['username'], $this->decrypt($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl'])) {
        if ($this->output)
          $this->output->show_message($this->imap->error_code == -1 ? 'imaperror' : 'sessionerror', 'error');
          $this->output->show_message($this->imap->get_error_code() == -1 ? 'imaperror' : 'sessionerror', 'error');
      }
      else {
        $this->set_imap_prop();
@@ -587,7 +659,7 @@
    if ($a_host['host']) {
      $host = $a_host['host'];
      $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null;
      if(!empty($a_host['port']))
      if (!empty($a_host['port']))
        $imap_port = $a_host['port'];
      else if ($imap_ssl && $imap_ssl != 'tls' && (!$config['default_port'] || $config['default_port'] == 143))
        $imap_port = 993;
@@ -606,14 +678,26 @@
        $username .= '@'.rcube_parse_host($config['username_domain']);
    }
    // try to resolve email address from virtuser table
    if (strpos($username, '@'))
      if ($virtuser = rcube_user::email2user($username))
        $username = $virtuser;
    // lowercase username if it's an e-mail address (#1484473)
    if (strpos($username, '@'))
    // Convert username to lowercase. If IMAP backend
    // is case-insensitive we need to store always the same username (#1487113)
    if ($config['login_lc']) {
      $username = mb_strtolower($username);
    }
    // try to resolve email address from virtuser table
    if (strpos($username, '@') && ($virtuser = rcube_user::email2user($username))) {
      $username = $virtuser;
    }
    // Here we need IDNA ASCII
    // Only rcube_contacts class is using domain names in Unicode
    $host = idn_to_ascii($host);
    if (strpos($username, '@')) {
      // lowercase domain name
      list($local, $domain) = explode('@', $username);
      $username = $local . '@' . mb_strtolower($domain);
      $username = idn_to_ascii($username);
    }
    // user already registered -> overwrite username
    if ($user = rcube_user::query($username, $host))
@@ -622,8 +706,22 @@
    if (!$this->imap)
      $this->imap_init();
    // try IMAP login
    if (!($imap_login = $this->imap->connect($host, $username, $pass, $imap_port, $imap_ssl))) {
      // try with lowercase
      $username_lc = mb_strtolower($username);
      if ($username_lc != $username) {
        // try to find user record again -> overwrite username
        if (!$user && ($user = rcube_user::query($username_lc, $host)))
          $username_lc = $user->data['username'];
        if ($imap_login = $this->imap->connect($host, $username_lc, $pass, $imap_port, $imap_ssl))
          $username = $username_lc;
      }
    }
    // exit if IMAP login failed
    if (!($imap_login  = $this->imap->connect($host, $username, $pass, $imap_port, $imap_ssl)))
    if (!$imap_login)
      return false;
    $this->set_imap_prop();
@@ -646,7 +744,7 @@
      else {
        raise_error(array(
          'code' => 600, 'type' => 'php',
         'file' => __FILE__, 'line' => __LINE__,
          'file' => __FILE__, 'line' => __LINE__,
          'message' => "Failed to create a user record. Maybe aborted by a plugin?"
          ), true, false);
      }
@@ -696,16 +794,12 @@
    if ($default_folders = $this->config->get('default_imap_folders')) {
      $this->imap->set_default_mailboxes($default_folders);
    }
    if (!empty($_SESSION['mbox'])) {
    if (isset($_SESSION['mbox'])) {
      $this->imap->set_mailbox($_SESSION['mbox']);
    }
    if (isset($_SESSION['page'])) {
      $this->imap->set_page($_SESSION['page']);
    }
    // cache IMAP root and delimiter in session for performance reasons
    $_SESSION['imap_root'] = $this->imap->root_dir;
    $_SESSION['imap_delimiter'] = $this->imap->delimiter;
  }
@@ -1121,8 +1215,14 @@
    if (function_exists('mcrypt_module_open') &&
        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")))
    {
      $iv = substr($cipher, 0, mcrypt_enc_get_iv_size($td));
      $cipher = substr($cipher, mcrypt_enc_get_iv_size($td));
      $iv_size = mcrypt_enc_get_iv_size($td);
      $iv = substr($cipher, 0, $iv_size);
      // session corruption? (#1485970)
      if (strlen($iv) < $iv_size)
        return '';
      $cipher = substr($cipher, $iv_size);
      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv);
      $clear = mdecrypt_generic($td, $cipher);
      mcrypt_generic_deinit($td);