· 6 years ago · Dec 03, 2019, 06:04 PM
1<?php
2
3class SMTP
4{
5 const VERSION = '5.2.9';
6 const CRLF = "\r\n";
7 const DEFAULT_SMTP_PORT = 25;
8 const MAX_LINE_LENGTH = 998;
9 const DEBUG_OFF = 0;
10 const DEBUG_CLIENT = 1;
11 const DEBUG_SERVER = 2;
12 const DEBUG_CONNECTION = 3;
13 const DEBUG_LOWLEVEL = 4;
14 public $Version = '5.2.9';
15 public $SMTP_PORT = 25;
16 public $CRLF = "\r\n";
17 public $do_debug = self::DEBUG_OFF;
18 public $Debugoutput = 'echo';
19 public $do_verp = false;
20 public $Timeout = 300;
21 public $Timelimit = 300;
22 protected $smtp_conn;
23 protected $error = array();
24 protected $helo_rply = null;
25 protected $server_caps = null;
26 protected $last_reply = '';
27
28 public function connect($host, $port = null, $timeout = 30, $options = array())
29 {
30 static $streamok;
31 if (is_null($streamok)) {
32 $streamok = function_exists('stream_socket_client');
33 }
34 $this->error = array();
35 if ($this->connected()) {
36 $this->error = array('error' => 'Already connected to a server');
37 return false;
38 }
39 if (empty($port)) {
40 $port = self::DEFAULT_SMTP_PORT;
41 }
42 $this->edebug("Connection: opening to $host:$port, t=$timeout, opt=" . var_export($options, true), self::DEBUG_CONNECTION);
43 $errno = 0;
44 $errstr = '';
45 if ($streamok) {
46 $socket_context = stream_context_create($options);
47 $this->smtp_conn = @stream_socket_client($host . ":" . $port, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $socket_context);
48 } else {
49 $this->edebug("Connection: stream_socket_client not available, falling back to fsockopen", self::DEBUG_CONNECTION);
50 $this->smtp_conn = fsockopen($host, $port, $errno, $errstr, $timeout);
51 }
52 if (!is_resource($this->smtp_conn)) {
53 $this->error = array('error' => 'Failed to connect to server', 'errno' => $errno, 'errstr' => $errstr);
54 $this->edebug('SMTP ERROR: ' . $this->error['error'] . ": $errstr ($errno)", self::DEBUG_CLIENT);
55 return false;
56 }
57 $this->edebug('Connection: opened', self::DEBUG_CONNECTION);
58 if (substr(PHP_OS, 0, 3) != 'WIN') {
59 $max = ini_get('max_execution_time');
60 if ($max != 0 && $timeout > $max) {
61 @set_time_limit($timeout);
62 }
63 stream_set_timeout($this->smtp_conn, $timeout, 0);
64 }
65 $announce = $this->get_lines();
66 $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);
67 return true;
68 }
69
70 public function connected()
71 {
72 if (is_resource($this->smtp_conn)) {
73 $sock_status = stream_get_meta_data($this->smtp_conn);
74 if ($sock_status['eof']) {
75 $this->edebug('SMTP NOTICE: EOF caught while checking if connected', self::DEBUG_CLIENT);
76 $this->close();
77 return false;
78 }
79 return true;
80 }
81 return false;
82 }
83
84 protected function edebug($str, $level = 0)
85 {
86 if ($level > $this->do_debug) {
87 return;
88 }
89 if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {
90 call_user_func($this->Debugoutput, $str, $this->do_debug);
91 return;
92 }
93 switch ($this->Debugoutput) {
94 case 'error_log':
95 error_log($str);
96 break;
97 case 'html':
98 echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, 'UTF-8') . "<br>\n";
99 break;
100 case 'echo':
101 default:
102 $str = preg_replace('/(\r\n|\r|\n)/ms', "\n", $str);
103 echo gmdate('Y-m-d H:i:s') . "\t" . str_replace("\n", "\n \t ", trim($str)) . "\n";
104 }
105 }
106
107 public function close()
108 {
109 $this->error = array();
110 $this->server_caps = null;
111 $this->helo_rply = null;
112 if (is_resource($this->smtp_conn)) {
113 fclose($this->smtp_conn);
114 $this->smtp_conn = null;
115 $this->edebug('Connection: closed', self::DEBUG_CONNECTION);
116 }
117 }
118
119 protected function get_lines()
120 {
121 if (!is_resource($this->smtp_conn)) {
122 return '';
123 }
124 $data = '';
125 $endtime = 0;
126 stream_set_timeout($this->smtp_conn, $this->Timeout);
127 if ($this->Timelimit > 0) {
128 $endtime = time() + $this->Timelimit;
129 }
130 while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {
131 $str = @fgets($this->smtp_conn, 515);
132 $this->edebug("SMTP -> get_lines(): \$data was \"$data\"", self::DEBUG_LOWLEVEL);
133 $this->edebug("SMTP -> get_lines(): \$str is \"$str\"", self::DEBUG_LOWLEVEL);
134 $data .= $str;
135 $this->edebug("SMTP -> get_lines(): \$data is \"$data\"", self::DEBUG_LOWLEVEL);
136 if ((isset($str[3]) and $str[3] == ' ')) {
137 break;
138 }
139 $info = stream_get_meta_data($this->smtp_conn);
140 if ($info['timed_out']) {
141 $this->edebug('SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)', self::DEBUG_LOWLEVEL);
142 break;
143 }
144 if ($endtime and time() > $endtime) {
145 $this->edebug('SMTP -> get_lines(): timelimit reached (' . $this->Timelimit . ' sec)', self::DEBUG_LOWLEVEL);
146 break;
147 }
148 }
149 return $data;
150 }
151
152 public function startTLS()
153 {
154 if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {
155 return false;
156 }
157 if (!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
158 return false;
159 }
160 return true;
161 }
162
163 protected function sendCommand($command, $commandstring, $expect)
164 {
165 if (!$this->connected()) {
166 $this->error = array('error' => "Called $command without being connected");
167 return false;
168 }
169 $this->client_send($commandstring . self::CRLF);
170 $this->last_reply = $this->get_lines();
171 $matches = array();
172 if (preg_match("/^([0-9]{3})[ -](?:([0-9]\\.[0-9]\\.[0-9]) )?/", $this->last_reply, $matches)) {
173 $code = $matches[1];
174 $code_ex = (count($matches) > 2 ? $matches[2] : null);
175 $detail = preg_replace("/{$code}[ -]" . ($code_ex ? str_replace('.', '\\.', $code_ex) . ' ' : '') . "/m", '', $this->last_reply);
176 } else {
177 $code = substr($this->last_reply, 0, 3);
178 $code_ex = null;
179 $detail = substr($this->last_reply, 4);
180 }
181 $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);
182 if (!in_array($code, (array)$expect)) {
183 $this->error = array('error' => "$command command failed", 'smtp_code' => $code, 'smtp_code_ex' => $code_ex, 'detail' => $detail);
184 $this->edebug('SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply, self::DEBUG_CLIENT);
185 return false;
186 }
187 $this->error = array();
188 return true;
189 }
190
191 public function client_send($data)
192 {
193 $this->edebug("CLIENT -> SERVER: $data", self::DEBUG_CLIENT);
194 return fwrite($this->smtp_conn, $data);
195 }
196
197 public function authenticate($username, $password, $authtype = null, $realm = '', $workstation = '')
198 {
199 if (!$this->server_caps) {
200 $this->error = array('error' => 'Authentication is not allowed before HELO/EHLO');
201 return false;
202 }
203 if (array_key_exists('EHLO', $this->server_caps)) {
204 if (!array_key_exists('AUTH', $this->server_caps)) {
205 $this->error = array('error' => 'Authentication is not allowed at this stage');
206 return false;}
207 self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);
208 self::edebug('Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']), self::DEBUG_LOWLEVEL);
209 if (empty($authtype)) {
210 foreach (array('LOGIN', 'CRAM-MD5', 'NTLM', 'PLAIN') as $method) {
211 if (in_array($method, $this->server_caps['AUTH'])) {
212 $authtype = $method;
213 break;
214 }
215 }
216 if (empty($authtype)) {
217 $this->error = array('error' => 'No supported authentication methods found');
218 return false;
219 }
220 self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);
221 }
222 if (!in_array($authtype, $this->server_caps['AUTH'])) {
223 $this->error = array('error' => 'The requested authentication method "' . $authtype . '" is not supported by the server');
224 return false;
225 }
226 } elseif (empty($authtype)) {
227 $authtype = 'LOGIN';
228 }
229 switch ($authtype) {
230 case 'PLAIN':
231 if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {
232 return false;
233 }
234 if (!$this->sendCommand('User & Password', base64_encode("\0" . $username . "\0" . $password), 235)) {
235 return false;
236 }
237 break;
238 case 'LOGIN':
239 if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {
240 return false;
241 }
242 if (!$this->sendCommand("Username", base64_encode($username), 334)) {
243 return false;
244 }
245 if (!$this->sendCommand("Password", base64_encode($password), 235)) {
246 return false;
247 }
248 break;
249 case 'NTLM':
250 require_once 'extras/ntlm_sasl_client.php';
251 $temp = new stdClass();
252 $ntlm_client = new ntlm_sasl_client_class;
253 if (!$ntlm_client->Initialize($temp)) {
254 $this->error = array('error' => $temp->error);
255 $this->edebug('You need to enable some modules in your php.ini file: ' . $this->error['error'], self::DEBUG_CLIENT);
256 return false;
257 }
258 $msg1 = $ntlm_client->TypeMsg1($realm, $workstation);
259 if (!$this->sendCommand('AUTH NTLM', 'AUTH NTLM ' . base64_encode($msg1), 334)) {
260 return false;
261 }
262 $challenge = substr($this->last_reply, 3);
263 $challenge = base64_decode($challenge);
264 $ntlm_res = $ntlm_client->NTLMResponse(substr($challenge, 24, 8), $password);
265 $msg3 = $ntlm_client->TypeMsg3($ntlm_res, $username, $realm, $workstation);
266 return $this->sendCommand('Username', base64_encode($msg3), 235);
267 case 'CRAM-MD5':
268 if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {
269 return false;
270 }
271 $challenge = base64_decode(substr($this->last_reply, 4));
272 $response = $username . ' ' . $this->hmac($challenge, $password);
273 return $this->sendCommand('Username', base64_encode($response), 235);
274 default:
275 $this->error = array('error' => 'Authentication method "' . $authtype . '" is not supported');
276 return false;
277 }
278 return true;
279 }
280
281 protected function hmac($data, $key)
282 {
283 if (function_exists('hash_hmac')) {
284 return hash_hmac('md5', $data, $key);
285 }
286 $bytelen = 64;
287 if (strlen($key) > $bytelen) {
288 $key = pack('H*', md5($key));
289 }
290 $key = str_pad($key, $bytelen, chr(0x00));
291 $ipad = str_pad('', $bytelen, chr(0x36));
292 $opad = str_pad('', $bytelen, chr(0x5c));
293 $k_ipad = $key ^ $ipad;
294 $k_opad = $key ^ $opad;
295 return md5($k_opad . pack('H*', md5($k_ipad . $data)));
296 }
297
298 public function data($msg_data)
299 {
300 if (!$this->sendCommand('DATA', 'DATA', 354)) {
301 return false;
302 }
303 $lines = explode("\n", str_replace(array("\r\n", "\r"), "\n", $msg_data));
304 $field = substr($lines[0], 0, strpos($lines[0], ':'));
305 $in_headers = false;
306 if (!empty($field) && strpos($field, ' ') === false) {
307 $in_headers = true;
308 }
309 foreach ($lines as $line) {
310 $lines_out = array();
311 if ($in_headers and $line == '') {
312 $in_headers = false;
313 }
314 while (isset($line[self::MAX_LINE_LENGTH])) {
315 $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');
316 if (!$pos) {
317 $pos = self::MAX_LINE_LENGTH - 1;
318 $lines_out[] = substr($line, 0, $pos);
319 $line = substr($line, $pos);
320 } else {
321 $lines_out[] = substr($line, 0, $pos);
322 $line = substr($line, $pos + 1);
323 }
324 if ($in_headers) {
325 $line = "\t" . $line;
326 }
327 }
328 $lines_out[] = $line;
329 foreach ($lines_out as $line_out) {
330 if (!empty($line_out) and $line_out[0] == '.') {
331 $line_out = '.' . $line_out;
332 }
333 $this->client_send($line_out . self::CRLF);
334 }
335 }
336 $savetimelimit = $this->Timelimit;
337 $this->Timelimit = $this->Timelimit * 2;
338 $result = $this->sendCommand('DATA END', '.', 250);
339 $this->Timelimit = $savetimelimit;
340 return $result;
341 }
342
343 public function hello($host = '')
344 {
345 return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));
346 }
347
348 protected function sendHello($hello, $host)
349 {
350 $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);
351 $this->helo_rply = $this->last_reply;
352 if ($noerror) {
353 $this->parseHelloFields($hello);
354 } else {
355 $this->server_caps = null;
356 }
357 return $noerror;
358 }
359
360 protected function parseHelloFields($type)
361 {
362 $this->server_caps = array();
363 $lines = explode("\n", $this->last_reply);
364 foreach ($lines as $n => $s) {
365 $s = trim(substr($s, 4));
366 if (!$s) {
367 continue;
368 }
369 $fields = explode(' ', $s);
370 if ($fields) {
371 if (!$n) {
372 $name = $type;
373 $fields = $fields[0];
374 } else {
375 $name = array_shift($fields);
376 if ($name == 'SIZE') {
377 $fields = ($fields) ? $fields[0] : 0;
378 }
379 }
380 $this->server_caps[$name] = ($fields ? $fields : true);
381 }
382 }
383 }
384
385 public function mail($from)
386 {
387 $useVerp = ($this->do_verp ? ' XVERP' : '');
388 return $this->sendCommand('MAIL FROM', 'MAIL FROM:<' . $from . '>' . $useVerp, 250);
389 }
390
391 public function quit($close_on_error = true)
392 {
393 $noerror = $this->sendCommand('QUIT', 'QUIT', 221);
394 $err = $this->error;
395 if ($noerror or $close_on_error) {
396 $this->close();
397 $this->error = $err;
398 }
399 return $noerror;
400 }
401
402 public function recipient($toaddr)
403 {
404 return $this->sendCommand('RCPT TO', 'RCPT TO:<' . $toaddr . '>', array(250, 251));
405 }
406
407 public function reset()
408 {
409 return $this->sendCommand('RSET', 'RSET', 250);
410 }
411
412 public function sendAndMail($from)
413 {
414 return $this->sendCommand('SAML', "SAML FROM:$from", 250);
415 }
416
417 public function verify($name)
418 {
419 return $this->sendCommand('VRFY', "VRFY $name", array(250, 251));
420 }
421
422 public function noop()
423 {
424 return $this->sendCommand('NOOP', 'NOOP', 250);
425 }
426
427 public function turn()
428 {
429 $this->error = array('error' => 'The SMTP TURN command is not implemented');
430 $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);
431 return false;
432 }
433
434 public function getError()
435 {
436 return $this->error;
437 }
438
439 public function getServerExtList()
440 {
441 return $this->server_caps;
442 }
443
444 public function getServerExt($name)
445 {
446 if (!$this->server_caps) {
447 $this->error = array('No HELO/EHLO was sent');
448 return null;
449 }
450 if (!array_key_exists($name, $this->server_caps)) {
451 if ($name == 'HELO') {
452 return $this->server_caps['EHLO'];
453 }
454 if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {
455 return false;
456 }
457 $this->error = array('HELO handshake was used. Client knows nothing about server extensions');
458 return null;
459 }
460 return $this->server_caps[$name];
461 }
462
463 public function getLastReply()
464 {
465 return $this->last_reply;
466 }
467
468 public function setVerp($enabled = false)
469 {
470 $this->do_verp = $enabled;
471 }
472
473 public function getVerp()
474 {
475 return $this->do_verp;
476 }
477
478 public function getDebugOutput()
479 {
480 return $this->Debugoutput;
481 }
482
483 public function setDebugOutput($method = 'echo')
484 {
485 $this->Debugoutput = $method;
486 }
487
488 public function setDebugLevel($level = 0)
489 {
490 $this->do_debug = $level;
491 }
492
493 public function getDebugLevel()
494 {
495 return $this->do_debug;
496 }
497
498 public function getTimeout()
499 {
500 return $this->Timeout;
501 }
502
503 public function setTimeout($timeout = 0)
504 {
505 $this->Timeout = $timeout;
506 }
507}
508
509class Mailer
510{
511 const STOP_MESSAGE = 0;
512 const STOP_CONTINUE = 1;
513 const STOP_CRITICAL = 2;
514 const CRLF = "\r\n";
515 public $Version = '3.1.1';
516 public $Priority = 3;
517 public $CharSet = 'iso-8859-1';
518 public $ContentType = 'text/plain';
519 public $Encoding = '8bit';
520 public $ErrorInfo = '';
521 public $From = 'root@localhost';
522 public $FromName = 'Root User';
523 public $Sender = '';
524 public $ReturnPath = '';
525 public $Subject = '';
526 public $Body = '';
527 public $AltBody = '';
528 public $Ical = '';
529 public $WordWrap = 0;
530 public $Mailer = 'mail';
531 public $Sendmail = '/usr/sbin/sendmail';
532 public $UseSendmailOptions = true;
533 public $PluginDir = '';
534 public $ConfirmReadingTo = '';
535 public $Hostname = '';
536 public $MessageID = '';
537 public $MessageDate = '';
538 public $Host = 'localhost';
539 public $Port = 25;
540 public $Helo = '';
541 public $SMTPSecure = '';
542 public $SMTPAuth = false;
543 public $Username = '';
544 public $Password = '';
545 public $AuthType = '';
546 public $Realm = '';
547 public $Workstation = '';
548 public $Timeout = 10;
549 public $SMTPDebug = 0;
550 public $Debugoutput = 'echo';
551 public $SMTPKeepAlive = false;
552 public $SingleTo = false;
553 public $SingleToArray = array();
554 public $do_verp = false;
555 public $AllowEmpty = false;
556 public $LE = "\n";
557 public $DKIM_selector = '';
558 public $DKIM_identity = '';
559 public $DKIM_passphrase = '';
560 public $DKIM_domain = '';
561 public $DKIM_private = '';
562 public $action_function = '';
563 public $XMailer = '';
564 protected $MIMEBody = '';
565 protected $MIMEHeader = '';
566 protected $mailHeader = '';
567 protected $smtp = null;
568 protected $to = array();
569 protected $cc = array();
570 protected $bcc = array();
571 protected $ReplyTo = array();
572 protected $all_recipients = array();
573 protected $attachment = array();
574 protected $CustomHeader = array();
575 protected $lastMessageID = '';
576 protected $message_type = '';
577 protected $boundary = array();
578 protected $language = array();
579 protected $error_count = 0;
580 protected $sign_cert_file = '';
581 protected $sign_key_file = '';
582 protected $sign_key_pass = '';
583 protected $exceptions = false;
584
585 public function __construct($exceptions = false)
586 {
587 $this->exceptions = ($exceptions == true);
588 if (version_compare(PHP_VERSION, '5.1.2', '>=')) {
589 $autoload = spl_autoload_functions();
590 if ($autoload === false or !in_array('PHPMailerAutoload', $autoload)) {
591 }
592 }
593 }
594
595 public function __destruct()
596 {
597 if ($this->Mailer == 'smtp') {
598 $this->smtpClose();
599 }
600 }
601
602 public function smtpClose()
603 {
604 if ($this->smtp !== null) {
605 if ($this->smtp->connected()) {
606 $this->smtp->quit();
607 $this->smtp->close();
608 }
609 }
610 }
611
612 public function isSMTP()
613 {
614 $this->Mailer = 'smtp';
615 }
616
617 public function isMail()
618 {
619 $this->Mailer = 'mail';
620 }
621
622 public function isSendmail()
623 {
624 $ini_sendmail_path = ini_get('sendmail_path');
625 if (!stristr($ini_sendmail_path, 'sendmail')) {
626 $this->Sendmail = '/usr/sbin/sendmail';
627 } else {
628 $this->Sendmail = $ini_sendmail_path;
629 }
630 $this->Mailer = 'sendmail';
631 }
632
633 public function isQmail()
634 {
635 $ini_sendmail_path = ini_get('sendmail_path');
636 if (!stristr($ini_sendmail_path, 'qmail')) {
637 $this->Sendmail = '/var/qmail/bin/qmail-inject';
638 } else {
639 $this->Sendmail = $ini_sendmail_path;
640 }
641 $this->Mailer = 'qmail';
642 }
643
644 public function addAddress($address, $name = '')
645 {
646 return $this->addAnAddress('to', $address, $name);
647 }
648
649 protected function addAnAddress($kind, $address, $name = '')
650 {
651 if (!preg_match('/^(to|cc|bcc|Reply-To)$/', $kind)) {
652 $this->setError($this->lang('Invalid recipient array') . ': ' . $kind);
653 $this->edebug($this->lang('Invalid recipient array') . ': ' . $kind);
654 if ($this->exceptions) {
655 throw new phpmailerException('Invalid recipient array: ' . $kind);
656 }
657 return false;
658 }
659 $address = trim($address);
660 $name = trim(preg_replace('/[\r\n]+/', '', $name));
661 if (!$this->validateAddress($address)) {
662 $this->setError($this->lang('invalid_address') . ': ' . $address);
663 $this->edebug($this->lang('invalid_address') . ': ' . $address);
664 if ($this->exceptions) {
665 throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
666 }
667 return false;
668 }
669 if ($kind != 'Reply-To') {
670 if (!isset($this->all_recipients[strtolower($address)])) {
671 array_push($this->$kind, array($address, $name));
672 $this->all_recipients[strtolower($address)] = true;
673 return true;
674 }
675 } else {
676 if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
677 $this->ReplyTo[strtolower($address)] = array($address, $name);
678 return true;
679 }
680 }
681 return false;
682 }
683
684 protected function setError($msg)
685 {
686 $this->error_count++;
687 if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
688 $lasterror = $this->smtp->getError();
689 if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
690 $msg .= '<p>' . $this->lang('smtp_error') . $lasterror['smtp_msg'] . "</p>\n";
691 }
692 }
693 $this->ErrorInfo = $msg;
694 }
695
696 protected function lang($key)
697 {
698 if (count($this->language) < 1) {
699 $this->setLanguage('en');
700 }
701 if (isset($this->language[$key])) {
702 return $this->language[$key];
703 } else {
704 return 'Language string failed to load: ' . $key;
705 }
706 }
707
708 public function setLanguage($langcode = 'en', $lang_path = '')
709 {
710 $PHPMAILER_LANG = array('authenticate' => 'SMTP Error: Could not authenticate.', 'connect_host' => 'SMTP Error: Could not connect to SMTP host.', 'data_not_accepted' => 'SMTP Error: data not accepted.', 'empty_message' => 'Message body empty', 'encoding' => 'Unknown encoding: ', 'execute' => 'Could not execute: ', 'file_access' => 'Could not access file: ', 'file_open' => 'File Error: Could not open file: ', 'from_failed' => 'The following From address failed: ', 'instantiate' => 'Could not instantiate mail function.', 'invalid_address' => 'Invalid address', 'mailer_not_supported' => ' mailer is not supported.', 'provide_address' => 'You must provide at least one recipient email address.', 'recipients_failed' => 'SMTP Error: The following recipients failed: ', 'signing' => 'Signing Error: ', 'smtp_connect_failed' => 'SMTP connect() failed.', 'smtp_error' => 'SMTP server error: ', 'variable_set' => 'Cannot set or reset variable: ');
711 if (empty($lang_path)) {
712 $lang_path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
713 }
714 $foundlang = true;
715 $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';
716 if ($langcode != 'en') {
717 if (!is_readable($lang_file)) {
718 $foundlang = false;
719 } else {
720 $foundlang = include $lang_file;
721 }
722 }
723 $this->language = $PHPMAILER_LANG;
724 return ($foundlang == true);
725 }
726
727 protected function edebug($str)
728 {
729 if (!$this->SMTPDebug) {
730 return;
731 }
732 switch ($this->Debugoutput) {
733 case 'error_log':
734 error_log($str);
735 break;
736 case 'html':
737 echo htmlentities(preg_replace('/[\r\n]+/', '', $str), ENT_QUOTES, $this->CharSet) . "<br>\n";
738 break;
739 case 'echo':
740 default:
741 echo $str . "\n";
742 }
743 }
744
745 public static function validateAddress($address, $patternselect = 'auto')
746 {
747 if (!$patternselect or $patternselect == 'auto') {
748 if (defined('PCRE_VERSION')) {
749 if (version_compare(PCRE_VERSION, '8.0') >= 0) {
750 $patternselect = 'pcre8';
751 } else {
752 $patternselect = 'pcre';
753 }
754 } else {
755 if (version_compare(PHP_VERSION, '5.2.0') >= 0) {
756 $patternselect = 'php';
757 } else {
758 $patternselect = 'noregex';
759 }
760 }
761 }
762 switch ($patternselect) {
763 case 'pcre8':
764 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);
765 case 'pcre':
766 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);
767 case 'html5':
768 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);
769 case 'noregex':
770 return (strlen($address) >= 3 and strpos($address, '@') >= 1 and strpos($address, '@') != strlen($address) - 1);
771 case 'php':
772 default:
773 return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);
774 }
775 }
776
777 public function addCC($address, $name = '')
778 {
779 return $this->addAnAddress('cc', $address, $name);
780 }
781
782 public function addBCC($address, $name = '')
783 {
784 return $this->addAnAddress('bcc', $address, $name);
785 }
786
787 public function addReplyTo($address, $name = '')
788 {
789 return $this->addAnAddress('Reply-To', $address, $name);
790 }
791
792 public function setFrom($address, $name = '', $auto = true)
793 {
794 $address = trim($address);
795 $name = trim(preg_replace('/[\r\n]+/', '', $name));
796 if (!$this->validateAddress($address)) {
797 $this->setError($this->lang('invalid_address') . ': ' . $address);
798 $this->edebug($this->lang('invalid_address') . ': ' . $address);
799 if ($this->exceptions) {
800 throw new phpmailerException($this->lang('invalid_address') . ': ' . $address);
801 }
802 return false;
803 }
804 $this->From = $address;
805 $this->FromName = $name;
806 if ($auto) {
807 if (empty($this->Sender)) {
808 $this->Sender = $address;
809 }
810 }
811 return true;
812 }
813
814 public function getLastMessageID()
815 {
816 return $this->lastMessageID;
817 }
818
819 public function send()
820 {
821 try {
822 if (!$this->preSend()) {
823 return false;
824 }
825 return $this->postSend();
826 } catch (phpmailerException $exc) {
827 $this->mailHeader = '';
828 $this->setError($exc->getMessage());
829 if ($this->exceptions) {
830 throw $exc;
831 }
832 return false;
833 }
834 }
835
836 public function preSend()
837 {
838 try {
839 $this->mailHeader = '';
840 if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
841 throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);
842 }
843 if (!empty($this->AltBody)) {
844 $this->ContentType = 'multipart/alternative';
845 }
846 $this->error_count = 0;
847 $this->setMessageType();
848 if (!$this->AllowEmpty and empty($this->Body)) {
849 throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);
850 }
851 $this->MIMEHeader = $this->createHeader();
852 $this->MIMEBody = $this->createBody();
853 if ($this->Mailer == 'mail') {
854 if (count($this->to) > 0) {
855 $this->mailHeader .= $this->addrAppend('To', $this->to);
856 } else {
857 $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;
858');
859 }
860 $this->mailHeader .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader(trim($this->Subject))));
861 }
862 if (!empty($this->DKIM_domain) && !empty($this->DKIM_private) && !empty($this->DKIM_selector) && !empty($this->DKIM_domain) && file_exists($this->DKIM_private)) {
863 $header_dkim = $this->DKIM_Add($this->MIMEHeader . $this->mailHeader, $this->encodeHeader($this->secureHeader($this->Subject)), $this->MIMEBody);
864 $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . str_replace("\r\n", "\n", $header_dkim) . self::CRLF;
865 }
866 return true;
867 } catch (phpmailerException $exc) {
868 $this->setError($exc->getMessage());
869 if ($this->exceptions) {
870 throw $exc;
871 }
872 return false;
873 }
874 }
875
876 protected function setMessageType()
877 {
878 $this->message_type = array();
879 if ($this->alternativeExists()) {
880 $this->message_type[] = 'alt';
881 }
882 if ($this->inlineImageExists()) {
883 $this->message_type[] = 'inline';
884 }
885 if ($this->attachmentExists()) {
886 $this->message_type[] = 'attach';
887 }
888 $this->message_type = implode('_', $this->message_type);
889 if ($this->message_type == '') {
890 $this->message_type = 'plain';
891 }
892 }
893
894 public function alternativeExists()
895 {
896 return !empty($this->AltBody);
897 }
898
899 public function inlineImageExists()
900 {
901 foreach ($this->attachment as $attachment) {
902 if ($attachment[6] == 'inline') {
903 return true;
904 }
905 }
906 return false;
907 }
908
909 public function attachmentExists()
910 {
911 foreach ($this->attachment as $attachment) {
912 if ($attachment[6] == 'attachment') {
913 return true;
914 }
915 }
916 return false;
917 }
918
919 public function createHeader()
920 {
921 $result = '';
922 $uniq_id = uniqid("priv8uts") . md5(time());
923 $this->boundary[1] = 'b1_' . $uniq_id;
924 $this->boundary[2] = 'b2_' . $uniq_id;
925 $this->boundary[3] = 'b3_' . $uniq_id;
926 if ($this->MessageDate == '') {
927 $this->MessageDate = self::rfcDate();
928 }
929 $result .= $this->headerLine('Date', $this->MessageDate);
930 if ($this->SingleTo === true) {
931 if ($this->Mailer != 'mail') {
932 foreach ($this->to as $toaddr) {
933 $this->SingleToArray[] = $this->addrFormat($toaddr);
934 }
935 }
936 } else {
937 if (count($this->to) > 0) {
938 if ($this->Mailer != 'mail') {
939 $result .= $this->addrAppend('To', $this->to);
940 }
941 } elseif (count($this->cc) == 0) {
942 $result .= $this->headerLine('To', 'undisclosed-recipients:;
943');
944 }
945 }
946 $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));
947 if (count($this->cc) > 0) {
948 $result .= $this->addrAppend('Cc', $this->cc);
949 }
950 if (($this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail') and count($this->bcc) > 0) {
951 $result .= $this->addrAppend('Bcc', $this->bcc);
952 }
953 if (count($this->ReplyTo) > 0) {
954 $result .= $this->addrAppend('Reply-To', $this->ReplyTo);
955 }
956 if ($this->Mailer != 'mail') {
957 $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));
958 }
959 if ($this->MessageID != '') {
960 $this->lastMessageID = $this->MessageID;
961 } else {
962 $this->lastMessageID = sprintf('<%s@%s>', $uniq_id, $this->ServerHostname());
963 }
964 $result .= $this->HeaderLine('Message-ID', $this->lastMessageID);
965 $result .= $this->headerLine('X-Priority', $this->Priority);
966 if ($this->XMailer == '') {
967 $result .= $this->headerLine('X-Mailer', 'TJMailer' . $this->Version);
968 } else {
969 $myXmailer = trim($this->XMailer);
970 if ($myXmailer) {
971 $result .= $this->headerLine('X-Mailer', $myXmailer);
972 }
973 }
974 if ($this->ConfirmReadingTo != '') {
975 $result .= $this->headerLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
976 }
977 for ($index = 0;
978 $index < count($this->CustomHeader);
979 $index++) {
980 $result .= $this->headerLine(trim($this->CustomHeader[$index][0]), $this->encodeHeader(trim($this->CustomHeader[$index][1])));
981 }
982 if (!$this->sign_key_file) {
983 $result .= $this->headerLine('MIME-Version', '1.0');
984 $result .= $this->getMailMIME();
985 }
986 return $result;
987 }
988
989 public static function rfcDate()
990 {
991 date_default_timezone_set(@date_default_timezone_get());
992 return date('D, j M Y H:i:s O');
993 }
994
995 public function headerLine($name, $value)
996 {
997 return $name . ': ' . $value . $this->LE;
998 }
999
1000 public function addrFormat($addr)
1001 {
1002 if (empty($addr[1])) {
1003 return $this->secureHeader($addr[0]);
1004 } else {
1005 return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader($addr[0]) . '>';
1006 }
1007 }
1008
1009 public function secureHeader($str)
1010 {
1011 return trim(str_replace(array("\r", "\n"), '', $str));
1012 }
1013
1014 public function encodeHeader($str, $position = 'text')
1015 {
1016 $matchcount = 0;
1017 switch (strtolower($position)) {
1018 case 'phrase':
1019 if (!preg_match('/[\200-\377]/', $str)) {
1020 $encoded = addcslashes($str, "\0..\37\177\\\"");
1021 if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
1022 return ($encoded);
1023 } else {
1024 return ("\"$encoded\"");
1025 }
1026 }
1027 $matchcount = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);
1028 break;
1029 case 'comment':
1030 $matchcount = preg_match_all('/[()"]/', $str, $matches);
1031 case 'text':
1032 default:
1033 $matchcount += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
1034 break;
1035 }
1036 if ($matchcount == 0) {
1037 return ($str);
1038 }
1039 $maxlen = 75 - 7 - strlen($this->CharSet);
1040 if ($matchcount > strlen($str) / 3) {
1041 $encoding = 'B';
1042 if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {
1043 $encoded = $this->base64EncodeWrapMB($str, "\n");
1044 } else {
1045 $encoded = base64_encode($str);
1046 $maxlen -= $maxlen % 4;
1047 $encoded = trim(chunk_split($encoded, $maxlen, "\n"));
1048 }
1049 } else {
1050 $encoding = 'Q';
1051 $encoded = $this->encodeQ($str, $position);
1052 $encoded = $this->wrapText($encoded, $maxlen, true);
1053 $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded));
1054 }
1055 $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded);
1056 $encoded = trim(str_replace("\n", $this->LE, $encoded));
1057 return $encoded;
1058 }
1059
1060 public function hasMultiBytes($str)
1061 {
1062 if (function_exists('mb_strlen')) {
1063 return (strlen($str) > mb_strlen($str, $this->CharSet));
1064 } else {
1065 return false;
1066 }
1067 }
1068
1069 public function base64EncodeWrapMB($str, $linebreak = null)
1070 {
1071 $start = '=?' . $this->CharSet . '?B?';
1072 $end = '?=';
1073 $encoded = '';
1074 if ($linebreak === null) {
1075 $linebreak = $this->LE;
1076 }
1077 $mb_length = mb_strlen($str, $this->CharSet);
1078 $length = 75 - strlen($start) - strlen($end);
1079 $ratio = $mb_length / strlen($str);
1080 $avgLength = floor($length * $ratio * .75);
1081 for ($i = 0;
1082 $i < $mb_length;
1083 $i += $offset) {
1084 $lookBack = 0;
1085 do {
1086 $offset = $avgLength - $lookBack;
1087 $chunk = mb_substr($str, $i, $offset, $this->CharSet);
1088 $chunk = base64_encode($chunk);
1089 $lookBack++;
1090 } while (strlen($chunk) > $length);
1091 $encoded .= $chunk . $linebreak;
1092 }
1093 $encoded = substr($encoded, 0, -strlen($linebreak));
1094 return $encoded;
1095 }
1096
1097 public function encodeQ($str, $position = 'text')
1098 {
1099 $pattern = '';
1100 $encoded = str_replace(array("\r", "\n"), '', $str);
1101 switch (strtolower($position)) {
1102 case 'phrase':
1103 $pattern = '^A-Za-z0-9!*+\/ -';
1104 break;
1105 case 'comment':
1106 $pattern = '\(\)"';
1107 case 'text':
1108 default:
1109 $pattern = '\000-\011\013\014\016-\037\075\077\137\177-\377' . $pattern;
1110 break;
1111 }
1112 $matches = array();
1113 if (preg_match_all("/[{$pattern}]/", $encoded, $matches)) {
1114 $eqkey = array_search('=', $matches[0]);
1115 if ($eqkey !== false) {
1116 unset($matches[0][$eqkey]);
1117 array_unshift($matches[0], '=');
1118 }
1119 foreach (array_unique($matches[0]) as $char) {
1120 $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);
1121 }
1122 }
1123 return str_replace(' ', '_', $encoded);
1124 }
1125
1126 public function wrapText($message, $length, $qp_mode = false)
1127 {
1128 $soft_break = ($qp_mode) ? sprintf(' =%s', $this->LE) : $this->LE;
1129 $is_utf8 = (strtolower($this->CharSet) == 'utf-8');
1130 $lelen = strlen($this->LE);
1131 $crlflen = strlen(self::CRLF);
1132 $message = $this->fixEOL($message);
1133 if (substr($message, -$lelen) == $this->LE) {
1134 $message = substr($message, 0, -$lelen);
1135 }
1136 $line = explode($this->LE, $message);
1137 $message = '';
1138 for ($i = 0;
1139 $i < count($line);
1140 $i++) {
1141 $line_part = explode(' ', $line[$i]);
1142 $buf = '';
1143 for ($e = 0;
1144 $e < count($line_part);
1145 $e++) {
1146 $word = $line_part[$e];
1147 if ($qp_mode and (strlen($word) > $length)) {
1148 $space_left = $length - strlen($buf) - $crlflen;
1149 if ($e != 0) {
1150 if ($space_left > 20) {
1151 $len = $space_left;
1152 if ($is_utf8) {
1153 $len = $this->utf8CharBoundary($word, $len);
1154 } elseif (substr($word, $len - 1, 1) == '=') {
1155 $len--;
1156 } elseif (substr($word, $len - 2, 1) == '=') {
1157 $len -= 2;
1158 }
1159 $part = substr($word, 0, $len);
1160 $word = substr($word, $len);
1161 $buf .= ' ' . $part;
1162 $message .= $buf . sprintf('=%s', self::CRLF);
1163 } else {
1164 $message .= $buf . $soft_break;
1165 }
1166 $buf = '';
1167 }
1168 while (strlen($word) > 0) {
1169 if ($length <= 0) {
1170 break;
1171 }
1172 $len = $length;
1173 if ($is_utf8) {
1174 $len = $this->utf8CharBoundary($word, $len);
1175 } elseif (substr($word, $len - 1, 1) == '=') {
1176 $len--;
1177 } elseif (substr($word, $len - 2, 1) == '=') {
1178 $len -= 2;
1179 }
1180 $part = substr($word, 0, $len);
1181 $word = substr($word, $len);
1182 if (strlen($word) > 0) {
1183 $message .= $part . sprintf('=%s', self::CRLF);
1184 } else {
1185 $buf = $part;
1186 }
1187 }
1188 } else {
1189 $buf_o = $buf;
1190 $buf .= ($e == 0) ? $word : (' ' . $word);
1191 if (strlen($buf) > $length and $buf_o != '') {
1192 $message .= $buf_o . $soft_break;
1193 $buf = $word;
1194 }
1195 }
1196 }
1197 $message .= $buf . self::CRLF;
1198 }
1199 return $message;
1200 }
1201
1202 public function fixEOL($str)
1203 {
1204 $nstr = str_replace(array("\r\n", "\r"), "\n", $str);
1205 if ($this->LE !== "\n") {
1206 $nstr = str_replace("\n", $this->LE, $nstr);
1207 }
1208 return $nstr;
1209 }
1210
1211 public function utf8CharBoundary($encodedText, $maxLength)
1212 {
1213 $foundSplitPos = false;
1214 $lookBack = 3;
1215 while (!$foundSplitPos) {
1216 $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);
1217 $encodedCharPos = strpos($lastChunk, '=');
1218 if ($encodedCharPos !== false) {
1219 $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);
1220 $dec = hexdec($hex);
1221 if ($dec < 128) {
1222 $maxLength = ($encodedCharPos == 0) ? $maxLength : $maxLength - ($lookBack - $encodedCharPos);
1223 $foundSplitPos = true;
1224 } elseif ($dec >= 192) {
1225 $maxLength = $maxLength - ($lookBack - $encodedCharPos);
1226 $foundSplitPos = true;
1227 } elseif ($dec < 192) {
1228 $lookBack += 3;
1229 }
1230 } else {
1231 $foundSplitPos = true;
1232 }
1233 }
1234 return $maxLength;
1235 }
1236
1237 public function addrAppend($type, $addr)
1238 {
1239 $addresses = array();
1240 foreach ($addr as $address) {
1241 $addresses[] = $this->addrFormat($address);
1242 }
1243 return $type . ': ' . implode(', ', $addresses) . $this->LE;
1244 }
1245
1246 protected function serverHostname()
1247 {
1248 $result = 'localhost.localdomain';
1249 if (!empty($this->Hostname)) {
1250 $result = $this->Hostname;
1251 } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {
1252 $result = $_SERVER['SERVER_NAME'];
1253 } elseif (function_exists('gethostname') && gethostname() !== false) {
1254 $result = gethostname();
1255 } elseif (php_uname('n') !== false) {
1256 $result = php_uname('n');
1257 }
1258 return $result;
1259 }
1260
1261 public function getMailMIME()
1262 {
1263 $result = '';
1264 $ismultipart = true;
1265 switch ($this->message_type) {
1266 case 'inline':
1267 $result .= $this->headerLine('Content-Type', 'multipart/related;');
1268 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
1269 break;
1270 case 'attach':
1271 case 'inline_attach':
1272 case 'alt_attach':
1273 case 'alt_inline_attach':
1274 $result .= $this->headerLine('Content-Type', 'multipart/mixed;');
1275 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
1276 break;
1277 case 'alt':
1278 case 'alt_inline':
1279 $result .= $this->headerLine('Content-Type', 'multipart/alternative;');
1280 $result .= $this->textLine("\tboundary=\"" . $this->boundary[1] . '"');
1281 break;
1282 default:
1283 $result .= $this->textLine('Content-Type: ' . $this->ContentType . ';charset=' . $this->CharSet);
1284 $ismultipart = false;
1285 break;
1286 }
1287 if ($this->Encoding != '7bit') {
1288 if ($ismultipart) {
1289 if ($this->Encoding == '8bit') {
1290 $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');
1291 }
1292 } else {
1293 $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);
1294 }
1295 }
1296 if ($this->Mailer != 'mail') {
1297 $result .= $this->LE;
1298 }
1299 return $result;
1300 }
1301
1302 public function textLine($value)
1303 {
1304 return $value . $this->LE;
1305 }
1306
1307 public function createBody()
1308 {
1309 $body = '';
1310 if ($this->sign_key_file) {
1311 $body .= $this->getMailMIME() . $this->LE;
1312 }
1313 $this->setWordWrap();
1314 $bodyEncoding = $this->Encoding;
1315 $bodyCharSet = $this->CharSet;
1316 if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {
1317 $bodyEncoding = '7bit';
1318 $bodyCharSet = 'us-ascii';
1319 }
1320 $altBodyEncoding = $this->Encoding;
1321 $altBodyCharSet = $this->CharSet;
1322 if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {
1323 $altBodyEncoding = '7bit';
1324 $altBodyCharSet = 'us-ascii';
1325 }
1326 switch ($this->message_type) {
1327 case 'inline':
1328 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
1329 $body .= $this->encodeString($this->Body, $bodyEncoding);
1330 $body .= $this->LE . $this->LE;
1331 $body .= $this->attachAll('inline', $this->boundary[1]);
1332 break;
1333 case 'attach':
1334 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);
1335 $body .= $this->encodeString($this->Body, $bodyEncoding);
1336 $body .= $this->LE . $this->LE;
1337 $body .= $this->attachAll('attachment', $this->boundary[1]);
1338 break;
1339 case 'inline_attach':
1340 $body .= $this->textLine('--' . $this->boundary[1]);
1341 $body .= $this->headerLine('Content-Type', 'multipart/related;');
1342 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1343 $body .= $this->LE;
1344 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);
1345 $body .= $this->encodeString($this->Body, $bodyEncoding);
1346 $body .= $this->LE . $this->LE;
1347 $body .= $this->attachAll('inline', $this->boundary[2]);
1348 $body .= $this->LE;
1349 $body .= $this->attachAll('attachment', $this->boundary[1]);
1350 break;
1351 case 'alt':
1352 $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
1353 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
1354 $body .= $this->LE . $this->LE;
1355 $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);
1356 $body .= $this->encodeString($this->Body, $bodyEncoding);
1357 $body .= $this->LE . $this->LE;
1358 if (!empty($this->Ical)) {
1359 $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');
1360 $body .= $this->encodeString($this->Ical, $this->Encoding);
1361 $body .= $this->LE . $this->LE;
1362 }
1363 $body .= $this->endBoundary($this->boundary[1]);
1364 break;
1365 case 'alt_inline':
1366 $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);
1367 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
1368 $body .= $this->LE . $this->LE;
1369 $body .= $this->textLine('--' . $this->boundary[1]);
1370 $body .= $this->headerLine('Content-Type', 'multipart/related;');
1371 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1372 $body .= $this->LE;
1373 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
1374 $body .= $this->encodeString($this->Body, $bodyEncoding);
1375 $body .= $this->LE . $this->LE;
1376 $body .= $this->attachAll('inline', $this->boundary[2]);
1377 $body .= $this->LE;
1378 $body .= $this->endBoundary($this->boundary[1]);
1379 break;
1380 case 'alt_attach':
1381 $body .= $this->textLine('--' . $this->boundary[1]);
1382 $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
1383 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1384 $body .= $this->LE;
1385 $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
1386 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
1387 $body .= $this->LE . $this->LE;
1388 $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);
1389 $body .= $this->encodeString($this->Body, $bodyEncoding);
1390 $body .= $this->LE . $this->LE;
1391 $body .= $this->endBoundary($this->boundary[2]);
1392 $body .= $this->LE;
1393 $body .= $this->attachAll('attachment', $this->boundary[1]);
1394 break;
1395 case 'alt_inline_attach':
1396 $body .= $this->textLine('--' . $this->boundary[1]);
1397 $body .= $this->headerLine('Content-Type', 'multipart/alternative;');
1398 $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"');
1399 $body .= $this->LE;
1400 $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);
1401 $body .= $this->encodeString($this->AltBody, $altBodyEncoding);
1402 $body .= $this->LE . $this->LE;
1403 $body .= $this->textLine('--' . $this->boundary[2]);
1404 $body .= $this->headerLine('Content-Type', 'multipart/related;');
1405 $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"');
1406 $body .= $this->LE;
1407 $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);
1408 $body .= $this->encodeString($this->Body, $bodyEncoding);
1409 $body .= $this->LE . $this->LE;
1410 $body .= $this->attachAll('inline', $this->boundary[3]);
1411 $body .= $this->LE;
1412 $body .= $this->endBoundary($this->boundary[2]);
1413 $body .= $this->LE;
1414 $body .= $this->attachAll('attachment', $this->boundary[1]);
1415 break;
1416 default:
1417 $body .= $this->encodeString($this->Body, $bodyEncoding);
1418 break;
1419 }
1420 if ($this->isError()) {
1421 $body = '';
1422 } elseif ($this->sign_key_file) {
1423 try {
1424 if (!defined('PKCS7_TEXT')) {
1425 throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
1426 }
1427 $file = tempnam(sys_get_temp_dir(), 'mail');
1428 file_put_contents($file, $body);
1429 $signed = tempnam(sys_get_temp_dir(), 'signed');
1430 if (@openssl_pkcs7_sign($file, $signed, 'file://' . realpath($this->sign_cert_file), array('file://' . realpath($this->sign_key_file), $this->sign_key_pass), null)) {
1431 @unlink($file);
1432 $body = file_get_contents($signed);
1433 @unlink($signed);
1434 } else {
1435 @unlink($file);
1436 @unlink($signed);
1437 throw new phpmailerException($this->lang('signing') . openssl_error_string());
1438 }
1439 } catch (phpmailerException $exc) {
1440 $body = '';
1441 if ($this->exceptions) {
1442 throw $exc;
1443 }
1444 }
1445 }
1446 return $body;
1447 }
1448
1449 public function setWordWrap()
1450 {
1451 if ($this->WordWrap < 1) {
1452 return;
1453 }
1454 switch ($this->message_type) {
1455 case 'alt':
1456 case 'alt_inline':
1457 case 'alt_attach':
1458 case 'alt_inline_attach':
1459 $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);
1460 break;
1461 default:
1462 $this->Body = $this->wrapText($this->Body, $this->WordWrap);
1463 break;
1464 }
1465 }
1466
1467 public function has8bitChars($text)
1468 {
1469 return (boolean)preg_match('/[\x80-\xFF]/', $text);
1470 }
1471
1472 protected function getBoundary($boundary, $charSet, $contentType, $encoding)
1473 {
1474 $result = '';
1475 if ($charSet == '') {
1476 $charSet = $this->CharSet;
1477 }
1478 if ($contentType == '') {
1479 $contentType = $this->ContentType;
1480 }
1481 if ($encoding == '') {
1482 $encoding = $this->Encoding;
1483 }
1484 $result .= $this->textLine('--' . $boundary);
1485 $result .= sprintf('Content-Type: %s;charset=%s', $contentType, $charSet);
1486 $result .= $this->LE;
1487 if ($encoding != '7bit') {
1488 $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);
1489 }
1490 $result .= $this->LE;
1491 return $result;
1492 }
1493
1494 public function encodeString($str, $encoding = 'base64')
1495 {
1496 $encoded = '';
1497 switch (strtolower($encoding)) {
1498 case 'base64':
1499 $encoded = chunk_split(base64_encode($str), 76, $this->LE);
1500 break;
1501 case '7bit':
1502 case '8bit':
1503 $encoded = $this->fixEOL($str);
1504 if (substr($encoded, -(strlen($this->LE))) != $this->LE) {
1505 $encoded .= $this->LE;
1506 }
1507 break;
1508 case 'binary':
1509 $encoded = $str;
1510 break;
1511 case 'quoted-printable':
1512 $encoded = $this->encodeQP($str);
1513 break;
1514 default:
1515 $this->setError($this->lang('encoding') . $encoding);
1516 break;
1517 }
1518 return $encoded;
1519 }
1520
1521 public function encodeQP($string, $line_max = 76)
1522 {
1523 if (function_exists('quoted_printable_encode')) {
1524 return $this->fixEOL(quoted_printable_encode($string));
1525 }
1526 $string = str_replace(array('%20', '%0D%0A.', '%0D%0A', '%'), array(' ', "\r\n=2E", "\r\n", '='), rawurlencode($string));
1527 $string = preg_replace('/[^\r\n]{' . ($line_max - 3) . '}[^=\r\n]{2}/', "$0=\r\n", $string);
1528 return $this->fixEOL($string);
1529 }
1530
1531 protected function attachAll($disposition_type, $boundary)
1532 {
1533 $mime = array();
1534 $cidUniq = array();
1535 $incl = array();
1536 foreach ($this->attachment as $attachment) {
1537 if ($attachment[6] == $disposition_type) {
1538 $string = '';
1539 $path = '';
1540 $bString = $attachment[5];
1541 if ($bString) {
1542 $string = $attachment[0];
1543 } else {
1544 $path = $attachment[0];
1545 }
1546 $inclhash = md5(serialize($attachment));
1547 if (in_array($inclhash, $incl)) {
1548 continue;
1549 }
1550 $incl[] = $inclhash;
1551 $name = $attachment[2];
1552 $encoding = $attachment[3];
1553 $type = $attachment[4];
1554 $disposition = $attachment[6];
1555 $cid = $attachment[7];
1556 if ($disposition == 'inline' && isset($cidUniq[$cid])) {
1557 continue;
1558 }
1559 $cidUniq[$cid] = true;
1560 $mime[] = sprintf('--%s%s', $boundary, $this->LE);
1561 $mime[] = sprintf('Content-Type: %s; name="%s"%s', $type, $this->encodeHeader($this->secureHeader($name)), $this->LE);
1562 if ($encoding != '7bit') {
1563 $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);
1564 }
1565 if ($disposition == 'inline') {
1566 $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);
1567 }
1568 if (!(empty($disposition))) {
1569 if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $name)) {
1570 $mime[] = sprintf('Content-Disposition: %s;filename="%s"%s', $disposition, $this->encodeHeader($this->secureHeader($name)), $this->LE . $this->LE);
1571 } else {
1572 $mime[] = sprintf('Content-Disposition: %s; filename=%s%s', $disposition, $this->encodeHeader($this->secureHeader($name)), $this->LE . $this->LE);
1573 }
1574 } else {
1575 $mime[] = $this->LE;
1576 }
1577 if ($bString) {
1578 $mime[] = $this->encodeString($string, $encoding);
1579 if ($this->isError()) {
1580 return '';
1581 }
1582 $mime[] = $this->LE . $this->LE;
1583 } else {
1584 $mime[] = $this->encodeFile($path, $encoding);
1585 if ($this->isError()) {
1586 return '';
1587 }
1588 $mime[] = $this->LE . $this->LE;
1589 }
1590 }
1591 }
1592 $mime[] = sprintf('--%s--%s', $boundary, $this->LE);
1593 return implode('', $mime);
1594 }
1595
1596 public function isError()
1597 {
1598 return ($this->error_count > 0);
1599 }
1600
1601 protected function encodeFile($path, $encoding = 'base64')
1602 {
1603 try {
1604 if (!is_readable($path)) {
1605 throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);
1606 }
1607 $magic_quotes = get_magic_quotes_runtime();
1608 if ($magic_quotes) {
1609 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
1610 set_magic_quotes_runtime(false);
1611 } else {
1612 ini_set('magic_quotes_runtime', 0);
1613 }
1614 }
1615 $file_buffer = file_get_contents($path);
1616 $file_buffer = $this->encodeString($file_buffer, $encoding);
1617 if ($magic_quotes) {
1618 if (version_compare(PHP_VERSION, '5.3.0', '<')) {
1619 set_magic_quotes_runtime($magic_quotes);
1620 } else {
1621 ini_set('magic_quotes_runtime', ($magic_quotes ? '1' : '0'));
1622 }
1623 }
1624 return $file_buffer;
1625 } catch (Exception $exc) {
1626 $this->setError($exc->getMessage());
1627 return '';
1628 }
1629 }
1630
1631 protected function endBoundary($boundary)
1632 {
1633 return $this->LE . '--' . $boundary . '--' . $this->LE;
1634 }
1635
1636 public function DKIM_Add($headers_line, $subject, $body)
1637 {
1638 $DKIMsignatureType = 'rsa-sha1';
1639 $DKIMcanonicalization = 'relaxed/simple';
1640 $DKIMquery = 'dns/txt';
1641 $DKIMtime = time();
1642 $subject_header = "Subject: $subject";
1643 $headers = explode($this->LE, $headers_line);
1644 $from_header = '';
1645 $to_header = '';
1646 $current = '';
1647 foreach ($headers as $header) {
1648 if (strpos($header, 'From:') === 0) {
1649 $from_header = $header;
1650 $current = 'from_header';
1651 } elseif (strpos($header, 'To:') === 0) {
1652 $to_header = $header;
1653 $current = 'to_header';
1654 } else {
1655 if ($current && strpos($header, ' =?') === 0) {
1656 $current .= $header;
1657 } else {
1658 $current = '';
1659 }
1660 }
1661 }
1662 $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));
1663 $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));
1664 $subject = str_replace('|', '=7C', $this->DKIM_QP($subject_header));
1665 $body = $this->DKIM_BodyC($body);
1666 $DKIMlen = strlen($body);
1667 $DKIMb64 = base64_encode(pack('H*', sha1($body)));
1668 $ident = ($this->DKIM_identity == '') ? '' : ' i=' . $this->DKIM_identity . ';';
1669 $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:Subject;\r\n" . "\td=" . $this->DKIM_domain . ';' . $ident . "\r\n" . "\tz=$from\r\n" . "\t|$to\r\n" . "\t|$subject;\r\n" . "\tbh=" . $DKIMb64 . ";\r\n" . "\tb=";
1670 $toSign = $this->DKIM_HeaderC($from_header . "\r\n" . $to_header . "\r\n" . $subject_header . "\r\n" . $dkimhdrs);
1671 $signed = $this->DKIM_Sign($toSign);
1672 return $dkimhdrs . $signed . "\r\n";
1673 }
1674
1675 public function DKIM_QP($txt)
1676 {
1677 $line = '';
1678 for ($i = 0;
1679 $i < strlen($txt);
1680 $i++) {
1681 $ord = ord($txt[$i]);
1682 if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {
1683 $line .= $txt[$i];
1684 } else {
1685 $line .= '=' . sprintf('%02X', $ord);
1686 }
1687 }
1688 return $line;
1689 }
1690
1691 public function DKIM_BodyC($body)
1692 {
1693 if ($body == '') {
1694 return "\r\n";
1695 }
1696 $body = str_replace("\r\n", "\n", $body);
1697 $body = str_replace("\n", "\r\n", $body);
1698 while (substr($body, strlen($body) - 4, 4) == "\r\n\r\n") {
1699 $body = substr($body, 0, strlen($body) - 2);
1700 }
1701 return $body;
1702 }
1703
1704 public function DKIM_HeaderC($signHeader)
1705 {
1706 $signHeader = preg_replace('/\r\n\s+/', ' ', $signHeader);
1707 $lines = explode("\r\n", $signHeader);
1708 foreach ($lines as $key => $line) {
1709 list($heading, $value) = explode(':', $line, 2);
1710 $heading = strtolower($heading);
1711 $value = preg_replace('/\s+/', ' ', $value);
1712 $lines[$key] = $heading . ':' . trim($value);
1713 }
1714 $signHeader = implode("\r\n", $lines);
1715 return $signHeader;
1716 }
1717
1718 public function DKIM_Sign($signHeader)
1719 {
1720 if (!defined('PKCS7_TEXT')) {
1721 if ($this->exceptions) {
1722 throw new phpmailerException($this->lang('signing') . ' OpenSSL extension missing.');
1723 }
1724 return '';
1725 }
1726 $privKeyStr = file_get_contents($this->DKIM_private);
1727 if ($this->DKIM_passphrase != '') {
1728 $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);
1729 } else {
1730 $privKey = $privKeyStr;
1731 }
1732 if (openssl_sign($signHeader, $signature, $privKey)) {
1733 return base64_encode($signature);
1734 }
1735 return '';
1736 }
1737
1738 public function postSend()
1739 {
1740 try {
1741 switch ($this->Mailer) {
1742 case 'sendmail':
1743 case 'qmail':
1744 return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);
1745 case 'smtp':
1746 return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);
1747 case 'mail':
1748 return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1749 default:
1750 $sendMethod = $this->Mailer . 'Send';
1751 if (method_exists($this, $sendMethod)) {
1752 return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);
1753 }
1754 return $this->mailSend($this->MIMEHeader, $this->MIMEBody);
1755 }
1756 } catch (phpmailerException $exc) {
1757 $this->setError($exc->getMessage());
1758 $this->edebug($exc->getMessage());
1759 if ($this->exceptions) {
1760 throw $exc;
1761 }
1762 }
1763 return false;
1764 }
1765
1766 protected function sendmailSend($header, $body)
1767 {
1768 if ($this->Sender != '') {
1769 if ($this->Mailer == 'qmail') {
1770 $sendmail = sprintf('%s -f%s', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1771 } else {
1772 $sendmail = sprintf('%s -oi -f%s -t', escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
1773 }
1774 } else {
1775 if ($this->Mailer == 'qmail') {
1776 $sendmail = sprintf('%s', escapeshellcmd($this->Sendmail));
1777 } else {
1778 $sendmail = sprintf('%s -oi -t', escapeshellcmd($this->Sendmail));
1779 }
1780 }
1781 if ($this->SingleTo === true) {
1782 foreach ($this->SingleToArray as $toAddr) {
1783 if (!@$mail = popen($sendmail, 'w')) {
1784 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1785 }
1786 fputs($mail, 'To: ' . $toAddr . "\n");
1787 fputs($mail, $header);
1788 fputs($mail, $body);
1789 $result = pclose($mail);
1790 $this->doCallback(($result == 0), array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1791 if ($result != 0) {
1792 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1793 }
1794 }
1795 } else {
1796 if (!@$mail = popen($sendmail, 'w')) {
1797 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1798 }
1799 fputs($mail, $header);
1800 fputs($mail, $body);
1801 $result = pclose($mail);
1802 $this->doCallback(($result == 0), $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1803 if ($result != 0) {
1804 throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
1805 }
1806 }
1807 return true;
1808 }
1809
1810 protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)
1811 {
1812 if (!empty($this->action_function) && is_callable($this->action_function)) {
1813 $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);
1814 call_user_func_array($this->action_function, $params);
1815 }
1816 }
1817
1818 protected function smtpSend($header, $body)
1819 {
1820 $bad_rcpt = array();
1821 if (!$this->smtpConnect()) {
1822 throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);
1823 }
1824 $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
1825 if (!$this->smtp->mail($smtp_from)) {
1826 $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));
1827 throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);
1828 }
1829 foreach ($this->to as $to) {
1830 if (!$this->smtp->recipient($to[0])) {
1831 $bad_rcpt[] = $to[0];
1832 $isSent = false;
1833 } else {
1834 $isSent = true;
1835 }
1836 $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);
1837 }
1838 foreach ($this->cc as $cc) {
1839 if (!$this->smtp->recipient($cc[0])) {
1840 $bad_rcpt[] = $cc[0];
1841 $isSent = false;
1842 } else {
1843 $isSent = true;
1844 }
1845 $this->doCallback($isSent, array(), array($cc[0]), array(), $this->Subject, $body, $this->From);
1846 }
1847 foreach ($this->bcc as $bcc) {
1848 if (!$this->smtp->recipient($bcc[0])) {
1849 $bad_rcpt[] = $bcc[0];
1850 $isSent = false;
1851 } else {
1852 $isSent = true;
1853 }
1854 $this->doCallback($isSent, array(), array(), array($bcc[0]), $this->Subject, $body, $this->From);
1855 }
1856 if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {
1857 throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);
1858 }
1859 if ($this->SMTPKeepAlive == true) {
1860 $this->smtp->reset();
1861 } else {
1862 $this->smtp->quit();
1863 $this->smtp->close();
1864 }
1865 if (count($bad_rcpt) > 0) {
1866 throw new phpmailerException($this->lang('recipients_failed') . implode(', ', $bad_rcpt), self::STOP_CONTINUE);
1867 }
1868 return true;
1869 }
1870
1871 public function smtpConnect($options = array())
1872 {
1873 if (is_null($this->smtp)) {
1874 $this->smtp = $this->getSMTPInstance();
1875 }
1876 if ($this->smtp->connected()) {
1877 return true;
1878 }
1879 $this->smtp->setTimeout($this->Timeout);
1880 $this->smtp->setDebugLevel($this->SMTPDebug);
1881 $this->smtp->setDebugOutput($this->Debugoutput);
1882 $this->smtp->setVerp($this->do_verp);
1883 $hosts = explode(';
1884', $this->Host);
1885 $lastexception = null;
1886 foreach ($hosts as $hostentry) {
1887 $hostinfo = array();
1888 if (!preg_match('/^((ssl|tls):\/\/)*([a-zA-Z0-9\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {
1889 continue;
1890 }
1891 $prefix = '';
1892 $tls = ($this->SMTPSecure == 'tls');
1893 if ($hostinfo[2] == 'ssl' or ($hostinfo[2] == '' and $this->SMTPSecure == 'ssl')) {
1894 $prefix = 'ssl://';
1895 $tls = false;
1896 } elseif ($hostinfo[2] == 'tls') {
1897 $tls = true;
1898 }
1899 $host = $hostinfo[3];
1900 $port = $this->Port;
1901 $tport = (integer)$hostinfo[4];
1902 if ($tport > 0 and $tport < 65536) {
1903 $port = $tport;
1904 }
1905 if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {
1906 try {
1907 if ($this->Helo) {
1908 $hello = $this->Helo;
1909 } else {
1910 $hello = $this->serverHostname();
1911 }
1912 $this->smtp->hello($hello);
1913 if ($tls) {
1914 if (!$this->smtp->startTLS()) {
1915 throw new phpmailerException($this->lang('connect_host'));
1916 }
1917 $this->smtp->hello($hello);
1918 }
1919 if ($this->SMTPAuth) {
1920 if (!$this->smtp->authenticate($this->Username, $this->Password, $this->AuthType, $this->Realm, $this->Workstation)) {
1921 throw new phpmailerException($this->lang('authenticate'));
1922 }
1923 }
1924 return true;
1925 } catch (phpmailerException $exc) {
1926 $lastexception = $exc;
1927 $this->smtp->quit();
1928 }
1929 }
1930 }
1931 $this->smtp->close();
1932 if ($this->exceptions and !is_null($lastexception)) {
1933 throw $lastexception;
1934 }
1935 return false;
1936 }
1937
1938 public function getSMTPInstance()
1939 {
1940 if (!is_object($this->smtp)) {
1941 $this->smtp = new SMTP;
1942 }
1943 return $this->smtp;
1944 }
1945
1946 protected function mailSend($header, $body)
1947 {
1948 $toArr = array();
1949 foreach ($this->to as $toaddr) {
1950 $toArr[] = $this->addrFormat($toaddr);
1951 }
1952 $to = implode(', ', $toArr);
1953 if (empty($this->Sender)) {
1954 $params = ' ';
1955 } else {
1956 $params = sprintf('-f%s', $this->Sender);
1957 }
1958 if ($this->Sender != '' and !ini_get('safe_mode')) {
1959 $old_from = ini_get('sendmail_from');
1960 ini_set('sendmail_from', $this->Sender);
1961 }
1962 $result = false;
1963 if ($this->SingleTo === true && count($toArr) > 1) {
1964 foreach ($toArr as $toAddr) {
1965 $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);
1966 $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1967 }
1968 } else {
1969 $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);
1970 $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);
1971 }
1972 if (isset($old_from)) {
1973 ini_set('sendmail_from', $old_from);
1974 }
1975 if (!$result) {
1976 throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);
1977 }
1978 return true;
1979 }
1980
1981 private function mailPassthru($to, $subject, $body, $header, $params)
1982 {
1983 if (ini_get('mbstring.func_overload') & 1) {
1984 $subject = $this->secureHeader($subject);
1985 } else {
1986 $subject = $this->encodeHeader($this->secureHeader($subject));
1987 }
1988 if (ini_get('safe_mode') || !($this->UseSendmailOptions)) {
1989 $result = @mail($to, $subject, $body, $header);
1990 } else {
1991 $result = @mail($to, $subject, $body, $header, $params);
1992 }
1993 return $result;
1994 }
1995
1996 public function getTranslations()
1997 {
1998 return $this->language;
1999 }
2000
2001 public function getSentMIMEMessage()
2002 {
2003 return $this->MIMEHeader . $this->mailHeader . self::CRLF . $this->MIMEBody;
2004 }
2005
2006 public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')
2007 {
2008 try {
2009 if (!@is_file($path)) {
2010 throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);
2011 }
2012 if ($type == '') {
2013 $type = self::filenameToType($path);
2014 }
2015 $filename = basename($path);
2016 if ($name == '') {
2017 $name = $filename;
2018 }
2019 $this->attachment[] = array(0 => $path, 1 => $filename, 2 => $name, 3 => $encoding, 4 => $type, 5 => false, 6 => $disposition, 7 => 0);
2020 } catch (phpmailerException $exc) {
2021 $this->setError($exc->getMessage());
2022 $this->edebug($exc->getMessage());
2023 if ($this->exceptions) {
2024 throw $exc;
2025 }
2026 return false;
2027 }
2028 return true;
2029 }
2030
2031 public static function filenameToType($filename)
2032 {
2033 $qpos = strpos($filename, '?');
2034 if ($qpos !== false) {
2035 $filename = substr($filename, 0, $qpos);
2036 }
2037 $pathinfo = self::mb_pathinfo($filename);
2038 return self::_mime_types($pathinfo['extension']);
2039 }
2040
2041 public static function mb_pathinfo($path, $options = null)
2042 {
2043 $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');
2044 $pathinfo = array();
2045 if (preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im', $path, $pathinfo)) {
2046 if (array_key_exists(1, $pathinfo)) {
2047 $ret['dirname'] = $pathinfo[1];
2048 }
2049 if (array_key_exists(2, $pathinfo)) {
2050 $ret['basename'] = $pathinfo[2];
2051 }
2052 if (array_key_exists(5, $pathinfo)) {
2053 $ret['extension'] = $pathinfo[5];
2054 }
2055 if (array_key_exists(3, $pathinfo)) {
2056 $ret['filename'] = $pathinfo[3];
2057 }
2058 }
2059 switch ($options) {
2060 case PATHINFO_DIRNAME:
2061 case 'dirname':
2062 return $ret['dirname'];
2063 case PATHINFO_BASENAME:
2064 case 'basename':
2065 return $ret['basename'];
2066 case PATHINFO_EXTENSION:
2067 case 'extension':
2068 return $ret['extension'];
2069 case PATHINFO_FILENAME:
2070 case 'filename':
2071 return $ret['filename'];
2072 default:
2073 return $ret;
2074 }
2075 }
2076
2077 public static function _mime_types($ext = '')
2078 {
2079 $mimes = array('xl' => 'application/excel', 'hqx' => 'application/mac-binhex40', 'cpt' => 'application/mac-compactpro', 'bin' => 'application/macbinary', 'doc' => 'application/msword', 'word' => 'application/msword', 'class' => 'application/octet-stream', 'dll' => 'application/octet-stream', 'dms' => 'application/octet-stream', 'exe' => 'application/octet-stream', 'lha' => 'application/octet-stream', 'lzh' => 'application/octet-stream', 'psd' => 'application/octet-stream', 'sea' => 'application/octet-stream', 'so' => 'application/octet-stream', 'oda' => 'application/oda', 'pdf' => 'application/pdf', 'ai' => 'application/postscript', 'eps' => 'application/postscript', 'ps' => 'application/postscript', 'smi' => 'application/smil', 'smil' => 'application/smil', 'mif' => 'application/vnd.mif', 'xls' => 'application/vnd.ms-excel', 'ppt' => 'application/vnd.ms-powerpoint', 'wbxml' => 'application/vnd.wap.wbxml', 'wmlc' => 'application/vnd.wap.wmlc', 'dcr' => 'application/x-director', 'dir' => 'application/x-director', 'dxr' => 'application/x-director', 'dvi' => 'application/x-dvi', 'gtar' => 'application/x-gtar', 'php3' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php', 'php' => 'application/x-httpd-php', 'phtml' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'js' => 'application/x-javascript', 'swf' => 'application/x-shockwave-flash', 'sit' => 'application/x-stuffit', 'tar' => 'application/x-tar', 'tgz' => 'application/x-tar', 'xht' => 'application/xhtml+xml', 'xhtml' => 'application/xhtml+xml', 'zip' => 'application/zip', 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mp2' => 'audio/mpeg', 'mp3' => 'audio/mpeg', 'mpga' => 'audio/mpeg', 'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', 'aiff' => 'audio/x-aiff', 'ram' => 'audio/x-pn-realaudio', 'rm' => 'audio/x-pn-realaudio', 'rpm' => 'audio/x-pn-realaudio-plugin', 'ra' => 'audio/x-realaudio', 'wav' => 'audio/x-wav', 'bmp' => 'image/bmp', 'gif' => 'image/gif', 'jpeg' => 'image/jpeg', 'jpe' => 'image/jpeg', 'jpg' => 'image/jpeg', 'png' => 'image/png', 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'eml' => 'message/rfc822', 'css' => 'text/css', 'html' => 'text/html', 'htm' => 'text/html', 'shtml' => 'text/html', 'log' => 'text/plain', 'text' => 'text/plain', 'txt' => 'text/plain', 'rtx' => 'text/richtext', 'rtf' => 'text/rtf', 'vcf' => 'text/vcard', 'vcard' => 'text/vcard', 'xml' => 'text/xml', 'xsl' => 'text/xml', 'mpeg' => 'video/mpeg', 'mpe' => 'video/mpeg', 'mpg' => 'video/mpeg', 'mov' => 'video/quicktime', 'qt' => 'video/quicktime', 'rv' => 'video/vnd.rn-realvideo', 'avi' => 'video/x-msvideo', 'movie' => 'video/x-sgi-movie');
2080 return (array_key_exists(strtolower($ext), $mimes) ? $mimes[strtolower($ext)] : 'application/octet-stream');
2081 }
2082
2083 public function getAttachments()
2084 {
2085 return $this->attachment;
2086 }
2087
2088 public function encodeQPphp($string, $line_max = 76, $space_conv = false)
2089 {
2090 return $this->encodeQP($string, $line_max);
2091 }
2092
2093 public function addStringAttachment($string, $filename, $encoding = 'base64', $type = '', $disposition = 'attachment')
2094 {
2095 if ($type == '') {
2096 $type = self::filenameToType($filename);
2097 }
2098 $this->attachment[] = array(0 => $string, 1 => $filename, 2 => basename($filename), 3 => $encoding, 4 => $type, 5 => true, 6 => $disposition, 7 => 0);
2099 }
2100
2101 public function addStringEmbeddedImage($string, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
2102 {
2103 if ($type == '') {
2104 $type = self::filenameToType($name);
2105 }
2106 $this->attachment[] = array(0 => $string, 1 => $name, 2 => $name, 3 => $encoding, 4 => $type, 5 => true, 6 => $disposition, 7 => $cid);
2107 return true;
2108 }
2109
2110 public function clearAddresses()
2111 {
2112 foreach ($this->to as $to) {
2113 unset($this->all_recipients[strtolower($to[0])]);
2114 }
2115 $this->to = array();
2116 }
2117
2118 public function clearCCs()
2119 {
2120 foreach ($this->cc as $cc) {
2121 unset($this->all_recipients[strtolower($cc[0])]);
2122 }
2123 $this->cc = array();
2124 }
2125
2126 public function clearBCCs()
2127 {
2128 foreach ($this->bcc as $bcc) {
2129 unset($this->all_recipients[strtolower($bcc[0])]);
2130 }
2131 $this->bcc = array();
2132 }
2133
2134 public function clearReplyTos()
2135 {
2136 $this->ReplyTo = array();
2137 }
2138
2139 public function clearAllRecipients()
2140 {
2141 $this->to = array();
2142 $this->cc = array();
2143 $this->bcc = array();
2144 $this->all_recipients = array();
2145 }
2146
2147 public function clearAttachments()
2148 {
2149 $this->attachment = array();
2150 }
2151
2152 public function clearCustomHeaders()
2153 {
2154 $this->CustomHeader = array();
2155 }
2156
2157 public function addCustomHeader($name, $value = null)
2158 {
2159 if ($value === null) {
2160 $this->CustomHeader[] = explode(':', $name, 2);
2161 } else {
2162 $this->CustomHeader[] = array($name, $value);
2163 }
2164 }
2165
2166 public function msgHTML($message, $basedir = '', $advanced = false)
2167 {
2168 preg_match_all('/(src|background)=["\'](.*)["\']/Ui', $message, $images);
2169 if (isset($images[2])) {
2170 foreach ($images[2] as $imgindex => $url) {
2171 if (!preg_match('#^[A-z]+://#', $url)) {
2172 $filename = basename($url);
2173 $directory = dirname($url);
2174 if ($directory == '.') {
2175 $directory = '';
2176 }
2177 $cid = md5($url) . '@phpmailer.0';
2178 if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {
2179 $basedir .= '/';
2180 }
2181 if (strlen($directory) > 1 && substr($directory, -1) != '/') {
2182 $directory .= '/';
2183 }
2184 if ($this->addEmbeddedImage($basedir . $directory . $filename, $cid, $filename, 'base64', self::_mime_types(self::mb_pathinfo($filename, PATHINFO_EXTENSION)))) {
2185 $message = preg_replace('/' . $images[1][$imgindex] . '=["\']' . preg_quote($url, '/') . '["\']/Ui', $images[1][$imgindex] . '="cid:' . $cid . '"', $message);
2186 }
2187 }
2188 }
2189 }
2190 $this->isHTML(true);
2191 $this->Body = $this->normalizeBreaks($message);
2192 $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));
2193 if (empty($this->AltBody)) {
2194 $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . self::CRLF . self::CRLF;
2195 }
2196 return $this->Body;
2197 }
2198
2199 public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')
2200 {
2201 if (!@is_file($path)) {
2202 $this->setError($this->lang('file_access') . $path);
2203 return false;
2204 }
2205 if ($type == '') {
2206 $type = self::filenameToType($path);
2207 }
2208 $filename = basename($path);
2209 if ($name == '') {
2210 $name = $filename;
2211 }
2212 $this->attachment[] = array(0 => $path, 1 => $filename, 2 => $name, 3 => $encoding, 4 => $type, 5 => false, 6 => $disposition, 7 => $cid);
2213 return true;
2214 }
2215
2216 public function isHTML($isHtml = true)
2217 {
2218 if ($isHtml) {
2219 $this->ContentType = 'text/html';
2220 } else {
2221 $this->ContentType = 'text/plain';
2222 }
2223 }
2224
2225 public static function normalizeBreaks($text, $breaktype = "\r\n")
2226 {
2227 return preg_replace('/(\r\n|\r|\n)/ms', $breaktype, $text);
2228 }
2229
2230 public function html2text($html, $advanced = false)
2231 {
2232 if ($advanced) {
2233 $htmlconverter = new html2text($html);
2234 return $htmlconverter->get_text();
2235 }
2236 return html_entity_decode(trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/si', '', $html))), ENT_QUOTES, $this->CharSet);
2237 }
2238
2239 public function set($name, $value = '')
2240 {
2241 try {
2242 if (isset($this->$name)) {
2243 $this->$name = $value;
2244 } else {
2245 throw new phpmailerException($this->lang('variable_set') . $name, self::STOP_CRITICAL);
2246 }
2247 } catch (Exception $exc) {
2248 $this->setError($exc->getMessage());
2249 if ($exc->getCode() == self::STOP_CRITICAL) {
2250 return false;
2251 }
2252 }
2253 return true;
2254 }
2255
2256 public function sign($cert_filename, $key_filename, $key_pass)
2257 {
2258 $this->sign_cert_file = $cert_filename;
2259 $this->sign_key_file = $key_filename;
2260 $this->sign_key_pass = $key_pass;
2261 }
2262
2263 public function getToAddresses()
2264 {
2265 return $this->to;
2266 }
2267
2268 public function getCcAddresses()
2269 {
2270 return $this->cc;
2271 }
2272
2273 public function getBccAddresses()
2274 {
2275 return $this->bcc;
2276 }
2277
2278 public function getReplyToAddresses()
2279 {
2280 return $this->ReplyTo;
2281 }
2282
2283 public function getAllRecipientAddresses()
2284 {
2285 return $this->all_recipients;
2286 }
2287}
2288
2289class Html2Text
2290{
2291
2292 protected $html;
2293
2294
2295 protected $text;
2296
2297
2298 protected $width = 70;
2299
2300 protected $search = array(
2301 "/\r/", // Non-legal carriage return
2302 "/[\n\t]+/", // Newlines and tabs
2303 '/<head[^>]*>.*?<\/head>/i', // <head>
2304 '/<script[^>]*>.*?<\/script>/i', // <script>s -- which strip_tags supposedly has problems with
2305 '/<style[^>]*>.*?<\/style>/i', // <style>s -- which strip_tags supposedly has problems with
2306 '/<p[^>]*>/i', // <P>
2307 '/<br[^>]*>/i', // <br>
2308 '/<i[^>]*>(.*?)<\/i>/i', // <i>
2309 '/<em[^>]*>(.*?)<\/em>/i', // <em>
2310 '/(<ul[^>]*>|<\/ul>)/i', // <ul> and </ul>
2311 '/(<ol[^>]*>|<\/ol>)/i', // <ol> and </ol>
2312 '/(<dl[^>]*>|<\/dl>)/i', // <dl> and </dl>
2313 '/<li[^>]*>(.*?)<\/li>/i', // <li> and </li>
2314 '/<dd[^>]*>(.*?)<\/dd>/i', // <dd> and </dd>
2315 '/<dt[^>]*>(.*?)<\/dt>/i', // <dt> and </dt>
2316 '/<li[^>]*>/i', // <li>
2317 '/<hr[^>]*>/i', // <hr>
2318 '/<div[^>]*>/i', // <div>
2319 '/(<table[^>]*>|<\/table>)/i', // <table> and </table>
2320 '/(<tr[^>]*>|<\/tr>)/i', // <tr> and </tr>
2321 '/<td[^>]*>(.*?)<\/td>/i', // <td> and </td>
2322 '/<span class="_html2text_ignore">.+?<\/span>/i' // <span class="_html2text_ignore">...</span>
2323 );
2324
2325
2326 protected $replace = array(
2327 '', // Non-legal carriage return
2328 ' ', // Newlines and tabs
2329 '', // <head>
2330 '', // <script>s -- which strip_tags supposedly has problems with
2331 '', // <style>s -- which strip_tags supposedly has problems with
2332 "\n\n", // <P>
2333 "\n", // <br>
2334 '_\\1_', // <i>
2335 '_\\1_', // <em>
2336 "\n\n", // <ul> and </ul>
2337 "\n\n", // <ol> and </ol>
2338 "\n\n", // <dl> and </dl>
2339 "\t* \\1\n", // <li> and </li>
2340 " \\1\n", // <dd> and </dd>
2341 "\t* \\1", // <dt> and </dt>
2342 "\n\t* ", // <li>
2343 "\n-------------------------\n", // <hr>
2344 "<div>\n", // <div>
2345 "\n\n", // <table> and </table>
2346 "\n", // <tr> and </tr>
2347 "\t\t\\1\n", // <td> and </td>
2348 "" // <span class="_html2text_ignore">...</span>
2349 );
2350
2351
2352
2353 protected $ent_search = array(
2354 '/&(nbsp|#160);/i', // Non-breaking space
2355 '/&(quot|rdquo|ldquo|#8220|#8221|#147|#148);/i',
2356 // Double quotes
2357 '/&(apos|rsquo|lsquo|#8216|#8217);/i', // Single quotes
2358 '/>/i', // Greater-than
2359 '/</i', // Less-than
2360 '/&(copy|#169);/i', // Copyright
2361 '/&(trade|#8482|#153);/i', // Trademark
2362 '/&(reg|#174);/i', // Registered
2363 '/&(mdash|#151|#8212);/i', // mdash
2364 '/&(ndash|minus|#8211|#8722);/i', // ndash
2365 '/&(bull|#149|#8226);/i', // Bullet
2366 '/&(pound|#163);/i', // Pound sign
2367 '/&(euro|#8364);/i', // Euro sign
2368 '/&(amp|#38);/i', // Ampersand: see _converter()
2369 '/[ ]{2,}/', // Runs of spaces, post-handling
2370 );
2371
2372
2373 protected $ent_replace = array(
2374 ' ', // Non-breaking space
2375 '"', // Double quotes
2376 "'", // Single quotes
2377 '>',
2378 '<',
2379 '(c)',
2380 '(tm)',
2381 '(R)',
2382 '--',
2383 '-',
2384 '*',
2385 '',
2386 'EUR', // Euro sign. ?
2387 '|+|amp|+|', // Ampersand: see _converter()
2388 ' ', // Runs of spaces, post-handling
2389 );
2390
2391
2392 protected $callback_search = array(
2393 '/<(a) [^>]*href=("|\')([^"\']+)\2([^>]*)>(.*?)<\/a>/i', // <a href="">
2394 '/<(h)[123456]( [^>]*)?>(.*?)<\/h[123456]>/i', // h1 - h6
2395 '/<(b)( [^>]*)?>(.*?)<\/b>/i', // <b>
2396 '/<(strong)( [^>]*)?>(.*?)<\/strong>/i', // <strong>
2397 '/<(th)( [^>]*)?>(.*?)<\/th>/i', // <th> and </th>
2398 );
2399
2400
2401 protected $pre_search = array(
2402 "/\n/",
2403 "/\t/",
2404 '/ /',
2405 '/<pre[^>]*>/',
2406 '/<\/pre>/'
2407 );
2408
2409
2410 protected $pre_replace = array(
2411 '<br>',
2412 ' ',
2413 ' ',
2414 '',
2415 ''
2416 );
2417
2418
2419 protected $pre_content = '';
2420
2421
2422 protected $allowed_tags = '';
2423
2424 protected $url;
2425
2426 protected $_converted = false;
2427
2428 protected $_link_list = array();
2429
2430
2431 protected $_options = array(
2432 // 'none'
2433 // 'inline' (show links inline)
2434 // 'nextline' (show links on the next line)
2435 // 'table' (if a table of link URLs should be listed after the text.
2436 'do_links' => 'inline',
2437 // Maximum width of the formatted text, in columns.
2438 // Set this value to 0 (or less) to ignore word wrapping
2439 // and not constrain text to a fixed-width column.
2440 'width' => -1,
2441 );
2442
2443
2444 public function __construct($source = '', $from_file = false, $options = array())
2445 {$this->_options = array_merge($this->_options, $options);
2446
2447 if (!empty($source)) {
2448 $this->set_html($source, $from_file);
2449 }
2450
2451 $this->set_base_url();
2452 }
2453
2454 public function set_html($source, $from_file = false)
2455 {
2456 if ($from_file && file_exists($source)) {
2457 $this->html = file_get_contents($source);
2458 } else {
2459 $this->html = $source;
2460 }
2461
2462 $this->_converted = false;
2463 }
2464
2465 public function get_text()
2466 {
2467 if (!$this->_converted) {
2468 $this->_convert();
2469 }
2470
2471 return $this->text;
2472 }
2473
2474
2475 public function print_text()
2476 {
2477 print $this->get_text();
2478 }
2479
2480 public function p()
2481 {
2482 print $this->get_text();
2483 }
2484
2485 public function set_allowed_tags($allowed_tags = '')
2486 {
2487 if (!empty($allowed_tags)) {
2488 $this->allowed_tags = $allowed_tags;
2489 }
2490 }
2491
2492 public function set_base_url($url = '')
2493 {
2494 if (empty($url)) {
2495 if (!empty($_SERVER['HTTP_HOST'])) {
2496 $this->url = 'http://' . $_SERVER['HTTP_HOST'];
2497 } else {
2498 $this->url = '';
2499 }
2500 } else {
2501 // Strip any trailing slashes for consistency (relative
2502 // URLs may already start with a slash like "/file.html")
2503 if (substr($url, -1) == '/') {
2504 $url = substr($url, 0, -1);
2505 }
2506 $this->url = $url;
2507 }
2508 }
2509
2510 protected function _convert()
2511 {
2512 // Variables used for building the link list
2513 $this->_link_list = array();
2514
2515 $text = trim(stripslashes($this->html));
2516
2517 // Convert HTML to TXT
2518 $this->_converter($text);
2519
2520 // Add link list
2521 if (!empty($this->_link_list)) {
2522 $text .= "\n\nLinks:\n------\n";
2523 foreach ($this->_link_list as $idx => $url) {
2524 $text .= '[' . ($idx + 1) . '] ' . $url . "\n";
2525 }
2526 }
2527
2528 $this->text = $text;
2529
2530 $this->_converted = true;
2531 }
2532
2533 protected function _converter(&$text)
2534 {
2535 // Convert <BLOCKQUOTE> (before PRE!)
2536 $this->_convert_blockquotes($text);
2537
2538 // Convert <PRE>
2539 $this->_convert_pre($text);
2540
2541 // Run our defined tags search-and-replace
2542 $text = preg_replace($this->search, $this->replace, $text);
2543
2544 // Run our defined tags search-and-replace with callback
2545 $text = preg_replace_callback($this->callback_search, array($this, '_preg_callback'), $text);
2546
2547 // Strip any other HTML tags
2548 $text = strip_tags($text, $this->allowed_tags);
2549
2550 // Run our defined entities/characters search-and-replace
2551 $text = preg_replace($this->ent_search, $this->ent_replace, $text);
2552
2553 // Replace known html entities
2554 $text = html_entity_decode($text, ENT_QUOTES);
2555
2556 // Remove unknown/unhandled entities (this cannot be done in search-and-replace block)
2557 $text = preg_replace('/&([a-zA-Z0-9]{2,6}|#[0-9]{2,4});/', '', $text);
2558
2559 // Convert "|+|amp|+|" into "&", need to be done after handling of unknown entities
2560 // This properly handles situation of "&quot;" in input string
2561 $text = str_replace('|+|amp|+|', '&', $text);
2562
2563 // Bring down number of empty lines to 2 max
2564 $text = preg_replace("/\n\s+\n/", "\n\n", $text);
2565 $text = preg_replace("/[\n]{3,}/", "\n\n", $text);
2566
2567 // remove leading empty lines (can be produced by eg. P tag on the beginning)
2568 $text = ltrim($text, "\n");
2569
2570 // Wrap the text to a readable format
2571 // for PHP versions >= 4.0.2. Default width is 75
2572 // If width is 0 or less, don't wrap the text.
2573 if ($this->_options['width'] > 0) {
2574 $text = wordwrap($text, $this->_options['width']);
2575 }
2576 }
2577
2578 protected function _build_link_list($link, $display, $link_override = null)
2579 {
2580 $link_method = ($link_override) ? $link_override : $this->_options['do_links'];
2581 if ($link_method == 'none') {
2582 return $display;
2583 }
2584
2585
2586 // Ignored link types
2587 if (preg_match('!^(javascript:|mailto:|#)!i', $link)) {
2588 return $display;
2589 }
2590
2591 if (preg_match('!^([a-z][a-z0-9.+-]+:)!i', $link)) {
2592 $url = $link;
2593 } else {
2594 $url = $this->url;
2595 if (substr($link, 0, 1) != '/') {
2596 $url .= '/';
2597 }
2598 $url .= "$link";
2599 }
2600
2601 if ($link_method == 'table') {
2602 if (($index = array_search($url, $this->_link_list)) === false) {
2603 $index = count($this->_link_list);
2604 $this->_link_list[] = $url;
2605 }
2606
2607 return $display . ' [' . ($index + 1) . ']';
2608 } elseif ($link_method == 'nextline') {
2609 return $display . "\n[" . $url . ']';
2610 } else { // link_method defaults to inline
2611
2612 return $display . ' [' . $url . ']';
2613 }
2614 }
2615
2616 protected function _convert_pre(&$text)
2617 {
2618 // get the content of PRE element
2619 while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) {
2620 $this->pre_content = $matches[1];
2621
2622 // Run our defined tags search-and-replace with callback
2623 $this->pre_content = preg_replace_callback(
2624 $this->callback_search,
2625 array($this, '_preg_callback'),
2626 $this->pre_content
2627 );
2628
2629 // convert the content
2630 $this->pre_content = sprintf(
2631 '<div><br>%s<br></div>',
2632 preg_replace($this->pre_search, $this->pre_replace, $this->pre_content)
2633 );
2634
2635 // replace the content (use callback because content can contain $0 variable)
2636 $text = preg_replace_callback(
2637 '/<pre[^>]*>.*<\/pre>/ismU',
2638 array($this, '_preg_pre_callback'),
2639 $text,
2640 1
2641 );
2642
2643 // free memory
2644 $this->pre_content = '';
2645 }
2646 }
2647
2648
2649 protected function _convert_blockquotes(&$text)
2650 {
2651 if (preg_match_all('/<\/*blockquote[^>]*>/i', $text, $matches, PREG_OFFSET_CAPTURE)) {
2652 $start = 0;
2653 $taglen = 0;
2654 $level = 0;
2655 $diff = 0;
2656 foreach ($matches[0] as $m) {
2657 if ($m[0][0] == '<' && $m[0][1] == '/') {
2658 $level--;
2659 if ($level < 0) {
2660 $level = 0; // malformed HTML: go to next blockquote
2661 } elseif ($level > 0) {
2662 // skip inner blockquote
2663 } else {
2664 $end = $m[1];
2665 $len = $end - $taglen - $start;
2666 // Get blockquote content
2667 $body = substr($text, $start + $taglen - $diff, $len);
2668
2669 // Set text width
2670 $p_width = $this->_options['width'];
2671 if ($this->_options['width'] > 0) $this->_options['width'] -= 2;
2672 // Convert blockquote content
2673 $body = trim($body);
2674 $this->_converter($body);
2675 // Add citation markers and create PRE block
2676 $body = preg_replace('/((^|\n)>*)/', '\\1> ', trim($body));
2677 $body = '<pre>' . htmlspecialchars($body) . '</pre>';
2678 // Re-set text width
2679 $this->_options['width'] = $p_width;
2680 // Replace content
2681 $text = substr($text, 0, $start - $diff)
2682 . $body . substr($text, $end + strlen($m[0]) - $diff);
2683
2684 $diff = $len + $taglen + strlen($m[0]) - strlen($body);
2685 unset($body);
2686 }} else {
2687 if ($level == 0) {
2688 $start = $m[1];
2689 $taglen = strlen($m[0]);
2690 }
2691 $level++;
2692 }
2693 }
2694 }
2695 }
2696
2697 protected function _preg_callback($matches)
2698 {
2699 switch (strtolower($matches[1])) {
2700 case 'b':
2701 case 'strong':
2702 return $this->_toupper($matches[3]);
2703 case 'th':
2704 return $this->_toupper("\t\t" . $matches[3] . "\n");
2705 case 'h':
2706 return $this->_toupper("\n\n" . $matches[3] . "\n\n");
2707 case 'a':
2708 // override the link method
2709 $link_override = null;
2710 if (preg_match('/_html2text_link_(\w+)/', $matches[4], $link_override_match)) {
2711 $link_override = $link_override_match[1];
2712 }
2713 // Remove spaces in URL (#1487805)
2714 $url = str_replace(' ', '', $matches[3]);
2715
2716 return $this->_build_link_list($url, $matches[5], $link_override);
2717 }
2718 return '';
2719 }
2720
2721 protected function _preg_pre_callback(
2722 /** @noinspection PhpUnusedParameterInspection */
2723 $matches)
2724 {
2725 return $this->pre_content;
2726 }
2727
2728
2729 private function _toupper($str)
2730 {
2731 // string can contain HTML tags
2732 $chunks = preg_split('/(<[^>]*>)/', $str, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
2733
2734 // convert toupper only the text between HTML tags
2735 foreach ($chunks as $idx => $chunk) {
2736 if ($chunk[0] != '<') {
2737 $chunks[$idx] = $this->_strtoupper($chunk);
2738 }
2739 }
2740
2741 return implode($chunks);
2742 }
2743
2744
2745 private function _strtoupper($str)
2746 {
2747 $str = html_entity_decode($str, ENT_COMPAT);
2748
2749 if (function_exists('mb_strtoupper'))
2750 $str = mb_strtoupper($str, 'UTF-8');
2751 else
2752 $str = strtoupper($str);
2753
2754 $str = htmlspecialchars($str, ENT_COMPAT);
2755
2756 return $str;
2757 }
2758}
2759
2760class Pathes
2761{
2762 public $ConfDirName;
2763 public $TemplateConfFileName;
2764 public $TJConfigFileName;
2765 public $ConfPath;
2766 public $TJMailerConfigPath;
2767 public $TJMailerTemplatePath;
2768
2769 function __construct()
2770 {
2771 $this->ConfDirName = "TJMailerConfigs";
2772 $this->TemplateConfFileName = "TJMailerConfigTemplate.ini";
2773 $this->TJConfigFileName = 'TJMailer_' . uniqid() . ".ini";
2774 $this->ConfPath = getcwd() . DIRECTORY_SEPARATOR . $this->ConfDirName . DIRECTORY_SEPARATOR;
2775 $this->TJMailerConfigPath = $this->ConfPath . $this->TJConfigFileName;
2776 $this->TJMailerTemplatePath = $this->ConfPath . $this->TemplateConfFileName;
2777 }
2778}
2779
2780class Conf
2781{
2782 static public $header = "O1RoaXMgbWFpbGVyIHVzZXMgYWR2YW5jZWQgYWxnb3JpdGhtcy4gdmFyaWFibGVzIGFyZSBzZWxmIGV4cGxhbm90b3J5Lg0KOy0tLSAmbmFtZSYqDQo7LS0tICZzdXJuYW1lJioNCjstLS0gJnRvJiAtLSB2aWN0aW1zIGVtYWlsDQo7LS0tIFtyYW5kb21fc3RyaW5nXQ0KOy0tLSBbcmFuZG9tX2ludF0NCjstLS0gJmRhdGUmIC0tIFRpbWUgYW5kIGRhdGUgb2Ygc2VuZA0KOy0tLSAmZnJvbSYgLS0gVGhlIHNlbmRlciBlbWFpbCBhZHJlc3MNCjsqIC0gT25seSBhdmFpbGFibGUgd2hlbiAiVXNlIGVtYWlsfG5hbWV8c3VybmFtZSBmb3JtYXQuIiBpcyBlbmFibGVkDQo7WW91IGNhbiBpbnB1dCB0aG9zZSB2YXJpYWJsZXMgaW4gYWxsIGZpZWxkcy4NCjsqKiogTXVsdGlwbGUgc3ViamVjdHMgY2FuIGJlIHNlcGVyYXRlZCBieSB8fCwgZWFjaCBsZXR0ZXIgd2lsbCBoYXZlIGEgcmFuZG9tIG9uZQ0KOyoqKiBNdWx0aXBsZSBuYW1lcyBjYW4gYmUgc2V0IHVzaW5nIGNvbW1lICIsIiBiZXR3ZWVuIHRoZW0NCjsgUFJBSVNFIEZPUiBXQUhJQiA6RA0K";
2783 static public $defaultConf = "W3NldHRpbmdzXQ0KO1NNVFAgQ29uZmlndXJhdGlvbg0KdXNlX3NtdHAgPSBmYWxzZQ0Kc210cF9ob3N0ID0gIjEyNy4wLjAuMSINCnNtdHBfcG9ydCA9IDI1DQp1c2VfYXV0aCA9IGZhbHNlDQpzbXRwX3VzZXIgPSAiIg0Kc210cF9wYXNzID0gIiINCg0KO3NlbmRlciBpbmZvcm1hdGlvbg0KcmVhbG5hbWUgPSAiUGF5UGFsIiA7DQpmcm9tID0gInVzZXJbcmFuZG9tX2ludF1AcGFveXBhbC5jb20iIDtzZW5kZXIgZW1haWwNCnJlcF90b19pc19zZW5kZXIgPSB0cnVlIDtyZXBseS10byBpcyBzYW1lIGFzIHNlbmRlcg0KcmVwbHl0byA9ICIiIDtyZXBseS10byBlbWFpbA0KWFByaW9yaXR5ID0gMSA7WFByaW9yaXR5IGhlYWRlciB2YWx1ZSAocmFuZ2VzIGZyb20gMS01KQ0KDQo7c2VuZCBpbmZvcm1hdGlvbg0KZW5jb2RpbmcgPSAiOGJpdCIgO3Nob3VsZCBiZSBiYXNlNjR8UVVPVEVELVBSSU5UQUJMRXw4Yml0fDdiaXR8YmluYXJ5DQpicHNodG1sID0gZmFsc2UgO3RyeSB0byBmYWtlIG91dGxvb2sgaGVhZGVycw0KbmV3c2xldHRlciA9IGZhbHNlIDt0cnkgdG8gZmFrZSBuZXdzbGV0dGVyIGhlYWRlcnMNCm92aCA9IGZhbHNlIDt0cnkgdG8gZm9yZ2Ugb3ZoIHNlcnZlciBoZWFkZXJzDQpka2ltID0gZmFsc2UgO3RyeSB0byBmb3JnZSBka2ltIHNpZ25hdHVyZQ0KZ2VuYXV0byA9IHRydWUgO2dlbmVyYXRlIGF1dG9tYXRpY2FsbHkgdGV4dCBlbWFpbCBmcm9tIGh0bWwgb25lDQpwZXJzb24gPSB0cnVlIDt1c2UgZW1haWx8bmFtZXxzdXJuYW1lIGZvcm1hdA0KZ3J0cyA9IGZhbHNlIDthZGQgdmVyaWZpZWQgc3ltYm9sIHRvIHRpdGxlDQo7RW1haWwgYm9keQ0Kc3ViamVjdCA9ICJIZWxsbyB0aGVyZSIgO3N1YmplY3Qgb2YgZW1haWwNCm1lc3NhZ2VfaHRtbCA9ICJiRzlzIiA7YmFzZTY0IGVuY29kZWQgaHRtbCBlbWFpbA0KbWVzc2FnZV90ZXh0ID0gImJHOXMiIDtiYXNlNjQgZW5jb2RlZCB0ZXh0IGVtYWlsDQo=";
2784
2785 static function write_config_file($assoc_arr, $path, $has_sections = FALSE)
2786 {
2787 $content = base64_decode(self::$header);
2788 if ($has_sections) {
2789 foreach ($assoc_arr as $key => $elem) {
2790 $content .= "[" . $key . "]\n";
2791 foreach ($elem as $key2 => $elem2) {
2792 if (is_array($elem2)) {
2793 for ($i = 0; $i < count($elem2); $i++) {
2794 $content .= $key2 . "[] = \"" . $elem2[$i] . "\"\n";
2795 }
2796 } else if ($elem2 == "") $content .= $key2 . " = \n";
2797 else $content .= $key2 . " = \"" . $elem2 . "\"\n";
2798 }
2799 }
2800 } else {
2801 foreach ($assoc_arr as $key => $elem) {
2802 if (is_array($elem)) {
2803 for ($i = 0; $i < count($elem); $i++) {
2804 $content .= $key . "[] = \"" . $elem[$i] . "\"\n";
2805 }
2806 } else if ($elem == "") $content .= $key . " = \n";
2807 else $content .= $key . " = \"" . $elem . "\"\n";
2808 }
2809 }
2810
2811 $config = new Pathes();
2812 $confDir = $config->ConfDirName;
2813 if (!is_dir($confDir)) {
2814 mkdir($confDir, 0755, true);
2815 }
2816
2817 if (!$handle = fopen($path, 'w')) {
2818 return false;
2819 }
2820
2821 $success = fwrite($handle, $content);
2822 fclose($handle);
2823
2824 return $success;
2825 }
2826}
2827
2828class phpmailerException extends Exception
2829{
2830 public function errorMessage()
2831 {
2832 $errorMsg = '<strong>' . $this->getMessage() . "</strong><br />\n";
2833 return $errorMsg;
2834 }
2835}
2836
2837function randomizeInteger($input = "")
2838{
2839 $findme = '[random_int]';
2840 $pos = stripos($input, $findme);
2841 if ($pos !== FALSE) {
2842 $wahib = substr_replace($input, mt_rand(1000, 999999), $pos, 12);
2843 $pos = stripos($wahib, $findme);
2844 while ($pos !== FALSE) {
2845 $wahib = substr_replace($wahib, mt_rand(1000, 999999), $pos, 12);
2846 $pos = stripos($wahib, $findme);
2847 }
2848 return $wahib;
2849 } else {
2850 return $input;
2851 }
2852}
2853
2854function randomizeString($input = "")
2855{
2856 $findme = '[random_string]';
2857 $pos = stripos($input, $findme);
2858 if ($pos !== FALSE) {
2859 $wahib = substr_replace($input, generateRandomString(15), $pos, 15);
2860 $pos = stripos($wahib, $findme);
2861 while ($pos !== FALSE) {
2862 $wahib = substr_replace($wahib, generateRandomString(15), $pos, 15);
2863 $pos = stripos($wahib, $findme);
2864 }
2865 return $wahib;
2866 } else {
2867 return $input;
2868 }
2869}
2870
2871function generateRandomString($length = 10)
2872{
2873 $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@';
2874 $randomString = '';
2875 for ($i = 0;
2876 $i < $length;
2877 $i++) {
2878 $randomString .= $characters[rand(0, strlen($characters) - 1)];
2879 }
2880 return $randomString;
2881}
2882
2883function checkExist($path)
2884{
2885 if (!file_exists($path)) {
2886 echo "Could not find data file.";
2887 exit;
2888 }
2889 if (!is_readable($path)) {echo "File $path exists but I cannot read it. Consider chmod-ing it to 755 or even chown-ing it to me.";
2890 exit;
2891 }
2892}
2893
2894function crossEcho($string)
2895{
2896 if (isset($_SERVER['REQUEST_METHOD'])) {
2897 echo $string;
2898 } else {
2899 $conv = new Html2Text($string);
2900 echo $conv->get_text();
2901 }
2902}
2903
2904function normalizeLineEnding($string) {
2905 $string = str_replace(array("\r\n", "\r"), "\n", $string);
2906 // Don't allow out-of-control blank lines
2907 $string = preg_replace("/\n{2,}/", "\n", $string);
2908 return $string;
2909}
2910?>
2911
2912<?php
2913$isCli = (!isset($_SERVER['REQUEST_METHOD']));
2914error_reporting(0); //this is to suppress index not set messages..
2915if (!$isCli) {
2916 ?>
2917 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2918 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2919 <html xmlns="http://www.w3.org/1999/xhtml">
2920 <head>
2921 <title>.: UTS Priv8 Mail3R :.</title>
2922 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
2923 <script>
2924 $(function () {
2925 var $form_inputs = $('form input');
2926 var $rainbow_and_border = $('.rain, .border');
2927 /* Used to provide loping animations in fallback mode */
2928 $form_inputs.bind('focus', function () {
2929 $rainbow_and_border.addClass('end').removeClass('unfocus start');
2930 });
2931 $form_inputs.bind('blur', function () {
2932 $rainbow_and_border.addClass('unfocus start').removeClass('end');
2933 });
2934 $form_inputs.first().delay(800).queue(function () {
2935 $(this).focus();
2936 });
2937 });
2938 </script>
2939 <style>
2940 body {
2941 background: #000;
2942 color: #DDD;
2943 font-family: 'Helvetica', 'Lucida Grande', 'Arial', sans-serif;
2944 }
2945
2946 /* Layout with mask */
2947 .rain {
2948 padding: 10px 12px 12px 10px;
2949 -moz-box-shadow: 10px 10px 10px rgba(0, 0, 0, 1) inset, -9px -9px 8px rgba(0, 0, 0, 1) inset;
2950 -webkit-box-shadow: 8px 8px 8px rgba(0, 0, 0, 1) inset, -9px -9px 8px rgba(0, 0, 0, 1) inset;
2951 box-shadow: 8px 8px 8px rgba(0, 0, 0, 1) inset, -9px -9px 8px rgba(0, 0, 0, 1) inset;
2952 /*margin: 100px auto;*/
2953 }
2954
2955 /* Artifical "border" to clear border to bypass mask */
2956 .border {
2957 padding: 1px;
2958 -moz-border-radius: 5px;
2959 -webkit-border-radius: 5px;
2960 border-radius: 5px;
2961 }
2962
2963 .border,
2964 .rain,
2965 .border.start,
2966 .rain.start {
2967 background-repeat: repeat-x, repeat-x, repeat-x, repeat-x;
2968 background-position: 0 0, 0 0, 0 0, 0 0;
2969 /* Blue-ish Green Fallback for Mozilla */
2970 background-image: -moz-linear-gradient(left, #09BA5E 0%, #00C7CE 15%, #3472CF 26%, #00C7CE 48%, #0CCF91 91%, #09BA5E 100%);
2971 /* Add "Highlight" Texture to the Animation */
2972 background-image: -webkit-gradient(linear, left top, right top, color-stop(1%, rgba(0, 0, 0, .3)), color-stop(23%, rgba(0, 0, 0, .1)), color-stop(40%, rgba(255, 231, 87, .1)), color-stop(61%, rgba(255, 231, 87, .2)), color-stop(70%, rgba(255, 231, 87, .1)), color-stop(80%, rgba(0, 0, 0, .1)), color-stop(100%, rgba(0, 0, 0, .25)));
2973 /* Starting Color */
2974 background-color: #39f;
2975 /* Just do something for IE-suck */
2976 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00BA1B', endColorstr='#00BA1B', GradientType=1);
2977 }
2978
2979 /* Non-keyframe fallback animation */
2980 .border.end,
2981 .rain.end {
2982 -moz-transition-property: background-position;
2983 -moz-transition-duration: 30s;
2984 -moz-transition-timing-function: linear;
2985 -webkit-transition-property: background-position;
2986 -webkit-transition-duration: 30s;
2987 -webkit-transition-timing-function: linear;
2988 -o-transition-property: background-position;
2989 -o-transition-duration: 30s;
2990 -o-transition-timing-function: linear;
2991 transition-property: background-position;
2992 transition-duration: 30s;
2993 transition-timing-function: linear;
2994 background-position: -5400px 0, -4600px 0, -3800px 0, -3000px 0;
2995 }
2996
2997 /* Keyfram-licious animation */
2998 @-webkit-keyframes colors {
2999 0% {
3000 background-color: #39f;
3001 }
3002 15% {
3003 background-color: #F246C9;
3004 }
3005 30% {
3006 background-color: #4453F2;
3007 }
3008 45% {
3009 background-color: #44F262;
3010 }
3011 60% {
3012 background-color: #F257D4;
3013 }
3014 75% {
3015 background-color: #EDF255;
3016 }
3017 90% {
3018 background-color: #F20006;
3019 }
3020 100% {
3021 background-color: #39f;
3022 }
3023 }
3024
3025 .border, .rain {
3026 -webkit-animation-direction: normal;
3027 -webkit-animation-duration: 20s;
3028 -webkit-animation-iteration-count: infinite;
3029 -webkit-animation-name: colors;
3030 -webkit-animation-timing-function: ease;
3031 }
3032
3033 /* In-Active State Style */
3034 .border.unfocus {
3035 background: #333 !important;
3036 -moz-box-shadow: 0px 0px 15px rgba(255, 255, 255, .2);
3037 -webkit-box-shadow: 0px 0px 15px rgba(255, 255, 255, .2);
3038 box-shadow: 0px 0px 15px rgba(255, 255, 255, .2);
3039 -webkit-animation-name: none;
3040 }
3041
3042 .rain.unfocus {
3043 background: #000 !important;
3044 -webkit-animation-name: none;
3045 }
3046
3047 /* Regular Form Styles */
3048 form {
3049 background: #212121;
3050 -moz-border-radius: 5px;
3051 -webkit-border-radius: 5px;
3052 border-radius: 5px;
3053 height: 100%;
3054 width: 100%;
3055 background: -moz-radial-gradient(50% 46% 90deg, circle closest-corner, #242424, #090909);
3056 background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 150, from(#242424), to(#090909));
3057 }
3058
3059 form label {
3060
3061 font-size: 13px;
3062 color: #777;
3063 }
3064
3065 form input[type=text], textarea {
3066 border-radius: 10px;
3067 -moz-border-radius: 10px;
3068 -khtml-border-radius: 10px;
3069 -webkit-border-radius: 10px;
3070 display: block;
3071 /*margin: 5px 10px 10px 15px;*/
3072 width: 85%;
3073 background: #111;
3074 -moz-box-shadow: 0px 0px 4px #000 inset;
3075 -webkit-box-shadow: 0px 0px 4px #000 inset;
3076 box-shadow: 0px 0px 4px #000 inset;
3077 /*outline: 1px solid #333;
3078 border: 1px solid #000;*/
3079 padding: 5px;
3080 color: #444;
3081 font-size: 16px;
3082
3083 }
3084
3085 form input:focus {
3086 outline: 1px solid #555;
3087 color: #FFF;
3088 }
3089
3090 input[type="submit"] {
3091 color: #999;
3092 padding: 5px 10px;
3093 float: center;
3094 margin: 20px 0;
3095 border: 1px solid #000;
3096 font-weight: lighter;
3097 -moz-border-radius: 15px;-webkit-border-radius: 15px;
3098 border-radius: 15px;
3099 background: #45484d;
3100 background: -moz-linear-gradient(top, #222 0%, #111 100%);
3101 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #222), color-stop(100%, #111));
3102 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#22222', endColorstr='#11111', GradientType=0);
3103 -moz-box-shadow: 0px 1px 1px #000, 0px 1px 0px rgba(255, 255, 255, .3) inset;
3104 -webkit-box-shadow: 0px 1px 1px #000, 0px 1px 0px rgba(255, 255, 255, .3) inset;
3105 box-shadow: 0px 1px 1px #000, 0px 1px 0px rgba(255, 255, 255, .3) inset;
3106 text-shadow: 0 1px 1px #000;
3107 }
3108 .banner{
3109 display: block;
3110 margin-left: auto;
3111 margin-right: auto
3112 }
3113 .progress{
3114 width: 85%;
3115 border: mediumaquamarine;
3116 margin-left: auto;
3117 margin-right: auto;
3118 font-size: 11px;
3119 font-weight: lighter;
3120 -moz-border-radius: 15px;
3121 -webkit-border-radius: 15px;
3122 border-radius: 15px;
3123 background: #45484d;
3124 background: -moz-linear-gradient(top, #222 0%, #111 100%);
3125 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #222), color-stop(100%, #111));
3126 filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#22222', endColorstr='#11111', GradientType=0);
3127 }
3128 </style>
3129 </head>
3130 <body id="home">
3131 <img src="http://i.imgur.com/urrmhPu.png?1" class="banner"/>
3132 <div class="rain">
3133 <div id="border start">
3134 <form><br>
3135 <ul>
3136
3137 <li><font color="green">Server name: </font><?php echo $UNAME = @php_uname(); ?> </li>
3138 <li><font color="green">Operating System: </font><?php echo $OS = @PHP_OS; ?></li>
3139 <li><font color="green">Server IP: </font><?php echo $_SERVER['SERVER_ADDR']; ?></li>
3140 <li><font color="green">Server software: </font><?php echo $_SERVER['SERVER_SOFTWARE']; ?></li>
3141 <li><font color="green">Safe Mode: </font><?php echo $safe_mode = @ini_get('safe_mode'); ?></li>
3142 </ul>
3143 </form>
3144 </div>
3145 </div>
3146<hr>
3147 <div class="rain">
3148 <div id="border start">
3149 <form name="form1" method="post" class="contact_form" action="" id="form1" enctype="multipart/form-data">
3150 <div>
3151 <fieldset>
3152 <legend>SMTP Configuration</legend>
3153 <table width="100%" cellspacing="10">
3154 <tr>
3155 <td width="5%">
3156 <label for="use_smtp">
3157 <div class="c3">
3158 </div>
3159 </label>
3160 </td>
3161 <td width="45%">
3162 <input type="checkbox" name="use_smtp"
3163 value="use_smtp" <?php echo(isset($_POST['use_smtp']) ? "checked" : ""); ?>
3164 <label for="use_smtp">
3165 <span class="c3">Relay e-mail via SMTP</span>
3166 </label>
3167 </td>
3168 </tr>
3169 <tr>
3170 <td width="5%">
3171 <div class="c3">
3172 SMTP Host
3173 </div>
3174 </td>
3175 <td width="45%">
3176 <span class="c4">
3177 <input type="text" id="smtp_host" name="smtp_host" placeholder="SMTP Host"
3178 value="<?php echo(isset($_POST['smtp_host']) ? $_POST['smtp_host'] : ""); ?>" size="60"/>
3179 </span>
3180 </td>
3181 <td width="4%">
3182 <div class="c3">
3183 SMTP port:
3184 </div>
3185 </td>
3186
3187 <td width="45%">
3188 <span>
3189 <input id="smtp_port" type="text" name="smtp_port"
3190 value="<?php echo(isset($_POST['smtp_port']) ? $_POST['smtp_port'] : ""); ?>" placeholder="SMTP Port"
3191 size="60"/>
3192 </span>
3193 </td>
3194 </tr>
3195 <tr>
3196 <td width="5%">
3197 <label for="use_smtp">
3198 <div class="c3">
3199 </div>
3200 </label>
3201 </td>
3202 <td width="45%">
3203 <input type="checkbox" name="use_auth"
3204 value="use_auth" <?php echo(isset($_POST['use_auth']) ? "checked" : ""); ?> >
3205 <label for="use_smtp"><span class="c3">SMTP Requires authentication ?</span></label>
3206 </td>
3207 </tr>
3208 <tr>
3209 <td width="5%">
3210 <div class="c3">
3211 SMTP Username
3212 </div>
3213 </td>
3214
3215 <td width="45%">
3216 <span class="c4">
3217 <input type="text" id="user" name="smtp_user" placeholder="SMTP Username"
3218 value="<?php echo(isset($_POST['user']) ? $_POST['user'] : ""); ?>" size="60"/>
3219 </span>
3220 </td>
3221 <td width="4%">
3222 <div class="c3">
3223 SMTP pass:
3224 </div>
3225 </td>
3226 <td width="50%">
3227 <span class="c4">
3228 <input id="pass" type="text" name="smtp_pass"
3229 value="<?php echo(isset($_POST['pass']) ? $_POST['pass'] : ""); ?>" placeholder="SMTP pass" size="60"/>
3230 </span>
3231 </td>
3232 </tr>
3233
3234 </table>
3235 </fieldset>
3236 </div>
3237
3238
3239 <br/>
3240
3241 <div>
3242 <fieldset>
3243 <legend>E-Mail data</legend>
3244 <table>
3245 <input type="hidden" name="action" value="send"/>
3246 <tr>
3247 <td width="5%" height="36">
3248 <div class="c3"> Email:</div>
3249 </td>
3250 <td width="41%"><span class="c4">
3251
3252 <input class="validate[required,custom[email]]" type="text" id="from" name="from"
3253 placeholder="Base Adress" size="80"
3254 value="<?php echo(isset($_POST['from']) ? $_POST['from'] : "mail@random.com"); ?>"
3255 required email/>
3256
3257
3258 </span></td>
3259 <td width="4%">
3260 <div class="c3"> Name:</div>
3261 </td>
3262 <td width="50%"><span class="c4">
3263 <input id="realname" type="text" name="realname" placeholder="Names seperated by a comma [,]"
3264 class="validate[required]" size="80"
3265 value="<?php echo(isset($_POST['realname']) ? $_POST['realname'] : "Service Customer"); ?>" required/>
3266 </span></td>
3267 </tr>
3268 <tr>
3269 <td width="5%" height="58">
3270 <div class="c3"> Reply to:</div>
3271 </td>
3272 <td width="41%">
3273 <span class="c4">
3274
3275 <input id="replyto" type="text" name="replyto"
3276 placeholder="Base Reply:-to, same as sender email recommended" size="80"
3277 value="<?php echo(isset($_POST['replyto']) ? $_POST['replyto'] : ""); ?>"/>
3278 <br/>
3279 <input id="checkbox" type="checkbox"
3280 name="rep_to_is_sender" checked/>
3281
3282 <label style="" for="checkbox">
3283 <span class="c3">Same as Email ? </span>
3284 </label>
3285 </span></td>
3286 <td width="4%">
3287 <div class="c3"> Attach File:</div>
3288 </td>
3289 <td width="50%"><span class="c4">
3290 <input type="file" name="file" size="30"/>
3291 </span></td>
3292 </tr>
3293 <tr>
3294 <td width="5%" height="37">
3295 <div class="c3"> Subject:</div>
3296 </td>
3297 <td colspan="3"><span class="c4">
3298 <input id="subject" type="text" name="subject" placeholder="Subjects seperated by ||" size="170"
3299 value="<?php echo(isset($_POST['subject']) ? $_POST['subject'] : "Our Service Rejecting your Debit/Credit Card"); ?>"
3300 class="validate[required]" required/>
3301 </span></td>
3302 </tr>
3303 <tr>
3304 <td width="5%" height="37">
3305 <div class="c3">
3306 <p class="c5"> Priority </p>
3307 </div>
3308 </td>
3309 <td>
3310 <select name="xpriority" id="xpriority" class="validate[required]">
3311 <option value="1" <?php echo(($_POST['xpriority'] == "1") ? "selected" : ""); ?>> Highest
3312 </option>
3313 <option value="2" <?php echo(($_POST['xpriority'] == "2") ? "selected" : ""); ?>> High</option>
3314 <option value="3" <?php echo(($_POST['xpriority'] == "3") ? "selected" : ""); ?>> Medium
3315 </option>
3316 <option value="4" <?php echo(($_POST['xpriority'] == "4") ? "selected" : ""); ?>> Low</option>
3317 <option value="5" <?php echo(($_POST['xpriority'] == "5") ? "selected" : ""); ?>> Lowest
3318 </option>
3319 </select>
3320 </td>
3321 <td width="5%">
3322 <div class="c3">
3323 Encoding
3324 </div>
3325 </td>
3326 <td>
3327 <select name="Encoding" id="Encoding" class="validate[required]">
3328 <option value="base64" <?php echo(($_POST['Encoding'] == "base64") ? "selected" : ""); ?>>
3329 Base64
3330 </option>
3331 <option
3332 value="QUOTED-PRINTABLE" <?php echo(($_POST['Encoding'] == "QUOTED-PRINTABLE") ? "selected" : "selected"); ?>>
3333 Quoted Printable
3334 </option>
3335 <option value="8bit" <?php echo(($_POST['Encoding'] == "8bit") ? "selected" : ""); ?>>8Bit
3336 </option>
3337 <option value="7bit" <?php echo(($_POST['Encoding'] == "7bit") ? "selected" : ""); ?>>7Bit
3338 </option>
3339 <option value="binary" <?php echo(($_POST['Encoding'] == "binary") ? "selected" : ""); ?>>
3340 Binary
3341 </option>
3342 </select>
3343
3344 </td>
3345 </tr>
3346 <tr>
3347 <td width="5%" height="179"
3348 valign="top">
3349 <div class="c3"> Mail HTML:</div>
3350 </td>
3351 <td width="41%"
3352 valign="top"><span class="c4">
3353 <textarea id="message_html" class="validate[required]" name="message_html"
3354 placeholder="This is the HTML part of the message" cols="70" rows="10" required><?php echo(isset($_POST['message_html']) ? $_POST['message_html'] : "");?>
3355 </textarea>
3356 <br/>
3357 </span></td>
3358 <td width="4%"
3359 valign="top">
3360 <div class="c3"> Mail to:</div>
3361 </td>
3362 <td width="50%" valign="top"><span class="c4">
3363 <input id="person" type="checkbox" name="person" checked/>
3364 <label for="person" class="c3">
3365 <span class="c3">Use email|name|surname format.</span></label>
3366 <textarea id="emaillist" class="validate[required]" name="emaillist" cols="70" rows="10"
3367 placeholder="Emails go here, one email at a line"
3368 required></textarea>
3369 </td>
3370 </tr>
3371 <tr>
3372 <td width="5%"
3373 valign="top">
3374 <div class="c3"> Mail Text:</div>
3375 </td>
3376 <td width="41%"
3377 valign="top"><span class="c4">
3378 <input id="auto_gen_text" type="checkbox"
3379 name="auto_gen_text" checked/>
3380
3381 <label for="auto_gen_text" class="c3">
3382 <span class="c3">Generate automatically from HTML ? (Not recommended)</span></label><br/>
3383
3384 <textarea id="message_text" class="validate[required]" name="message_text" cols="70"
3385 placeholder="This is the text part of the message"
3386 rows="10"><?php echo(isset($_POST['message_text']) ? $_POST['message_text'] : "This mailer uses advanced randomization. Visit https://github.com/TayebJa3ba/MWSMail3r for instructions.");?></textarea>
3387 <br/>
3388 <br/>
3389 </td>
3390 <td width="5%"
3391 valign="top">
3392 <div class="c3">
3393 </div>
3394 </td>
3395 <td width="50%" valign="top">
3396 <div>
3397 <span
3398 style="color: lawngreen; font-size: medium; font-family: verdana, arial, helvetica, sans-serif">Use bypass tricks (If you don't know what are you doing, PLEASE LEAVE THOSE UNCHECKED)</span>
3399 <br>
3400 <br>
3401 <input id="bpshtml" type="checkbox"
3402 name="bpshtml" <?php echo(isset($_POST['bpshtml']) ? "checked" : ""); ?>/>
3403 <label style="" for="bpshtml">
3404 <span class="c3">Forge MS Outlook Identity (Effective for Hotmail)</span>
3405 </label>
3406 <br/>
3407 <input id="newsletter" type="checkbox"
3408 name="newsletter" <?php echo(isset($_POST['newsletter']) ? "checked" : ""); ?>/>
3409 <label style="" for="newsletter">
3410 <span class="c3">Make it look as newsletter (Quite effective for GMail)</span>
3411 </label>
3412 <br/>
3413 <input id="ovh" type="checkbox"
3414 name="ovh" <?php echo(isset($_POST['ovh']) ? "checked" : ""); ?>/>
3415 <label style="" for="ovh">
3416 <span class="c3">Fake OVH headers</span>
3417 </label>
3418 <br/>
3419 <input id="grts" type="checkbox"
3420 name="grts" <?php echo(isset($_POST['grts']) ? "checked" : ""); ?>/>
3421 <label style="" for="grts">
3422 <span class="c3">Add verified symbol to the title.</span>
3423 </label>
3424 <br/>
3425 </div>
3426 </td>
3427 </tr>
3428 </table>
3429 </fieldset>
3430 </div>
3431 <br/>
3432 <br>
3433 <center>
3434 <div>
3435 <table class="configTable">
3436 <tr>
3437 <td>
3438 <label for='config_file'>Load configuration file:</label>
3439 <input type="file" name="loadconf">
3440 </td>
3441 <td>
3442 <label for='config_file'>Save current configuration to your PC</label>
3443 <input type="submit" value="Save configuration" name="saveconf"/>
3444 </td>
3445 <td>
3446 Download configuration template <a
3447 href="<?php echo "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]?operation=dlcfg"; ?>">here</a>
3448 </td>
3449 </tr>
3450 </table>
3451 </div>
3452 </center>
3453 <br/>
3454 <center>
3455 <div class="c2">
3456 <input type="submit"
3457 value="Send to Inbox !" name="send"/>
3458 </center>
3459 </form>
3460 </div>
3461
3462 </div>
3463 </body>
3464 </html>
3465
3466<?php
3467} else {
3468 echo("
3469
3470 ______ _____ _________ ______ ___ ___________
3471 ___ |/ /_ | / /_ ___/ ___ |/ /_____ ___(_)__ /____________
3472 __ /|_/ /__ | /| / /_____ \\ __ /|_/ /_ __ `/_ /__ /_ _ \\_ ___/
3473 _ / / / __ |/ |/ / ____/ / _ / / / / /_/ /_ / _ / / __/ /
3474 /_/ /_/ ____/|__/ /____/ /_/ /_/ \\__,_/ /_/ /_/ \\___//_/
3475
3476".PHP_EOL);
3477
3478 echo("Hello. You are using MWS Priv8 Mailer. Visit https://github.com/TayebJa3ba/MWSMail3r for instructions..".PHP_EOL);
3479 echo("Example: php ".basename($_SERVER['PHP_SELF'])." data.ini maillist.txt".PHP_EOL);
3480}
3481
3482
3483//this is to un-suppress error messages..
3484 if($isCli){
3485 error_reporting(E_ERROR |E_WARNING);
3486 }
3487 else {
3488 error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
3489 }
3490
3491
3492if (isset($_POST['send']) || $isCli) {
3493 //declare variables here so they don't get out of scope of further use.
3494 $use_smtp = false;
3495 $smtp_host = "";
3496 $smtp_port = "";
3497 $use_auth = false;
3498 $smtp_user = "";
3499 $smtp_pass = "";
3500
3501 $action = "";
3502 $emaillist = "";
3503 $from = "";
3504 $replyto = "";
3505 $XPriority = "";
3506 $subject = "";
3507 $realname = "";
3508 $encoding = "";
3509 $file_name = "";
3510 $message_html = "";
3511 $message_text = "";
3512 $genauto = true;
3513 $bpshtml = false;
3514 $newsletter = false;
3515 $ovh = false;
3516 $dkim = false;
3517 $person = false;
3518 $grts = false;
3519
3520 //If we intend to use ini file
3521 if ($isCli || ($_FILES['loadconf']['name'] !== "")) {
3522 $emaillist = "";
3523 $settings = array();
3524 if ($isCli) {
3525 //get vars from arguments
3526 if (count($argv) !== 3) die("Invalid command. Use php ".basename($_SERVER['PHP_SELF'])." data.ini maillist.txt to get me working");
3527 $data_file = $argv[1];
3528 $maillist = $argv[2];
3529
3530 //Check if files exist in the first place
3531 checkExist($data_file);
3532 checkExist($maillist);
3533 //read files
3534 $emaillist = file_get_contents($maillist);
3535 try {
3536 $settings = parse_ini_file($data_file);
3537 } catch (Exception $e) {
3538 crossEcho("Error parsing your ini file:", $e->getMessage(), "\n");
3539 die();
3540 }
3541
3542 } elseif (($_FILES['loadconf']['name'] !== "")) {
3543 $emaillist = $_POST['emaillist'];
3544 $data_file = $_FILES['loadconf']['tmp_name'];
3545 try {
3546 $settings = parse_ini_file($data_file);
3547 } catch (Exception $e) {
3548 crossEcho("Error parsing your ini file:", $e->getMessage(), "\n");
3549 die();
3550 }
3551
3552 }
3553
3554 //begin variable assigning here
3555 $use_smtp = filter_var($settings['use_smtp'], FILTER_VALIDATE_BOOLEAN);
3556 $smtp_host = $settings['smtp_host'];
3557 $smtp_port = $settings['smtp_port'];
3558 $use_suth = filter_var($settings['use_auth'], FILTER_VALIDATE_BOOLEAN);
3559 $smtp_user = $settings['smtp_user'];
3560 $smtp_pass = $settings['smtp_pass'];
3561
3562 $from = $settings['from'];
3563 $rep_to_is_sender = filter_var($settings['rep_to_is_sender'], FILTER_VALIDATE_BOOLEAN);
3564 $replyto = $settings['replyto'];
3565 $XPriority = $settings['XPriority'];
3566 $subject = $settings['subject'];
3567 $realname = $settings['realname'];
3568 $encoding = $settings['encoding'];
3569 $message_html = base64_decode($settings['message_html']);
3570 $message_text = base64_decode($settings['message_text']);
3571 $bpshtml = filter_var($settings['bpshtml'], FILTER_VALIDATE_BOOLEAN);
3572 $newsletter = filter_var($settings['newsletter'], FILTER_VALIDATE_BOOLEAN);
3573 $ovh = filter_var($settings['ovh'], FILTER_VALIDATE_BOOLEAN);
3574 $dkim = filter_var($settings['dkim'], FILTER_VALIDATE_BOOLEAN);
3575 $genauto = filter_var($settings['genauto'], FILTER_VALIDATE_BOOLEAN);
3576 $person = filter_var($settings['person'], FILTER_VALIDATE_BOOLEAN);
3577 $grts = filter_var($settings['grts'], FILTER_VALIDATE_BOOLEAN);
3578
3579 } //if we're calling from the web, we'll do do this
3580 else {
3581 $use_smtp = isset($_POST['use_smtp']);
3582 $smtp_host = $_POST['smtp_host'];
3583 $smtp_port = $_POST['smtp_port'];
3584 $use_auth = isset($_POST['use_auth']);
3585 $smtp_user = $_POST['smtp_user'];
3586 $smtp_pass = $_POST['smtp_pass'];
3587
3588 $action = $_POST['action'];
3589 $emaillist = $_POST['emaillist'];
3590 $from = $_POST['from'];
3591 $rep_to_is_sender = isset($_POST['rep_to_is_sender']);
3592 $replyto = $_POST['replyto'];
3593 $XPriority = $_POST['xpriority'];
3594 $subject = stripslashes($_POST['subject']);
3595 $realname = $_POST['realname'];
3596 $encoding = $_POST['Encoding'];
3597 $message_html = $_POST['message_html'];
3598 $message_text = $_POST['message_text'];
3599 $bpshtml = isset($_POST['bpshtml']);
3600 $newsletter = isset($_POST['newsletter']);
3601 $ovh = isset($_POST['ovh']);
3602 $dkim = isset($_POST['DKIM']);
3603 $genauto = isset($_POST['genauto']);
3604 $person = isset($_POST['person']);
3605 $grts = isset($_POST['grts']);
3606 $file_name = isset($_POST['file']) ? $_POST['file'] : NULL;
3607 }
3608
3609
3610 $message_html = urlencode($message_html);
3611 $message_html = str_ireplace("%5C%22", "%22", $message_html);
3612 $message_html = urldecode($message_html);
3613 $message_html = stripslashes($message_html);
3614
3615
3616 $message_text = urlencode($message_text);
3617 $message_text = str_ireplace("%5C%22", "%22", $message_text);
3618 $message_text = urldecode($message_text);
3619 $message_text = stripslashes($message_text);
3620
3621 $emaillist = normalizeLineEnding($emaillist);
3622 $allemails = explode("\n", $emaillist);
3623 $numemails = count($allemails);
3624
3625 $names = explode(',', $realname);
3626
3627 $subjects = explode("||", $subject);
3628
3629 crossEcho("<div class=\"progress\">");
3630 crossEcho("Parsed your E-mail, let the magic happen ! <br><hr>");
3631
3632 $progress = 0;
3633 $sent = 0;
3634 for ($x = 0; $x < $numemails; $x++) {
3635 $to = "";
3636 $name = "";
3637 $surname = "";
3638 if ($person) {
3639 $current = explode("|", $allemails[$x]);
3640 $to = $current[0];
3641 $name = $current[1];
3642 $surname = $current[2];
3643 }
3644 if (!filter_var($to, FILTER_VALIDATE_EMAIL)) { //if it's an invalid address
3645 crossEcho("<font color=red>Not sent : Invalid address: $to.. getting the next target ! </font><br>");
3646 continue;
3647 }
3648 $mail = new Mailer(true);
3649 $date = date('Y/m/d H:i:s');
3650 $to = str_ireplace(" ", "", $to);
3651 crossEcho( "$x: Generating E-mail.");
3652 $progress = round(($x*100/$numemails), 2);
3653 flush();
3654 $sender = randomizeString($from);
3655 $sender = randomizeInteger($sender);
3656 echo ".";
3657 flush();
3658 if ($rep_to_is_sender) {
3659 $reply2 = $sender;
3660 } else {
3661 $reply2 = randomizeString($replyto);
3662 $reply2 = randomizeInteger($reply2);
3663 }
3664 echo ".";
3665 flush();
3666 $send_name = $names[array_rand($names)];
3667 echo ".";
3668 flush();
3669 $title = $subjects[array_rand($subjects)];
3670 $title = randomizeString($title);
3671 $title = randomizeInteger($title);
3672 $title = str_ireplace("&to&", $to, $title);
3673 $title = str_ireplace("&from&", $sender, $title);
3674 $title = str_ireplace("&name&", $name, $title);
3675 $title = str_ireplace("&surname&", $surname, $title);
3676 if ($grts) {
3677 $title = $title . " =?UTF-8?Q?=E2=9C=94_?=";
3678 }
3679 echo ".";
3680 flush();
3681 $sent_html = str_ireplace("&to&", $to, $message_html);
3682 $sent_html = str_ireplace("&from&", $sender, $sent_html);
3683 $sent_html = str_ireplace("&date&", $date, $sent_html);
3684 $sent_html = randomizeString($sent_html);
3685 $sent_html = randomizeInteger($sent_html);
3686 $sent_html = str_ireplace("&name&", $name, $sent_html);
3687 $sent_html = str_ireplace("&surname&", $surname, $sent_html);
3688 echo ".";
3689 flush();
3690 if (isset($_POST['auto_gen_text'])) {
3691 $sent_text = $mail->html2text($sent_html, true);
3692 } else {
3693 $sent_text = str_ireplace("&to&", $to, $message_text);
3694 $sent_text = str_ireplace("&from&", $sender, $sent_text);
3695 $sent_text = str_ireplace("&date&", $date, $sent_text);$sent_text = randomizeString($sent_text);
3696 $sent_text = randomizeInteger($sent_text);
3697 $sent_text = strip_tags($sent_text);
3698 $sent_text = str_ireplace("&name&", $name, $sent_text);
3699 $sent_text = str_ireplace("&surname&", $surname, $sent_text);
3700 }
3701 echo ". =>";
3702 flush();
3703 crossEcho("Sending to $to <font color=yellow>-</font> Subject: $title <font color=yellow>-</font> Sender name: $send_name <font color=yellow>-</font> Sender email: $sender <font color=yellow>-</font> reply-to: $reply2 => ");
3704 flush();
3705 try {
3706
3707 $mail->MailerDebug = true;
3708 $mail->Priority = $XPriority;
3709 $mail->Encoding = $encoding;
3710 $mail->SetFrom($sender);
3711 $mail->FromName = $send_name;
3712 $mail->AddReplyTo($reply2, $send_name);
3713 $mail->AddAddress($to);
3714 $mail->Body = $sent_html;
3715 $mail->IsHTML(true);
3716 $mail->Subject = $title;
3717 $mail->AltBody = $sent_text;
3718 $mail->addCustomHeader("Reply-To: $reply2 <$send_name>");
3719 if ($use_smtp) {
3720 $mail->IsSMTP();
3721 $mail->SMTPDebug = 2;
3722 $mail->Host = $smtp_host;
3723 $mail->Port = $smtp_port;
3724 if ($use_auth) {
3725 $mail->SMTPAuth = true;
3726 $mail->Username = $smtp_user;
3727 $mail->Password = $smtp_pass;
3728 }
3729 }
3730 if (isset($_FILES['file']) && $_FILES['file']['error'] == UPLOAD_ERR_OK) {
3731 $test = mime_content_type($_FILES['file']['tmp_name']);
3732 $mail->AddAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name'], "base64", mime_content_type($_FILES['file']['tmp_name']));
3733 }
3734 if ($bpshtml) {
3735 $mail->XMailer = "Microsoft Office Outlook, Build 17.551210\n";
3736 }
3737 if ($newsletter) {
3738 $mail->set('List-Unsubscribe', '<mailto:unsubscribe@' . $HTTP_HOST . '>, <http://' . $HTTP_HOST . '/user/unsubscribe/?sid=abcdefg>');
3739 $mail->addCustomHeader("X-Mailer: phplist v2.10.17");
3740 $mail->addCustomHeader("X-Virus-Scanned: clamav-milter 0.98.1 at stamps.cs.ucsb.edu");
3741 $mail->addCustomHeader("X-Virus-Status: Clean");
3742 $mail->addCustomHeader("X-Spam-Status: No, score=1.3 required=5.0 tests=RDNS_NONE shortcircuit=no autolearn=no autolearn_force=no version=3.4.0");
3743 $mail->addCustomHeader("X-Spam-Level: *");
3744 $mail->addCustomHeader("X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on stamps.cs.ucsb.edu");
3745 }
3746 if ($ovh) {
3747 $mail->set("X-Ovh-Tracer-Id", mt_rand(1000, 999999) . mt_rand(1000, 999999) . mt_rand(1000, 999999) . mt_rand(1000, 999999));
3748 $mail->set("X-VR-SPAMSTATE", "OK");
3749 $mail->set("X-VR-SPAMSCORE", "-100");
3750 $mail->set("X-VR-SPAMCAUSE", generateRandomString(154));
3751 $mail->set("Return-Path", "bounce-id=D" . mt_rand(100, 200) . "=U" . mt_rand(1000, 10000) . "start.ovh.net" . mt_rand(1000, 999999) . mt_rand(1000, 999999) . mt_rand(1000, 999999) . "@89.mail-out.ovh.net");
3752 }
3753 if ($dkim) {
3754 $mail->DKIM_selector = 'alpha';
3755 $mail->DKIM_identity = $mail->From;
3756 $mail->DKIM_domain = $_SERVER['SERVER_NAME'];
3757 $mail->DKIM_private = $privateKey;
3758 $mail->DKIM_passphrase = '';
3759 }
3760 $mail->send();
3761 crossEcho("<font color=green>Sent ! </font> <br>");
3762 $sent++;
3763 }
3764 catch (phpmailerException $e) {
3765 $excp = $e->getMessage();
3766 if( strpos($excp, 'Invalid address') !== false ) { //IF THE EMAIL GETS THROUGH THE FILTER VAR
3767 crossEcho("<font color=red>Not sent : Invalid address: $to.. getting the next target ! </font>");
3768 continue;
3769 }
3770 crossEcho("<font color=red>-------A fatal error has occurred: $excp QUITTING !</font>");
3771 break;
3772 }
3773
3774 catch (Exception $e) {
3775 echo "<font color=red>Not sent, sorry !</font><br>";
3776 echo "<font color=red>-------A fatal error has occured: " . $e->errorMessage() . " QUITTING !</font>";
3777 break;
3778 }
3779 }
3780 if (!$isCli) {
3781 crossEcho("</div><script>alert(\"Sending Complete\\nSent $sent emails out of $numemails\");</script>");
3782 } else {
3783 echo "DONE SENDING EMAILS. SENT $sent EMAILS, HAVE A NICE DAY.\n";
3784 }
3785
3786} elseif (isset($_POST['saveconf'])) {
3787
3788 //write data here
3789 $data = array(
3790 "use_smtp" => isset($_POST['use_smtp']) ? "true" : "false",
3791 "smtp_host" => $_POST['smtp_host'],
3792 "smtp_port" => $_POST['smtp_port'],
3793 "use_auth" => isset($_POST['use_auth']) ? "true" : "false",
3794 "smtp_user" => $_POST['smtp_user'],
3795 "smtp_pass" => $_POST['smtp_pass'],
3796 "realname" => $_POST['realname'],
3797 "from" => $_POST['from'],
3798 "rep_to_is_sender" => isset($_POST['rep_to_is_sender']) ? "true" : "false",
3799 "replyto" => $_POST['replyto'],
3800 "XPriority" => $_POST['xpriority'],
3801 "encoding" => $_POST['Encoding'],
3802 "bpshtml" => isset($_POST['bpshtml']) ? "true" : "false",
3803 "newsletter" => isset($_POST['newsletter']) ? "true" : "false",
3804 "ovh" => isset($_POST['ovh']) ? "true" : "false",
3805 "dkim" => isset($_POST['DKIM']) ? "true" : "false",
3806 "genauto" => isset($_POST['genauto']) ? "true" : "false",
3807 "person" => isset($_POST['person']) ? "true" : "false",
3808 "subject" => stripslashes($_POST['subject']),
3809 "message_html" => base64_encode($_POST['message_html']),
3810 "message_text" => base64_encode($_POST['message_text']),
3811 "grts" => isset($_POST['grts']) ? "true" : "false");
3812 //write the file
3813 $paths = new Pathes();
3814 $tempConf = $paths->TJMailerConfigPath;
3815 $confDir = $paths->ConfDirName;
3816 $confFile = $paths->TJConfigFileName;
3817 $config = new Conf();
3818 $config->write_config_file($data, $tempConf);
3819
3820 //now download it
3821 try {
3822 echo "<center>Saved under /$confDir/$confFile ! </script>";
3823 echo "<script type=\"text/javascript\"> window.open(\"./$confDir/$confFile\"); </script>";
3824 } catch (Exception $e) {
3825 die("An error has occurred downloading file: " . $e->getMessage());
3826 }
3827} elseif ((isset($_GET['operation']) && $_GET['operation'] == "dlcfg")|| ($isCli && $argv[1] == "-saveTemp")) {
3828 $paths = new Pathes();
3829 $templatePath = $paths->TJMailerTemplatePath;
3830 $confDir = $paths->ConfDirName;
3831 $confFile = $paths->TemplateConfFileName;
3832 $templateString = Conf::$header . Conf::$defaultConf;
3833 $fileName = $paths->TemplateConfFileName;
3834 if (!is_dir($confDir)) {
3835 mkdir($confDir, 0755, true);
3836 }
3837 if (!file_exists($templatePath)) {
3838 try {
3839 $myfile = fopen($templatePath, "wb") or die("Unable to open file!");
3840 fwrite($myfile, base64_decode($templateString));
3841 fclose($myfile);
3842 }
3843 catch (Exception $e) {
3844 die("An error has occurred generating file: " . $e->getMessage());
3845 }
3846 }
3847 if($isCli){
3848 echo "Template saved under ./$confDir/$fileName";
3849 }
3850
3851 else{
3852 echo "<script type=\"text/javascript\">window.open(\"./$confDir/$fileName\"); </script>";
3853 }
3854
3855}?>