From 8bd4531b04d21e516ce6ca8bd93b1fd9539a63b6 Mon Sep 17 00:00:00 2001 From: Janos SUTO Date: Sun, 23 Dec 2018 20:00:22 +0000 Subject: [PATCH] gui: Fix journal handling Signed-off-by: Janos SUTO --- webui/controller/message/bulkrestore.php | 3 +- webui/controller/message/restore.php | 3 +- webui/model/message/restore.php | 4 +- webui/model/search/message.php | 87 ++---------------------- webui/system/helper/mime.php | 51 +++++++++++++- 5 files changed, 62 insertions(+), 86 deletions(-) diff --git a/webui/controller/message/bulkrestore.php b/webui/controller/message/bulkrestore.php index 3adb8c8c..60a97589 100644 --- a/webui/controller/message/bulkrestore.php +++ b/webui/controller/message/bulkrestore.php @@ -1,5 +1,6 @@ model_search_message->get_piler_id_by_id($id); $msg = $this->model_search_message->get_raw_message($piler_id); - $this->model_search_message->remove_journal($msg); + Piler_Mime_Decode::removeJournal($msg); if(RESTORE_OVER_IMAP == 1 && Registry::get('auditor_user') == 0) { if($imap_ok) { diff --git a/webui/controller/message/restore.php b/webui/controller/message/restore.php index 4bcdc977..74b9f1ef 100644 --- a/webui/controller/message/restore.php +++ b/webui/controller/message/restore.php @@ -1,5 +1,6 @@ model_search_message->get_raw_message($this->data['piler_id']); - $this->model_search_message->remove_journal($msg); + Piler_Mime_Decode::removeJournal($msg); if(RESTORE_OVER_IMAP == 1) { if($this->model_mail_mail->connect_imap()) { diff --git a/webui/model/message/restore.php b/webui/model/message/restore.php index 63315d9f..86a77c93 100644 --- a/webui/model/message/restore.php +++ b/webui/model/message/restore.php @@ -1,5 +1,7 @@ model_search_message->get_raw_message($piler_id); - $this->model_search_message->remove_journal($rawemail); + Piler_Mime_Decode::removeJournal($rawemail); $zip->addFromString($filename . ".eml", $rawemail); diff --git a/webui/model/search/message.php b/webui/model/search/message.php index 0cc526bc..8b7944a6 100644 --- a/webui/model/search/message.php +++ b/webui/model/search/message.php @@ -105,12 +105,13 @@ class ModelSearchMessage extends Model { public function get_message_headers($id = '') { $headers = ''; + $has_journal = 0; $msg = $this->get_raw_message($id); - Piler_Mime_Decode::splitMessageRaw($msg, $headers, $body); + Piler_Mime_Decode::splitMessageRaw($msg, $headers, $journal, $body); - $has_journal = $this->remove_journal($headers); + if($journal) { $has_journal = 1; } $headers = Piler_Mime_Decode::escape_lt_gt_symbols($headers); @@ -119,87 +120,11 @@ class ModelSearchMessage extends Model { public function get_message_journal($id = '') { - $data = '< >'; - $boundary = ''; - $msg = $this->get_raw_message($id); - $hdr = substr($msg, 0, 8192); + Piler_Mime_Decode::splitMessageRaw($msg, $headers, $journal, $body); - $s = preg_split("/\n/", $hdr); - while(list($k, $v) = each($s)) { - if(preg_match("/boundary\s{0,}=\s{0,}\"{0,}([\w\_\-\@\.]+)\"{0,}/i", $v, $m)) { - if(isset($m[1])) { $boundary = $m[1]; break; } - } - } - - - $p = strstr($msg, "\nX-MS-Journal-Report:"); - $msg = ''; - - if($p) { - - $s = preg_split("/\n/", $p); - - $i=0; $j=0; $data = ''; - - while(list($k, $v) = each($s)) { - if(strstr($v, $boundary)) { $i++; } - if($i > 0 && preg_match("/^\s{1,}$/", $v)) { $j++; } - - if($j == 1) { - $data .= "$v\n"; - } - - if($i >= 2) { break; } - } - - $p = ''; - - $data = Piler_Mime_Decode::escape_lt_gt_symbols($data); - } - - return $data; - } - - - public function remove_journal(&$msg = '') { - $p = $q = ''; - $boundary = ''; - $has_journal = 0; - - $hdr = substr($msg, 0, 4096); - - $s = preg_split("/\n/", $hdr); - while(list($k, $v) = each($s)) { - if(preg_match("/boundary\s{0,}=\s{0,}\"{0,}([\w\_\-\@\.]+)\"{0,}/i", $v, $m)) { - if(isset($m[1])) { $boundary = $m[1]; break; } - } - } - - $p = strstr($msg, "\nX-MS-Journal-Report:"); - - if($p) { - $has_journal = 1; - - $msg = ''; - $q = strstr($p, "Received: from"); - if($q) { - $p = ''; - $msg = $q; - $q = ''; - } - else { - $msg = $p; - $p = ''; - } - - if($boundary) { - $msg = substr($msg, 0, strlen($msg) - strlen($boundary) - 6); - } - } - - return $has_journal; + return Piler_Mime_Decode::escape_lt_gt_symbols($journal); } @@ -212,7 +137,7 @@ class ModelSearchMessage extends Model { $msg = $this->get_raw_message($id); - $has_journal = $this->remove_journal($msg); + $has_journal = Piler_Mime_Decode::removeJournal($msg); Piler_Mime_Decode::splitMessage($msg, $headers, $body); diff --git a/webui/system/helper/mime.php b/webui/system/helper/mime.php index 65eb750c..fab49373 100644 --- a/webui/system/helper/mime.php +++ b/webui/system/helper/mime.php @@ -87,12 +87,12 @@ class Piler_Mime_Decode { public static function splitMessage($message, &$headers, &$body, $EOL = "\n") { - self::splitMessageRaw($message, $headers, $body); + self::splitMessageRaw($message, $headers, $journal, $body); $headers = self::splitHeaders($headers); } - public static function splitMessageRaw($message, &$headers, &$body, $EOL = "\n") { + public static function splitMessageRaw($message, &$headers, &$journal, &$body, $EOL = "\n") { $headers = []; $body = ''; @@ -102,6 +102,27 @@ class Piler_Mime_Decode { if(strpos($message, $EOL . $EOL)) { list($headers, $body) = explode($EOL . $EOL, $message, 2); + + // Check if the header is actually a journal header + $headers_array = self::splitHeaders($headers); + + if(isset($headers_array['x-ms-journal-report']) && isset($headers_array['content-type']['boundary'])) { + $boundary = $headers_array['content-type']['boundary']; + $parts = self::splitMime($body, $boundary); + + if(count($parts) >= 2) { + self::splitMessageRaw($parts[0], $s, $j, $journal); + + $i = strpos($parts[1], "\n"); + $msg = substr($parts[1], $i); + + $i = 0; + while(ctype_space($msg[$i])) { $i++; } + if($i > 0) { $msg = substr($msg, $i); } + + self::splitMessageRaw($msg, $headers, $j, $body); + } + } } else { $headers = $message; @@ -109,6 +130,32 @@ class Piler_Mime_Decode { } + public static function removeJournal(&$message, $EOL = '\n') { + $has_journal = 0; + + $s = self::remove_LF($message); + if(strpos($s, $EOL . $EOL)) { + list($headers, $body) = explode($EOL . $EOL, $s, 2); + if(strstr($headers, "\nX-MS-Journal-Report:")) { + return $has_journal; + } + } + + $p = strstr($message, "\nX-MS-Journal-Report:"); + if($p) { + $q = stristr($p, "message/rfc822"); + if($q) { + $has_journal = 1; + $i = strlen("message/rfc822"); + while(ctype_space($q[$i])) { $i++; } + if($i > 0) { $message = substr($q, $i); } + } + } + + return $has_journal; + } + + public static function splitHeaders($headers) { $headers = self::headersToArray($headers);