thomascube
2008-06-24 0d88e5095509ebf69ba748d5bb52460807c3880d
program/include/main.inc
@@ -39,111 +39,6 @@
define('RCUBE_INPUT_GPC', 0x0103);
/**
 * Create unique authorization hash
 *
 * @param string Session ID
 * @param int Timestamp
 * @return string The generated auth hash
 */
function rcmail_auth_hash($sess_id, $ts)
  {
  global $CONFIG;
  $auth_string = sprintf('rcmail*sess%sR%s*Chk:%s;%s',
                         $sess_id,
                         $ts,
                         $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***',
                         $_SERVER['HTTP_USER_AGENT']);
  if (function_exists('sha1'))
    return sha1($auth_string);
  else
    return md5($auth_string);
  }
/**
 * Check the auth hash sent by the client against the local session credentials
 *
 * @return boolean True if valid, False if not
 */
function rcmail_authenticate_session()
  {
  global $CONFIG, $SESS_CLIENT_IP, $SESS_CHANGED;
  // advanced session authentication
  if ($CONFIG['double_auth'])
  {
    $now = time();
    $valid = ($_COOKIE['sessauth'] == rcmail_auth_hash(session_id(), $_SESSION['auth_time']) ||
              $_COOKIE['sessauth'] == rcmail_auth_hash(session_id(), $_SESSION['last_auth']));
    // renew auth cookie every 5 minutes (only for GET requests)
    if (!$valid || ($_SERVER['REQUEST_METHOD']!='POST' && $now-$_SESSION['auth_time'] > 300))
    {
      $_SESSION['last_auth'] = $_SESSION['auth_time'];
      $_SESSION['auth_time'] = $now;
      setcookie('sessauth', rcmail_auth_hash(session_id(), $now));
    }
  }
  else
    $valid = $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] == $SESS_CLIENT_IP : true;
  // check session filetime
  if (!empty($CONFIG['session_lifetime']) && isset($SESS_CHANGED)
      && $SESS_CHANGED + $CONFIG['session_lifetime']*60 < time())
    $valid = false;
  return $valid;
  }
/**
 * Destroy session data and remove cookie
 */
function rcmail_kill_session()
  {
  global $USER;
  if ((isset($_SESSION['sort_col']) && $_SESSION['sort_col']!=$a_user_prefs['message_sort_col']) ||
      (isset($_SESSION['sort_order']) && $_SESSION['sort_order']!=$a_user_prefs['message_sort_order']))
    {
    $a_user_prefs = array('message_sort_col' => $_SESSION['sort_col'], 'message_sort_order' => $_SESSION['sort_order']);
    $USER->save_prefs($a_user_prefs);
    }
  $_SESSION = array('language' => $USER->language, 'auth_time' => time(), 'temp' => true);
  setcookie('sessauth', '-del-', time()-60);
  $USER->reset();
  }
/**
 * Do server side actions on logout
 */
function rcmail_logout_actions()
  {
  global $CONFIG, $IMAP, $RCMAIL;
  // on logout action we're not connected to imap server
  if (($CONFIG['logout_purge'] && !empty($CONFIG['trash_mbox']))
      || $CONFIG['logout_expunge'])
    {
      if (!rcmail_authenticate_session())
        return;
      $RCMAIL->imap_init(true);
    }
  if ($CONFIG['logout_purge'] && !empty($CONFIG['trash_mbox']))
    $IMAP->clear_mailbox($CONFIG['trash_mbox']);
  if ($CONFIG['logout_expunge'])
    $IMAP->expunge('INBOX');
  }
/**
 * Return correct name for a specific database table
@@ -174,93 +69,39 @@
 */
