diff --git a/include/api.tickets.php b/include/api.tickets.php index 55dc5cf1ea6ceccd93a54fb51e7a5467ff7c6991..7268d0ffabaacedf3707c9a50071a955b17809e0 100644 --- a/include/api.tickets.php +++ b/include/api.tickets.php @@ -72,6 +72,15 @@ class TicketApiController extends ApiController { if(!($attachment['data'] = base64_decode($attachment['data'], true))) $attachment['error'] = sprintf('%s: Poorly encoded base64 data', Format::htmlchars($attachment['name'])); } + if (!$attachment['error'] + && ($size = $ost->getConfig()->getMaxFileSize()) + && ($fsize = $attachment['size'] ?: strlen($attachment['data'])) + && $fsize > $size) { + $attachment['error'] = sprintf('File %s (%s) is too big. Maximum of %s allowed', + Format::htmlchars($attachment['name']), + Format::file_size($fsize), + Format::file_size($size)); + } } unset($attachment); } diff --git a/include/class.mailer.php b/include/class.mailer.php index c80421fcb798e51b2aa7011c902e78f9d6e30615..1c43398bcf4d3af04540fdbe6c01fbc181d2f2e2 100644 --- a/include/class.mailer.php +++ b/include/class.mailer.php @@ -206,21 +206,38 @@ class Mailer { $body = $mime->get($encodings); //encode the headers. $headers = $mime->headers($headers, true); + + // Cache smtp connections made during this request + static $smtp_connections = array(); if(($smtp=$this->getSMTPInfo())) { //Send via SMTP - $mail = mail::factory('smtp', - array ('host' => $smtp['host'], - 'port' => $smtp['port'], - 'auth' => $smtp['auth'], - 'username' => $smtp['username'], - 'password' => $smtp['password'], - 'timeout' => 20, - 'debug' => false, - )); + $key = sprintf("%s:%s:%s", $smtp['host'], $smtp['port'], + $smtp['username']); + if (!isset($smtp_connections[$key])) { + $mail = mail::factory('smtp', array( + 'host' => $smtp['host'], + 'port' => $smtp['port'], + 'auth' => $smtp['auth'], + 'username' => $smtp['username'], + 'password' => $smtp['password'], + 'timeout' => 20, + 'debug' => false, + 'persist' => true, + )); + if ($mail->connect()) + $smtp_connections[$key] = $mail; + } + else { + // Use persistent connection + $mail = $smtp_connections[$key]; + } $result = $mail->send($to, $headers, $body); if(!PEAR::isError($result)) return $messageId; + // Force reconnect on next ->send() + unset($smtp_connections[$key]); + $alert=sprintf("Unable to email via SMTP:%s:%d [%s]\n\n%s\n", $smtp['host'], $smtp['port'], $smtp['username'], $result->getMessage()); $this->logError($alert); diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index efddf6404d228d2512985f1d60cc81f6d14e39f9..73ac6184521639c58142324c269127d185b51c0f 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -20,6 +20,7 @@ require_once(INCLUDE_DIR.'class.dept.php'); require_once(INCLUDE_DIR.'class.email.php'); require_once(INCLUDE_DIR.'class.filter.php'); require_once(INCLUDE_DIR.'html2text.php'); +require_once(INCLUDE_DIR.'tnef_decoder.php'); class MailFetcher { @@ -30,6 +31,8 @@ class MailFetcher { var $charset = 'UTF-8'; + var $tnef = false; + function MailFetcher($email, $charset='UTF-8') { @@ -377,6 +380,10 @@ class MailFetcher { } } + if ($this->tnef && !strcasecmp($mimeType, 'text/html') + && ($content = $this->tnef->getBody('text/html', $encoding))) + return $content; + //Do recursive search $text=''; if($struct && $struct->parts && $recurse) { @@ -512,6 +519,10 @@ class MailFetcher { } function getPriority($mid) { + if ($this->tnef && isset($this->tnef->Importance)) + // PidTagImportance is 0, 1, or 2 + // http://msdn.microsoft.com/en-us/library/ee237166(v=exchg.80).aspx + return $this->tnef->Importance + 1; return Mail_Parse::parsePriority($this->getHeader($mid)); } @@ -570,6 +581,23 @@ class MailFetcher { return true; //Report success (moved or delete) } + // Parse MS TNEF emails + if (($struct = imap_fetchstructure($this->mbox, $mid)) + && ($attachments = $this->getAttachments($struct))) { + foreach ($attachments as $i=>$info) { + if (0 === strcasecmp('application/ms-tnef', $info['type'])) { + $data = $this->decode(imap_fetchbody($self->mbox, + $mid, $info['index']), $info['encoding']); + $tnef = new TnefStreamParser($data); + $this->tnef = $tnef->getMessage(); + // No longer considered an attachment + unset($attachments[$i]); + // There should only be one of these + break; + } + } + } + $vars = $mailinfo; $vars['name'] = $mailinfo['name']; $vars['subject'] = $mailinfo['subject'] ? $mailinfo['subject'] : '[No Subject]'; @@ -604,10 +632,18 @@ class MailFetcher { $seen = false; // Fetch attachments if any. - if($ost->getConfig()->allowEmailAttachments() - && ($struct = imap_fetchstructure($this->mbox, $mid)) - && ($attachments=$this->getAttachments($struct))) { - + if($ost->getConfig()->allowEmailAttachments()) { + // Include TNEF attachments in the attachments list + if ($this->tnef) { + foreach ($this->tnef->attachments as $at) { + $attachments[] = array( + 'cid' => @$at->AttachContentId ?: false, + 'data' => $at->Data, + 'type' => @$at->AttachMimeTag ?: false, + 'name' => $at->getName(), + ); + } + } $vars['attachments'] = array(); foreach($attachments as $a ) { $file = array('name' => $a['name'], 'type' => $a['type']); diff --git a/include/class.mailparse.php b/include/class.mailparse.php index 7cbb910c6c462ffa12708433e0ede6aa79bd9d96..6883cdaf6a7560437c4ee0fcc5a00886bf111004 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -400,7 +400,6 @@ class Mail_Parse { 'data' => $at->Data, 'type' => @$at->AttachMimeTag ?: false, 'name' => $at->getName(), - 'encoding' => @$at->AttachEncoding ?: false, ); } return $files; diff --git a/include/class.ostsession.php b/include/class.ostsession.php index db51e89e771caaaff6fe9bdb1d3e2808b96e548c..beb344f9f3734f5e286e9d2e4aff0060d6406cb2 100644 --- a/include/class.ostsession.php +++ b/include/class.ostsession.php @@ -26,8 +26,12 @@ class osTicketSession { if(!$this->ttl) $this->ttl=SESSION_TTL; + // Set osTicket specific session name. session_name('OSTSESSID'); + // Forced cleanup on shutdown + register_shutdown_function('session_write_close'); + if (OsticketConfig::getDBVersion()) return session_start(); @@ -56,8 +60,6 @@ class osTicketSession { array(&$this, 'destroy'), array(&$this, 'gc') ); - //Forced cleanup. - register_shutdown_function('session_write_close'); //Start the session. session_start(); diff --git a/include/class.ticket.php b/include/class.ticket.php index 855d4650431164713b28c85ee2390e4482c7f258..df83644a8da74e58bda87435ab10701eb9adf1a2 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -2234,6 +2234,10 @@ class Ticket { # function if (isset($vars['autorespond'])) $autorespond=$vars['autorespond']; + # Apply filter-specific priority + if ($vars['priorityId']) + $form->setAnswer('priority', null, $vars['priorityId']); + // OK...just do it. $deptId=$vars['deptId']; //pre-selected Dept if any. $source=ucfirst($vars['source']); diff --git a/include/tnef_decoder.php b/include/tnef_decoder.php index f0eba4e792914621fefbbbdf4f2f1cd5f9c94e76..18e95d697c5eba8bb218ff81d5e9c903b2cedbd7 100644 --- a/include/tnef_decoder.php +++ b/include/tnef_decoder.php @@ -110,10 +110,13 @@ class TnefStreamReader implements Iterator { } function check($block) { - $sum = 0; - for ($i=0, $k=strlen($block['data']); $i < $k; $i++) - $sum += ord($block['data'][$i]); - if ($block['checksum'] != ($sum % 65536)) + $sum = 0; $bytes = strlen($block['data']); $bs = 1024; + for ($i=0; $i < $bytes; $i+=$bs) { + $b = unpack('C*', substr($block['data'], $i, min($bs, $bytes-$i))); + $sum += array_sum($b); + $sum = $sum % 65536; + } + if ($block['checksum'] != $sum) throw new TnefException('Corrupted block. Invalid checksum'); }