From aa370627b211a51dc46891cfa4b6e3d2ef3e52db Mon Sep 17 00:00:00 2001 From: mcramer <m.cramer@pixcept.de> Date: Tue, 16 Jul 2013 10:45:17 -0400 Subject: [PATCH] - Fixed FS#2924 - the month will not set automatically in the autoresponder by click now Along with this fixed some display problems with the combo boxes introduced in 3.0.5. Some fields were not correctly displayed with the predefined values if value and text of the underlying option element differ. --- interface/lib/classes/ispcmail.inc.php | 150 ++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 133 insertions(+), 17 deletions(-) diff --git a/interface/lib/classes/ispcmail.inc.php b/interface/lib/classes/ispcmail.inc.php index d8a70dc..d49af96 100644 --- a/interface/lib/classes/ispcmail.inc.php +++ b/interface/lib/classes/ispcmail.inc.php @@ -55,6 +55,7 @@ private $body = ''; private $_mail_sender = ''; private $_sent_mails = 0; + private $user_agent = 'ISPConfig/3 (Mailer Class)'; /**#@-*/ /** @@ -100,6 +101,22 @@ * How many mails should be sent via one single smtp connection */ private $smtp_max_mails = 20; + /** + * Should the mail be signed + */ + private $sign_email = false; + /** + * The cert and key to use for email signing + */ + private $sign_key = ''; + private $sign_key_pass = ''; + private $sign_cert = ''; + private $sign_bundle = ''; + private $_is_signed = false; + /** + * get disposition notification + */ + private $notification = false; /**#@-*/ public function __construct($options = array()) { @@ -110,6 +127,7 @@ $this->attachments = array(); $this->headers['MIME-Version'] = '1.0'; + $this->headers['User-Agent'] = $this->user_agent; if(is_array($options) && count($options) > 0) $this->setOptions($options); } @@ -155,8 +173,26 @@ if($value != 'ssl' && $value != 'tls') $value = ''; $this->smtp_crypt = $value; break; + case 'sign_email': + $this->sign_email = ($value == true ? true : false); + break; + case 'sign_key': + $this->sign_key = $value; + break; + case 'sign_key_pass': + $this->sign_key_pass = $value; + break; + case 'sign_cert': + $this->sign_cert = $value; + break; + case 'sign_bundle': + $this->sign_bundle = $value; + break; case 'mail_charset': $this->mail_charset = $value; + break; + case 'notify': + $this->notification = ($value == true ? true : false); break; } } @@ -378,23 +414,30 @@ $this->body = "This is a multi-part message in MIME format.\n\n"; if($text) { - $this->body .= "--{$this->mime_boundary}\n" . + /*$this->body .= "--{$this->mime_boundary}\n" . "Content-Type:text/plain; charset=\"" . strtolower($this->mail_charset) . "\"\n" . - "Content-Transfer-Encoding: 7bit\n\n" . $this->text_part . "\n\n"; - } + "Content-Transfer-Encoding: 7bit\n\n" . $this->text_part . "\n\n";*/ + $this->body .= "--{$this->mime_boundary}\n" . + "Content-Type:text/plain; charset=\"UTF-8\"\n" . + "Content-Transfer-Encoding: 8bit\n\n" . $this->text_part . "\n\n"; + } if($html) { - $this->body .= "--{$this->mime_boundary}\n" . + /*$this->body .= "--{$this->mime_boundary}\n" . "Content-Type:text/html; charset=\"" . strtolower($this->mail_charset) . "\"\n" . - "Content-Transfer-Encoding: 7bit\n\n" . $this->html_part . "\n\n"; - } + "Content-Transfer-Encoding: 7bit\n\n" . $this->html_part . "\n\n";*/ + $this->body .= "--{$this->mime_boundary}\n" . + "Content-Type:text/html; charset=\"UTF-8\"\n" . + "Content-Transfer-Encoding: 8bit\n\n" . $this->html_part . "\n\n"; + } if($attach) { foreach($this->attachments as $att) { $this->body .= "--{$this->mime_boundary}\n" . "Content-Type: " . $att['type'] . ";\n" . " name=\"" . $att['filename'] . "\"\n" . - "Content-Transfer-Encoding: base64\n\n" . + "Content-Transfer-Encoding: base64\n" . + "Content-Disposition: attachment;\n\n" . chunk_split(base64_encode($att['content'])) . "\n\n"; } } @@ -416,16 +459,79 @@ } /** + * Function to sign an email body + */ + private function sign() { + if($this->sign_email == false || $this->sign_key == '' || $this->sign_cert == '') return false; + if(function_exists('openssl_pkcs7_sign') == false) return false; + + $tmpin = tempnam(sys_get_temp_dir(), 'sign'); + $tmpout = tempnam(sys_get_temp_dir(), 'sign'); + if(!file_exists($tmpin) || !is_writable($tmpin)) return false; + + file_put_contents($tmpin, 'Content-Type: ' . $this->getHeader('Content-Type') . "\n\n" . $this->body); + $tmpf_key = tempnam(sys_get_temp_dir(), 'sign'); + file_put_contents($tmpf_key, $this->sign_key); + $tmpf_cert = tempnam(sys_get_temp_dir(), 'sign'); + file_put_contents($tmpf_cert, $this->sign_cert); + if($this->sign_bundle != '') { + $tmpf_bundle = tempnam(sys_get_temp_dir(), 'sign'); + file_put_contents($tmpf_bundle, $this->sign_bundle); + openssl_pkcs7_sign($tmpin, $tmpout, 'file://' . realpath($tmpf_cert), array('file://' . realpath($tmpf_key), $this->sign_key_pass), array(), PKCS7_DETACHED, realpath($tmpf_bundle)); + } else { + openssl_pkcs7_sign($tmpin, $tmpout, 'file://' . realpath($tmpf_cert), array('file://' . realpath($tmpf_key), $this->sign_key_pass), array()); + } + unlink($tmpin); + unlink($tmpf_cert); + unlink($tmpf_key); + if(file_exists($tmpf_bundle)) unlink($tmpf_bundle); + + if(!file_exists($tmpout) || !is_readable($tmpout)) return false; + $this->body = file_get_contents($tmpout); + unlink($tmpout); + + unset($this->headers['Content-Type']); + unset($this->headers['MIME-Version']); + + $this->_is_signed = true; + } + + private function _char_to_hex($matches) { + return '=' . strtoupper(dechex(ord($matches[1]))); + } + + /** * Function to encode a header if necessary * according to RFC2047 * @access private */ private function _encodeHeader($input, $charset = 'ISO-8859-1') { - preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches); - foreach ($matches[1] as $value) { - $replacement = preg_replace('/([\x20\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value); - $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input); - } + preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches); + foreach ($matches[1] as $value) { + $replacement = preg_replace_callback('/([\x20\x80-\xFF])/', array($this, '_char_to_hex'), $value); + $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input); + } + + return $input; + } + + /** + * Function to encode the subject if necessary + * according to RFC2047 + * @access private + */ + private function _encodeSubject($input, $charset = 'ISO-8859-1') { + /* + if($charset == 'UTF-8' && function_exists('imap_8bit')) { + $input = "=?utf-8?Q?" . imap_8bit($input) . "?="; + } else { + preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches); + foreach ($matches[1] as $value) { + $replacement = preg_replace('/([\x20\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value); + $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input); + } + }*/ + $input='=?UTF-8?B?'.base64_encode($input).'?='; return $input; } @@ -492,16 +598,23 @@ public function send($recipients) { if(!is_array($recipients)) $recipients = array($recipients); + if($this->use_smtp == true) $this->_crlf = "\r\n"; + else $this->_crlf = "\n"; + $this->create(); + if($this->sign_email == true) $this->sign(); $subject = ''; if (!empty($this->headers['Subject'])) { //$subject = $this->_encodeHeader($this->headers['Subject'], $this->mail_charset); $subject = $this->headers['Subject']; - $enc_subject = $this->_encodeHeader($subject, $this->mail_charset); + //$enc_subject = $this->_encodeHeader($subject, $this->mail_charset); + $enc_subject = $this->_encodeSubject($subject, $this->mail_charset); unset($this->headers['Subject']); } + + if($this->notification == true) $this->setHeader('Disposition-Notification-To', $this->getHeader('From')); unset($this->headers['To']); // always reset the To header to prevent from sending to multiple users at once $this->headers['Date'] = date('r'); //date('D, d M Y H:i:s O'); @@ -547,11 +660,11 @@ if($recipname && !is_numeric($recipname)) $this->setHeader('To', $recipname . ' <' . $recip . '>'); else $this->setHeader('To', $recip); - $mail_content = 'To: ' . $this->getHeader('To') . $this->_crlf; + $mail_content = 'Subject: ' . $enc_subject . $this->_crlf; + $mail_content .= 'To: ' . $this->getHeader('To') . $this->_crlf; if($this->getHeader('Bcc') != '') $mail_content .= 'Bcc: ' . $this->_encodeHeader($this->getHeader('Bcc'), $this->mail_charset) . $this->_crlf; if($this->getHeader('Cc') != '') $mail_content .= 'Cc: ' . $this->_encodeHeader($this->getHeader('Cc'), $this->mail_charset) . $this->_crlf; - $mail_content .= 'Subject: ' . $enc_subject . $this->_crlf; - $mail_content .= implode($this->_crlf, $headers) . $this->_crlf . $this->_crlf . $this->body; + $mail_content .= implode($this->_crlf, $headers) . $this->_crlf . ($this->_is_signed == false ? $this->_crlf : '') . $this->body; fputs($this->_smtp_conn, $mail_content . $this->_crlf . '.' . $this->_crlf); $response = fgets($this->_smtp_conn, 515); @@ -571,7 +684,8 @@ else $rec_string .= $recip; } $to = $this->_encodeHeader($rec_string, $this->mail_charset); - $result = mail($to, $subject, $this->body, implode($this->_crlf, $headers)); + //$result = mail($to, $subject, $this->body, implode($this->_crlf, $headers)); + $result = mail($to, $enc_subject, $this->body, implode($this->_crlf, $headers)); } // Reset the subject in case mail is resent @@ -602,6 +716,7 @@ $this->html_part = ''; $this->headers['MIME-Version'] = '1.0'; + $this->headers['User-Agent'] = $this->user_agent; $this->smtp_helo = ''; $this->smtp_host = ''; @@ -612,6 +727,7 @@ $this->smtp_crypt = false; $this->mail_charset = 'UTF-8'; $this->_sent_mails = 0; + return; } } -- Gitblit v1.9.1