security updates

have to check views and entityreference for custom patches
This commit is contained in:
Bachir Soussi Chiadmi
2015-04-19 20:45:16 +02:00
parent 802ec0c6f3
commit b3221c71e2
516 changed files with 14267 additions and 7349 deletions

View File

@@ -1,5 +1,26 @@
Mime Mail 7.x-1.x, xxxx-xx-xx
-----------------------
Mime Mail 7.x-1.0-beta3, 2014-03-05
-----------------------
- Public files test incorrect if similar path is not below root.
Mime Mail 7.x-1.0-beta2, 2014-02-26
-----------------------
- Stronger authentication for incoming messages.
- #2031143 by sgabe, das-peter: Support @import by using drupal_load_stylesheet().
- #2087913 by sgabe | alancsilver: Allow spaces in attachment filenames.
- #1852694 by clemens.tolboom | Pixelstyle: Convert float to align for images.
- #2145659 by sgabe, fatherguddha | raincloud: Images with 'itok' token are not embedded.
- #2119613 by sgabe, david_garcia_garcia: Further improve boundary collision avoidance.
- #2185909 by cyrus_bt5, ekidman: Extra space in long header fields.
- #2152705 by gargsuchi: Images with 'itok' token not showing up.
- #2129149 by pokap | satvision83: Undefined offset in mimemail_headers.
Mime Mail 7.x-1.0-beta1, 2013-10-07
-----------------------
- #1702868 by sgabe, kid_icarus: Remove tokens if no replacement value can be generated.
- #1719570 by sgabe, oadaeh | greggles: Fix for SA-CONTRIB-2012-124.
- #2020875 by das-peter, Propaganistas: Provide option to set language in Rules actions.
- #2045699 by sgabe | Punk_UnDeaD: Boundaries are not unique on Windows.
- #1798324 by sgabe, kienan | ShaneOnABike: Return-Path is incorrectly using sender name.

View File

@@ -112,6 +112,10 @@
CSS definitions into tags within the HTML based on the CSS selectors. To use the
Compressor, just enable it.
The 'send arbitrary files' permission allows you to attach or embed files located
outside Drupal's public files directory. Note that this has security implications:
arbitrary means even your settings.php! Give to trusted roles only!
-- CREDITS --

View File

