summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube/rcube.php
diff options
context:
space:
mode:
Diffstat (limited to 'program/lib/Roundcube/rcube.php')
-rw-r--r--program/lib/Roundcube/rcube.php139
1 files changed, 127 insertions, 12 deletions
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index 03f49637c..547e2b4ac 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -28,9 +28,15 @@
*/
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
*
@@ -101,6 +107,12 @@ class rcube
*/
public $user;
+ /**
+ * Request status
+ *
+ * @var int
+ */
+ public $request_status = 0;
/* private/protected vars */
protected $texts;
@@ -978,6 +990,104 @@ class rcube
/**
+ * 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;
+ }
+
+
+ /**
* Build a valid URL to this instance of Roundcube
*
* @param mixed Either a string with the action or url parameters as key-value pairs
@@ -1551,7 +1661,7 @@ class rcube
// 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'];
@@ -1651,19 +1761,24 @@ class rcube
// 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) : ''));
}
}