equal
deleted
inserted
replaced
11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> |
11 * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net> |
12 * @author Brent R. Matzelle (original founder) |
12 * @author Brent R. Matzelle (original founder) |
13 * @copyright 2012 - 2020 Marcus Bointon |
13 * @copyright 2012 - 2020 Marcus Bointon |
14 * @copyright 2010 - 2012 Jim Jagielski |
14 * @copyright 2010 - 2012 Jim Jagielski |
15 * @copyright 2004 - 2009 Andy Prevost |
15 * @copyright 2004 - 2009 Andy Prevost |
16 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License |
16 * @license https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html GNU Lesser General Public License |
17 * @note This program is distributed in the hope that it will be useful - WITHOUT |
17 * @note This program is distributed in the hope that it will be useful - WITHOUT |
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
19 * FITNESS FOR A PARTICULAR PURPOSE. |
19 * FITNESS FOR A PARTICULAR PURPOSE. |
20 */ |
20 */ |
21 |
21 |
150 /** |
150 /** |
151 * An iCal message part body. |
151 * An iCal message part body. |
152 * Only supported in simple alt or alt_inline message types |
152 * Only supported in simple alt or alt_inline message types |
153 * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator. |
153 * To generate iCal event structures, use classes like EasyPeasyICS or iCalcreator. |
154 * |
154 * |
155 * @see http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/ |
155 * @see https://kigkonsult.se/iCalcreator/ |
156 * @see http://kigkonsult.se/iCalcreator/ |
|
157 * |
156 * |
158 * @var string |
157 * @var string |
159 */ |
158 */ |
160 public $Ical = ''; |
159 public $Ical = ''; |
161 |
160 |
252 * An ID to be used in the Message-ID header. |
251 * An ID to be used in the Message-ID header. |
253 * If empty, a unique id will be generated. |
252 * If empty, a unique id will be generated. |
254 * You can set your own, but it must be in the format "<id@domain>", |
253 * You can set your own, but it must be in the format "<id@domain>", |
255 * as defined in RFC5322 section 3.6.4 or it will be ignored. |
254 * as defined in RFC5322 section 3.6.4 or it will be ignored. |
256 * |
255 * |
257 * @see https://tools.ietf.org/html/rfc5322#section-3.6.4 |
256 * @see https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4 |
258 * |
257 * |
259 * @var string |
258 * @var string |
260 */ |
259 */ |
261 public $MessageID = ''; |
260 public $MessageID = ''; |
262 |
261 |
356 * @var string |
355 * @var string |
357 */ |
356 */ |
358 public $AuthType = ''; |
357 public $AuthType = ''; |
359 |
358 |
360 /** |
359 /** |
361 * SMTP SMTPXClient command attibutes |
360 * SMTP SMTPXClient command attributes |
362 * |
361 * |
363 * @var array |
362 * @var array |
364 */ |
363 */ |
365 protected $SMTPXClient = []; |
364 protected $SMTPXClient = []; |
366 |
365 |
386 * 'SUCCESS' will notify you when your mail has arrived at its destination. |
385 * 'SUCCESS' will notify you when your mail has arrived at its destination. |
387 * 'FAILURE' will arrive if an error occurred during delivery. |
386 * 'FAILURE' will arrive if an error occurred during delivery. |
388 * 'DELAY' will notify you if there is an unusual delay in delivery, but the actual |
387 * 'DELAY' will notify you if there is an unusual delay in delivery, but the actual |
389 * delivery's outcome (success or failure) is not yet decided. |
388 * delivery's outcome (success or failure) is not yet decided. |
390 * |
389 * |
391 * @see https://tools.ietf.org/html/rfc3461 See section 4.1 for more information about NOTIFY |
390 * @see https://www.rfc-editor.org/rfc/rfc3461.html#section-4.1 for more information about NOTIFY |
392 */ |
391 */ |
393 public $dsn = ''; |
392 public $dsn = ''; |
394 |
393 |
395 /** |
394 /** |
396 * SMTP class debug output mode. |
395 * SMTP class debug output mode. |
466 /** |
465 /** |
467 * Whether to generate VERP addresses on send. |
466 * Whether to generate VERP addresses on send. |
468 * Only applicable when sending via SMTP. |
467 * Only applicable when sending via SMTP. |
469 * |
468 * |
470 * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path |
469 * @see https://en.wikipedia.org/wiki/Variable_envelope_return_path |
471 * @see http://www.postfix.org/VERP_README.html Postfix VERP info |
470 * @see https://www.postfix.org/VERP_README.html Postfix VERP info |
472 * |
471 * |
473 * @var bool |
472 * @var bool |
474 */ |
473 */ |
475 public $do_verp = false; |
474 public $do_verp = false; |
476 |
475 |
549 * Callback Action function name. |
548 * Callback Action function name. |
550 * |
549 * |
551 * The function that handles the result of the send email action. |
550 * The function that handles the result of the send email action. |
552 * It is called out by send() for each email sent. |
551 * It is called out by send() for each email sent. |
553 * |
552 * |
554 * Value can be any php callable: http://www.php.net/is_callable |
553 * Value can be any php callable: https://www.php.net/is_callable |
555 * |
554 * |
556 * Parameters: |
555 * Parameters: |
557 * bool $result result of the send action |
556 * bool $result result of the send action |
558 * array $to email addresses of the recipients |
557 * array $to email addresses of the recipients |
559 * array $cc cc email addresses |
558 * array $cc cc email addresses |
560 * array $bcc bcc email addresses |
559 * array $bcc bcc email addresses |
561 * string $subject the subject |
560 * string $subject the subject |
562 * string $body the email body |
561 * string $body the email body |
755 /** |
754 /** |
756 * The PHPMailer Version number. |
755 * The PHPMailer Version number. |
757 * |
756 * |
758 * @var string |
757 * @var string |
759 */ |
758 */ |
760 const VERSION = '6.9.1'; |
759 const VERSION = '6.9.3'; |
761 |
760 |
762 /** |
761 /** |
763 * Error severity: message only, continue processing. |
762 * Error severity: message only, continue processing. |
764 * |
763 * |
765 * @var int |
764 * @var int |
901 if ($this->SMTPDebug <= 0) { |
900 if ($this->SMTPDebug <= 0) { |
902 return; |
901 return; |
903 } |
902 } |
904 //Is this a PSR-3 logger? |
903 //Is this a PSR-3 logger? |
905 if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { |
904 if ($this->Debugoutput instanceof \Psr\Log\LoggerInterface) { |
906 $this->Debugoutput->debug($str); |
905 $this->Debugoutput->debug(rtrim($str, "\r\n")); |
907 |
906 |
908 return; |
907 return; |
909 } |
908 } |
910 //Avoid clash with built-in function names |
909 //Avoid clash with built-in function names |
911 if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { |
910 if (is_callable($this->Debugoutput) && !in_array($this->Debugoutput, ['error_log', 'html', 'echo'])) { |
1070 * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer |
1069 * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer |
1071 * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still |
1070 * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still |
1072 * be modified after calling this function), addition of such addresses is delayed until send(). |
1071 * be modified after calling this function), addition of such addresses is delayed until send(). |
1073 * Addresses that have been added already return false, but do not throw exceptions. |
1072 * Addresses that have been added already return false, but do not throw exceptions. |
1074 * |
1073 * |
1075 * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo' |
1074 * @param string $kind One of 'to', 'cc', 'bcc', or 'Reply-To' |
1076 * @param string $address The email address |
1075 * @param string $address The email address |
1077 * @param string $name An optional username associated with the address |
1076 * @param string $name An optional username associated with the address |
1078 * |
1077 * |
1079 * @throws Exception |
1078 * @throws Exception |
1080 * |
1079 * |
1210 * Parse and validate a string containing one or more RFC822-style comma-separated email addresses |
1209 * Parse and validate a string containing one or more RFC822-style comma-separated email addresses |
1211 * of the form "display name <address>" into an array of name/address pairs. |
1210 * of the form "display name <address>" into an array of name/address pairs. |
1212 * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. |
1211 * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. |
1213 * Note that quotes in the name part are removed. |
1212 * Note that quotes in the name part are removed. |
1214 * |
1213 * |
1215 * @see http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation |
1214 * @see https://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation |
1216 * |
1215 * |
1217 * @param string $addrstr The address list string |
1216 * @param string $addrstr The address list string |
1218 * @param bool $useimap Whether to use the IMAP extension to parse the list |
1217 * @param bool $useimap Whether to use the IMAP extension to parse the list |
1219 * @param string $charset The charset to use when decoding the address list string. |
1218 * @param string $charset The charset to use when decoding the address list string. |
1220 * |
1219 * |
1405 * * numeric TLDs: `a@b.123` |
1404 * * numeric TLDs: `a@b.123` |
1406 * * unbracketed IPv4 literals: `a@192.168.0.1` |
1405 * * unbracketed IPv4 literals: `a@192.168.0.1` |
1407 * * IPv6 literals: 'first.last@[IPv6:a1::]' |
1406 * * IPv6 literals: 'first.last@[IPv6:a1::]' |
1408 * Not all of these will necessarily work for sending! |
1407 * Not all of these will necessarily work for sending! |
1409 * |
1408 * |
1410 * @see http://squiloople.com/2009/12/20/email-address-validation/ |
|
1411 * @copyright 2009-2010 Michael Rushton |
1409 * @copyright 2009-2010 Michael Rushton |
1412 * Feel free to use and redistribute this code. But please keep this copyright notice. |
1410 * Feel free to use and redistribute this code. But please keep this copyright notice. |
1413 */ |
1411 */ |
1414 return (bool) preg_match( |
1412 return (bool) preg_match( |
1415 '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . |
1413 '/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}@)' . |
1734 } |
1732 } |
1735 $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; |
1733 $header = static::stripTrailingWSP($header) . static::$LE . static::$LE; |
1736 //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver |
1734 //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver |
1737 //A space after `-f` is optional, but there is a long history of its presence |
1735 //A space after `-f` is optional, but there is a long history of its presence |
1738 //causing problems, so we don't use one |
1736 //causing problems, so we don't use one |
1739 //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html |
1737 //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html |
1740 //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html |
1738 //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html |
1741 //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html |
|
1742 //Example problem: https://www.drupal.org/node/1057954 |
1739 //Example problem: https://www.drupal.org/node/1057954 |
1743 |
1740 |
1744 //PHP 5.6 workaround |
1741 //PHP 5.6 workaround |
1745 $sendmail_from_value = ini_get('sendmail_from'); |
1742 $sendmail_from_value = ini_get('sendmail_from'); |
1746 if (empty($this->Sender) && !empty($sendmail_from_value)) { |
1743 if (empty($this->Sender) && !empty($sendmail_from_value)) { |
1874 * |
1871 * |
1875 * @return bool |
1872 * @return bool |
1876 */ |
1873 */ |
1877 protected static function isPermittedPath($path) |
1874 protected static function isPermittedPath($path) |
1878 { |
1875 { |
1879 //Matches scheme definition from https://tools.ietf.org/html/rfc3986#section-3.1 |
1876 //Matches scheme definition from https://www.rfc-editor.org/rfc/rfc3986#section-3.1 |
1880 return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path); |
1877 return !preg_match('#^[a-z][a-z\d+.-]*://#i', $path); |
1881 } |
1878 } |
1882 |
1879 |
1883 /** |
1880 /** |
1884 * Check whether a file path is safe, accessible, and readable. |
1881 * Check whether a file path is safe, accessible, and readable. |
1901 } |
1898 } |
1902 |
1899 |
1903 /** |
1900 /** |
1904 * Send mail using the PHP mail() function. |
1901 * Send mail using the PHP mail() function. |
1905 * |
1902 * |
1906 * @see http://www.php.net/manual/en/book.mail.php |
1903 * @see https://www.php.net/manual/en/book.mail.php |
1907 * |
1904 * |
1908 * @param string $header The message headers |
1905 * @param string $header The message headers |
1909 * @param string $body The message body |
1906 * @param string $body The message body |
1910 * |
1907 * |
1911 * @throws Exception |
1908 * @throws Exception |
1931 |
1928 |
1932 $params = null; |
1929 $params = null; |
1933 //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver |
1930 //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver |
1934 //A space after `-f` is optional, but there is a long history of its presence |
1931 //A space after `-f` is optional, but there is a long history of its presence |
1935 //causing problems, so we don't use one |
1932 //causing problems, so we don't use one |
1936 //Exim docs: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html |
1933 //Exim docs: https://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_exim_command_line.html |
1937 //Sendmail docs: http://www.sendmail.org/~ca/email/man/sendmail.html |
1934 //Sendmail docs: https://www.sendmail.org/~ca/email/man/sendmail.html |
1938 //Qmail docs: http://www.qmail.org/man/man8/qmail-inject.html |
|
1939 //Example problem: https://www.drupal.org/node/1057954 |
1935 //Example problem: https://www.drupal.org/node/1057954 |
1940 //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. |
1936 //CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped. |
1941 |
1937 |
1942 //PHP 5.6 workaround |
1938 //PHP 5.6 workaround |
1943 $sendmail_from_value = ini_get('sendmail_from'); |
1939 $sendmail_from_value = ini_get('sendmail_from'); |
2709 if ('mail' !== $this->Mailer) { |
2705 if ('mail' !== $this->Mailer) { |
2710 $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); |
2706 $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject))); |
2711 } |
2707 } |
2712 |
2708 |
2713 //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 |
2709 //Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4 |
2714 //https://tools.ietf.org/html/rfc5322#section-3.6.4 |
2710 //https://www.rfc-editor.org/rfc/rfc5322#section-3.6.4 |
2715 if ( |
2711 if ( |
2716 '' !== $this->MessageID && |
2712 '' !== $this->MessageID && |
2717 preg_match( |
2713 preg_match( |
2718 '/^<((([a-z\d!#$%&\'*+\/=?^_`{|}~-]+(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)' . |
2714 '/^<((([a-z\d!#$%&\'*+\/=?^_`{|}~-]+(\.[a-z\d!#$%&\'*+\/=?^_`{|}~-]+)*)' . |
2719 '|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])' . |
2715 '|("(([\x01-\x08\x0B\x0C\x0E-\x1F\x7F]|[\x21\x23-\x5B\x5D-\x7E])' . |
3634 /** |
3630 /** |
3635 * Encode and wrap long multibyte strings for mail headers |
3631 * Encode and wrap long multibyte strings for mail headers |
3636 * without breaking lines within a character. |
3632 * without breaking lines within a character. |
3637 * Adapted from a function by paravoid. |
3633 * Adapted from a function by paravoid. |
3638 * |
3634 * |
3639 * @see http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 |
3635 * @see https://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283 |
3640 * |
3636 * |
3641 * @param string $str multi-byte text to wrap encode |
3637 * @param string $str multi-byte text to wrap encode |
3642 * @param string $linebreak string to use as linefeed/end-of-line |
3638 * @param string $linebreak string to use as linefeed/end-of-line |
3643 * |
3639 * |
3644 * @return string |
3640 * @return string |
3690 } |
3686 } |
3691 |
3687 |
3692 /** |
3688 /** |
3693 * Encode a string using Q encoding. |
3689 * Encode a string using Q encoding. |
3694 * |
3690 * |
3695 * @see http://tools.ietf.org/html/rfc2047#section-4.2 |
3691 * @see https://www.rfc-editor.org/rfc/rfc2047#section-4.2 |
3696 * |
3692 * |
3697 * @param string $str the text to encode |
3693 * @param string $str the text to encode |
3698 * @param string $position Where the text is going to be used, see the RFC for what that means |
3694 * @param string $position Where the text is going to be used, see the RFC for what that means |
3699 * |
3695 * |
3700 * @return string |
3696 * @return string |
4228 $result = $this->Hostname; |
4224 $result = $this->Hostname; |
4229 } elseif (isset($_SERVER) && array_key_exists('SERVER_NAME', $_SERVER)) { |
4225 } elseif (isset($_SERVER) && array_key_exists('SERVER_NAME', $_SERVER)) { |
4230 $result = $_SERVER['SERVER_NAME']; |
4226 $result = $_SERVER['SERVER_NAME']; |
4231 } elseif (function_exists('gethostname') && gethostname() !== false) { |
4227 } elseif (function_exists('gethostname') && gethostname() !== false) { |
4232 $result = gethostname(); |
4228 $result = gethostname(); |
4233 } elseif (php_uname('n') !== false) { |
4229 } elseif (php_uname('n') !== '') { |
4234 $result = php_uname('n'); |
4230 $result = php_uname('n'); |
4235 } |
4231 } |
4236 if (!static::isValidHost($result)) { |
4232 if (!static::isValidHost($result)) { |
4237 return 'localhost.localdomain'; |
4233 return 'localhost.localdomain'; |
4238 } |
4234 } |
4253 //Simple syntax limits |
4249 //Simple syntax limits |
4254 if ( |
4250 if ( |
4255 empty($host) |
4251 empty($host) |
4256 || !is_string($host) |
4252 || !is_string($host) |
4257 || strlen($host) > 256 |
4253 || strlen($host) > 256 |
4258 || !preg_match('/^([a-zA-Z\d.-]*|\[[a-fA-F\d:]+\])$/', $host) |
4254 || !preg_match('/^([a-z\d.-]*|\[[a-f\d:]+\])$/i', $host) |
4259 ) { |
4255 ) { |
4260 return false; |
4256 return false; |
4261 } |
4257 } |
4262 //Looks like a bracketed IPv6 address |
4258 //Looks like a bracketed IPv6 address |
4263 if (strlen($host) > 2 && substr($host, 0, 1) === '[' && substr($host, -1, 1) === ']') { |
4259 if (strlen($host) > 2 && substr($host, 0, 1) === '[' && substr($host, -1, 1) === ']') { |
4267 //Need to check this first because otherwise things like `999.0.0.0` are considered valid host names |
4263 //Need to check this first because otherwise things like `999.0.0.0` are considered valid host names |
4268 if (is_numeric(str_replace('.', '', $host))) { |
4264 if (is_numeric(str_replace('.', '', $host))) { |
4269 //Is it a valid IPv4 address? |
4265 //Is it a valid IPv4 address? |
4270 return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; |
4266 return filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false; |
4271 } |
4267 } |
4272 //Is it a syntactically valid hostname (when embeded in a URL)? |
4268 //Is it a syntactically valid hostname (when embedded in a URL)? |
4273 return filter_var('http://' . $host, FILTER_VALIDATE_URL) !== false; |
4269 return filter_var('https://' . $host, FILTER_VALIDATE_URL) !== false; |
4274 } |
4270 } |
4275 |
4271 |
4276 /** |
4272 /** |
4277 * Get an error message in the current language. |
4273 * Get an error message in the current language. |
4278 * |
4274 * |
4679 |
4675 |
4680 /** |
4676 /** |
4681 * Multi-byte-safe pathinfo replacement. |
4677 * Multi-byte-safe pathinfo replacement. |
4682 * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe. |
4678 * Drop-in replacement for pathinfo(), but multibyte- and cross-platform-safe. |
4683 * |
4679 * |
4684 * @see http://www.php.net/manual/en/function.pathinfo.php#107461 |
4680 * @see https://www.php.net/manual/en/function.pathinfo.php#107461 |
4685 * |
4681 * |
4686 * @param string $path A filename or path, does not need to exist as a file |
4682 * @param string $path A filename or path, does not need to exist as a file |
4687 * @param int|string $options Either a PATHINFO_* constant, |
4683 * @param int|string $options Either a PATHINFO_* constant, |
4688 * or a string name to return only the specified piece |
4684 * or a string name to return only the specified piece |
4689 * |
4685 * |
4914 /** |
4910 /** |
4915 * Generate a DKIM canonicalization header. |
4911 * Generate a DKIM canonicalization header. |
4916 * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2. |
4912 * Uses the 'relaxed' algorithm from RFC6376 section 3.4.2. |
4917 * Canonicalized headers should *always* use CRLF, regardless of mailer setting. |
4913 * Canonicalized headers should *always* use CRLF, regardless of mailer setting. |
4918 * |
4914 * |
4919 * @see https://tools.ietf.org/html/rfc6376#section-3.4.2 |
4915 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.2 |
4920 * |
4916 * |
4921 * @param string $signHeader Header |
4917 * @param string $signHeader Header |
4922 * |
4918 * |
4923 * @return string |
4919 * @return string |
4924 */ |
4920 */ |
4926 { |
4922 { |
4927 //Normalize breaks to CRLF (regardless of the mailer) |
4923 //Normalize breaks to CRLF (regardless of the mailer) |
4928 $signHeader = static::normalizeBreaks($signHeader, self::CRLF); |
4924 $signHeader = static::normalizeBreaks($signHeader, self::CRLF); |
4929 //Unfold header lines |
4925 //Unfold header lines |
4930 //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` |
4926 //Note PCRE \s is too broad a definition of whitespace; RFC5322 defines it as `[ \t]` |
4931 //@see https://tools.ietf.org/html/rfc5322#section-2.2 |
4927 //@see https://www.rfc-editor.org/rfc/rfc5322#section-2.2 |
4932 //That means this may break if you do something daft like put vertical tabs in your headers. |
4928 //That means this may break if you do something daft like put vertical tabs in your headers. |
4933 $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); |
4929 $signHeader = preg_replace('/\r\n[ \t]+/', ' ', $signHeader); |
4934 //Break headers out into an array |
4930 //Break headers out into an array |
4935 $lines = explode(self::CRLF, $signHeader); |
4931 $lines = explode(self::CRLF, $signHeader); |
4936 foreach ($lines as $key => $line) { |
4932 foreach ($lines as $key => $line) { |
4958 /** |
4954 /** |
4959 * Generate a DKIM canonicalization body. |
4955 * Generate a DKIM canonicalization body. |
4960 * Uses the 'simple' algorithm from RFC6376 section 3.4.3. |
4956 * Uses the 'simple' algorithm from RFC6376 section 3.4.3. |
4961 * Canonicalized bodies should *always* use CRLF, regardless of mailer setting. |
4957 * Canonicalized bodies should *always* use CRLF, regardless of mailer setting. |
4962 * |
4958 * |
4963 * @see https://tools.ietf.org/html/rfc6376#section-3.4.3 |
4959 * @see https://www.rfc-editor.org/rfc/rfc6376#section-3.4.3 |
4964 * |
4960 * |
4965 * @param string $body Message Body |
4961 * @param string $body Message Body |
4966 * |
4962 * |
4967 * @return string |
4963 * @return string |
4968 */ |
4964 */ |
4994 $DKIMsignatureType = 'rsa-sha256'; //Signature & hash algorithms |
4990 $DKIMsignatureType = 'rsa-sha256'; //Signature & hash algorithms |
4995 $DKIMcanonicalization = 'relaxed/simple'; //Canonicalization methods of header & body |
4991 $DKIMcanonicalization = 'relaxed/simple'; //Canonicalization methods of header & body |
4996 $DKIMquery = 'dns/txt'; //Query method |
4992 $DKIMquery = 'dns/txt'; //Query method |
4997 $DKIMtime = time(); |
4993 $DKIMtime = time(); |
4998 //Always sign these headers without being asked |
4994 //Always sign these headers without being asked |
4999 //Recommended list from https://tools.ietf.org/html/rfc6376#section-5.4.1 |
4995 //Recommended list from https://www.rfc-editor.org/rfc/rfc6376#section-5.4.1 |
5000 $autoSignHeaders = [ |
4996 $autoSignHeaders = [ |
5001 'from', |
4997 'from', |
5002 'to', |
4998 'to', |
5003 'cc', |
4999 'cc', |
5004 'date', |
5000 'date', |
5100 if ('' !== $this->DKIM_identity) { |
5096 if ('' !== $this->DKIM_identity) { |
5101 $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE; |
5097 $ident = ' i=' . $this->DKIM_identity . ';' . static::$LE; |
5102 } |
5098 } |
5103 //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag |
5099 //The DKIM-Signature header is included in the signature *except for* the value of the `b` tag |
5104 //which is appended after calculating the signature |
5100 //which is appended after calculating the signature |
5105 //https://tools.ietf.org/html/rfc6376#section-3.5 |
5101 //https://www.rfc-editor.org/rfc/rfc6376#section-3.5 |
5106 $dkimSignatureHeader = 'DKIM-Signature: v=1;' . |
5102 $dkimSignatureHeader = 'DKIM-Signature: v=1;' . |
5107 ' d=' . $this->DKIM_domain . ';' . |
5103 ' d=' . $this->DKIM_domain . ';' . |
5108 ' s=' . $this->DKIM_selector . ';' . static::$LE . |
5104 ' s=' . $this->DKIM_selector . ';' . static::$LE . |
5109 ' a=' . $DKIMsignatureType . ';' . |
5105 ' a=' . $DKIMsignatureType . ';' . |
5110 ' q=' . $DKIMquery . ';' . |
5106 ' q=' . $DKIMquery . ';' . |