From 79f3c6b0b0e74018f272c3e085ac17d15b3bd712 Mon Sep 17 00:00:00 2001 From: Jared Hancock <jared@osticket.com> Date: Mon, 26 May 2014 13:23:24 -0500 Subject: [PATCH] mail: Add signals to interact with mail processing Signals added: * mail.received Called after the mail is received into the system and before it is processed by the mail system. This signal is useful to do header injection. Raw message/rfc822 included in 'raw' key in the info * mail.decoded Called after the initial decoding of the message. The header and bodies are broken out, however, Unicode decoded may not have been performed yet. This signal is useful to affect the interpretation of the message, such as TNEF processing, etc. * mail.processed Called after all internal processing is completed. All Unicode processing is complete, bounce detection and other mechanisms have completed. This signal is useful to do things like attachment scanning or content filtering. --- include/api.tickets.php | 2 +- include/class.mailfetch.php | 15 ++++++++++++++- include/class.mailparse.php | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/api.tickets.php b/include/api.tickets.php index 9fbbd8536..fcb55d81b 100644 --- a/include/api.tickets.php +++ b/include/api.tickets.php @@ -40,7 +40,7 @@ class TicketApiController extends ApiController { $supported = array_merge($supported, array('header', 'mid', 'emailId', 'to-email-id', 'ticketId', 'reply-to', 'reply-to-name', 'in-reply-to', 'references', 'thread-type', - 'flags' => array('bounce', 'auto-reply'), + 'flags' => array('bounce', 'auto-reply', 'spam', 'viral'), 'recipients' => array('*' => array('name', 'email', 'source')) )); diff --git a/include/class.mailfetch.php b/include/class.mailfetch.php index 3ab0d891a..7bddd9ef0 100644 --- a/include/class.mailfetch.php +++ b/include/class.mailfetch.php @@ -269,13 +269,22 @@ class MailFetcher { if(!($headerinfo=imap_headerinfo($this->mbox, $mid)) || !$headerinfo->from) return null; + $raw_header = $this->getHeader($mid); + $info = array( + 'raw_header' => &$raw_header, + 'headers' => $headerinfo, + 'decoder' => $this, + 'type' => $this->getMimeType($headerinfo), + ); + Signal::send('mail.decoded', $this, $info); + $sender=$headerinfo->from[0]; //Just what we need... $header=array('name' => $this->mime_decode(@$sender->personal), 'email' => trim(strtolower($sender->mailbox).'@'.$sender->host), 'subject'=> $this->mime_decode(@$headerinfo->subject), 'mid' => trim(@$headerinfo->message_id), - 'header' => $this->getHeader($mid), + 'header' => $raw_header, 'in-reply-to' => $headerinfo->in_reply_to, 'references' => $headerinfo->references, ); @@ -624,6 +633,7 @@ class MailFetcher { $vars['subject'] = $mailinfo['subject'] ?: '[No Subject]'; $vars['emailId'] = $mailinfo['emailId'] ?: $this->getEmailId(); $vars['to-email-id'] = $mailinfo['emailId'] ?: 0; + $vars['flags'] = new ArrayObject(); if ($this->isBounceNotice($mid)) { // Fetch the original References and assign to 'references' @@ -694,6 +704,9 @@ class MailFetcher { } } + // Allow signal handlers to interact with the message decoding + Signal::send('mail.processed', $this, $vars); + $seen = false; if (($thread = ThreadEntry::lookupByEmailHeaders($vars, $seen)) && ($message = $thread->postEmail($vars))) { diff --git a/include/class.mailparse.php b/include/class.mailparse.php index d498a77f7..91d0f5700 100644 --- a/include/class.mailparse.php +++ b/include/class.mailparse.php @@ -58,6 +58,9 @@ class Mail_Parse { 'decode_headers'=> $this->decode_headers, 'decode_bodies' => $this->decode_bodies); + $info = array('raw' => &$this->mime_message); + Signal::send('mail.received', $this, $info); + $this->splitBodyHeader(); $decoder = new Mail_mimeDecode($this->mime_message); @@ -66,6 +69,18 @@ class Mail_Parse { if (PEAR::isError($this->struct)) return false; + $info = array( + 'raw_header' => &$this->header, + 'headers' => &$this->struct->headers, + 'body' => &$this->struct->parts, + 'type' => $this->struct->ctype_primary.'/'.$this->struct->ctype_secondary, + 'mail' => $this->struct, + 'decoder' => $decoder, + ); + + // Allow signal handlers to interact with the processing + Signal::send('mail.decoded', $decoder, $info); + // Handle wrapped emails when forwarded if ($this->struct && $this->struct->parts) { $outer = $this->struct; @@ -533,6 +548,7 @@ class EmailDataParser { $data['header'] = $parser->getHeader(); $data['mid'] = $parser->getMessageId(); $data['priorityId'] = $parser->getPriority(); + $data['flags'] = new ArrayObject(); //FROM address: who sent the email. if(($fromlist = $parser->getFromAddressList())) { -- GitLab