1<?php
2/*
3	FusionPBX
4	Version: MPL 1.1
5
6	The contents of this file are subject to the Mozilla Public License Version
7	1.1 (the "License"); you may not use this file except in compliance with
8	the License. You may obtain a copy of the License at
9	http://www.mozilla.org/MPL/
10
11	Software distributed under the License is distributed on an "AS IS" basis,
12	WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13	for the specific language governing rights and limitations under the
14	License.
15
16	The Original Code is FusionPBX
17
18	The Initial Developer of the Original Code is
19	Mark J Crane <markjcrane@fusionpbx.com>
20	Portions created by the Initial Developer are Copyright (C) 2008-2018
21	the Initial Developer. All Rights Reserved.
22
23	Contributor(s):
24	Mark J Crane <markjcrane@fusionpbx.com>
25	Luis Daniel Lucio Quiroz <dlucio@okay.com.mx>
26*/
27
28//set the include path
29	if (defined('STDIN')) {
30		$document_root = str_replace("\\", "/", $_SERVER["PHP_SELF"]);
31		preg_match("/^(.*)\/secure\/.*$/", $document_root, $matches);
32		$document_root = $matches[1];
33		set_include_path($document_root);
34		$_SERVER["DOCUMENT_ROOT"] = $document_root;
35	}
36
37//includes
38	if (!defined('STDIN')) { include "root.php"; }
39	require_once "resources/require.php";
40
41//define a function to remove html tags
42	function remove_tags($string) {
43		//remove HTML tags
44		$string = preg_replace ('/<[^>]*>/', ' ', $string);
45
46		//remove control characters
47		$string = str_replace("\r", '', $string);    // --- replace with empty space
48		$string = str_replace("\n", ' ', $string);   // --- replace with space
49		$string = str_replace("\t", ' ', $string);   // --- replace with space
50
51		//remove multiple spaces
52		$string = trim(preg_replace('/ {2,}/', ' ', $string));
53		return $string;
54	}
55
56//set init settings
57	ini_set('max_execution_time',1800); //30 minutes
58	ini_set('memory_limit', '512M');
59
60//listen for standard input
61	if ($msg == '') {
62		$fd = fopen("php://stdin", "r");
63		$msg = file_get_contents ("php://stdin");
64		fclose($fd);
65	}
66
67//save output to
68	$fp = fopen(sys_get_temp_dir()."/mailer-app.log", "w");
69
70//prepare the output buffers
71	ob_end_clean();
72	ob_start();
73
74//testing show the raw email
75	//echo "Message: \n".$msg."\n";
76
77//includes
78	require('resources/pop3/mime_parser.php');
79	require('resources/pop3/rfc822_addresses.php');
80	if (file_exists($_SERVER["PROJECT_ROOT"]."/app/emails/email_transcription.php")) {
81		require_once($_SERVER["PROJECT_ROOT"]."/app/emails/email_transcription.php");
82	}
83
84//parse the email message
85	$mime=new mime_parser_class;
86	$mime->decode_bodies = 1;
87	$parameters=array(
88		//'File'=>$message_file,
89
90		// Read a message from a string instead of a file
91		'Data'=>$msg,
92
93		// Save the message body parts to a directory
94		// 'SaveBody'=>'/tmp',
95
96		// Do not retrieve or save message body parts
97		//   'SkipBody'=>1,
98	);
99	$success=$mime->Decode($parameters, $decoded);
100
101	if(!$success) {
102		echo "MIME message decoding error: ".HtmlSpecialChars($mime->error)."\n";
103	}
104	else {
105		//get the headers
106			//print_r($decoded[0]);
107			$headers = json_decode($decoded[0]["Headers"]["x-headers:"], true);
108			$subject = $decoded[0]["Headers"]["subject:"];
109			$from = $decoded[0]["Headers"]["from:"];
110			$reply_to = $decoded[0]["Headers"]["reply-to:"];
111			$to = $decoded[0]["Headers"]["to:"];
112			$date = $decoded[0]["Headers"]["date:"];
113
114		//get the body
115			$body = ''; //$parts_array["Parts"][0]["Headers"]["content-type:"];
116
117		//get the body
118			$body = '';
119			$content_type = $decoded[0]['Headers']['content-type:'];
120			if (substr($content_type, 0, 15) == "multipart/mixed" || substr($content_type, 0, 21) == "multipart/alternative") {
121				foreach($decoded[0]["Parts"] as $row) {
122					$body_content_type = $row["Headers"]["content-type:"];
123					if (substr($body_content_type, 0, 9) == "text/html") { $body = $row["Body"]; }
124					if (substr($body_content_type, 0, 10) == "text/plain") { $body_plain = $row["Body"];  $body = $body_plain; }
125				}
126			}
127			else {
128				$content_type_array = explode(";", $content_type);
129				$body = $decoded[0]["Body"];
130				//if ($content_type_array[0] == "text/html" || $content_type_array[0] == "text/plain") {
131				//	$body = $row["Body"];
132				//}
133			}
134	}
135
136//prepare smtp server settings
137	// load default smtp settings
138	$smtp['host'] 		= (strlen($_SESSION['email']['smtp_host']['text'])?$_SESSION['email']['smtp_host']['text']:'127.0.0.1');
139	if (isset($_SESSION['email']['smtp_port'])) {
140		$smtp['port'] = (int)$_SESSION['email']['smtp_port']['numeric'];
141	} else {
142		$smtp['port'] = 0;
143	}
144	$smtp['secure'] 	= $_SESSION['email']['smtp_secure']['text'];
145	$smtp['auth'] 		= $_SESSION['email']['smtp_auth']['text'];
146	$smtp['username'] 	= $_SESSION['email']['smtp_username']['text'];
147	$smtp['password'] 	= $_SESSION['email']['smtp_password']['text'];
148	$smtp['from'] 		= $_SESSION['email']['smtp_from']['text'];
149	$smtp['from_name'] 	= $_SESSION['email']['smtp_from_name']['text'];
150
151	if (isset($_SESSION['voicemail']['smtp_from']) && strlen($_SESSION['voicemail']['smtp_from']['text']) > 0) {
152		$smtp['from'] = $_SESSION['voicemail']['smtp_from']['text'];
153	}
154	if (isset($_SESSION['voicemail']['smtp_from_name']) && strlen($_SESSION['voicemail']['smtp_from_name']['text']) > 0) {
155		$smtp['from_name'] = $_SESSION['voicemail']['smtp_from_name']['text'];
156	}
157
158	// overwrite with domain-specific smtp server settings, if any
159	if ($headers["X-FusionPBX-Domain-UUID"] != '') {
160		$sql = "select domain_setting_subcategory, domain_setting_value ";
161		$sql .= "from v_domain_settings ";
162		$sql .= "where domain_uuid = '".$headers["X-FusionPBX-Domain-UUID"]."' ";
163		$sql .= "and (domain_setting_category = 'email' or domain_setting_category = 'voicemail') ";
164		$sql .= "and domain_setting_name = 'text' ";
165		$sql .= "and domain_setting_enabled = 'true' ";
166		$prep_statement = $db->prepare($sql);
167		if ($prep_statement) {
168			$prep_statement->execute();
169			$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
170			foreach ($result as $row) {
171				if ($row['domain_setting_value'] != '') {
172					$smtp[str_replace('smtp_','',$row["domain_setting_subcategory"])] = $row['domain_setting_value'];
173				}
174			}
175		}
176		unset($sql, $prep_statement);
177	}
178	// value adjustments
179	$smtp['auth'] 		= ($smtp['auth'] == "true") ? true : false;
180	$smtp['password'] 	= ($smtp['password'] != '') ? $smtp['password'] : null;
181	$smtp['secure'] 	= ($smtp['secure'] != "none") ? $smtp['secure'] : null;
182	$smtp['username'] 	= ($smtp['username'] != '') ? $smtp['username'] : null;
183
184//send the email
185	include "resources/phpmailer/class.phpmailer.php";
186	include "resources/phpmailer/class.smtp.php";
187	$mail = new PHPMailer();
188	if (isset($_SESSION['email']['method'])) {
189		switch($_SESSION['email']['method']['text']) {
190			case 'sendmail': $mail->IsSendmail(); break;
191			case 'qmail': $mail->IsQmail(); break;
192			case 'mail': $mail->IsMail(); break;
193			default: $mail->IsSMTP(); break;
194		}
195	} else $mail->IsSMTP();
196
197// optional bypass TLS certificate check e.g. for self-signed certificates
198	if (isset($_SESSION['email']['smtp_validate_certificate'])) {
199	    if ($_SESSION['email']['smtp_validate_certificate']['boolean'] == "false") {
200
201		    // this is needed to work around TLS certificate problems
202		    $mail->SMTPOptions = array(
203			    'ssl' => array(
204			    'verify_peer' => false,
205			    'verify_peer_name' => false,
206			    'allow_self_signed' => true
207			    )
208		    );
209	    }
210	}
211
212	$mail->SMTPAuth = $smtp['auth'];
213	$mail->Host = $smtp['host'];
214	if ($smtp['port']!=0) $mail->Port=$smtp['port'];
215	if ($smtp['secure'] != '') {
216		$mail->SMTPSecure = $smtp['secure'];
217	}
218	if ($smtp['auth']) {
219		$mail->Username = $smtp['username'];
220		$mail->Password = $smtp['password'];
221	}
222	$mail->SMTPDebug  = 2;
223
224//send context to the temp log
225	if (sizeof($headers)>0) {
226		foreach ($headers as $header => $value) {
227			echo $header.": ".$value."\n";
228		}
229	}
230	echo "Subject: ".$subject."\n";
231	echo "From: ".$from."\n";
232	echo "Reply-to: ".$reply_to."\n";
233	echo "To: ".$to."\n";
234	echo "Date: ".$date."\n";
235	//echo "Body: ".$body."\n";
236
237//add to, from, fromname, custom headers and subject to the email
238	$mail->From = $smtp['from'] ;
239	$mail->FromName = $smtp['from_name'];
240	if (sizeof($headers)>0) {
241		foreach ($headers as $header => $value) {
242			$mail->addCustomHeader($header.": ".$value);
243		}
244	}
245	$mail->Subject = $subject;
246
247	$to = trim($to, "<> ");
248	$to = str_replace(";", ",", $to);
249	$to_array = explode(",", $to);
250	if (count($to_array) == 0) {
251		$mail->AddAddress($to);
252	}
253	else {
254		foreach($to_array as $to_row) {
255			if (strlen($to_row) > 0) {
256				echo "Add Address: $to_row\n";
257				$mail->AddAddress(trim($to_row));
258			}
259		}
260	}
261
262//get the attachments and add to the email
263	if($success) {
264		foreach ($decoded[0][Parts] as &$parts_array) {
265			$content_type = $parts_array["Parts"][0]["Headers"]["content-type:"];
266				//image/tiff;name="testfax.tif"
267				//text/plain; charset=ISO-8859-1; format=flowed
268			$content_transfer_encoding = $parts_array["Parts"][0]["Headers"]["content-transfer-encoding:"];
269				//base64
270				//7bit
271			$content_disposition = $parts_array["Parts"][0]["Headers"]["content-disposition"];
272				//inline;filename="testfax.tif"
273			$file = $parts_array["FileName"];
274				//testfax.tif
275			$filedisposition = $parts_array["FileDisposition"];
276				//inline
277			$bodypart = $parts_array["BodyPart"];
278			$bodylength = $parts_array["BodyLength"];
279			if (strlen($file) > 0) {
280				//get the file information
281					$file_ext = pathinfo($file, PATHINFO_EXTENSION);
282					$file_name = substr($file, 0, (strlen($file) - strlen($file_ext))-1 );
283					$encoding = "base64"; //base64_decode
284
285					switch($file_ext){
286						case "wav":
287							$mime_type = "audio/x-wav";
288							break;
289						case "mp3":
290							$mime_type = "audio/x-mp3";
291							break;
292						case "pdf":
293							$mime_type = "application/pdf";
294							break;
295						case "tif":
296							$mime_type = "image/tiff";
297							break;
298						case "tiff":
299							$mime_type = "image/tiff";
300							break;
301						default:
302							$mime_type = "binary/octet-stream";
303							break;
304					}
305
306				//add an attachment
307					$mail->AddStringAttachment($parts_array["Body"],$file,$encoding,$mime_type);
308					if (function_exists(get_transcription)) {
309						$attachments_array = $mail->GetAttachments();
310						$transcription = get_transcription($attachments_array[0]);
311						echo "Transcription: " . $transcription;
312					} else {
313						$transcription = '';
314					}
315			}
316		}
317	}
318
319//add the body to the email
320	$body_plain = remove_tags($body);
321	//echo "body_plain = $body_plain\n";
322	if ((substr($body, 0, 5) == "<html") ||  (substr($body, 0, 9) == "<!doctype")) {
323		$mail->ContentType = "text/html";
324		$mail->Body = $body."<br><br>".nl2br($transcription);
325		$mail->AltBody = $body_plain."\n\n$transcription";
326	}
327	else {
328		// $mail->Body = ($body != '') ? $body : $body_plain;
329		$mail->Body = $body_plain."\n\n$transcription";
330		$mail->AltBody = $body_plain."\n\n$transcription";
331	}
332
333//send the email
334	if(!$mail->Send()) {
335		$mailer_error = $mail->ErrorInfo;
336		echo "Mailer Error: ".$mailer_error."\n\n";
337
338		$call_uuid = $headers["X-FusionPBX-Call-UUID"];
339		if ($resend == true) {
340			echo "Retained in v_emails \n";
341		} else {
342			// log/store message in database for review
343			if (!isset($email_uuid)) {
344				$email_uuid = uuid();
345				$sql = "insert into v_emails ( ";
346				$sql .= "email_uuid, ";
347				if ($call_uuid) {
348					$sql .= "call_uuid, ";
349				}
350				$sql .= "domain_uuid, ";
351				$sql .= "sent_date, ";
352				$sql .= "type, ";
353				$sql .= "status, ";
354				$sql .= "email ";
355				$sql .= ") values ( ";
356				$sql .= "'".$email_uuid."', ";
357				if ($call_uuid) {
358					$sql .= "'".$call_uuid."', ";
359				}
360				$sql .= "'".$headers["X-FusionPBX-Domain-UUID"]."', ";
361				$sql .= "now(),";
362				$sql .= "'".$headers["X-FusionPBX-Email-Type"]."', ";
363				$sql .= "'failed', ";
364				$sql .= "'".str_replace("'", "''", $msg)."' ";
365				$sql .= ") ";
366				$db->exec(check_sql($sql));
367				unset($sql);
368			}
369
370			echo "Retained in v_emails as email_uuid = ".$email_uuid."\n";
371		}
372
373	}
374	else {
375		echo "Message sent!";
376	}
377
378//get and save the output from the buffer
379	$content = ob_get_contents(); //get the output from the buffer
380	$content = str_replace("<br />", "", $content);
381
382	ob_end_clean(); //clean the buffer
383
384	fwrite($fp, $content);
385	fclose($fp);
386
387/*
388// save in /tmp as eml file
389
390$fp = fopen(sys_get_temp_dir()."/email.eml", "w");
391ob_end_clean();
392ob_start();
393
394$sql = "select email from v_emails where email_uuid = '".$email_uuid."'";
395$prep_statement = $db->prepare($sql);
396if ($prep_statement) {
397	$prep_statement->execute();
398	$result = $prep_statement->fetchAll(PDO::FETCH_NAMED);
399	foreach ($result as &$row) {
400		echo $row["email"];
401		break;
402	}
403}
404unset($sql, $prep_statement, $result);
405
406$content = ob_get_contents(); //get the output from the buffer
407$content = str_replace("<br />", "", $content);
408
409ob_end_clean(); //clean the buffer
410
411fwrite($fp, $content);
412fclose($fp);
413
414*/
415?>
416