function get_sequence_name($sequence)
  {
  global $CONFIG;
  // return table name if configured
  $config_key = 'db_sequence_'.$sequence;
  $opt = rcmail::get_instance()->config->get($config_key);
  if (strlen($CONFIG[$config_key]))
    return $CONFIG[$config_key];
  if (!empty($opt))
    {
    $db = &rcmail::get_instance()->db;
    if ($db->db_provider=='pgsql' && is_a($db, 'rcube_mdb2'))
      {
      $db->db_handle->setOption('disable_smart_seqname', true);
      $db->db_handle->setOption('seqname_format', '%s');
      }
    return $opt;
    }
  return $sequence;
  }
/**
 * Auto-select IMAP host based on the posted login information
 * Get localized text in the desired language
 * It's a global wrapper for rcmail::gettext()
 *
 * @return string Selected IMAP host
 * @param mixed Named parameters array or label name
 * @return string Localized text
 * @see rcmail::gettext()
 */
function rcmail_autoselect_host()
  {
  global $CONFIG;
  $host = isset($_POST['_host']) ? get_input_value('_host', RCUBE_INPUT_POST) : $CONFIG['default_host'];
  if (is_array($host))
    {
    list($user, $domain) = explode('@', get_input_value('_user', RCUBE_INPUT_POST));
    if (!empty($domain))
      {
      foreach ($host as $imap_host => $mail_domains)
        if (is_array($mail_domains) && in_array($domain, $mail_domains))
          {
          $host = $imap_host;
          break;
          }
      }
    // take the first entry if $host is still an array
    if (is_array($host))
      $host = array_shift($host);
    }
  return $host;
  }
/**
 * Load virtuser table in array
 *
 * @return array Virtuser table entries
 */
function rcmail_getvirtualfile()
  {
  global $CONFIG;
  if (empty($CONFIG['virtuser_file']) || !is_file($CONFIG['virtuser_file']))
    return FALSE;
  // read file
  $a_lines = file($CONFIG['virtuser_file']);
  return $a_lines;
  }
/**
 * Find matches of the given pattern in virtuser table
 *
 * @param string Regular expression to search for
 * @return array Matching entries
 */
function rcmail_findinvirtual($pattern)
  {
  $result = array();
  $virtual = rcmail_getvirtualfile();
  if ($virtual==FALSE)
    return $result;
  // check each line for matches
  foreach ($virtual as $line)
    {
    $line = trim($line);
    if (empty($line) || $line{0}=='#')
      continue;
    if (eregi($pattern, $line))
      $result[] = $line;
    }
  return $result;
  }
function rcube_label($p)
{
  return rcmail::get_instance()->gettext($p);
}
/**
@@ -287,137 +128,8 @@
function rcmail_url($action, $p=array(), $task=null)
{
  $app = rcmail::get_instance();
  $qstring = '';
  $base = $app->comm_path;
  if ($task && in_array($task, rcmail::$main_tasks))
    $base = ereg_replace('_task=[a-z]+', '_task='.$task, $app->comm_path);
  if (is_array($p))
    foreach ($p as $key => $val)
      $qstring .= '&'.urlencode($key).'='.urlencode($val);
  return $base . ($action ? '&_action='.$action : '') . $qstring;
  return $app->url((array)$p + array('_action' => $action, 'task' => $task));
}
// @deprecated
function show_message($message, $type='notice', $vars=NULL)
  {
  global $OUTPUT;
  $OUTPUT->show_message($message, $type, $vars);
  }
/**
 * Encrypt IMAP password using DES encryption
 *
 * @param string Password to encrypt
 * @return string Encryprted string
 */
function encrypt_passwd($pass)
{
  if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, get_des_key(), $iv);
    $cypher = mcrypt_generic($td, $pass);
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
  }
  else if (function_exists('des')) {
    $cypher = des(get_des_key(), $pass, 1, 0, NULL);
  }
  else {
    $cypher = $pass;
    raise_error(array(
      'code' => 500,
      'type' => 'php',
      'file' => __FILE__,
      'message' => "Could not convert encrypt password. Make sure Mcrypt is installed or lib/des.inc is available"
      ), true, false);
  }
  return base64_encode($cypher);
}
/**
 * Decrypt IMAP password using DES encryption
 *
 * @param string Encrypted password
 * @return string Plain password
 */
