Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Q
question2answer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
outils
question2answer
Commits
81a6e450
Commit
81a6e450
authored
Apr 03, 2017
by
ProThoughts
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated to v5.2.23
parent
438e4513
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
323 additions
and
97 deletions
+323
-97
class.phpmailer.php
qa-include/vendor/PHPMailer/class.phpmailer.php
+227
-71
class.smtp.php
qa-include/vendor/PHPMailer/class.smtp.php
+96
-26
No files found.
qa-include/vendor/PHPMailer/class.phpmailer.php
View file @
81a6e450
...
...
@@ -31,7 +31,7 @@ class PHPMailer
* The PHPMailer Version number.
* @var string
*/
public
$Version
=
'5.2.
14
'
;
public
$Version
=
'5.2.
23
'
;
/**
* Email priority.
...
...
@@ -201,6 +201,9 @@ class PHPMailer
/**
* An ID to be used in the Message-ID header.
* If empty, a unique id will be generated.
* You can set your own, but it must be in the format "<id@domain>",
* as defined in RFC5322 section 3.6.4 or it will be ignored.
* @see https://tools.ietf.org/html/rfc5322#section-3.6.4
* @var string
*/
public
$MessageID
=
''
;
...
...
@@ -285,7 +288,7 @@ class PHPMailer
/**
* SMTP auth type.
* Options are
LOGIN (default), PLAIN, NTLM, CRAM-MD5
* Options are
CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified
* @var string
*/
public
$AuthType
=
''
;
...
...
@@ -352,6 +355,7 @@ class PHPMailer
/**
* Whether to split multiple to addresses into multiple messages
* or send them all in one message.
* Only supported in `mail` and `sendmail` transports, not in SMTP.
* @var boolean
*/
public
$SingleTo
=
false
;
...
...
@@ -394,7 +398,7 @@ class PHPMailer
/**
* DKIM Identity.
* Usually the email address used as the source of the email
* Usually the email address used as the source of the email
.
* @var string
*/
public
$DKIM_identity
=
''
;
...
...
@@ -420,6 +424,13 @@ class PHPMailer
public
$DKIM_private
=
''
;
/**
* DKIM private key string.
* If set, takes precedence over `$DKIM_private`.
* @var string
*/
public
$DKIM_private_string
=
''
;
/**
* Callback Action function name.
*
* The function that handles the result of the send email action.
...
...
@@ -447,6 +458,15 @@ class PHPMailer
public
$XMailer
=
''
;
/**
* Which validator to use by default when validating email addresses.
* May be a callable to inject your own validator, but there are several built-in validators.
* @see PHPMailer::validateAddress()
* @var string|callable
* @static
*/
public
static
$validator
=
'auto'
;
/**
* An instance of the SMTP sender class.
* @var SMTP
* @access protected
...
...
@@ -634,9 +654,11 @@ class PHPMailer
* Constructor.
* @param boolean $exceptions Should we throw external exceptions?
*/
public
function
__construct
(
$exceptions
=
false
)
public
function
__construct
(
$exceptions
=
null
)
{
$this
->
exceptions
=
(
boolean
)
$exceptions
;
if
(
$exceptions
!==
null
)
{
$this
->
exceptions
=
(
boolean
)
$exceptions
;
}
}
/**
...
...
@@ -645,9 +667,7 @@ class PHPMailer
public
function
__destruct
()
{
//Close any open SMTP connection nicely
if
(
$this
->
Mailer
==
'smtp'
)
{
$this
->
smtpClose
();
}
$this
->
smtpClose
();
}
/**
...
...
@@ -671,14 +691,16 @@ class PHPMailer
}
else
{
$subject
=
$this
->
encodeHeader
(
$this
->
secureHeader
(
$subject
));
}
if
(
ini_get
(
'safe_mode'
)
||
!
(
$this
->
UseSendmailOptions
))
{
//Can't use additional_parameters in safe_mode, calling mail() with null params breaks
//@link http://php.net/manual/en/function.mail.php
if
(
ini_get
(
'safe_mode'
)
or
!
$this
->
UseSendmailOptions
or
is_null
(
$params
))
{
$result
=
@
mail
(
$to
,
$subject
,
$body
,
$header
);
}
else
{
$result
=
@
mail
(
$to
,
$subject
,
$body
,
$header
,
$params
);
}
return
$result
;
}
/**
* Output debugging info via user-defined method.
* Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).
...
...
@@ -713,7 +735,7 @@ class PHPMailer
case
'echo'
:
default
:
//Normalize line breaks
$str
=
preg_replace
(
'/
(\r\n|\r|\n)
/ms'
,
"
\n
"
,
$str
);
$str
=
preg_replace
(
'/
\r\n?
/ms'
,
"
\n
"
,
$str
);
echo
gmdate
(
'Y-m-d H:i:s'
)
.
"
\t
"
.
str_replace
(
"
\n
"
,
"
\n
\t
"
,
...
...
@@ -850,7 +872,7 @@ class PHPMailer
$name
=
trim
(
preg_replace
(
'/[\r\n]+/'
,
''
,
$name
));
//Strip breaks and trim
if
((
$pos
=
strrpos
(
$address
,
'@'
))
===
false
)
{
// At-sign is misssing.
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
$address
;
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
" (addAnAddress
$kind
):
$address
"
;
$this
->
setError
(
$error_message
);
$this
->
edebug
(
$error_message
);
if
(
$this
->
exceptions
)
{
...
...
@@ -900,7 +922,7 @@ class PHPMailer
return
false
;
}
if
(
!
$this
->
validateAddress
(
$address
))
{
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
$address
;
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
" (addAnAddress
$kind
):
$address
"
;
$this
->
setError
(
$error_message
);
$this
->
edebug
(
$error_message
);
if
(
$this
->
exceptions
)
{
...
...
@@ -994,7 +1016,7 @@ class PHPMailer
if
((
$pos
=
strrpos
(
$address
,
'@'
))
===
false
or
(
!
$this
->
has8bitChars
(
substr
(
$address
,
++
$pos
))
or
!
$this
->
idnSupported
())
and
!
$this
->
validateAddress
(
$address
))
{
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
$address
;
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
" (setFrom)
$address
"
;
$this
->
setError
(
$error_message
);
$this
->
edebug
(
$error_message
);
if
(
$this
->
exceptions
)
{
...
...
@@ -1027,19 +1049,30 @@ class PHPMailer
/**
* Check that a string looks like an email address.
* @param string $address The email address to check
* @param string $patternselect A selector for the validation pattern to use :
* @param string
|callable
$patternselect A selector for the validation pattern to use :
* * `auto` Pick best pattern automatically;
* * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
* * `pcre` Use old PCRE implementation;
* * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;
* * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.
* * `noregex` Don't use a regex: super fast, really dumb.
* Alternatively you may pass in a callable to inject your own validator, for example:
* PHPMailer::validateAddress('user@example.com', function($address) {
* return (strpos($address, '@') !== false);
* });
* You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
* @return boolean
* @static
* @access public
*/
public
static
function
validateAddress
(
$address
,
$patternselect
=
'auto'
)
public
static
function
validateAddress
(
$address
,
$patternselect
=
null
)
{
if
(
is_null
(
$patternselect
))
{
$patternselect
=
self
::
$validator
;
}
if
(
is_callable
(
$patternselect
))
{
return
call_user_func
(
$patternselect
,
$address
);
}
//Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
if
(
strpos
(
$address
,
"
\n
"
)
!==
false
or
strpos
(
$address
,
"
\r
"
)
!==
false
)
{
return
false
;
...
...
@@ -1216,7 +1249,7 @@ class PHPMailer
}
$this
->
$address_kind
=
$this
->
punyencodeAddress
(
$this
->
$address_kind
);
if
(
!
$this
->
validateAddress
(
$this
->
$address_kind
))
{
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
$this
->
$address_kind
;
$error_message
=
$this
->
lang
(
'invalid_address'
)
.
' (punyEncode) '
.
$this
->
$address_kind
;
$this
->
setError
(
$error_message
);
$this
->
edebug
(
$error_message
);
if
(
$this
->
exceptions
)
{
...
...
@@ -1227,7 +1260,7 @@ class PHPMailer
}
// Set whether the message is multipart/alternative
if
(
!
empty
(
$this
->
AltBody
))
{
if
(
$this
->
alternativeExists
(
))
{
$this
->
ContentType
=
'multipart/alternative'
;
}
...
...
@@ -1261,9 +1294,11 @@ class PHPMailer
// Sign with DKIM if enabled
if
(
!
empty
(
$this
->
DKIM_domain
)
&&
!
empty
(
$this
->
DKIM_private
)
&&
!
empty
(
$this
->
DKIM_selector
)
&&
file_exists
(
$this
->
DKIM_private
))
{
&&
(
!
empty
(
$this
->
DKIM_private_string
)
||
(
!
empty
(
$this
->
DKIM_private
)
&&
file_exists
(
$this
->
DKIM_private
))
)
)
{
$header_dkim
=
$this
->
DKIM_Add
(
$this
->
MIMEHeader
.
$this
->
mailHeader
,
$this
->
encodeHeader
(
$this
->
secureHeader
(
$this
->
Subject
)),
...
...
@@ -1329,19 +1364,24 @@ class PHPMailer
*/
protected
function
sendmailSend
(
$header
,
$body
)
{
if
(
$this
->
Sender
!=
''
)
{
// CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
if
(
!
empty
(
$this
->
Sender
)
and
self
::
isShellSafe
(
$this
->
Sender
))
{
if
(
$this
->
Mailer
==
'qmail'
)
{
$sendmail
=
sprintf
(
'%s -f%s'
,
escapeshellcmd
(
$this
->
Sendmail
),
escapeshellarg
(
$this
->
Sender
))
;
$sendmail
Fmt
=
'%s -f%s'
;
}
else
{
$sendmail
=
sprintf
(
'%s -oi -f%s -t'
,
escapeshellcmd
(
$this
->
Sendmail
),
escapeshellarg
(
$this
->
Sender
))
;
$sendmail
Fmt
=
'%s -oi -f%s -t'
;
}
}
else
{
if
(
$this
->
Mailer
==
'qmail'
)
{
$sendmail
=
sprintf
(
'%s'
,
escapeshellcmd
(
$this
->
Sendmail
))
;
$sendmail
Fmt
=
'%s'
;
}
else
{
$sendmail
=
sprintf
(
'%s -oi -t'
,
escapeshellcmd
(
$this
->
Sendmail
))
;
$sendmail
Fmt
=
'%s -oi -t'
;
}
}
// TODO: If possible, this should be changed to escapeshellarg. Needs thorough testing.
$sendmail
=
sprintf
(
$sendmailFmt
,
escapeshellcmd
(
$this
->
Sendmail
),
$this
->
Sender
);
if
(
$this
->
SingleTo
)
{
foreach
(
$this
->
SingleToArray
as
$toAddr
)
{
if
(
!@
$mail
=
popen
(
$sendmail
,
'w'
))
{
...
...
@@ -1388,6 +1428,40 @@ class PHPMailer
}
/**
* Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.
*
* Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.
* @param string $string The string to be validated
* @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report
* @access protected
* @return boolean
*/
protected
static
function
isShellSafe
(
$string
)
{
// Future-proof
if
(
escapeshellcmd
(
$string
)
!==
$string
or
!
in_array
(
escapeshellarg
(
$string
),
array
(
"'
$string
'"
,
"
\"
$string
\"
"
))
)
{
return
false
;
}
$length
=
strlen
(
$string
);
for
(
$i
=
0
;
$i
<
$length
;
$i
++
)
{
$c
=
$string
[
$i
];
// All other characters have a special meaning in at least one common shell, including = and +.
// Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.
// Note that this does permit non-Latin alphanumeric characters based on the current locale.
if
(
!
ctype_alnum
(
$c
)
&&
strpos
(
'@_-.'
,
$c
)
===
false
)
{
return
false
;
}
}
return
true
;
}
/**
* Send mail using the PHP mail() function.
* @param string $header The message headers
* @param string $body The message body
...
...
@@ -1404,17 +1478,20 @@ class PHPMailer
}
$to
=
implode
(
', '
,
$toArr
);
if
(
empty
(
$this
->
Sender
))
{
$params
=
' '
;
}
else
{
$params
=
sprintf
(
'-f%s'
,
$this
->
Sender
);
$params
=
null
;
//This sets the SMTP envelope sender which gets turned into a return-path header by the receiver
if
(
!
empty
(
$this
->
Sender
)
and
$this
->
validateAddress
(
$this
->
Sender
))
{
// CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.
if
(
self
::
isShellSafe
(
$this
->
Sender
))
{
$params
=
sprintf
(
'-f%s'
,
$this
->
Sender
);
}
}
if
(
$this
->
Sender
!=
''
and
!
ini_get
(
'safe_mode'
))
{
if
(
!
empty
(
$this
->
Sender
)
and
!
ini_get
(
'safe_mode'
)
and
$this
->
validateAddress
(
$this
->
Sender
))
{
$old_from
=
ini_get
(
'sendmail_from'
);
ini_set
(
'sendmail_from'
,
$this
->
Sender
);
}
$result
=
false
;
if
(
$this
->
SingleTo
&&
count
(
$toArr
)
>
1
)
{
if
(
$this
->
SingleTo
and
count
(
$toArr
)
>
1
)
{
foreach
(
$toArr
as
$toAddr
)
{
$result
=
$this
->
mailPassthru
(
$toAddr
,
$this
->
Subject
,
$body
,
$header
,
$params
);
$this
->
doCallback
(
$result
,
array
(
$toAddr
),
$this
->
cc
,
$this
->
bcc
,
$this
->
Subject
,
$body
,
$this
->
From
);
...
...
@@ -1463,10 +1540,10 @@ class PHPMailer
if
(
!
$this
->
smtpConnect
(
$this
->
SMTPOptions
))
{
throw
new
phpmailerException
(
$this
->
lang
(
'smtp_connect_failed'
),
self
::
STOP_CRITICAL
);
}
if
(
''
==
$this
->
Sender
)
{
$smtp_from
=
$this
->
From
;
}
else
{
if
(
!
empty
(
$this
->
Sender
)
and
$this
->
validateAddress
(
$this
->
Sender
))
{
$smtp_from
=
$this
->
Sender
;
}
else
{
$smtp_from
=
$this
->
From
;
}
if
(
!
$this
->
smtp
->
mail
(
$smtp_from
))
{
$this
->
setError
(
$this
->
lang
(
'from_failed'
)
.
$smtp_from
.
' : '
.
implode
(
','
,
$this
->
smtp
->
getError
()));
...
...
@@ -1520,12 +1597,17 @@ class PHPMailer
* @throws phpmailerException
* @return boolean
*/
public
function
smtpConnect
(
$options
=
array
()
)
public
function
smtpConnect
(
$options
=
null
)
{
if
(
is_null
(
$this
->
smtp
))
{
$this
->
smtp
=
$this
->
getSMTPInstance
();
}
//If no options are provided, use whatever is set in the instance
if
(
is_null
(
$options
))
{
$options
=
$this
->
SMTPOptions
;
}
// Already connected?
if
(
$this
->
smtp
->
connected
())
{
return
true
;
...
...
@@ -1595,7 +1677,7 @@ class PHPMailer
if
(
!
$this
->
smtp
->
startTLS
())
{
throw
new
phpmailerException
(
$this
->
lang
(
'connect_host'
));
}
// We must resend
HELO after tls
negotiation
// We must resend
EHLO after TLS
negotiation
$this
->
smtp
->
hello
(
$hello
);
}
if
(
$this
->
SMTPAuth
)
{
...
...
@@ -1634,7 +1716,7 @@ class PHPMailer
*/
public
function
smtpClose
()
{
if
(
$this
->
smtp
!==
null
)
{
if
(
is_a
(
$this
->
smtp
,
'SMTP'
)
)
{
if
(
$this
->
smtp
->
connected
())
{
$this
->
smtp
->
quit
();
$this
->
smtp
->
close
();
...
...
@@ -1653,6 +1735,19 @@ class PHPMailer
*/
public
function
setLanguage
(
$langcode
=
'en'
,
$lang_path
=
''
)
{
// Backwards compatibility for renamed language codes
$renamed_langcodes
=
array
(
'br'
=>
'pt_br'
,
'cz'
=>
'cs'
,
'dk'
=>
'da'
,
'no'
=>
'nb'
,
'se'
=>
'sv'
,
);
if
(
isset
(
$renamed_langcodes
[
$langcode
]))
{
$langcode
=
$renamed_langcodes
[
$langcode
];
}
// Define full set of translatable strings in English
$PHPMAILER_LANG
=
array
(
'authenticate'
=>
'SMTP Error: Could not authenticate.'
,
...
...
@@ -1679,6 +1774,10 @@ class PHPMailer
// Calculate an absolute path so it can work if CWD is not here
$lang_path
=
dirname
(
__FILE__
)
.
DIRECTORY_SEPARATOR
.
'language'
.
DIRECTORY_SEPARATOR
;
}
//Validate $langcode
if
(
!
preg_match
(
'/^[a-z]{2}(?:_[a-zA-Z]{2})?$/'
,
$langcode
))
{
$langcode
=
'en'
;
}
$foundlang
=
true
;
$lang_file
=
$lang_path
.
'phpmailer.lang-'
.
$langcode
.
'.php'
;
// There is no English translation file
...
...
@@ -1972,7 +2071,9 @@ class PHPMailer
$result
.=
$this
->
headerLine
(
'Subject'
,
$this
->
encodeHeader
(
$this
->
secureHeader
(
$this
->
Subject
)));
}
if
(
$this
->
MessageID
!=
''
)
{
// Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4
// https://tools.ietf.org/html/rfc5322#section-3.6.4
if
(
''
!=
$this
->
MessageID
and
preg_match
(
'/^<.*@.*>$/'
,
$this
->
MessageID
))
{
$this
->
lastMessageID
=
$this
->
MessageID
;
}
else
{
$this
->
lastMessageID
=
sprintf
(
'<%s@%s>'
,
$this
->
uniqueid
,
$this
->
serverHostname
());
...
...
@@ -2074,7 +2175,15 @@ class PHPMailer
*/
public
function
getSentMIMEMessage
()
{
return
$this
->
MIMEHeader
.
$this
->
mailHeader
.
self
::
CRLF
.
$this
->
MIMEBody
;
return
rtrim
(
$this
->
MIMEHeader
.
$this
->
mailHeader
,
"
\n\r
"
)
.
self
::
CRLF
.
self
::
CRLF
.
$this
->
MIMEBody
;
}
/**
* Create unique ID
* @return string
*/
protected
function
generateId
()
{
return
md5
(
uniqid
(
time
()));
}
/**
...
...
@@ -2088,7 +2197,7 @@ class PHPMailer
{
$body
=
''
;
//Create unique IDs and preset boundaries
$this
->
uniqueid
=
md5
(
uniqid
(
time
())
);
$this
->
uniqueid
=
$this
->
generateId
(
);
$this
->
boundary
[
1
]
=
'b1_'
.
$this
->
uniqueid
;
$this
->
boundary
[
2
]
=
'b2_'
.
$this
->
uniqueid
;
$this
->
boundary
[
3
]
=
'b3_'
.
$this
->
uniqueid
;
...
...
@@ -2104,12 +2213,12 @@ class PHPMailer
//Can we do a 7-bit downgrade?
if
(
$bodyEncoding
==
'8bit'
and
!
$this
->
has8bitChars
(
$this
->
Body
))
{
$bodyEncoding
=
'7bit'
;
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$bodyCharSet
=
'us-ascii'
;
}
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding
//change to quoted-printable transfer encoding
for the body part only
if
(
'base64'
!=
$this
->
Encoding
and
self
::
hasLineLongerThanMax
(
$this
->
Body
))
{
$this
->
Encoding
=
'quoted-printable'
;
$bodyEncoding
=
'quoted-printable'
;
}
...
...
@@ -2118,10 +2227,12 @@ class PHPMailer
//Can we do a 7-bit downgrade?
if
(
$altBodyEncoding
==
'8bit'
and
!
$this
->
has8bitChars
(
$this
->
AltBody
))
{
$altBodyEncoding
=
'7bit'
;
//All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit
$altBodyCharSet
=
'us-ascii'
;
}
//If lines are too long, change to quoted-printable transfer encoding
if
(
self
::
hasLineLongerThanMax
(
$this
->
AltBody
))
{
//If lines are too long, and we're not already using an encoding that will shorten them,
//change to quoted-printable transfer encoding for the alt body part only
if
(
'base64'
!=
$altBodyEncoding
and
self
::
hasLineLongerThanMax
(
$this
->
AltBody
))
{
$altBodyEncoding
=
'quoted-printable'
;
}
//Use this as a preamble in all multipart message types
...
...
@@ -2224,8 +2335,10 @@ class PHPMailer
$body
.=
$this
->
attachAll
(
'attachment'
,
$this
->
boundary
[
1
]);
break
;
default
:
// catch case 'plain' and case ''
$body
.=
$this
->
encodeString
(
$this
->
Body
,
$bodyEncoding
);
// Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types
//Reset the `Encoding` property in case we changed it for line length reasons
$this
->
Encoding
=
$bodyEncoding
;
$body
.=
$this
->
encodeString
(
$this
->
Body
,
$this
->
Encoding
);
break
;
}
...
...
@@ -2331,8 +2444,7 @@ class PHPMailer
/**
* Set the message type.
* PHPMailer only supports some preset message types,
* not arbitrary MIME structures.
* PHPMailer only supports some preset message types, not arbitrary MIME structures.
* @access protected
* @return void
*/
...
...
@@ -2350,6 +2462,7 @@ class PHPMailer
}
$this
->
message_type
=
implode
(
'_'
,
$type
);
if
(
$this
->
message_type
==
''
)
{
//The 'plain' message_type refers to the message having a single body element, not that it is plain-text
$this
->
message_type
=
'plain'
;
}
}
...
...
@@ -2379,6 +2492,7 @@ class PHPMailer
/**
* Add an attachment from a path on the filesystem.
* Never use a user-supplied path to a file!
* Returns false if the file could not be found or read.
* @param string $path Path to the attachment.
* @param string $name Overrides the attachment name.
...
...
@@ -2904,6 +3018,7 @@ class PHPMailer
* displayed inline with the message, not just attached for download.
* This is used in HTML messages that embed the images
* the HTML refers to using the $cid value.
* Never use a user-supplied path to a file!
* @param string $path Path to the attachment.
* @param string $cid Content ID of the attachment; Use this to reference
* the content when using an embedded image in HTML.
...
...
@@ -3264,21 +3379,29 @@ class PHPMailer
}
/**
* Create a message from an HTML string.
* Automatically makes modifications for inline images and backgrounds
* and creates a plain-text version by converting the HTML.
* Overwrites any existing values in $this->Body and $this->AltBody
* Create a message body from an HTML string.
* Automatically inlines images and creates a plain-text version by converting the HTML,
* overwriting any existing values in Body and AltBody.
* Do not source $message content from user input!
* $basedir is prepended when handling relative URLs, e.g. <img src="/images/a.png"> and must not be empty
* will look for an image file in $basedir/images/a.png and convert it to inline.
* If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)
* If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.
* @access public
* @param string $message HTML message string
* @param string $basedir
baseline directory for path
* @param string $basedir
Absolute path to a base directory to prepend to relative paths to images
* @param boolean|callable $advanced Whether to use the internal HTML to text converter
* or your own custom converter @see PHPMailer::html2text()
* @return string $message
* @return string $message
The transformed message Body
*/
public
function
msgHTML
(
$message
,
$basedir
=
''
,
$advanced
=
false
)
{
preg_match_all
(
'/(src|background)=["\'](.*)["\']/Ui'
,
$message
,
$images
);
if
(
array_key_exists
(
2
,
$images
))
{
if
(
strlen
(
$basedir
)
>
1
&&
substr
(
$basedir
,
-
1
)
!=
'/'
)
{
// Ensure $basedir has a trailing /
$basedir
.=
'/'
;
}
foreach
(
$images
[
2
]
as
$imgindex
=>
$url
)
{
// Convert data URIs into embedded images
if
(
preg_match
(
'#^data:(image[^;,]*)(;base64)?,#'
,
$url
,
$match
))
{
...
...
@@ -3296,18 +3419,24 @@ class PHPMailer
$message
);
}
}
elseif
(
substr
(
$url
,
0
,
4
)
!==
'cid:'
&&
!
preg_match
(
'#^[A-z]+://#'
,
$url
))
{
// Do not change urls for absolute images (thanks to corvuscorax)
continue
;
}
if
(
// Only process relative URLs if a basedir is provided (i.e. no absolute local paths)
!
empty
(
$basedir
)
// Ignore URLs containing parent dir traversal (..)
&&
(
strpos
(
$url
,
'..'
)
===
false
)
// Do not change urls that are already inline images
&&
substr
(
$url
,
0
,
4
)
!==
'cid:'
// Do not change absolute URLs, including anonymous protocol
&&
!
preg_match
(
'#^[a-z][a-z0-9+.-]*:?//#i'
,
$url
)
)
{
$filename
=
basename
(
$url
);
$directory
=
dirname
(
$url
);
if
(
$directory
==
'.'
)
{
$directory
=
''
;
}
$cid
=
md5
(
$url
)
.
'@phpmailer.0'
;
// RFC2392 S 2
if
(
strlen
(
$basedir
)
>
1
&&
substr
(
$basedir
,
-
1
)
!=
'/'
)
{
$basedir
.=
'/'
;
}
if
(
strlen
(
$directory
)
>
1
&&
substr
(
$directory
,
-
1
)
!=
'/'
)
{
$directory
.=
'/'
;
}
...
...
@@ -3332,7 +3461,7 @@ class PHPMailer
// Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better
$this
->
Body
=
$this
->
normalizeBreaks
(
$message
);
$this
->
AltBody
=
$this
->
normalizeBreaks
(
$this
->
html2text
(
$message
,
$advanced
));
if
(
empty
(
$this
->
AltBody
))
{
if
(
!
$this
->
alternativeExists
(
))
{
$this
->
AltBody
=
'To view this email message, open it in a program that understands HTML!'
.
self
::
CRLF
.
self
::
CRLF
;
}
...
...
@@ -3343,7 +3472,7 @@ class PHPMailer
* Convert an HTML string into plain text.
* This is used by msgHTML().
* Note - older versions of this function used a bundled advanced converter
* which was been removed for license reasons in #232
* which was been removed for license reasons in #232
.
* Example usage:
* <code>
* // Use default conversion
...
...
@@ -3643,7 +3772,7 @@ class PHPMailer
* @access public
* @param string $signHeader
* @throws phpmailerException
* @return string
* @return string
The DKIM signature value
*/
public
function
DKIM_Sign
(
$signHeader
)
{
...
...
@@ -3653,15 +3782,35 @@ class PHPMailer
}
return
''
;
}
$privKeyStr
=
file_get_contents
(
$this
->
DKIM_private
);
if
(
$this
->
DKIM_passphrase
!=
''
)
{
$privKeyStr
=
!
empty
(
$this
->
DKIM_private_string
)
?
$this
->
DKIM_private_string
:
file_get_contents
(
$this
->
DKIM_private
);
if
(
''
!=
$this
->
DKIM_passphrase
)
{
$privKey
=
openssl_pkey_get_private
(
$privKeyStr
,
$this
->
DKIM_passphrase
);
}
else
{
$privKey
=
$privKeyStr
;
$privKey
=
openssl_pkey_get_private
(
$privKeyStr
)
;
}
if
(
openssl_sign
(
$signHeader
,
$signature
,
$privKey
))
{
return
base64_encode
(
$signature
);
//Workaround for missing digest algorithms in old PHP & OpenSSL versions
//@link http://stackoverflow.com/a/11117338/333340
if
(
version_compare
(
PHP_VERSION
,
'5.3.0'
)
>=
0
and
in_array
(
'sha256WithRSAEncryption'
,
openssl_get_md_methods
(
true
)))
{
if
(
openssl_sign
(
$signHeader
,
$signature
,
$privKey
,
'sha256WithRSAEncryption'
))
{
openssl_pkey_free
(
$privKey
);
return
base64_encode
(
$signature
);
}
}
else
{
$pinfo
=
openssl_pkey_get_details
(
$privKey
);
$hash
=
hash
(
'sha256'
,
$signHeader
);
//'Magic' constant for SHA256 from RFC3447
//@link https://tools.ietf.org/html/rfc3447#page-43
$t
=
'3031300d060960864801650304020105000420'
.
$hash
;
$pslen
=
$pinfo
[
'bits'
]
/
8
-
(
strlen
(
$t
)
/
2
+
3
);
$eb
=
pack
(
'H*'
,
'0001'
.
str_repeat
(
'FF'
,
$pslen
)
.
'00'
.
$t
);
if
(
openssl_private_encrypt
(
$eb
,
$signature
,
$privKey
,
OPENSSL_NO_PADDING
))
{
openssl_pkey_free
(
$privKey
);
return
base64_encode
(
$signature
);
}
}
openssl_pkey_free
(
$privKey
);
return
''
;
}
...
...
@@ -3678,7 +3827,7 @@ class PHPMailer
foreach
(
$lines
as
$key
=>
$line
)
{
list
(
$heading
,
$value
)
=
explode
(
':'
,
$line
,
2
);
$heading
=
strtolower
(
$heading
);
$value
=
preg_replace
(
'/\s
+
/'
,
' '
,
$value
);
// Compress useless spaces
$value
=
preg_replace
(
'/\s
{2,}
/'
,
' '
,
$value
);
// Compress useless spaces
$lines
[
$key
]
=
$heading
.
':'
.
trim
(
$value
);
// Don't forget to remove WSP around the value
}
$signHeader
=
implode
(
"
\r\n
"
,
$lines
);
...
...
@@ -3716,7 +3865,7 @@ class PHPMailer
*/
public
function
DKIM_Add
(
$headers_line
,
$subject
,
$body
)
{
$DKIMsignatureType
=
'rsa-sha
1
'
;
// Signature & hash algorithms
$DKIMsignatureType
=
'rsa-sha
256
'
;
// Signature & hash algorithms
$DKIMcanonicalization
=
'relaxed/simple'
;
// Canonicalization of header/body
$DKIMquery
=
'dns/txt'
;
// Query method
$DKIMtime
=
time
();
// Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)
...
...
@@ -3724,6 +3873,7 @@ class PHPMailer
$headers
=
explode
(
$this
->
LE
,
$headers_line
);
$from_header
=
''
;
$to_header
=
''
;
$date_header
=
''
;
$current
=
''
;
foreach
(
$headers
as
$header
)
{
if
(
strpos
(
$header
,
'From:'
)
===
0
)
{
...
...
@@ -3732,6 +3882,9 @@ class PHPMailer
}
elseif
(
strpos
(
$header
,
'To:'
)
===
0
)
{
$to_header
=
$header
;
$current
=
'to_header'
;
}
elseif
(
strpos
(
$header
,
'Date:'
)
===
0
)
{
$date_header
=
$header
;
$current
=
'date_header'
;
}
else
{
if
(
!
empty
(
$$current
)
&&
strpos
(
$header
,
' =?'
)
===
0
)
{
$$current
.=
$header
;
...
...
@@ -3742,6 +3895,7 @@ class PHPMailer
}
$from
=
str_replace
(
'|'
,
'=7C'
,
$this
->
DKIM_QP
(
$from_header
));
$to
=
str_replace
(
'|'
,
'=7C'
,
$this
->
DKIM_QP
(
$to_header
));
$date
=
str_replace
(
'|'
,
'=7C'
,
$this
->
DKIM_QP
(
$date_header
));
$subject
=
str_replace
(
'|'
,
'=7C'
,
...
...
@@ -3749,7 +3903,7 @@ class PHPMailer
);
// Copied header fields (dkim-quoted-printable)
$body
=
$this
->
DKIM_BodyC
(
$body
);
$DKIMlen
=
strlen
(
$body
);
// Length of body
$DKIMb64
=
base64_encode
(
pack
(
'H*'
,
sha1
(
$body
)));
// Base64 of packed binary SHA-1
hash of body
$DKIMb64
=
base64_encode
(
pack
(
'H*'
,
hash
(
'sha256'
,
$body
)));
// Base64 of packed binary SHA-256
hash of body
if
(
''
==
$this
->
DKIM_identity
)
{
$ident
=
''
;
}
else
{
...
...
@@ -3762,16 +3916,18 @@ class PHPMailer
$this
->
DKIM_selector
.
";
\r\n
"
.
"
\t
t="
.
$DKIMtime
.
'; c='
.
$DKIMcanonicalization
.
";
\r\n
"
.
"
\t
h=From:To:Subject;
\r\n
"
.
"
\t
h=From:To:
Date:
Subject;
\r\n
"
.
"
\t
d="
.
$this
->
DKIM_domain
.
';'
.
$ident
.
"
\r\n
"
.
"
\t
z=
$from
\r\n
"
.
"
\t
|
$to
\r\n
"
.
"
\t
|
$date
\r\n
"
.
"
\t
|
$subject
;
\r\n
"
.
"
\t
bh="
.
$DKIMb64
.
";
\r\n
"
.
"
\t
b="
;
$toSign
=
$this
->
DKIM_HeaderC
(
$from_header
.
"
\r\n
"
.
$to_header
.
"
\r\n
"
.
$date_header
.
"
\r\n
"
.
$subject_header
.
"
\r\n
"
.
$dkimhdrs
);
...
...
qa-include/vendor/PHPMailer/class.smtp.php
View file @
81a6e450
...
...
@@ -30,7 +30,7 @@ class SMTP
* The PHPMailer SMTP version number.
* @var string
*/
const
VERSION
=
'5.2.
14
'
;
const
VERSION
=
'5.2.
23
'
;
/**
* SMTP line break constant.
...
...
@@ -81,7 +81,7 @@ class SMTP
* @deprecated Use the `VERSION` constant instead
* @see SMTP::VERSION
*/
public
$Version
=
'5.2.
14
'
;
public
$Version
=
'5.2.
23
'
;
/**
* SMTP server port number.
...
...
@@ -151,6 +151,17 @@ class SMTP
public
$Timelimit
=
300
;
/**
* @var array patterns to extract smtp transaction id from smtp reply
* Only first capture group will be use, use non-capturing group to deal with it
* Extend this class to override this property to fulfil your needs.
*/
protected
$smtp_transaction_id_patterns
=
array
(
'exim'
=>
'/[0-9]{3} OK id=(.*)/'
,
'sendmail'
=>
'/[0-9]{3} 2.0.0 (.*) Message/'
,
'postfix'
=>
'/[0-9]{3} 2.0.0 Ok: queued as (.*)/'
);
/**
* The socket for the server connection.
* @var resource
*/
...
...
@@ -206,7 +217,7 @@ class SMTP
}
//Avoid clash with built-in function names
if
(
!
in_array
(
$this
->
Debugoutput
,
array
(
'error_log'
,
'html'
,
'echo'
))
and
is_callable
(
$this
->
Debugoutput
))
{
call_user_func
(
$this
->
Debugoutput
,
$str
,
$
this
->
do_debug
);
call_user_func
(
$this
->
Debugoutput
,
$str
,
$
level
);
return
;
}
switch
(
$this
->
Debugoutput
)
{
...
...
@@ -220,8 +231,7 @@ class SMTP
preg_replace
(
'/[\r\n]+/'
,
''
,
$str
),
ENT_QUOTES
,
'UTF-8'
)
.
"<br>
\n
"
;
)
.
"<br>
\n
"
;
break
;
case
'echo'
:
default
:
...
...
@@ -231,7 +241,7 @@ class SMTP
"
\n
"
,
"
\n
\t
"
,
trim
(
$str
)
)
.
"
\n
"
;
)
.
"
\n
"
;
}
}
...
...
@@ -265,15 +275,16 @@ class SMTP
}
// Connect to the SMTP server
$this
->
edebug
(
"Connection: opening to
$host
:
$port
, timeout=
$timeout
, options="
.
var_export
(
$options
,
true
),
"Connection: opening to
$host
:
$port
, timeout=
$timeout
, options="
.
var_export
(
$options
,
true
),
self
::
DEBUG_CONNECTION
);
$errno
=
0
;
$errstr
=
''
;
if
(
$streamok
)
{
$socket_context
=
stream_context_create
(
$options
);
//Suppress errors; connection failures are handled at a higher level
$this
->
smtp_conn
=
@
stream_socket_client
(
set_error_handler
(
array
(
$this
,
'errorHandler'
));
$this
->
smtp_conn
=
stream_socket_client
(
$host
.
":"
.
$port
,
$errno
,
$errstr
,
...
...
@@ -281,12 +292,14 @@ class SMTP
STREAM_CLIENT_CONNECT
,
$socket_context
);
restore_error_handler
();
}
else
{
//Fall back to fsockopen which should work in more places, but is missing some features
$this
->
edebug
(
"Connection: stream_socket_client not available, falling back to fsockopen"
,
self
::
DEBUG_CONNECTION
);
set_error_handler
(
array
(
$this
,
'errorHandler'
));
$this
->
smtp_conn
=
fsockopen
(
$host
,
$port
,
...
...
@@ -294,6 +307,7 @@ class SMTP
$errstr
,
$timeout
);
restore_error_handler
();
}
// Verify we connected properly
if
(
!
is_resource
(
$this
->
smtp_conn
))
{
...
...
@@ -336,15 +350,26 @@ class SMTP
if
(
!
$this
->
sendCommand
(
'STARTTLS'
,
'STARTTLS'
,
220
))
{
return
false
;
}
//Allow the best TLS version(s) we can
$crypto_method
=
STREAM_CRYPTO_METHOD_TLS_CLIENT
;
//PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
//so add them back in manually if we can
if
(
defined
(
'STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT'
))
{
$crypto_method
|=
STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
;
$crypto_method
|=
STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
;
}
// Begin encrypted connection
if
(
!
stream_socket_enable_crypto
(
set_error_handler
(
array
(
$this
,
'errorHandler'
));
$crypto_ok
=
stream_socket_enable_crypto
(
$this
->
smtp_conn
,
true
,
STREAM_CRYPTO_METHOD_TLS_CLIENT
))
{
return
false
;
}
return
true
;
$crypto_method
);
restore_error_handler
();
return
$crypto_ok
;
}
/**
...
...
@@ -373,8 +398,7 @@ class SMTP
}
if
(
array_key_exists
(
'EHLO'
,
$this
->
server_caps
))
{
// SMTP extensions are available. Let's try to find a proper authentication method
// SMTP extensions are available; try to find a proper authentication method
if
(
!
array_key_exists
(
'AUTH'
,
$this
->
server_caps
))
{
$this
->
setError
(
'Authentication is not allowed at this stage'
);
// 'at this stage' means that auth may be allowed after the stage changes
...
...
@@ -389,7 +413,7 @@ class SMTP
);
if
(
empty
(
$authtype
))
{
foreach
(
array
(
'
LOGIN'
,
'CRAM-MD5'
,
'NTLM'
,
'PLAIN
'
,
'XOAUTH2'
)
as
$method
)
{
foreach
(
array
(
'
CRAM-MD5'
,
'LOGIN'
,
'PLAIN'
,
'NTLM
'
,
'XOAUTH2'
)
as
$method
)
{
if
(
in_array
(
$method
,
$this
->
server_caps
[
'AUTH'
]))
{
$authtype
=
$method
;
break
;
...
...
@@ -399,7 +423,7 @@ class SMTP
$this
->
setError
(
'No supported authentication methods found'
);
return
false
;
}
self
::
edebug
(
'Auth method selected: '
.
$authtype
,
self
::
DEBUG_LOWLEVEL
);
self
::
edebug
(
'Auth method selected: '
.
$authtype
,
self
::
DEBUG_LOWLEVEL
);
}
if
(
!
in_array
(
$authtype
,
$this
->
server_caps
[
'AUTH'
]))
{
...
...
@@ -463,7 +487,7 @@ class SMTP
$temp
=
new
stdClass
;
$ntlm_client
=
new
ntlm_sasl_client_class
;
//Check that functions are available
if
(
!
$ntlm_client
->
I
nitialize
(
$temp
))
{
if
(
!
$ntlm_client
->
i
nitialize
(
$temp
))
{
$this
->
setError
(
$temp
->
error
);
$this
->
edebug
(
'You need to enable some modules in your php.ini file: '
...
...
@@ -473,7 +497,7 @@ class SMTP
return
false
;
}
//msg1
$msg1
=
$ntlm_client
->
T
ypeMsg1
(
$realm
,
$workstation
);
//msg1
$msg1
=
$ntlm_client
->
t
ypeMsg1
(
$realm
,
$workstation
);
//msg1
if
(
!
$this
->
sendCommand
(
'AUTH NTLM'
,
...
...
@@ -492,7 +516,7 @@ class SMTP
$password
);
//msg3
$msg3
=
$ntlm_client
->
T
ypeMsg3
(
$msg3
=
$ntlm_client
->
t
ypeMsg3
(
$ntlm_res
,
$username
,
$realm
,
...
...
@@ -525,7 +549,7 @@ class SMTP
* Works like hash_hmac('md5', $data, $key)
* in case that function is not available
* @param string $data The data to hash
* @param string $key
The key to hash with
* @param string $key The key to hash with
* @access protected
* @return string
*/
...
...
@@ -736,7 +760,7 @@ class SMTP
protected
function
parseHelloFields
(
$type
)
{
$this
->
server_caps
=
array
();
$lines
=
explode
(
"
\n
"
,
$this
->
last_re
ply
);
$lines
=
explode
(
"
\n
"
,
$this
->
helo_r
ply
);
foreach
(
$lines
as
$n
=>
$s
)
{
//First 4 chars contain response code followed by - or space
...
...
@@ -868,7 +892,8 @@ class SMTP
$code_ex
=
(
count
(
$matches
)
>
2
?
$matches
[
2
]
:
null
);
// Cut off error code from each response line
$detail
=
preg_replace
(
"/
{
$code
}
[ -]"
.
(
$code_ex
?
str_replace
(
'.'
,
'\\.'
,
$code_ex
)
.
' '
:
''
)
.
"/m"
,
"/
{
$code
}
[ -]"
.
(
$code_ex
?
str_replace
(
'.'
,
'\\.'
,
$code_ex
)
.
' '
:
''
)
.
"/m"
,
''
,
$this
->
last_reply
);
...
...
@@ -1080,7 +1105,7 @@ class SMTP
// Now check if reads took too long
if
(
$endtime
and
time
()
>
$endtime
)
{
$this
->
edebug
(
'SMTP -> get_lines(): timelimit reached ('
.
'SMTP -> get_lines(): timelimit reached ('
.
$this
->
Timelimit
.
' sec)'
,
self
::
DEBUG_LOWLEVEL
);
...
...
@@ -1178,4 +1203,49 @@ class SMTP
{
return
$this
->
Timeout
;
}
/**
* Reports an error number and string.
* @param integer $errno The error number returned by PHP.
* @param string $errmsg The error message returned by PHP.
* @param string $errfile The file the error occurred in
* @param integer $errline The line number the error occurred on
*/
protected
function
errorHandler
(
$errno
,
$errmsg
,
$errfile
=
''
,
$errline
=
0
)
{
$notice
=
'Connection failed.'
;
$this
->
setError
(
$notice
,
$errno
,
$errmsg
);
$this
->
edebug
(
$notice
.
' Error #'
.
$errno
.
': '
.
$errmsg
.
" [
$errfile
line
$errline
]"
,
self
::
DEBUG_CONNECTION
);
}
/**
* Will return the ID of the last smtp transaction based on a list of patterns provided
* in SMTP::$smtp_transaction_id_patterns.
* If no reply has been received yet, it will return null.
* If no pattern has been matched, it will return false.
* @return bool|null|string
*/
public
function
getLastTransactionID
()
{
$reply
=
$this
->
getLastReply
();
if
(
empty
(
$reply
))
{
return
null
;
}
foreach
(
$this
->
smtp_transaction_id_patterns
as
$smtp_transaction_id_pattern
)
{
if
(
preg_match
(
$smtp_transaction_id_pattern
,
$reply
,
$matches
))
{
return
$matches
[
1
];
}
}
return
false
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment