diff --git a/webui/controller/message/bulkrestore.php b/webui/controller/message/bulkrestore.php index 589c6733..6a24540f 100644 --- a/webui/controller/message/bulkrestore.php +++ b/webui/controller/message/bulkrestore.php @@ -58,8 +58,6 @@ class ControllerMessageBulkrestore extends Controller { } - $this->model_search_message->connect_to_pilergetd(); - foreach($idlist as $id) { AUDIT(ACTION_RESTORE_MESSAGE, '', '', $id, ''); @@ -110,8 +108,6 @@ class ControllerMessageBulkrestore extends Controller { } } - $this->model_search_message->disconnect_from_pilergetd(); - if(RESTORE_OVER_IMAP == 1) { $this->model_mail_mail->disconnect_imap(); } diff --git a/webui/controller/message/download.php b/webui/controller/message/download.php index 372147b5..c823a5f8 100644 --- a/webui/controller/message/download.php +++ b/webui/controller/message/download.php @@ -49,9 +49,7 @@ class ControllerMessageDownload extends Controller { header("Content-Disposition: attachment; filename=" . $filename . ".eml"); header("Content-Transfer-Encoding: binary\n"); - $this->model_search_message->connect_to_pilergetd(); $msg = $this->model_search_message->get_raw_message($this->data['piler_id']); - $this->model_search_message->disconnect_from_pilergetd(); $this->model_search_message->remove_journal($msg); print $msg; diff --git a/webui/controller/message/restore.php b/webui/controller/message/restore.php index ddfbd4cc..d33e2db6 100644 --- a/webui/controller/message/restore.php +++ b/webui/controller/message/restore.php @@ -70,9 +70,7 @@ class ControllerMessageRestore extends Controller { $this->data['piler_id'] = $this->model_search_message->get_piler_id_by_id($this->data['id']); - $this->model_search_message->connect_to_pilergetd(); $msg = $this->model_search_message->get_raw_message($this->data['piler_id']); - $this->model_search_message->disconnect_from_pilergetd(); $this->model_search_message->remove_journal($msg); diff --git a/webui/model/message/restore.php b/webui/model/message/restore.php index e718b24f..63315d9f 100644 --- a/webui/model/message/restore.php +++ b/webui/model/message/restore.php @@ -14,8 +14,6 @@ class ModelMessageRestore extends Model { if($zip->open($zipname, ZIPARCHIVE::CREATE) != true) { exit("cannot open <$zipname>\n"); } - $this->model_search_message->connect_to_pilergetd(); - foreach($idlist as $id) { $i++; @@ -35,8 +33,6 @@ class ModelMessageRestore extends Model { AUDIT(ACTION_DOWNLOAD_MESSAGE, '', '', $id, ''); } - $this->model_search_message->disconnect_from_pilergetd(); - $zip->close(); diff --git a/webui/model/search/message.php b/webui/model/search/message.php index 77ce3142..8c303096 100644 --- a/webui/model/search/message.php +++ b/webui/model/search/message.php @@ -10,6 +10,25 @@ class ModelSearchMessage extends Model { ); + public function get_boundary($line='') { + $parts = explode(";", $line); + + for($i=0; $i 0) { return $a[2]; } - - return 0; - } - - - public function read_file($sd, $f = '', $size = 0) { - global $start; - $s = ''; - $len = 0; - - if($size <= 0) { return $s; } - - fputs($sd, "RETR $f\r\n"); - - while(!safe_feof($sd, $start) && (microtime(true) - $start) < PILERGETD_TIMEOUT) { - $s .= fread($sd, PILERGETD_READ_LENGTH); - $len += PILERGETD_READ_LENGTH; - if($len >= $size) break; - } - - return $s; - } - - - public function connect_to_pilergetd() { - if(PILERGETD_HOST) { - $sd = fsockopen(PILERGETD_HOST, PILERGETD_PORT); - if(!$sd) { return FALSE; } - - $l = fgets($sd, 4096); - - if(substr(PILERGETD_HOST, 0, 6) == 'ssl://') { - fputs($sd, "AUTH " . PILERGETD_PASSWORD . "\r\n"); - $l = fgets($sd, 4096); - } - - Registry::set('sd', $sd); - } - } - - - public function disconnect_from_pilergetd() { - if(PILERGETD_HOST) { - $sd = Registry::get('sd'); - - fputs($sd, "QUIT\r\n"); - - fclose($sd); - } - } - - public function get_raw_message($id = '') { $s = ''; if($id == '' || !preg_match("/^([0-9a-f]+)$/", $id)) { return $s; } - if(PILERGETD_HOST) { - - $sd = Registry::get('sd'); - - fputs($sd, "MESSAGE $id\r\n"); - - $l = fgets($sd, 8192); - $message = explode(" ", rtrim($l)); - - while(list($k, $v) = each($message)) { - if($k == 0) { - $size = $this->get_file_size($sd, $v); - - $s = $this->read_file($sd, $v, $size); - $s = gzuncompress($s); - } - else { - $size = $this->get_file_size($sd, $v); - $a = $this->read_file($sd, $v, $size); - $a = gzuncompress($a); - - $repl = "ATTACHMENT_POINTER_" . $id . ".a" . $k . "_XXX_PILER"; - - $s = preg_replace("/$repl/", $a, $s); - - $a = ''; - } - } + $handle = popen(DECRYPT_BINARY . " $id", "r"); + while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))) { + $s .= $buf; } - else { - $handle = popen(DECRYPT_BINARY . " $id", "r"); + pclose($handle); + + if($s == '') { + $handle = popen(DECRYPT_BINARY . " $id nocrypt", "r"); while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))) { $s .= $buf; } pclose($handle); - - if($s == '') { - $handle = popen(DECRYPT_BINARY . " $id nocrypt", "r"); - while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))) { - $s .= $buf; - } - pclose($handle); - } } - if(Registry::get('auditor_user') == 0 && HEADER_LINE_TO_HIDE) { $s = preg_replace("/" . HEADER_LINE_TO_HIDE . ".{1,}(\n(\ |\t){1,}.{1,}){0,}" . "\n/i", "", $s); } @@ -159,26 +88,11 @@ class ModelSearchMessage extends Model { if($piler_id == '' || $attachment_id == '' || !preg_match("/^([0-9a-f]+)$/", $piler_id) || !preg_match("/^([0-9m]+)$/", $attachment_id)) { return $data; } - if(PILERGETD_HOST) { - $sd = fsockopen(PILERGETD_HOST, PILERGETD_PORT); - if(!$sd) { return $data; } - - $l = fgets($sd, 4096); - - $size = $this->get_file_size($sd, $piler_id . ".a" . $attachment_id); - - $data = $this->read_file($sd, $piler_id . ".a" . $attachment_id, $size); - $data = gzuncompress($data); - - fclose($sd); - } - else { - $handle = popen(DECRYPT_ATTACHMENT_BINARY . " $piler_id $attachment_id", "r"); - while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))){ - $data .= $buf; - } - pclose($handle); + $handle = popen(DECRYPT_ATTACHMENT_BINARY . " $piler_id $attachment_id", "r"); + while(($buf = fread($handle, DECRYPT_BUFFER_LENGTH))){ + $data .= $buf; } + pclose($handle); /* check if it's a base64 encoded stuff */ @@ -196,9 +110,7 @@ class ModelSearchMessage extends Model { public function get_message_headers($id = '') { $headers = ''; - $this->connect_to_pilergetd(); $msg = $this->get_raw_message($id); - $this->disconnect_from_pilergetd(); Zend_Mime_Decode::splitMessageRaw($msg, $headers, $body); @@ -208,8 +120,7 @@ class ModelSearchMessage extends Model { $headers = preg_replace("/" . HEADER_LINE_TO_HIDE . ".{1,}(\n(\ |\t){1,}.{1,}){0,}" . "\n/i", "", $headers); } - $headers = preg_replace("/\/", ">", $headers); + $headers = $this->escape_lt_gt_symbols($headers); return array('headers' => $headers, 'has_journal' => $has_journal); } @@ -219,9 +130,7 @@ class ModelSearchMessage extends Model { $data = '< >'; $boundary = ''; - $this->connect_to_pilergetd(); $msg = $this->get_raw_message($id); - $this->disconnect_from_pilergetd(); $hdr = substr($msg, 0, 8192); @@ -255,9 +164,7 @@ class ModelSearchMessage extends Model { $p = ''; - $data = preg_replace("/\/", ">", $data); - + $data = $this->escape_lt_gt_symbols($data); } return $data; @@ -305,184 +212,112 @@ class ModelSearchMessage extends Model { public function extract_message($id = '', $terms = '') { - $header = ""; - $body_chunk = ""; - $is_header = 1; - $state = "UNDEF"; - $b = array(); - $boundary = array(); - $text_plain = 1; - $text_html = 0; - $charset = ""; - $qp = $base64 = 0; - $has_text_plain = 0; - $rfc822 = 0; - $_1st_header = 1; - $verification = 1; - - $from = $to = $subject = $date = $text_message = $html_message = ""; - - $this->connect_to_pilergetd(); $msg = $this->get_raw_message($id); if(ENABLE_ON_THE_FLY_VERIFICATION == 0) { $verification = $this->verify_message($id, $msg); } - $this->disconnect_from_pilergetd(); - $has_journal = $this->remove_journal($msg); - $a = explode("\n", $msg); $msg = ""; + Zend_Mime_Decode::splitMessage($msg, $headers, $body); + $boundary = $this->get_boundary($headers['content-type']); - while(list($k, $l) = each($a)){ - $l .= "\n"; + if(is_array($headers['date'])) { $headers['date'] = $headers['date'][0]; } - if(($l[0] == "\r" && $l[1] == "\n" && $is_header == 1) || ($l[0] == "\n" && $is_header == 1) ){ - $is_header = $_1st_header = 0; + $from = "From: " . $this->escape_lt_gt_symbols($headers['from']); + $to = "To: " . $this->escape_lt_gt_symbols($headers['to']); + $subject = "Subject: " . $headers['subject']; + $date = "Date: " . $headers['date']; - if($rfc822 == 1) { $rfc822 = 0; $is_header = 1; } + $message = array( + 'text' => '', + 'html' => '' + ); - } + $mime_parts = Zend_Mime_Decode::splitMessageStruct($body, $boundary); - if($is_header == 1 && preg_match("/^Content-Type:/i", $l)) $state = "CONTENT_TYPE"; - if($is_header == 1 && preg_match("/^Content-Transfer-Encoding:/i", $l)) $state = "CONTENT_TRANSFER_ENCODING"; + for($i=0; $i '', + 'encoding' => '' + ); - if($state == "CONTENT_TYPE"){ + if(isset($mime_parts[$i]['header']['content-type'])) + $mime['content-type'] = Zend_Mime_Decode::splitContentType($mime_parts[$i]['header']['content-type']); - $x = stristr($l, "boundary"); - if($x){ + if(isset($mime_parts[$i]['header']['content-transfer-encoding'])) + $mime['encoding'] = $mime_parts[$i]['header']['content-transfer-encoding']; - $s1 = explode(";", $x); - $x = $s1[0]; + if($mime['encoding'] == 'quoted-printable') + $mime_parts[$i]['body'] = Zend_Mime_Decode::decodeQuotedPrintable($mime_parts[$i]['body']); - $x = preg_replace("/boundary\s{0,}=\s{0,}/i", "boundary=", $x); - //$x = preg_replace("/boundary= /i", "boundary=", $x); + if($mime['encoding'] == 'base64') + $mime_parts[$i]['body'] = base64_decode($mime_parts[$i]['body']); - $x = preg_replace("/\"\;{0,1}/", "", $x); - $x = preg_replace("/\'/", "", $x); + if(strtolower($mime['content-type']['charset']) != 'utf-8') + $mime_parts[$i]['body'] = iconv($mime['content-type']['charset'], 'utf-8' . '//IGNORE', $mime_parts[$i]['body']); - $b = explode("boundary=", $x); + // some text/plain fixes - $__boundary = rtrim($b[count($b)-1]); + if(strtolower($mime['content-type']['type']) == 'text/plain') { - if($__boundary) { array_push($boundary, $__boundary); } - - } - - if(preg_match("/charset/i", $l)){ - $types = explode(";", $l); - foreach ($types as $type){ - if(preg_match("/charset/i", $type)){ - $type = preg_replace("/[\"\'\ ]/", "", $type); - - $x = explode("=", $type); - $charset = rtrim(strtoupper($x[1])); - - if(isset($this->encoding_aliases[$charset])) { $charset = $this->encoding_aliases[$charset]; } - - } - } - } - - if(strstr($l, "message/rfc822")) { $rfc822 = 1; } - - if(stristr($l, "text/plain")){ $text_plain = 1; $text_html = 0; $has_text_plain = 1; } - if(stristr($l, "text/html")){ $text_html = 1; $text_plain = 0; } - } - - if($state == "CONTENT_TRANSFER_ENCODING"){ - if(preg_match("/quoted-printable/i", $l)){ $qp = 1; } - if(preg_match("/base64/i", $l)){ $base64 = 1; } - } - - - if($is_header == 1){ - if($l[0] != " " && $l[0] != "\t"){ $state = "UNDEF"; } - if(preg_match("/^From:/i", $l)){ $state = "FROM"; } - if(preg_match("/^To:/i", $l) || preg_match("/^Cc:/i", $l)){ $state = "TO"; } - if(preg_match("/^Date:/i", $l)){ $state = "DATE"; } - if(preg_match("/^Subject:/i", $l)){ $state = "SUBJECT"; } - if(preg_match("/^Content-Type:/i", $l)){ $state = "CONTENT_TYPE"; } - if(preg_match("/^Content-Disposition:/i", $l)){ $state = "CONTENT_DISPOSITION"; } - - $l = preg_replace("//", ">", $l); - - if($_1st_header == 1) { - if($state == "FROM"){ $from .= preg_replace("/\r|\n/", "", $l); } - if($state == "TO"){ $to .= preg_replace("/\r|\n/", "", $l); } - if($state == "SUBJECT"){ $subject .= preg_replace("/\r|\n/", "", $l); } - if($state == "DATE"){ $date .= preg_replace("/\r|\n/", "", $l); } - } - } - else { - - if($this->check_boundary($boundary, $l) == 1){ - - if($text_plain == 1 || $has_text_plain == 0) { - $text_message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html); - } - - if($text_html == 1) { - $html_message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html); - } - - $text_plain = $text_html = $qp = $base64 = 0; - - $charset = $body_chunk = ""; - - $is_header = 1; - - continue; - } - - else if(($l[0] == "\r" && $l[1] == "\n") || $l[0] == "\n"){ - $state = "BODY"; - $body_chunk .= $l; - } - - else if($state == "BODY"){ - if($text_plain == 1 || $text_html == 1){ $body_chunk .= $l; } - } - - } + $mime_parts[$i]['body'] = $this->escape_lt_gt_symbols($mime_parts[$i]['body']); + $mime_parts[$i]['body'] = preg_replace("/\n/", "
\n", $mime_parts[$i]['body']); + $mime_parts[$i]['body'] = "\n" . $this->print_nicely($mime_parts[$i]['body']); + $message['text'] .= $mime_parts[$i]['body']; } - if($body_chunk) { - if($text_plain == 1 || $has_text_plain == 0) { - $text_message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html); + if(strtolower($mime['content-type']['type']) == 'text/html') { + + $mime_parts[$i]['body'] = preg_replace("/\/", "", $mime_parts[$i]['body']); + + if(ENABLE_REMOTE_IMAGES == 0) { + $mime_parts[$i]['body'] = preg_replace("/style([\s]{0,}=[\s]{0,})\"([^\"]+)/", "style=\"xxxx", $mime_parts[$i]['body']); + $mime_parts[$i]['body'] = preg_replace("/style([\s]{0,}=[\s]{0,})\'([^\']+)/", "style='xxxx", $mime_parts[$i]['body']); + + $mime_parts[$i]['body'] = preg_replace("/\]+)\>/i", "", $mime_parts[$i]['body']); + } + + $mime_parts[$i]['body'] = preg_replace("/\/i", "", $mime_parts[$i]['body']); + + $mime_parts[$i]['body'] = preg_replace("/\/i", "", $mime_parts[$i]['body']); + + + $message['html'] .= $mime_parts[$i]['body']; } - if($text_html == 1) { - $html_message .= $this->flush_body_chunk($body_chunk, $charset, $qp, $base64, $text_plain, $text_html); - } } - - if(strlen($html_message) > 20) { - $message = $this->highlight_search_terms($html_message, $terms, 1); - } else { - $message = $this->highlight_search_terms($text_message, $terms); - } - - return array('from' => $this->decode_my_str($from), - 'to' => $this->decode_my_str($to), - 'subject' => $this->highlight_search_terms($this->decode_my_str($subject), $terms), - 'date' => $this->decode_my_str($date), - 'message' => $message, + return array('from' => $from, + 'to' => $to, + 'subject' => $this->highlight_search_terms($subject, $terms), + 'date' => $date, + 'message' => $message['html'] ? $message['html'] : $message['text'], 'has_journal' => $has_journal, 'verification' => $verification ); } + private function escape_lt_gt_symbols($s = '') { + $s = preg_replace("//", ">", $s); + + return $s; + } + + private function highlight_search_terms($s = '', $terms = '', $html = 0) { $fields = array("from:", "to:", "subject:", "body:"); - $terms = preg_replace("/[^\w\s]/", "", $terms); + $terms = preg_replace("/(\,|\s){1,}/", " ", $terms); $a = explode(" ", $terms); $terms = array(); @@ -496,7 +331,6 @@ class ModelSearchMessage extends Model { if(count($terms) <= 0) { return $s; } - if($html == 0) { while(list($k, $v) = each($terms)) { $s = preg_replace("/$v/i", "$v", $s); @@ -505,7 +339,6 @@ class ModelSearchMessage extends Model { return $s; } - $tokens = preg_split("/\qp_decode($chunk); - } - - if($base64 == 1){ - $chunk = base64_decode($chunk); - } - - if($charset && !preg_match("/utf-8/i", $charset)){ - $s = @iconv($charset, 'utf-8' . '//IGNORE', $chunk); - if($s) { $chunk = $s; $s = ''; } - } - - if($text_plain == 1){ - $chunk = preg_replace("//", ">", $chunk); - - $chunk = preg_replace("/\n/", "
\n", $chunk); - $chunk = "\n" . $this->print_nicely($chunk); - } - - if($text_html == 1){ - - $h = preg_split("/\