function decrypt_passwd($cypher)
{
  if (function_exists('mcrypt_module_open') && ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, ""))) {
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    mcrypt_generic_init($td, get_des_key(), $iv);
    $pass = mdecrypt_generic($td, base64_decode($cypher));
    mcrypt_generic_deinit($td);
    mcrypt_module_close($td);
  }
  else if (function_exists('des')) {
    $pass = des(get_des_key(), base64_decode($cypher), 0, 0, NULL);
  }
  else {
    $pass = base64_decode($cypher);
  }
  return preg_replace('/\x00/', '', $pass);
  }
/**
 * Return a 24 byte key for the DES encryption
 *
 * @return string DES encryption key
 */
function get_des_key()
  {
  $key = !empty($GLOBALS['CONFIG']['des_key']) ? $GLOBALS['CONFIG']['des_key'] : 'rcmail?24BitPwDkeyF**ECB';
  $len = strlen($key);
  // make sure the key is exactly 24 chars long
  if ($len<24)
    $key .= str_repeat('_', 24-$len);
  else if ($len>24)
    substr($key, 0, 24);
  return $key;
  }
/**
 * Read directory program/localization and return a list of available languages
 *
 * @return array List of available localizations
 */
function rcube_list_languages()
  {
  global $CONFIG;
  static $sa_languages = array();
  if (!sizeof($sa_languages))
    {
    @include(INSTALL_PATH.'program/localization/index.inc');
    if ($dh = @opendir(INSTALL_PATH.'program/localization'))
      {
      while (($name = readdir($dh)) !== false)
        {
        if ($name{0}=='.' || !is_dir(INSTALL_PATH.'program/localization/'.$name))
          continue;
        if ($label = $rcube_languages[$name])
          $sa_languages[$name] = $label ? $label : $name;
        }
      closedir($dh);
      }
    }
  return $sa_languages;
  }
/**
@@ -511,7 +223,11 @@
  if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7')
    {
    $aliases['GB2312'] = 'GB18030';
    return iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str);
    $_iconv = iconv(($aliases[$from] ? $aliases[$from] : $from), ($aliases[$to] ? $aliases[$to] : $to) . "//IGNORE", $str);
    if ($_iconv !== false)
      {
        return $_iconv;
      }
    }
  // settings for mbstring module (by Tadashi Jokagi)
@@ -748,7 +464,7 @@
 */
function asciiwords($str)
{
  return preg_replace('/[^a-z0-9.-_]/i', '', $str);
  return preg_replace('/[^a-z0-9._-]/i', '', $str);
}
/**
@@ -776,22 +492,6 @@
/**
 * Check if a specific template exists
 *
 * @param string Template name
 * @return boolean True if template exists
 */
function template_exists($name)
  {
  global $CONFIG;
  $skin_path = $CONFIG['skin_path'];
  // check template file
  return is_file("$skin_path/templates/$name.html");
  }
/**
 * Create a HTML table based on the given data
 *
 * @param  array  Named table attributes
@@ -802,65 +502,46 @@
 */
