From ee895a2c96a33b854c62a5835a7a1fcd24c02b39 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 15 Jul 2016 15:24:45 +0200 Subject: [PATCH] Remove PHP mail() support, smtp_server is required now (#5340) --- CHANGELOG | 1 + INSTALL | 2 +- config/defaults.inc.php | 3 +- installer/config.php | 4 +- installer/test.php | 51 ++++----- program/lib/Roundcube/rcube.php | 149 ++++++++------------------- program/steps/mail/sendmail.inc | 4 +- program/steps/settings/func.inc | 2 +- skins/classic/templates/compose.html | 2 +- skins/larry/templates/compose.html | 2 +- 10 files changed, 68 insertions(+), 152 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a2ec7f354..e18683a52 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Remove PHP mail() support, smtp_server is required now (#5340) - Display full message subject in onmouseover on truncated subject in mail view (#5346) - Searching in both contacts and groups when LDAP addressbook with group_filters option is used - Update TinyMCE to version 4.3.13 (#5309) diff --git a/INSTALL b/INSTALL index f7b343625..25f09a113 100644 --- a/INSTALL +++ b/INSTALL @@ -37,7 +37,7 @@ REQUIREMENTS * A MySQL (4.0.8 or newer), PostgreSQL, MS SQL Server (2005 or newer), Oracle database or SQLite support in PHP * One of the above databases with permission to create tables -* An SMTP server (recommended) or PHP configured for mail delivery +* An SMTP server * Composer installed either locally or globally (https://getcomposer.org) diff --git a/config/defaults.inc.php b/config/defaults.inc.php index 0ce9539ed..1825b8c30 100644 --- a/config/defaults.inc.php +++ b/config/defaults.inc.php @@ -239,7 +239,6 @@ $config['messages_cache_threshold'] = 50; // SMTP server host (for sending mails). // To use SSL/TLS connection, enter hostname with prefix ssl:// or tls:// -// If left blank, the PHP mail() function is used // Supported replacement variables: // %h - user's IMAP hostname // %n - hostname ($_SERVER['SERVER_NAME']) @@ -247,7 +246,7 @@ $config['messages_cache_threshold'] = 50; // %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part) // %z - IMAP domain (IMAP hostname without the first part) // For example %n = mail.domain.tld, %t = domain.tld -$config['smtp_server'] = ''; +$config['smtp_server'] = 'localhost'; // SMTP port (default is 25; use 587 for STARTTLS or 465 for the // deprecated SSL over SMTP (aka SMTPS)) diff --git a/installer/config.php b/installer/config.php index 7e9390388..e8ca64751 100644 --- a/installer/config.php +++ b/installer/config.php @@ -461,12 +461,12 @@ echo $text_junkmbox->show($RCI->getprop('junk_mbox')); '_smtp_server', 'size' => 30, 'id' => "cfgsmtphost")); -echo $text_smtphost->show($RCI->getprop('smtp_server')); +echo $text_smtphost->show($RCI->getprop('smtp_server', 'localhost')); ?>
Use this host for sending mails
-

To use SSL connection, set ssl://smtp.host.com. If left blank, the PHP mail() function is used

+

To use SSL connection, set ssl://smtp.host.com.

smtp_port
diff --git a/installer/test.php b/installer/test.php index 237e8df73..1ed50ddb2 100644 --- a/installer/test.php +++ b/installer/test.php @@ -246,7 +246,7 @@ else {

Test SMTP config

-Server: getprop('smtp_server', 'PHP mail()')); ?>
+Server: getprop('smtp_server', 'localhost')); ?>
Port: getprop('smtp_port'); ?>
getprop('smtp_port'); ?>
if ($RCI->getprop('smtp_server')) { $user = $RCI->getprop('smtp_user', '(none)'); $pass = $RCI->getprop('smtp_pass', '(none)'); - + if ($user == '%u') { $user_field = new html_inputfield(array('name' => '_smtp_user')); $user = $user_field->show($_POST['_smtp_user']); @@ -263,7 +263,7 @@ if ($RCI->getprop('smtp_server')) { $pass_field = new html_passwordfield(array('name' => '_smtp_pass')); $pass = $pass_field->show(); } - + echo "User: $user
"; echo "Password: $pass
"; } @@ -293,42 +293,27 @@ if (isset($_POST['sendmail'])) { ); $body = 'This is a test to confirm that Roundcube can send email.'; - $smtp_response = array(); // send mail using configured SMTP server - if ($RCI->getprop('smtp_server')) { - $CONFIG = $RCI->config; + $CONFIG = $RCI->config; - if (!empty($_POST['_smtp_user'])) { - $CONFIG['smtp_user'] = $_POST['_smtp_user']; - } - if (!empty($_POST['_smtp_pass'])) { - $CONFIG['smtp_pass'] = $_POST['_smtp_pass']; - } - - $mail_object = new Mail_mime(); - $send_headers = $mail_object->headers($headers); + if (!empty($_POST['_smtp_user'])) { + $CONFIG['smtp_user'] = $_POST['_smtp_user']; + } + if (!empty($_POST['_smtp_pass'])) { + $CONFIG['smtp_pass'] = $_POST['_smtp_pass']; + } - $SMTP = new rcube_smtp(); - $SMTP->connect(rcube_utils::parse_host($RCI->getprop('smtp_server')), - $RCI->getprop('smtp_port'), $CONFIG['smtp_user'], $CONFIG['smtp_pass']); + $mail_object = new Mail_mime(); + $send_headers = $mail_object->headers($headers); + $head = $mail_object->txtHeaders($send_headers); - $status = $SMTP->send_mail($headers['From'], $headers['To'], - ($foo = $mail_object->txtHeaders($send_headers)), $body); + $SMTP = new rcube_smtp(); + $SMTP->connect(rcube_utils::parse_host($RCI->getprop('smtp_server')), + $RCI->getprop('smtp_port'), $CONFIG['smtp_user'], $CONFIG['smtp_pass']); - $smtp_response = $SMTP->get_response(); - } - else { // use mail() - $header_str = 'From: ' . $headers['From']; - - if (ini_get('safe_mode')) - $status = mail($headers['To'], $headers['Subject'], $body, $header_str); - else - $status = mail($headers['To'], $headers['Subject'], $body, $header_str, '-f'.$headers['From']); - - if (!$status) - $smtp_response[] = 'Mail delivery with mail() failed. Check your error logs for details'; - } + $status = $SMTP->send_mail($headers['From'], $headers['To'], $head, $body); + $smtp_response = $SMTP->get_response(); if ($status) { $RCI->pass('SMTP send'); diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php index 4944d3b8e..65b5fb51d 100644 --- a/program/lib/Roundcube/rcube.php +++ b/program/lib/Roundcube/rcube.php @@ -1548,98 +1548,58 @@ class rcube $message = $plugin['message']; $headers = $message->headers(); - // send thru SMTP server using custom SMTP library - if ($this->config->get('smtp_server')) { - // generate list of recipients - $a_recipients = (array) $mailto; - - if (strlen($headers['Cc'])) - $a_recipients[] = $headers['Cc']; - if (strlen($headers['Bcc'])) - $a_recipients[] = $headers['Bcc']; - - // remove Bcc header and get the whole head of the message as string - $smtp_headers = $this->message_head($message, array('Bcc')); - - if ($message->getParam('delay_file_io')) { - // use common temp dir - $temp_dir = $this->config->get('temp_dir'); - $body_file = tempnam($temp_dir, 'rcmMsg'); - $mime_result = $message->saveMessageBody($body_file); - - if (is_a($mime_result, 'PEAR_Error')) { - self::raise_error(array('code' => 650, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not create message: ".$mime_result->getMessage()), - true, false); - return false; - } - - $msg_body = fopen($body_file, 'r'); - } - else { - $msg_body = $message->get(); - } - - // send message - if (!is_object($this->smtp)) { - $this->smtp_init(true); - } - - $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options); - $response = $this->smtp->get_response(); - $error = $this->smtp->get_error(); + // generate list of recipients + $a_recipients = (array) $mailto; - // log error - if (!$sent) { - self::raise_error(array('code' => 800, 'type' => 'smtp', - 'line' => __LINE__, 'file' => __FILE__, - 'message' => join("\n", $response)), true, false); - } + if (strlen($headers['Cc'])) { + $a_recipients[] = $headers['Cc']; + } + if (strlen($headers['Bcc'])) { + $a_recipients[] = $headers['Bcc']; } - // send mail using PHP's mail() function - else { - // unset To,Subject headers because they will be added by the mail() function - $header_str = $this->message_head($message, array('To', 'Subject')); - - if (is_array($mailto)) { - $mailto = implode(', ', $mailto); - } - // #1485779 - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { - if (preg_match_all('/<([^@]+@[^>]+)>/', $mailto, $m)) { - $mailto = implode(', ', $m[1]); - } - } + // remove Bcc header and get the whole head of the message as string + $smtp_headers = $message->txtHeaders(array('Bcc' => null), true); - $msg_body = $message->get(); + if ($message->getParam('delay_file_io')) { + // use common temp dir + $temp_dir = $this->config->get('temp_dir'); + $body_file = tempnam($temp_dir, 'rcmMsg'); + $mime_result = $message->saveMessageBody($body_file); - if (is_a($msg_body, 'PEAR_Error')) { + if (is_a($mime_result, 'PEAR_Error')) { self::raise_error(array('code' => 650, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not create message: ".$msg_body->getMessage()), + 'message' => "Could not create message: ".$mime_result->getMessage()), true, false); + return false; } - else { - $delim = $this->config->header_delimiter(); - $to = $mailto; - $subject = $headers['Subject']; - $header_str = rtrim($header_str); - - if ($delim != "\r\n") { - $header_str = str_replace("\r\n", $delim, $header_str); - $msg_body = str_replace("\r\n", $delim, $msg_body); - $to = str_replace("\r\n", $delim, $to); - $subject = str_replace("\r\n", $delim, $subject); - } - $opts = filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN) ? null : "-f$from"; - $sent = mail($to, $subject, $msg_body, $header_str, $opts); - } + $msg_body = fopen($body_file, 'r'); + } + else { + $msg_body = $message->get(); } - if ($sent) { + // initialize SMTP connection + if (!is_object($this->smtp)) { + $this->smtp_init(true); + } + + // send message + $sent = $this->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $options); + $response = $this->smtp->get_response(); + $error = $this->smtp->get_error(); + + if (!$sent) { + self::raise_error(array('code' => 800, 'type' => 'smtp', + 'line' => __LINE__, 'file' => __FILE__, + 'message' => join("\n", $response)), true, false); + + // allow plugins to catch sending errors with the same parameters as in 'message_before_send' + $this->plugins->exec_hook('message_send_error', $plugin + array('error' => $error)); + } + else { $this->plugins->exec_hook('message_sent', array('headers' => $headers, 'body' => $msg_body)); // remove MDN headers after sending @@ -1647,16 +1607,7 @@ class rcube 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 = implode(',', $a_recipients); $mailto = rcube_mime::decode_address_list($mailto, null, false, null, true); self::write_log('sendmail', sprintf("User %s [%s]; Message for %s; %s", @@ -1666,10 +1617,6 @@ class rcube !empty($response) ? join('; ', $response) : '')); } } - else { - // allow plugins to catch sending errors with the same parameters as in 'message_before_send' - $this->plugins->exec_hook('message_send_error', $plugin + array('error' => $error)); - } if (is_resource($msg_body)) { fclose($msg_body); @@ -1679,20 +1626,6 @@ class rcube return $sent; } - - /** - * Return message headers as a string - */ - protected function message_head($message, $unset = array()) - { - // requires Mail_mime >= 1.9.0 - $headers = array(); - foreach ((array) $unset as $header) { - $headers[$header] = null; - } - - return $message->txtHeaders($headers, true); - } } diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index 8cf7e4b97..27cc55f70 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -368,9 +368,7 @@ $MAIL_MIME = new Mail_mime("\r\n"); // Check if we have enough memory to handle the message in it // It's faster than using files, so we'll do this if we only can -if (is_array($COMPOSE['attachments']) && $RCMAIL->config->get('smtp_server') - && ($mem_limit = parse_bytes(ini_get('memory_limit'))) -) { +if (is_array($COMPOSE['attachments']) && ($mem_limit = parse_bytes(ini_get('memory_limit')))) { $memory = 0; foreach ($COMPOSE['attachments'] as $id => $attachment) { $memory += $attachment['size']; diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc index 087b70ba6..93e780b46 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -749,7 +749,7 @@ function rcmail_user_prefs($current = null) ); } - if (!isset($no_override['dsn_default']) && $RCMAIL->config->get('smtp_server')) { + if (!isset($no_override['dsn_default'])) { if (!$current) { continue 2; } diff --git a/skins/classic/templates/compose.html b/skins/classic/templates/compose.html index aef064e41..979b5cb58 100644 --- a/skins/classic/templates/compose.html +++ b/skins/classic/templates/compose.html @@ -181,7 +181,7 @@ - + diff --git a/skins/larry/templates/compose.html b/skins/larry/templates/compose.html index 262a89db8..484445f82 100644 --- a/skins/larry/templates/compose.html +++ b/skins/larry/templates/compose.html @@ -152,7 +152,7 @@ - +