mirror of
https://github.com/Cacti/cacti.git
synced 2026-11-08 21:16:17 +09:00
- Enhancement of breadcrumbs to include Tree information in Ajax response. - Removing all double quotes from 'include' files for performance. - Some cleanups in cdef.php - Enhancement of 'Send Test Email' to use Dialog jQuery plugin - Fixed (finally) the last remaining issues with re-sizable columns - Some CSS cleanup - Fix main tabs not highlighting - Add consistent help screens to CLI and pollers relative to versions and copyright years (now a constant) git-svn-id: svn+ssh://repo.cacti.net/var/data/svnroot/cacti/cacti/branches/0.8.8@7551 860744bd-22fc-0310-8c96-e9fe5004b5ca
963 lines
28 KiB
PHP
963 lines
28 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2008=2014 The Cacti Group |
|
|
| |
|
|
| This program is free software; you can redistribute it and/or |
|
|
| modify it under the terms of the GNU General Public License |
|
|
| as published by the Free Software Foundation; either version 2 |
|
|
| of the License, or (at your option) any later version. |
|
|
| |
|
|
| This program is distributed in the hope that it will be useful, |
|
|
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
|
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
|
| GNU General Public License for more details. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDTool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
/* Mailer class for MIME email functionality */
|
|
class Mailer {
|
|
|
|
var $Config = array();
|
|
var $Message = array();
|
|
var $Error = "";
|
|
|
|
/*
|
|
* Create mailer object
|
|
*
|
|
* Create the mailer object
|
|
*
|
|
* @param config - Array of config value pairs. config=>value
|
|
* @param headers - Array of header value pairs. header=>value
|
|
* @return true
|
|
*/
|
|
function Mailer($config = array(), $headers = array()) {
|
|
|
|
/* Create configuration array */
|
|
$this->Config["User"] = "unknown";
|
|
$this->Config["Hostname"] = "localhost";
|
|
$this->Config["AttachMaxSize"] = 10240000;
|
|
$this->Config["MaxSize"] = 10240000;
|
|
$this->Config["HeaderOrder"] = array("From","To","Cc","Bcc","Reply-To","Date","X-Mailer","User-Agent","Subject","Content-Type");
|
|
$this->Config["HeaderMulti"] = array("To","Cc","Bcc");
|
|
$this->Config["HeaderRequire"] = array("To","From","Subject","Content-Type","Date");
|
|
$this->Config["Mail"]["Type"] = "PHP"; /* PHP or SMTP or DirectInject */
|
|
$this->Config["Mail"]["SMTP_Host"] = "localhost";
|
|
$this->Config["Mail"]["SMTP_Port"] = "25";
|
|
$this->Config["Mail"]["SMTP_Username"] = "";
|
|
$this->Config["Mail"]["SMTP_Password"] = "";
|
|
$this->Config["Mail"]["DirectInject_Path"] = ""; /* Message envelope will be contructed and passed to this executable via stdin */
|
|
$this->Config["Mail"]["WordWrap"] = "76";
|
|
$this->Config["Mail"]["CharSet"] = "UTF-8";
|
|
|
|
/* Process mailer configuration parameters */
|
|
if (sizeof($config) > 0) {
|
|
foreach ($config as $key => $value) {
|
|
if (($key == "Type") && (($value == "SMTP") || ($value == "PHP") || ($value == "DirectInject"))) {
|
|
$this->Config["Mail"]["Type"] = $value;
|
|
}
|
|
if ($key == "SMTP_Host") {
|
|
$this->Config["Mail"]["SMTP_Host"] = $value;
|
|
}
|
|
if ($key == "SMTP_Port") {
|
|
$this->Config["Mail"]["SMTP_Port"] = $value;
|
|
}
|
|
if ($key == "SMTP_Username") {
|
|
$this->Config["Mail"]["SMTP_Username"] = $value;
|
|
}
|
|
if ($key == "SMTP_Password") {
|
|
$this->Config["Mail"]["SMTP_Password"] = $value;
|
|
}
|
|
if ($key == "DirectInject_Path") {
|
|
$this->Config["Mail"]["DirectInject_Path"] = $value;
|
|
}
|
|
if ($key == "WordWrap") {
|
|
$this->Config["Mail"]["WordWrap"] = $value;
|
|
}
|
|
if ($key == "CharSet") {
|
|
$this->Config["Mail"]["CharSet"] = $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Find hostname */
|
|
if (isset($_SERVER["SERVER_NAME"])) {
|
|
$this->Config["Hostname"] = $_SERVER["SERVER_NAME"];
|
|
} else {
|
|
if (isset($_ENV["HOSTNAME"])) {
|
|
$this->Config["Hostname"] = $_ENV["HOSTNAME"];
|
|
}
|
|
}
|
|
|
|
/* Find Username */
|
|
if (isset($_ENV["USER"])) {
|
|
$this->Config["User"] = $_ENV["USER"];
|
|
}
|
|
|
|
/* Setup global headers */
|
|
$this->Message["headers"] = array();
|
|
$this->Message["headers"]["X-Mailer"] = "Cacti-Mailer-Class";
|
|
$this->Message["headers"]["User-Agent"] = "Cacti-Mailer-Class";
|
|
$this->Message["headers"]["Content-Type"] = "text/plain";
|
|
$this->Message["headers"]["MIME-Version"] = "1.0";
|
|
$this->Message["headers"]["From"] = $this->Config["User"] . "@" . $this->Config["Hostname"];
|
|
|
|
/* Add headers */
|
|
foreach ($headers as $header => $value) {
|
|
$this->header_set($header,$value, true);
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Close mailer object
|
|
*
|
|
* Closed the mailer object
|
|
*
|
|
* @return true
|
|
*/
|
|
function close() {
|
|
|
|
$this->Config = array();
|
|
$this->Message = array();
|
|
$this->Error = "";
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Send email
|
|
*
|
|
* Contructed and send the email
|
|
*
|
|
* @param message - string value of message body or array of text=>"", html=>""
|
|
* @param headers - array of header values, Subject required to be set
|
|
* @return true = success, false = error use error to get error string
|
|
*/
|
|
function send($body, $headers = array()) {
|
|
|
|
$body_text = "";
|
|
$body_html = "";
|
|
|
|
/* Check input */
|
|
if (! isset($body)) {
|
|
$this->Error = "No message body argument defined";
|
|
return false;
|
|
}
|
|
if (is_array($body)) {
|
|
if (isset($body["text"])) {
|
|
$body_text = wordwrap($body["text"], $this->Config["Mail"]["WordWrap"]);
|
|
} else {
|
|
$this->Error = "No text part of body defined";
|
|
return false;
|
|
}
|
|
if (isset($body["html"])) {
|
|
$body_html = wordwrap($body["html"], $this->Config["Mail"]["WordWrap"]);
|
|
} else {
|
|
$this->Error = "No html part of body defined";
|
|
return false;
|
|
}
|
|
} else {
|
|
$body_text = wordwrap($body, $this->Config["Mail"]["WordWrap"]);
|
|
}
|
|
if (empty($body)) {
|
|
$this->Error = "Empty body not allowed";
|
|
return false;
|
|
}
|
|
|
|
/* Set headers - Replace globals */
|
|
if (isset($headers)) {
|
|
if (is_array($headers)) {
|
|
foreach ($headers as $key => $value) {
|
|
$this->header_set($key, $value, true);
|
|
}
|
|
} else {
|
|
$this->Error = "Headers must be defined in an array";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Add date header */
|
|
$this->header_set("Date", $this->_get_email_date(), true);
|
|
|
|
|
|
/* Check that we have minimal headers */
|
|
foreach ($this->Config["HeaderRequire"] as $value) {
|
|
if (! isset($this->Message["headers"][$value])) {
|
|
$this->Error = "Required header \'" . $value . "\' is not defined";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Determine attachment types */
|
|
$attachment_inline = 0;
|
|
$attachment_attach = 0;
|
|
if (isset($this->Message["attachments"])) {
|
|
foreach ($this->Message["attachments"] as $value) {
|
|
if ($value["contentdisposition"] == "attachment") {
|
|
$attachment_attach++;
|
|
}
|
|
if ($value["contentdisposition"] == "inline") {
|
|
$attachment_inline++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Determine message content-type */
|
|
$content_type = $this->Message["headers"]["Content-Type"];
|
|
if (empty($body_html)) {
|
|
if ($attachment_attach > 0) {
|
|
$this->_boundary_set();
|
|
$content_type = "multipart/mixed; type=\"text/plain\";\n\tboundary=\"" . $this->Message["boundary"] . "\"";
|
|
}
|
|
} else {
|
|
$this->_boundary_set();
|
|
$content_type = "multipart/alternative; type=\"text/html\";\n\tboundary=\"" . $this->Message["boundary"] . "\"";
|
|
if ($attachment_attach > 0) {
|
|
$content_type = "multipart/mixed; type=\"text/html\";\n\tboundary=\"" . $this->Message["boundary"] . "\"";
|
|
}
|
|
|
|
}
|
|
|
|
/* Contruct message body */
|
|
$this->header_set("Content-Type", $content_type, true);
|
|
if ($content_type == "text/plain") {
|
|
$this->Message["body"] = $body_text;
|
|
} else {
|
|
/* Open MIME */
|
|
$this->Message["body"] = "This is a multi-part message in MIME format\n\n";
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "\n";
|
|
|
|
/* Open MIME ALT */
|
|
if (($attachment_attach > 0) && (! empty($body_html))) {
|
|
$this->Message["body"] .= "Content-Type: multipart/alternative;\n\tboundary=\"" . $this->Message["boundary"] . "_ALT\"\n\n";
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_ALT\n";
|
|
}
|
|
|
|
/* Message part - text/plain */
|
|
$this->Message["body"] .= "Content-Type: text/plain;";
|
|
$this->Message["body"] .= " charset=\"" . $this->Config["Mail"]["CharSet"] . "\"\n";
|
|
$this->Message["body"] .= "Content-Transfer-Encoding: 8-bit\n";
|
|
$this->Message["body"] .= "\n" . $body_text . "\n\n";
|
|
|
|
/* Open MIME HTML */
|
|
if ((! empty($body_html)) && ($attachment_attach > 0)) {
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_ALT\n";
|
|
} else {
|
|
if ($attachment_attach == 0) {
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "\n";
|
|
}
|
|
}
|
|
if ($attachment_inline > 0) {
|
|
$this->Message["body"] .= "Content-Type: multipart/related;\n\tboundary=\"" . $this->Message["boundary"] . "_HTML\"\n\n";
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_HTML\n";
|
|
}
|
|
|
|
if (! empty($body_html)) {
|
|
/* Message part - text/html */
|
|
$this->Message["body"] .= "Content-Type: text/html;";
|
|
$this->Message["body"] .= " charset=\"" . $this->Config["Mail"]["CharSet"] . "\"\n";
|
|
$this->Message["body"] .= "Content-Transfer-Encoding: 8-bit\n";
|
|
$this->Message["body"] .= "\n" . $body_html . "\n\n";
|
|
}
|
|
|
|
/* Attach inline */
|
|
if ($attachment_inline > 0) {
|
|
foreach ($this->Message["attachments"] as $attachment) {
|
|
if ($attachment["contentdisposition"] == "inline") {
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_HTML\n";
|
|
$this->Message["body"] .= "Content-Type: " . $attachment["contenttype"] . "; name=\"" . $attachment["filename"] . "\"\n";
|
|
$this->Message["body"] .= "Content-Transfer-Encoding: " . $attachment["encoding"] . "\n";
|
|
$this->Message["body"] .= "Content-Disposition: " . $attachment["contentdisposition"] . "; filename=\"" . $attachment["filename"] . "\"\n";
|
|
if (isset($attachment["contentid"])) {
|
|
$this->Message["body"] .= "Content-Id: <" . $attachment["contentid"] . ">\n";
|
|
}
|
|
$this->Message["body"] .= "\n" . $attachment["encoded_data"] . "\n";
|
|
}
|
|
}
|
|
/* Close MIME HTML */
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_HTML--\n\n";
|
|
|
|
}
|
|
|
|
/* Close MIME ALT */
|
|
if (($attachment_attach > 0) && (! empty($body_html))) {
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "_ALT--\n\n";
|
|
}
|
|
|
|
/* Attach files */
|
|
if ($attachment_attach > 0) {
|
|
foreach ($this->Message["attachments"] as $attachment) {
|
|
if ($attachment["contentdisposition"] != "inline") {
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "\n";
|
|
$this->Message["body"] .= "Content-Type: " . $attachment["contenttype"] . "; name=\"" . $attachment["filename"] . "\"\n";
|
|
$this->Message["body"] .= "Content-Transfer-Encoding: " . $attachment["encoding"] . "\n";
|
|
$this->Message["body"] .= "Content-Disposition: " . $attachment["contentdisposition"] . "; filename=\"" . $attachment["filename"] . "\"\n";
|
|
if (isset($attachment["contentid"])) {
|
|
$this->Message["body"] .= "Content-id: <" . $attachment["contentid"] . ">\n";
|
|
}
|
|
$this->Message["body"] .= "\n" . $attachment["encoded_data"] . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Close MIME */
|
|
$this->Message["body"] .= "--" . $this->Message["boundary"] . "--\n";
|
|
|
|
}
|
|
|
|
/* Send mail */
|
|
if (! $this->_send_mail()) {
|
|
return false;
|
|
}
|
|
|
|
/* Remove contructed message - save memory */
|
|
$this->Message = $this->_array_element_delete($this->Message, "body");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Set or append a header
|
|
*
|
|
* Set or append to a header, only To, CC, Bcc will append values
|
|
*
|
|
* @param header - string value of header, case sensitive
|
|
* @param value - value of the header
|
|
* @param replace - force replace on a multi-value header, optional, default = false
|
|
* @return true = success, false = error use error to get error text
|
|
*/
|
|
function header_set($header, $value, $replace = false) {
|
|
|
|
if (! isset($header)) {
|
|
$this->Error = "No header passed to set";
|
|
return false;
|
|
}
|
|
if (! isset($value)) {
|
|
$this->Error = "No header value passed, use header_unset to remove header";
|
|
return false;
|
|
}
|
|
|
|
if ((isset($this->Message["headers"][$header])) && (in_array($header, $this->Config["HeaderMulti"])) && (! $replace)) {
|
|
if (is_array($this->Message["headers"][$header])) {
|
|
if (is_array($value)) {
|
|
foreach ($value as $item) {
|
|
if (! in_array($item, $this->Message["headers"][$header])) {
|
|
array_push($this->Message["headers"][$header], $item);
|
|
}
|
|
}
|
|
} else {
|
|
if (! in_array($value, $this->Message["headers"][$header])) {
|
|
array_push($this->Message["headers"][$header], $value);
|
|
}
|
|
}
|
|
} else {
|
|
$this->Message["headers"][$header] = array( $this->Message["headers"][$header], $value );
|
|
}
|
|
} else {
|
|
if ( (! in_array($header, $this->Config["HeaderMulti"]) ) && (is_array($value) ) ) {
|
|
$this->Error = "Array value not valid for non-multi headers";
|
|
return false;
|
|
} else {
|
|
$this->Message["headers"][$header] = $value;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Remove a header
|
|
*
|
|
* Removes give header from the global header array
|
|
*
|
|
* @param header - string value of header, case sensitive
|
|
* @return true = success, false = error use error to get error text
|
|
*/
|
|
function header_unset($header) {
|
|
|
|
if (isset($this->Message["headers"][$header])) {
|
|
$this->Message["headers"] = $this->_array_element_delete($this->Message["headers"], $header);
|
|
return true;
|
|
}
|
|
$this->Error = "Header is not set";
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Format an email address
|
|
*
|
|
* Format an email address in full name <email> format
|
|
*
|
|
* @param name - string value of name
|
|
* @param email - string value of email address
|
|
* @return string - formatted email address
|
|
*/
|
|
function email_format($name = "", $email = "") {
|
|
|
|
if (! isset($name)) {
|
|
$this->Error = "Empty name value";
|
|
return false;
|
|
}
|
|
if (! isset($email)) {
|
|
$this->Error = "Empty email value";
|
|
return false;
|
|
}
|
|
|
|
return $name . " <" . $email . ">";
|
|
|
|
}
|
|
|
|
/*
|
|
* Generate an unique content id
|
|
*
|
|
* Generate an unique content id for use with inline attachments
|
|
*
|
|
* @return string - content id
|
|
*/
|
|
function content_id() {
|
|
|
|
list($usec, $sec) = explode(" ", microtime());
|
|
$usec = $usec * 10000000;
|
|
|
|
return getmypid() . "_" . $sec . "_" . $usec . "@" . $this->Config["Hostname"];
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Attach a file to the email
|
|
|
|
*
|
|
* Attach a file to the email, either attached or inline
|
|
*
|
|
* @param data - Data to encode as attachment
|
|
* @param filename - Name of the attachment, when saving this will be the file name
|
|
* @param contenttype = MIME type of the attachment
|
|
* @param contentdisposition - attachment or inline
|
|
* @param contentid - Content id for use in inline attachments
|
|
* @return string - content id
|
|
*/
|
|
function attach($data, $filename, $contenttype = "application/octet", $contentdisposition = "attachment", $contentid = "") {
|
|
|
|
$struc = array();
|
|
|
|
/* Check for required PHP functions */
|
|
if (! function_exists("base64_encode")) {
|
|
$this->Error = "Required function \'base64_encode\' not available";
|
|
return false;
|
|
}
|
|
|
|
/* Check size of the data */
|
|
if (strlen($data) == 0) {
|
|
$this->Error = "No data passed to attach, zero length data";
|
|
return false;
|
|
}
|
|
$struc["Size"] = strlen($data);
|
|
|
|
/* Encode the data */
|
|
$struc["encoded_data"] = chunk_split(base64_encode($data), 76, "\n");
|
|
$data = false; /* free up memory */
|
|
|
|
/* Check size of encoded data */
|
|
if (strlen($struc["encoded_data"]) > $this->Config["AttachMaxSize"]) {
|
|
$this->Error = "Encoded attachment size exceeds maximum size";
|
|
return false;
|
|
}
|
|
$struc["SizeEncoded"] = strlen($struc["encoded_data"]);
|
|
|
|
/* Set attachment properties */
|
|
$struc["filename"] = $filename;
|
|
$struc["contenttype"] = $contenttype;
|
|
$struc["contentdisposition"] = $contentdisposition;
|
|
$struc["encoding"] = "base64";
|
|
if (! empty($contentid)) {
|
|
$struc["contentid"] = $contentid;
|
|
}
|
|
|
|
/* Check all attachment sizes */
|
|
if (isset($this->Message["attachments_size"])) {
|
|
if ($this->Message["attachments_size"] + $struc["SizeEncoded"] > $this->Config["AttachMaxSize"]) {
|
|
$this->Error = "Unable to attach file, all attachments will exceed Max Size";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Push attachment into message attachments array */
|
|
if (! isset($this->Message["attachments_size"])) {
|
|
$this->Message["attachments_size"] = 0;
|
|
}
|
|
$this->Message["attachments_size"] += $struc["SizeEncoded"];
|
|
$this->Message["attachments"][] = $struc;
|
|
|
|
/* Set MIME boundary */
|
|
$this->_boundary_set();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Clear attached files
|
|
*
|
|
* Clear all attached files
|
|
*
|
|
* @return boolean - true = success, false = error
|
|
*/
|
|
function attach_clear() {
|
|
|
|
$this->Message = $this->_array_element_delete($this->Message, "attachments");
|
|
$this->Message = $this->_array_element_delete($this->Message, "attachments_size");
|
|
$this->Message = $this->_array_element_delete($this->Message, "boundary");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
/*
|
|
* Read a files content
|
|
*
|
|
* Read a files content and return it, binary safe
|
|
*
|
|
* @parma - string - file to read
|
|
* @return - binary - file data
|
|
*/
|
|
function read_file($file) {
|
|
|
|
|
|
if (preg_match('/^\S{3,4}:\/\//', $file)) {
|
|
$this->Error = "Only local files are allowed";
|
|
return false;
|
|
}
|
|
|
|
set_magic_quotes_runtime(0);
|
|
|
|
if (($fh = @fopen($file, "rb")) === false) {
|
|
$this->Error = "Unable to open file for read";
|
|
return false;
|
|
}
|
|
if (($data = fread($fh, filesize($file))) === false) {
|
|
$this->Error = "Unable to read file";
|
|
return false;
|
|
}
|
|
fclose($fh);
|
|
|
|
set_magic_quotes_runtime(get_magic_quotes_gpc());
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Read Mailer error
|
|
*
|
|
* Read the error the last ran mailer function generated
|
|
*
|
|
* @return - string - Error
|
|
*/
|
|
function error() {
|
|
|
|
return $this->Error;
|
|
|
|
}
|
|
|
|
/*
|
|
* Send email
|
|
*
|
|
* Internal mailer function to send the email. This will use whatever means have been configured to send email.
|
|
*
|
|
* @return - boolean - true = success, false = error
|
|
*/
|
|
function _send_mail() {
|
|
|
|
/* Add additional headers to header_order */
|
|
$headers = "";
|
|
$header_order = $this->Config["HeaderOrder"];
|
|
foreach ($this->Message["headers"] as $key => $value) {
|
|
if (! in_array($key, $header_order)) {
|
|
$header_order[] = $key;
|
|
}
|
|
}
|
|
|
|
if ($this->Config["Mail"]["Type"] == "PHP") {
|
|
/*
|
|
* Process Mail with PHP internal function
|
|
*/
|
|
if (! function_exists("mail")) {
|
|
$this->Error = "Required function \'mail\' not available";
|
|
return false;
|
|
}
|
|
|
|
/* Check ini settings in Windows */
|
|
if (strtoupper(substr(PHP_OS, 0, 3)) === "WIN") {
|
|
$smtp_ini = ini_get("SMTP");
|
|
if ((empty($smtp_ini)) || (strtoupper($smtp_ini) == "LOCALHOST")) {
|
|
if (empty($this->Config["Mail"]["SMTP_Host"])) {
|
|
$this->Error = "Unable to send email with php mail function, php.ini setting SMTP is not set or SMTP Host not defined";
|
|
return false;
|
|
} else {
|
|
if (ini_set("SMTP", $this->Config["Mail"]["SMTP_Host"]) == false) {
|
|
$this->Error = "Unable to set php setting SMTP";
|
|
return false;
|
|
}
|
|
if (ini_set("smtp_port", $this->Config["Mail"]["SMTP_Port"]) == false) {
|
|
$this->Error = "Unable to set php setting smtp_port";
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* Setup to */
|
|
$to = $this->Message["headers"]["To"];
|
|
if (is_array($to)) {
|
|
$to = implode(", ", $to);
|
|
}
|
|
|
|
/* Create additional headers */
|
|
foreach ($header_order as $key) {
|
|
if (($key != "To") && ($key != "Subject")) {
|
|
if (isset($this->Message["headers"][$key])) {
|
|
if (is_array($this->Message["headers"][$key])) {
|
|
$headers .= $key . ": " . implode(", ",$this->Message["headers"][$key]) . "\n";
|
|
} else {
|
|
$headers .= $key . ": " . $this->Message["headers"][$key] . "\n";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Send the email */
|
|
if (! @mail($to, $this->Message["headers"]["Subject"], $this->Message["body"], $headers)) {
|
|
$this->Error = "Unable to send email with php mail function, check your system logs";
|
|
return false;
|
|
}
|
|
|
|
} elseif ($this->Config["Mail"]["Type"] == "SMTP") {
|
|
/*
|
|
* Process Mail with SMTP
|
|
*/
|
|
if (! function_exists("fsockopen")) {
|
|
$this->Error = "Required function 'fsockopen' not available";
|
|
return false;
|
|
}
|
|
|
|
/* Create headers text */
|
|
foreach ($header_order as $key) {
|
|
if ((isset($this->Message["headers"][$key])) && ($key != "Bcc")) {
|
|
if (is_array($this->Message["headers"][$key])) {
|
|
$headers .= $key . ": " . str_replace("\n", "\r\n", implode(", ",$this->Message["headers"][$key])) . "\r\n";
|
|
} else {
|
|
$headers .= $key . ": " . str_replace("\n", "\r\n", $this->Message["headers"][$key]) . "\r\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Setup from address */
|
|
$from = $this->Message["headers"]["From"];
|
|
if (strpos($from, "<") != false) {
|
|
$from = substr($from, strpos($from, "<") + 1);
|
|
$from = substr($from, 0, strlen($from) - 1);
|
|
}
|
|
|
|
/* Setup to addresses */
|
|
if (is_array($this->Message["headers"]["To"])) {
|
|
$to = $this->Message["headers"]["To"];
|
|
} else {
|
|
$to = array($this->Message["headers"]["To"]);
|
|
}
|
|
if (isset($this->Message["headers"]["Cc"])) {
|
|
if (is_array($this->Message["headers"]["Cc"])) {
|
|
foreach ($this->Message["headers"]["Cc"] as $item) {
|
|
array_push($to, $item);
|
|
}
|
|
} else {
|
|
array_push($to, $this->Message["headers"]["Cc"]);
|
|
}
|
|
}
|
|
if (isset($this->Message["headers"]["Bcc"])) {
|
|
if (is_array($this->Message["headers"]["Bcc"])) {
|
|
foreach ($this->Message["headers"]["Bcc"] as $item) {
|
|
array_push($to, $item);
|
|
}
|
|
} else {
|
|
array_push($to, $this->Message["headers"]["Bcc"]);
|
|
}
|
|
}
|
|
|
|
/* Open SMTP connection */
|
|
if (($smtp_sock = @fsockopen($this->Config["Mail"]["SMTP_Host"], $this->Config["Mail"]["SMTP_Port"], $errno, $errstr, 1)) === false) {
|
|
$this->Error = "Unable to connect to SMTP Host '" . $this->Config["Mail"]["SMTP_Host"] . "': (" . $errno . ") " . $errstr;
|
|
return false;
|
|
}
|
|
|
|
/* Read SMTP Socket */
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "220") {
|
|
$this->Error = "Error returned by SMTP host: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Start SMTP conversation */
|
|
fputs($smtp_sock, "HELO " . $this->Config["Hostname"] . "\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "250") {
|
|
$this->Error = "Error returned by SMTP host: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Perform Authenication - If username and password set */
|
|
if ((! empty($this->Config["Mail"]["SMTP_Username"])) && (! empty($this->Config["Mail"]["SMTP_Password"]))) {
|
|
|
|
fputs($smtp_sock, "AUTH LOGIN\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "334") {
|
|
$this->Error = "SMTP Host does not appear to support authenication: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
fputs($smtp_sock, base64_encode($this->Config["Mail"]["SMTP_Username"]) . "\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "334") {
|
|
$this->Error = "SMTP Authenication failure: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
fputs($smtp_sock, base64_encode($this->Config["Mail"]["SMTP_Password"]) . "\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "235") {
|
|
$this->Error = "SMTP Authenication failure: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Send mail from */
|
|
fputs($smtp_sock, "MAIL FROM: <" . $from . ">\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "250") {
|
|
$this->Error = "SMTP Host rejected from address: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Send rcpt to */
|
|
foreach ($to as $item) {
|
|
fputs($smtp_sock, "RCPT TO: <" . $item . ">\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "250") {
|
|
$this->Error = "SMTP Host rejected to address: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/* Send data to start message */
|
|
fputs($smtp_sock, "DATA\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "354") {
|
|
$this->Error = "SMTP host rejected data command:" . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Send message headers and body */
|
|
$message = str_replace("\n", "\r\n", $this->Message["body"]);
|
|
fputs($smtp_sock, $headers . "\r\n" . $message . "\r\n.\r\n");
|
|
$smtp_response = fgets($smtp_sock,4096);
|
|
if (substr($smtp_response,0,3) != "250") {
|
|
$this->Error = "SMTP error while sending email: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Send quit */
|
|
fputs($smtp_sock,"QUIT\r\n");
|
|
$smtp_response = fgets($smtp_sock, 4096);
|
|
if (substr($smtp_response,0,3) != "221") {
|
|
$this->Error = "SMTP Host rejected quit command: " . $smtp_response;
|
|
fclose($smtp_sock);
|
|
return false;
|
|
}
|
|
|
|
/* Close connection */
|
|
fclose($smtp_sock);
|
|
|
|
|
|
} elseif ($this->Config["Mail"]["Type"] == "DirectInject") {
|
|
/*
|
|
* Process Mail with DirectInject
|
|
*/
|
|
|
|
/* Check and Process DirectInject path */
|
|
if (empty($this->Config["Mail"]["DirectInject_Path"])) {
|
|
$this->Error = "No DirectInject_Path defined";
|
|
return false;
|
|
}
|
|
list($cmd) = explode(" ",$this->Config["Mail"]["DirectInject_Path"]);
|
|
if (file_exists($cmd)) {
|
|
if (is_readable($cmd)) {
|
|
if (function_exists("is_executable")) {
|
|
if (! is_executable($cmd)) {
|
|
$this->Error = "DirectInject_Path is not executable";
|
|
return false;
|
|
}
|
|
}
|
|
} else {
|
|
$this->Error = "DirectInject_Path is not readable";
|
|
return false;
|
|
}
|
|
} else {
|
|
$this->Error = "DirectInject_Path does not exist";
|
|
return false;
|
|
}
|
|
|
|
/* Create headers */
|
|
foreach ($header_order as $key) {
|
|
if (isset($this->Message["headers"][$key])) {
|
|
if (is_array($this->Message["headers"][$key])) {
|
|
$headers .= $key . ": " . implode(", ",$this->Message["headers"][$key]) . "\n";
|
|
} else {
|
|
$headers .= $key . ": " . $this->Message["headers"][$key] . "\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Contruct process */
|
|
$desc_spec = array (
|
|
0 => array("pipe", "r"),
|
|
1 => array("pipe", "w"),
|
|
2 => array("pipe", "w")
|
|
);
|
|
$process = proc_open($this->Config["Mail"]["DirectInject_Path"], $desc_spec, $pipes, NULL, NULL);
|
|
if (! is_resource($process)) {
|
|
$this->Error = "Unable to open DirectInject executable process: (" . $errno . ") " . $errstr;
|
|
return false;
|
|
}
|
|
|
|
/* Write message to process on STDIN */
|
|
fwrite($pipes[0], $headers . "\n");
|
|
fwrite($pipes[0], $this->Message["body"] . "\n");
|
|
fclose($pipes[0]);
|
|
|
|
/* Read stderr and stdout from process */
|
|
$stdout = stream_get_contents($pipes[1]);
|
|
$stderr = stream_get_contents($pipes[2]);
|
|
fclose($pipes[1]);
|
|
fclose($pipes[2]);
|
|
|
|
/* Close the process */
|
|
$return_level = proc_close($process);
|
|
|
|
/* Process process results */
|
|
if ($return_level > 0) {
|
|
$this->Error = "DirectInject command output: '" . $stdout . "' error: '" . $stderr . "'";
|
|
return false;
|
|
}
|
|
|
|
|
|
} else {
|
|
$this->Error = "Invalid Mail Type Defined";
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* RFC SMTP Date
|
|
*
|
|
* Returns a RFC SMTP formatted date string
|
|
*
|
|
* @param - string - input date
|
|
* @return - string - date string
|
|
*/
|
|
function _get_email_date($time = "") {
|
|
|
|
if (empty($time)) {
|
|
$time = time();
|
|
}
|
|
|
|
return date("r", $time);
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Array Element Delete
|
|
*
|
|
* Deletes an element from an array
|
|
*
|
|
* @param - array - array to modify
|
|
* @param - string - key to delete
|
|
* @return - array
|
|
*/
|
|
function _array_element_delete($input, $search) {
|
|
|
|
$output = array();
|
|
|
|
if (isset($input)) {
|
|
if (is_array($input)) {
|
|
foreach ($input as $key => $value) {
|
|
if ($search != $key) {
|
|
$output[$key] = $value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $output;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
* Sets MIME message boundary
|
|
*
|
|
* Sets the MIME message boundary in the mailer object
|
|
*
|
|
* @return - true
|
|
*/
|
|
function _boundary_set() {
|
|
|
|
if (! isset($this->Message["boundary"])) {
|
|
list($usec, $sec) = explode(" ", microtime());
|
|
$usec = $usec * 10000000;
|
|
$this->Message["boundary"] = "--_MAILER_" . getmypid() . "_" . $sec . "_" . $usec;
|
|
}
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
/* end of class */
|
|
}
|
|
|
|
?>
|