function rcube_table_output($attrib, $table_data, $a_show_cols, $id_col)
  {
  global $DB;
  global $RCMAIL;
  
  // allow the following attributes to be added to the <table> tag
  $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
  $table = '<table' . $attrib_str . ">\n";
  $table = new html_table(/*array('cols' => count($a_show_cols))*/);
    
  // add table title
  $table .= "<thead><tr>\n";
  // add table header
  foreach ($a_show_cols as $col)
    $table .= '<td class="'.$col.'">' . Q(rcube_label($col)) . "</td>\n";
  $table .= "</tr></thead>\n<tbody>\n";
    $table->add_header($col, Q(rcube_label($col)));
  
  $c = 0;
  if (!is_array($table_data)) 
  {
    $db = $RCMAIL->get_dbh();
    while ($table_data && ($sql_arr = $db->fetch_assoc($table_data)))
    {
    while ($table_data && ($sql_arr = $DB->fetch_assoc($table_data)))
      {
      $zebra_class = $c%2 ? 'even' : 'odd';
      $table .= sprintf('<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", $sql_arr[$id_col]);
      $zebra_class = $c % 2 ? 'even' : 'odd';
      $table->add_row(array('id' => 'rcmrow' . $sql_arr[$id_col], 'class' => "contact $zebra_class"));
      // format each col
      foreach ($a_show_cols as $col)
        {
        $cont = Q($sql_arr[$col]);
        $table .= '<td class="'.$col.'">' . $cont . "</td>\n";
        }
      $table .= "</tr>\n";
        $table->add($col, Q($sql_arr[$col]));
      $c++;
      }
    }
  }
  else 
    {
  {
    foreach ($table_data as $row_data)
      {
      $zebra_class = $c%2 ? 'even' : 'odd';
      $table .= sprintf('<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", $row_data[$id_col]);
    {
      $zebra_class = $c % 2 ? 'even' : 'odd';
      $table->add_row(array('id' => 'rcmrow' . $row_data[$id_col], 'class' => "contact $zebra_class"));
      // format each col
      foreach ($a_show_cols as $col)
        {
        $cont = Q($row_data[$col]);
        $table .= '<td class="'.$col.'">' . $cont . "</td>\n";
        }
      $table .= "</tr>\n";
        $table->add($col, Q($row_data[$col]));
      $c++;
      }
    }
  }
  // complete message table
  $table .= "</tbody></table>\n";
  return $table;
  return $table->show($attrib);
  }
@@ -898,29 +579,6 @@
  $out = $input->show($value);
         
  return $out;
  }
/**
 * Return the mail domain configured for the given host
 *
 * @param string IMAP host
 * @return string Resolved SMTP host
 */
function rcmail_mail_domain($host)
  {
  global $CONFIG;
  $domain = $host;
  if (is_array($CONFIG['mail_domain']))
    {
    if (isset($CONFIG['mail_domain'][$host]))
      $domain = $CONFIG['mail_domain'][$host];
    }
  else if (!empty($CONFIG['mail_domain']))
    $domain = $CONFIG['mail_domain'];
  return $domain;
  }
@@ -971,26 +629,6 @@
  return $styles;
  }
/**
 * Try to autodetect operating system and find the correct line endings
 *
 * @return string The appropriate mail header delimiter
 */
function rcmail_header_delm()
{
  global $CONFIG;
  // use the configured delimiter for headers
  if (!empty($CONFIG['mail_header_delimiter']))
    return $CONFIG['mail_header_delimiter'];
  else if (strtolower(substr(PHP_OS, 0, 3)=='win'))
    return "\r\n";
  else if (strtolower(substr(PHP_OS, 0, 3)=='mac'))
    return "\r\n";
  else
    return "\n";
}
/**
@@ -1376,7 +1014,7 @@
      $class_name = 'junk';
    $js_name = htmlspecialchars(JQ($folder['id']));
    $out .= sprintf('<li id="rcmli%s" class="mailbox %s %s%s%s"><a href="%s"'.
    $out .= sprintf('<li id="rcmli%s" class="mailbox %s %s%s"><a href="%s"'.
                    ' onclick="return %s.command(\'list\',\'%s\',this)"'.
                    ' onmouseover="return %s.focus_folder(\'%s\')"' .
                    ' onmouseout="return %s.unfocus_folder(\'%s\')"' .
@@ -1384,7 +1022,6 @@
                    $folder_id,
                    $class_name,
                    $zebra_class,
                    $unread_count ? ' unread' : '',
                    $folder['id']==$mbox_name ? ' selected' : '',
                    Q(rcmail_url('', array('_mbox' => $folder['id']))),
                    JS_OBJECT_NAME,