| | |
| | | */ |
| | | 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 |
| | |
| | | */ |
| | | public $user; |
| | | |
| | | /** |
| | | * Request status |
| | | * |
| | | * @var int |
| | | */ |
| | | public $request_status = 0; |
| | | |
| | | /* private/protected vars */ |
| | | protected $texts; |
| | |
| | | * upon decryption; see http://php.net/mcrypt_generic#68082 |
| | | */ |
| | | $clear = pack("a*H2", $clear, "80"); |
| | | $ckey = $this->config->get_crypto_key($key); |
| | | |
| | | if (function_exists('openssl_encrypt')) { |
| | | $method = 'DES-EDE3-CBC'; |
| | |
| | | ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")) |
| | | ) { |
| | | $iv = $this->create_iv(mcrypt_enc_get_iv_size($td)); |
| | | mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); |
| | | mcrypt_generic_init($td, $ckey, $iv); |
| | | $cipher = $iv . mcrypt_generic($td, $clear); |
| | | mcrypt_generic_deinit($td); |
| | | mcrypt_module_close($td); |
| | |
| | | if (function_exists('des')) { |
| | | $des_iv_size = 8; |
| | | $iv = $this->create_iv($des_iv_size); |
| | | $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv); |
| | | $cipher = $iv . des($ckey, $clear, 1, 1, $iv); |
| | | } |
| | | else { |
| | | self::raise_error(array( |
| | |
| | | } |
| | | |
| | | $cipher = $base64 ? base64_decode($cipher) : $cipher; |
| | | $ckey = $this->config->get_crypto_key($key); |
| | | |
| | | if (function_exists('openssl_decrypt')) { |
| | | $method = 'DES-EDE3-CBC'; |
| | |
| | | ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")) |
| | | ) { |
| | | $iv_size = mcrypt_enc_get_iv_size($td); |
| | | $iv = substr($cipher, 0, $iv_size); |
| | | $iv = substr($cipher, 0, $iv_size); |
| | | |
| | | // session corruption? (#1485970) |
| | | if (strlen($iv) < $iv_size) { |
| | |
| | | } |
| | | |
| | | $cipher = substr($cipher, $iv_size); |
| | | mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv); |
| | | mcrypt_generic_init($td, $ckey, $iv); |
| | | $clear = mdecrypt_generic($td, $cipher); |
| | | mcrypt_generic_deinit($td); |
| | | mcrypt_module_close($td); |
| | |
| | | |
| | | if (function_exists('des')) { |
| | | $des_iv_size = 8; |
| | | $iv = substr($cipher, 0, $des_iv_size); |
| | | $iv = substr($cipher, 0, $des_iv_size); |
| | | $cipher = substr($cipher, $des_iv_size); |
| | | $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv); |
| | | $clear = des($ckey, $cipher, 0, 1, $iv); |
| | | } |
| | | else { |
| | | self::raise_error(array( |
| | | 'code' => 500, 'type' => 'php', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available" |
| | | 'message' => "Could not perform decryption; make sure OpenSSL or Mcrypt or lib/des.inc is available" |
| | | ), true, true); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | return $iv; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 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; |
| | | } |
| | | |
| | | |
| | |
| | | |
| | | exit(1); |
| | | } |
| | | else if ($cli) { |
| | | fwrite(STDERR, 'ERROR: ' . $arg['message']); |
| | | } |
| | | } |
| | | |
| | | |
| | |
| | | // send thru SMTP server using custom SMTP library |
| | | if ($this->config->get('smtp_server')) { |
| | | // generate list of recipients |
| | | $a_recipients = array($mailto); |
| | | $a_recipients = (array) $mailto; |
| | | |
| | | if (strlen($headers['Cc'])) |
| | | $a_recipients[] = $headers['Cc']; |
| | |
| | | if (!$sent) { |
| | | self::raise_error(array('code' => 800, 'type' => 'smtp', |
| | | 'line' => __LINE__, 'file' => __FILE__, |
| | | 'message' => "SMTP error: ".join("\n", $response)), TRUE, FALSE); |
| | | 'message' => join("\n", $response)), true, false); |
| | | } |
| | | } |
| | | // send mail using PHP's mail() function |
| | |
| | | // remove MDN headers after sending |
| | | unset($headers['Return-Receipt-To'], $headers['Disposition-Notification-To']); |
| | | |
| | | // get all recipients |
| | | if ($headers['Cc']) |
| | | $mailto .= $headers['Cc']; |
| | | if ($headers['Bcc']) |
| | | $mailto .= $headers['Bcc']; |
| | | if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m)) |
| | | $mailto = implode(', ', array_unique($m[1])); |
| | | |
| | | if ($this->config->get('smtp_log')) { |
| | | // get all recipient addresses |
| | | if (is_array($mailto)) { |
| | | $mailto = implode(',', $mailto); |
| | | } |
| | | if ($headers['Cc']) { |
| | | $mailto .= ',' . $headers['Cc']; |
| | | } |
| | | if ($headers['Bcc']) { |
| | | $mailto .= ',' . $headers['Bcc']; |
| | | } |
| | | |
| | | $mailto = rcube_mime::decode_address_list($mailto, null, false, null, true); |
| | | |
| | | self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", |
| | | $this->user->get_username(), |
| | | $_SERVER['REMOTE_ADDR'], |
| | | $mailto, |
| | | rcube_utils::remote_addr(), |
| | | implode(', ', $mailto), |
| | | !empty($response) ? join('; ', $response) : '')); |
| | | } |
| | | } |