@@ -101,7 +101,7 @@ function mimemail_admin_settings() {
$form['mimemail']['advanced']['mimemail_key'] = array(
'#type' => 'textfield',
'#title' => t('Message validation string'),
'#default_value' => variable_get('mimemail_key', md5(rand())),
'#default_value' => variable_get('mimemail_key', drupal_random_key()),
'#required' => TRUE,
'#description' => t('This string will be used to validate incoming messages. It can be anything, but must be used on both sides of the transfer.'),
);

View File

@@ -15,15 +15,23 @@
* The POSTed message.
*/
function mimemail_post() {
$message = $_POST['message'];
$token = $_POST['token'];
$hash = md5(variable_get('mimemail_key', '**') . $message);
if ($hash != $token) {
watchdog('access denied', 'Authentication error for POST e-mail', WATCHDOG_WARNING);
if (!isset($_POST['token']) || empty($_POST['token'])) {
return drupal_access_denied();
}
return mimemail_incoming($message);
if (isset($_POST['message']) && !empty($_POST['message'])) {
$key = variable_get('mimemail_key', drupal_random_key());
$hash = hash_hmac('sha1', $_POST['message'], $key);
if ($hash != $_POST['token']) {
watchdog('access denied', 'Authentication error for POST e-mail', WATCHDOG_WARNING);
return drupal_access_denied();
}
else {
return mimemail_incoming($_POST['message']);
}
}
return drupal_access_denied();
}
/**

View File

@@ -26,16 +26,18 @@ function mimemail_rfc_headers($headers) {
// Collapse spaces and get rid of newline characters.
$value = preg_replace('/(\s+|\n|\r|^\s|\s$)/', ' ', $value);
// Fold headers if they're too long.
// A CRLF may be inserted before any WSP.
// @see http://tools.ietf.org/html/rfc2822#section-2.2.3
if (drupal_strlen($value) > 60) {
// If there's a semicolon, use that to separate.
if (count($array = preg_split('/;\s*/', $value)) > 1) {
$value = trim(join(";$crlf ", $array));
$value = trim(join(";$crlf ", $array));
}
else {
$value = wordwrap($value, 50, "$crlf ", FALSE);
$value = wordwrap($value, 50, "$crlf ", FALSE);
}
}
$header .= "$key: $value$crlf";
$header .= $key . ":" . $value . $crlf;
}
return trim($header);
}
@@ -64,8 +66,9 @@ function mimemail_headers($headers, $from = NULL) {
}
// This may not work. The MTA may rewrite the Return-Path.
if (!isset($headers['Return-Path']) || $headers['Return-Path'] == $default_from) {
preg_match('/[a-z\d\-\.\+_]+@(?:[a-z\d\-]+\.)+[a-z\d]{2,4}/i', $from, $matches);
$headers['Return-Path'] = "<$matches[0]>";
if (preg_match('/[a-z\d\-\.\+_]+@(?:[a-z\d\-]+\.)+[a-z\d]{2,4}/i', $from, $matches)) {
$headers['Return-Path'] = "<$matches[0]>";
}
}
}
@@ -185,6 +188,12 @@ function _mimemail_file($url = NULL, $content = NULL, $name = '', $type = '', $d
}
if (isset($file) && (@is_file($file) || $content)) {
$public_path = file_default_scheme() . '://';
$no_access = !user_access('send arbitrary files');
$not_in_public_path = strpos(drupal_realpath($file), drupal_realpath($public_path)) !== 0;
if (@is_file($file) && $not_in_public_path && $no_access) {
return $url;
}
if (!$name) {
$name = (@is_file($file)) ? basename($file) : 'attachment.dat';
@@ -250,7 +259,10 @@ function _mimemail_file($url = NULL, $content = NULL, $name = '', $type = '', $d
* - headers: An array that includes some headers for the mail to be sent.
*/
function mimemail_multipart_body($parts, $content_type = 'multipart/mixed; charset=utf-8', $sub_part = FALSE) {
$boundary = md5(uniqid($_SERVER['REQUEST_TIME'], TRUE));
// Control variable to avoid boundary collision.
static $part_num = 0;
$boundary = sha1(uniqid($_SERVER['REQUEST_TIME'], TRUE)) . $part_num++;
$body = '';
$headers = array(
'Content-Type' => "$content_type; boundary=\"$boundary\"",
@@ -423,35 +435,41 @@ function mimemail_html_body($body, $subject, $plain = FALSE, $plaintext = NULL,
*
* @param string $url
* The file path.
* @param boolean $to_embed
* (optional) Wheter the URL is used to embed the file. Defaults to NULL.
*
* @return string
* A processed URL.
*/
function _mimemail_url($url, $embed_file = NULL) {
function _mimemail_url($url, $to_embed = NULL) {
global $base_url;
$url = urldecode($url);
// If the URL is absolute or a mailto, return it as-is.
if (strpos($url, '://') !== FALSE || preg_match('!(mailto|callto|tel)\:!', $url)) {
$url = str_replace(' ', '%20', $url);
return $url;
}
// If the image embedding is disabled, return the absolute URL for the image.
elseif (variable_get('mimemail_linkonly', 0) && preg_match('!\.(png|gif|jpg|jpeg)$!i', $url)) {
$url = $base_url . $url;
$url = str_replace(' ', '%20', $url);
return $url;
}
$to_link = variable_get('mimemail_linkonly', 0);
$is_image = preg_match('!\.(png|gif|jpg|jpeg)!i', $url);
$is_absolute = file_uri_scheme($url) != FALSE || preg_match('!(mailto|callto|tel)\:!', $url);
$url = preg_replace('!^' . base_path() . '!', '', $url, 1);
// If we're processing to embed the file, we're done here so return.
if ($embed_file) {
return $url;
if (!$to_embed) {
if ($is_absolute) {
return str_replace(' ', '%20', $url);
}
}
else {
$url = preg_replace('!^' . base_path() . '!', '', $url, 1);
if ($is_image) {
if ($to_link) {
// Exclude images from embedding if needed.
$url = file_create_url($url);
$url = str_replace(' ', '%20', $url);
}
else {
// Remove security token from URL, this allows for styled image embedding.
// @see https://drupal.org/drupal-7.20-release-notes
$url = preg_replace('/\\?itok=.*$/', '', $url);
}
if (!preg_match('!^\?q=*!', $url)) {
$strip_clean = TRUE;
}
return $url;
}
$url = str_replace('?q=', '', $url);
@@ -493,7 +511,7 @@ function _mimemail_url($url, $embed_file = NULL) {
$url = url($path, $options);
// If url() added a ?q= where there should not be one, remove it.
if (isset($strip_clean) && $strip_clean) {
if (preg_match('!^\?q=*!', $url)) {
$url = preg_replace('!\?q=!', '', $url);
}

View File

@@ -1,6 +1,7 @@
name = Mime Mail
description = Send MIME-encoded emails with embedded images and attachments.
dependencies[] = mailsystem
dependencies[] = system (>=7.24)
package = Mail
core = 7.x
@@ -13,9 +14,9 @@ files[] = tests/mimemail.test
files[] = tests/mimemail_rules.test
files[] = tests/mimemail_compress.test
; Information added by drupal.org packaging script on 2013-09-06
version = "7.x-1.0-alpha2+30-dev"
; Information added by Drupal.org packaging script on 2014-03-05
version = "7.x-1.0-beta3"
core = "7.x"
project = "mimemail"
datestamp = "1378431585"
datestamp = "1394018015"

View File

@@ -109,3 +109,10 @@ function mimemail_update_7001() {
variable_del('mimemail_theme');
}
/**
* Generate new key for authenticating incoming messages.
*/
function mimemail_update_7002() {
variable_set('mimemail_key', drupal_random_key());
return t('Mime Mail has generated a new key to authenticate incoming messages.');
}

View File

@@ -39,6 +39,11 @@ function mimemail_permission() {
'title' => t('Edit Mime Mail user settings'),
'description' => t('Edit user specific settings for Mime Mail.'),
),
'send arbitrary files' => array(
'title' => t('Send arbitrary files'),
'description' => t('Attach or embed files located outside the public files directory.'),
'restrict access' => TRUE,
),
);
}
@@ -133,6 +138,7 @@ function mimemail_theme() {
*/
function mimemail_mail($key, &$message, $params) {
$context = $params['context'];
$options = array('clear' => TRUE);
// Prepare the array of the attachments.
$attachments = array();
@@ -156,16 +162,16 @@ function mimemail_mail($key, &$message, $params) {
$params[$param_key] = empty($params[$param_key]) ? array() : explode(',', $params[$param_key]);
if (!empty($params[$param_key])) {
foreach ($params[$param_key] as $key => $address) {
$params[$param_key][$key] = token_replace($address, $context);
$params[$param_key][$key] = token_replace($address, $context, $options);
}
$message['headers'][$address_header] = implode(',', $params[$param_key]);
}
}
$message['to'] = token_replace($message['to'], $context);
$message['subject'] = token_replace($context['subject'], $context);
$message['body'][] = token_replace($context['body'], $context);
$message['params']['plaintext'] = token_replace($params['plaintext'], $context);
$message['to'] = token_replace($message['to'], $context, $options);
$message['subject'] = token_replace($context['subject'], $context, $options);
$message['body'][] = token_replace($context['body'], $context, $options);
$message['params']['plaintext'] = token_replace($params['plaintext'], $context, $options);
$message['params']['attachments'] = $attachments;
}
@@ -347,7 +353,8 @@ function mimemail_prepare_message($message) {
}
}
$subject = str_replace(array(" \n", "\n"), '', trim(drupal_html_to_text($subject)));
// Removing newline character introduced by _drupal_wrap_mail_line();
$subject = str_replace(array("\n"), '', trim(drupal_html_to_text($subject)));
$hook = array(
'mimemail_message__' . $key,

View File

@@ -6,9 +6,9 @@ dependencies[] = trigger
core = 7.x
; Information added by drupal.org packaging script on 2013-09-06
version = "7.x-1.0-alpha2+30-dev"
; Information added by Drupal.org packaging script on 2014-03-05
version = "7.x-1.0-beta3"
core = "7.x"
project = "mimemail"
datestamp = "1378431585"
datestamp = "1394018015"

View File

@@ -142,6 +142,14 @@ class mimemail_compress {
$style = trim($value['attributes']);
}
$node->setAttribute('style', $style);
// Convert float to align for images.
$float = preg_match ('/float:(left|right)/', $style, $matches);
if ($float) {
$node->setAttribute('align', $matches[1]);
$node->setAttribute('vspace', 5);
$node->setAttribute('hspace', 5);
}
}
}

View File

@@ -6,9 +6,9 @@ core = 7.x
files[] = mimemail_compress.inc
; Information added by drupal.org packaging script on 2013-09-06
version = "7.x-1.0-alpha2+30-dev"
; Information added by Drupal.org packaging script on 2014-03-05
version = "7.x-1.0-beta3"
core = "7.x"
project = "mimemail"
datestamp = "1378431585"
datestamp = "1394018015"

View File

@@ -41,6 +41,55 @@ class MimeMailUnitTestCase extends DrupalUnitTestCase {
function testUrl() {
$result = _mimemail_url('#');
$this->assertIdentical($result, '#', 'Hash mark URL without fragment left intact.');
$url = '/sites/default/files/styles/thumbnail/public/image.jpg?itok=Wrl6Qi9U';
$result = _mimemail_url($url, TRUE);
$expected = 'sites/default/files/styles/thumbnail/public/image.jpg';
$this->assertIdentical($result, $expected, 'Security token removed from styled image URL.');
$expected = $url = 'public://' . $this->randomName() . ' '. $this->randomName() . '.' . $this->randomName(3);
$result = _mimemail_url($url, TRUE);
$this->assertIdentical($result, $expected, 'Space in the filename of the attachment left intact.');
}
}
/**
* Tests functions from the Mime Mail module.
*/
class MimeMailWebTestCase extends DrupalWebTestCase {
protected $adminUser;
public static function getInfo() {
return array(
'name' => 'Mime Mail web tests',
'description' => 'Test that Mime Mail works properly.',
'group' => 'Mime Mail',
);
}
public function setUp() {
parent::setUp('mailsystem', 'mimemail');
// Create and login user.
$this->adminUser = $this->drupalCreateUser(array(
'access administration pages',
'administer site configuration',
));
$this->drupalLogin($this->adminUser);
}
public function testUrl() {
$this->drupalPost('admin/config/system/mimemail',
array('mimemail_linkonly' => TRUE),
t('Save configuration'));
$url = 'public://' . $this->randomName() . ' '. $this->randomName() . '.jpg';
$result = _mimemail_url($url, TRUE);
$expected = str_replace(' ', '%20', file_create_url($url));
$message = 'Stream wrapper converted to web accessible URL for linked image.';
$this->assertIdentical($result, $expected, $message);
}
}

View File

@@ -11,10 +11,6 @@
* Tests the Rules integration.
*/
class MimeMailRulesTestCase extends DrupalWebTestCase {
/**
* The user with administration permissions.
* @var object
*/
protected $adminUser;
public static function getInfo() {
@@ -25,14 +21,8 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
);
}
public function setUp(array $modules = array()) {
$modules[] = 'mailsystem';
$modules[] = 'locale';
$modules[] = 'entity';
$modules[] = 'entity_token';
$modules[] = 'rules';
$modules[] = 'mimemail';
parent::setUp($modules);
public function setUp() {
parent::setUp('mailsystem', 'locale', 'entity', 'entity_token', 'rules', 'mimemail');
// Create and login user.
$this->adminUser = $this->drupalCreateUser(array(
@@ -56,11 +46,10 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
drupal_static_reset('language_list');
}
/**
* Create mimemail action rule and fire it.
* Create rule with "mimemail" action and fire it.
*/
public function testMimemailAction() {
public function testMailToUserAction() {
$settings = array(
'key' => 'mail-key-' . $this->randomName(),
'to' => $this->randomName() . '@example.com',
@@ -70,7 +59,6 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
'plaintext' => $this->randomName(30) . '<div></div><br /><hr>',
);
// Set no language for the mail and check if the system default is used.
$rule = rule();
$rule->action('mimemail', array(
@@ -108,12 +96,12 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
}
/**
* Create mimemail to users by role action rule and fire it.
* Create rule with "mimemail_to_users_of_role" action and fire it.
*/
public function testMimemaiToUsersOfRoleAction() {
public function testMailToUsersOfRoleAction() {
$languages = language_list();
// Add more uses and roles.
// Add more users and roles.
$users = array(
$this->randomName() . '@example.com' => 'en',
$this->randomName() . '@example.com' => 'de',
@@ -121,7 +109,9 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
$this->randomName() . '@example.com' => '',
$this->randomName() . '@example.com' => 'invalid',
);
$mimemail_role = $this->drupalCreateRole(array());
foreach ($users as $email => $language) {
$user = $this->drupalCreateUser(array(
'access administration pages',
@@ -131,6 +121,7 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
$user->roles[$mimemail_role] = $mimemail_role;
user_save($user);
}
$settings = array(
'key' => 'mail-key-' . $this->randomName(),
'from' => $this->randomName() . '@example.com',
@@ -138,6 +129,7 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
'body' => $this->randomName(60) . '<div></div><br /><hr>',
'plaintext' => $this->randomName(30) . '<div></div><br /><hr>',
);
// Rest the collected mails.
variable_set('drupal_test_email_collector', array());
@@ -171,10 +163,11 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
$this->assertEqual($mail['language']->language, $user_language);
}
// Send mails to all users of a role and respect the language of the users.
// Enforce German as fallback language if an user doesn't have a language.
// Rest the collected mails.
variable_set('drupal_test_email_collector', array());
// Send mails to all users of a role and respect the language of the users.
// Enforce German as fallback language if an user doesn't have a language.
$rule->elementMap()->lookup(3)->settings['language'] = 'de';
$rule->save();
$rule->execute();
@@ -187,9 +180,10 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
$this->assertEqual($mail['language']->language, $user_language);
}
// Send mails to all users of a role but use the same language for all.
// Rest the collected mails.
variable_set('drupal_test_email_collector', array());
// Send mails to all users of a role but use the same language for all.
$rule->elementMap()->lookup(3)->settings['language_user'] = FALSE;
$rule->elementMap()->lookup(3)->settings['language'] = 'it';
$rule->save();
@@ -199,9 +193,10 @@ class MimeMailRulesTestCase extends DrupalWebTestCase {
$this->assertEqual($mail['language']->language, 'it');
}
// Send mails to all users of a role except deactivated users.
// Rest the collected mails.
variable_set('drupal_test_email_collector', array());
// Send mails to all users of a role except deactivated users.
// Disable one of the users.
reset($users);
$user = user_load_by_mail(key($users));

View File

@@ -81,31 +81,11 @@ function template_preprocess_mimemail_message(&$variables) {
if (isset($styles)) {
// Process each style sheet.
foreach (explode("\n", $styles) as $style) {
if (!empty($style) && @file_exists($style)) {
$css .= @file_get_contents($style);
if (!empty($style)) {
$css .= drupal_load_stylesheet($style, TRUE);
}
}
// Regexp to match comment blocks.
$comment = '/\*[^*]*\*+(?:[^/*][^*]*\*+)*/';
// Regexp to match double quoted strings.
$double_quot = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';
// Regexp to match single quoted strings.
$single_quot = "'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'";
// Perform some safe CSS optimizations (derived from core CSS aggregation).
$css = preg_replace_callback(
"<$double_quot|$single_quot|$comment>Sus", // Match all comment blocks along
"_mimemail_process_comment", // with double/single quoted strings
$css); // and feed them to _mimemail_process_comment().
$css = preg_replace(
'<\s*([@{}:;,]|\)\s|\s\()\s*[^\n\S]>S', // Remove whitespace around separators,
'\1', // but keep space around parentheses
$css); // and new lines between definitions.
// End the file with a new line.
$css .= "\n";
// Wordwrap to adhere to RFC821
$css = wordwrap($css, 700);
}
@@ -120,35 +100,3 @@ function template_preprocess_mimemail_message(&$variables) {
$variables['module'] = str_replace('_', '-', $variables['module']);
$variables['key'] = str_replace('_', '-', $variables['key']);
}
/**
* Process comment blocks. (derived from core CSS aggregation)
*
* This is the callback function for the preg_replace_callback()
* used in drupal_load_stylesheet_content(). Support for comment
* hacks is implemented here.
*/
function _mimemail_process_comment($matches) {
static $keep_nextone = FALSE;
// Quoted string, keep it.
if ($matches[0][0] == "'" || $matches[0][0] == '"') {
return $matches[0];
}
// End of IE-Mac hack, keep it.
if ($keep_nextone) {
$keep_nextone = FALSE;
return $matches[0];
}
switch (strrpos($matches[0], '\\')) {
case FALSE :
// No backslash, strip it.
return '';
case drupal_strlen($matches[0])-3 :
// Ends with \*/ so is a multi line IE-Mac hack, keep the next one also.
$keep_nextone = TRUE;
return '/*_\*/';
default :
// Single line IE-Mac hack.
return '/*\_*/';
}
}