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