diff --git a/changelog.md b/changelog.md index dbd38b23..d3c7fb1f 100644 --- a/changelog.md +++ b/changelog.md @@ -9,7 +9,13 @@ This is a major update that breaks backwards compatibility. * The custom autoloader has been removed, now PSR-4 compatible: [**use composer**](https://getcomposer.org)! * Classes & Exceptions renamed to make use of the namespace * Most statically called functions now use the `static` keyword instead of `self`, so it's possible to override static internal functions in subclasses, for example `validateAddress()` -* `Extras` classes have been removed - use packages from [packagist.org](https://packagist.org) instead +* Complete RFC standardisation on CRLF (`\r\n`) line breaks by default: + * `PHPMailer:$LE` removed + * `PHPMailer::CRLF` line ending constant renamed to `PHPMailer::LE`, defaults to , used everywhere + * All uses of `PHPMailer::$LE` property converted to use `static:LE` constant for consistency and ease of overriding + * Similar changes to line break handling in SMTP and POP3 classes. +* Extensive reworking of XOAUTH2, adding support for Google, Yahoo and Microsoft providers, thanks to @sherryl4george +* Major cleanup of docs and examples * All elements previously marked as deprecated have been removed: * `PHPMailer->Version` * `PHPMailer->ReturnPath` @@ -27,8 +33,10 @@ This is a major update that breaks backwards compatibility. * `parseAddresses()` is now static * `validateAddress()` is now called statically from `parseAddresses()` * `PHPMailer->SingleToArray` is now protected -* Extensive reworking of XOAUTH2, adding support for Google, Yahoo and Microsoft providers, thanks to @sherryl4george -* Major cleanup of docs and examples +* Don't try to use an auth mechanism if it's not supported by the server +* Reorder automatic AUTH mechanism selector to try most secure method first +* `Extras` classes have been removed - use packages from [packagist.org](https://packagist.org) instead +* Better handling of automatic transfer encoding switch in the presence of long lines ## Version 5.2.15 (May 10th 2016) * Added ability to inject custom address validators, and set the default validator diff --git a/examples/smtp_low_memory.phps b/examples/smtp_low_memory.phps index 0b7c67c7..463c2416 100644 --- a/examples/smtp_low_memory.phps +++ b/examples/smtp_low_memory.phps @@ -27,7 +27,7 @@ class SMTPLowMemory extends SMTP } /* The server is ready to accept data! - * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) + * According to rfc821 we should not send more than 1000 characters on a single line (including the LE) * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into * smaller lines to fit within the limit. * We will also look for lines that start with a '.' and prepend an additional '.'. @@ -93,7 +93,7 @@ class SMTPLowMemory extends SMTP if (!empty($line_out) and $line_out[0] == '.') { $line_out = '.' . $line_out; } - $this->client_send($line_out . self::CRLF); + $this->client_send($line_out . self::LE); } } diff --git a/src/PHPMailer.php b/src/PHPMailer.php index 0677cb0d..1a3ad4f9 100644 --- a/src/PHPMailer.php +++ b/src/PHPMailer.php @@ -262,7 +262,7 @@ class PHPMailer /** * SMTP auth type. - * Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified + * Options are CRAM-MD5, LOGIN, PLAIN, XOAUTH2, attempted in that order if not specified * @var string */ public $AuthType = ''; @@ -350,8 +350,8 @@ class PHPMailer /** * The default line ending. - * @note The default remains "\n". We force CRLF where we know - * it must be used via self::CRLF. + * @note The default remains "\n". We force LE where we know + * it must be used via static::LE. * @var string */ public $LE = "\n"; @@ -606,7 +606,7 @@ class PHPMailer /** * SMTP RFC standard line ending. */ - const CRLF = "\r\n"; + const LE = "\r\n"; /** * The maximum line length allowed by RFC 2822 section 2.1.1 @@ -1258,8 +1258,8 @@ class PHPMailer $this->encodeHeader($this->secureHeader($this->Subject)), $this->MIMEBody ); - $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . self::CRLF . - $this->fixEOL($header_dkim) . self::CRLF; + $this->MIMEHeader = rtrim($this->MIMEHeader, "\r\n ") . static::LE . + $this->fixEOL($header_dkim) . static::LE; } return true; } catch (Exception $exc) { @@ -1714,7 +1714,7 @@ class PHPMailer foreach ($addr as $address) { $addresses[] = $this->addrFormat($address); } - return $type . ': ' . implode(', ', $addresses) . $this->LE; + return $type . ': ' . implode(', ', $addresses) . static::LE; } /** @@ -1749,24 +1749,24 @@ class PHPMailer public function wrapText($message, $length, $qp_mode = false) { if ($qp_mode) { - $soft_break = sprintf(' =%s', $this->LE); + $soft_break = sprintf(' =%s', static::LE); } else { - $soft_break = $this->LE; + $soft_break = static::LE; } // If utf-8 encoding is used, we will need to make sure we don't // split multibyte characters when we wrap $is_utf8 = (strtolower($this->CharSet) == 'utf-8'); - $lelen = strlen($this->LE); - $crlflen = strlen(self::CRLF); + $lelen = strlen(static::LE); + $crlflen = strlen(static::LE); $message = $this->fixEOL($message); //Remove a trailing line break - if (substr($message, -$lelen) == $this->LE) { + if (substr($message, -$lelen) == static::LE) { $message = substr($message, 0, -$lelen); } //Split message into lines - $lines = explode($this->LE, $message); + $lines = explode(static::LE, $message); //Message will be rebuilt in here $message = ''; foreach ($lines as $line) { @@ -1789,7 +1789,7 @@ class PHPMailer $part = substr($word, 0, $len); $word = substr($word, $len); $buf .= ' ' . $part; - $message .= $buf . sprintf('=%s', self::CRLF); + $message .= $buf . sprintf('=%s', static::LE); } else { $message .= $buf . $soft_break; } @@ -1811,7 +1811,7 @@ class PHPMailer $word = substr($word, $len); if (strlen($word) > 0) { - $message .= $part . sprintf('=%s', self::CRLF); + $message .= $part . sprintf('=%s', static::LE); } else { $buf = $part; } @@ -1830,7 +1830,7 @@ class PHPMailer } $firstword = false; } - $message .= $buf . self::CRLF; + $message .= $buf . static::LE; } return $message; @@ -2051,7 +2051,7 @@ class PHPMailer } if ('mail' != $this->Mailer) { - $result .= $this->LE; + $result .= static::LE; } return $result; @@ -2067,7 +2067,7 @@ class PHPMailer */ public function getSentMIMEMessage() { - return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . self::CRLF . self::CRLF . $this->MIMEBody; + return rtrim($this->MIMEHeader . $this->mailHeader, "\n\r") . static::LE . static::LE . $this->MIMEBody; } /** @@ -2087,7 +2087,7 @@ class PHPMailer $this->boundary[3] = 'b3_' . $this->uniqueid; if ($this->sign_key_file) { - $body .= $this->getMailMIME() . $this->LE; + $body .= $this->getMailMIME() . static::LE; } $this->setWordWrap(); @@ -2120,20 +2120,20 @@ class PHPMailer $altBodyEncoding = 'quoted-printable'; } //Use this as a preamble in all multipart message types - $mimepre = "This is a multi-part message in MIME format." . $this->LE . $this->LE; + $mimepre = "This is a multi-part message in MIME format." . static::LE . static::LE; switch ($this->message_type) { case 'inline': $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->attachAll('inline', $this->boundary[1]); break; case 'attach': $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'inline_attach': @@ -2141,26 +2141,26 @@ class PHPMailer $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/related;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); - $body .= $this->LE; + $body .= static::LE; $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->attachAll('inline', $this->boundary[2]); - $body .= $this->LE; + $body .= static::LE; $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'alt': $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; if (!empty($this->Ical)) { $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', ''); $body .= $this->encodeString($this->Ical, $this->Encoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; } $body .= $this->endBoundary($this->boundary[1]); break; @@ -2168,16 +2168,16 @@ class PHPMailer $body .= $mimepre; $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/related;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); - $body .= $this->LE; + $body .= static::LE; $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->attachAll('inline', $this->boundary[2]); - $body .= $this->LE; + $body .= static::LE; $body .= $this->endBoundary($this->boundary[1]); break; case 'alt_attach': @@ -2185,15 +2185,15 @@ class PHPMailer $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); - $body .= $this->LE; + $body .= static::LE; $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->endBoundary($this->boundary[2]); - $body .= $this->LE; + $body .= static::LE; $body .= $this->attachAll('attachment', $this->boundary[1]); break; case 'alt_inline_attach': @@ -2201,21 +2201,21 @@ class PHPMailer $body .= $this->textLine('--' . $this->boundary[1]); $body .= $this->headerLine('Content-Type', 'multipart/alternative;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[2] . '"'); - $body .= $this->LE; + $body .= static::LE; $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding); $body .= $this->encodeString($this->AltBody, $altBodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->textLine('--' . $this->boundary[2]); $body .= $this->headerLine('Content-Type', 'multipart/related;'); $body .= $this->textLine("\tboundary=\"" . $this->boundary[3] . '"'); - $body .= $this->LE; + $body .= static::LE; $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding); $body .= $this->encodeString($this->Body, $bodyEncoding); - $body .= $this->LE . $this->LE; + $body .= static::LE . static::LE; $body .= $this->attachAll('inline', $this->boundary[3]); - $body .= $this->LE; + $body .= static::LE; $body .= $this->endBoundary($this->boundary[2]); - $body .= $this->LE; + $body .= static::LE; $body .= $this->attachAll('attachment', $this->boundary[1]); break; default: @@ -2265,7 +2265,7 @@ class PHPMailer @unlink($signed); //The message returned by openssl contains both headers and body, so need to split them up $parts = explode("\n\n", $body, 2); - $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE; + $this->MIMEHeader .= $parts[0] . static::LE . static::LE; $body = $parts[1]; } else { @unlink($file); @@ -2305,12 +2305,12 @@ class PHPMailer } $result .= $this->textLine('--' . $boundary); $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet); - $result .= $this->LE; + $result .= static::LE; // RFC1341 part 5 says 7bit is assumed if not specified if ('7bit' != $encoding) { $result .= $this->headerLine('Content-Transfer-Encoding', $encoding); } - $result .= $this->LE; + $result .= static::LE; return $result; } @@ -2323,7 +2323,7 @@ class PHPMailer */ protected function endBoundary($boundary) { - return $this->LE . '--' . $boundary . '--' . $this->LE; + return static::LE . '--' . $boundary . '--' . static::LE; } /** @@ -2360,7 +2360,7 @@ class PHPMailer */ public function headerLine($name, $value) { - return $name . ': ' . $value . $this->LE; + return $name . ': ' . $value . static::LE; } /** @@ -2371,7 +2371,7 @@ class PHPMailer */ public function textLine($value) { - return $value . $this->LE; + return $value . static::LE; } /** @@ -2476,29 +2476,29 @@ class PHPMailer } $cidUniq[$cid] = true; - $mime[] = sprintf('--%s%s', $boundary, $this->LE); + $mime[] = sprintf('--%s%s', $boundary, static::LE); //Only include a filename property if we have one if (!empty($name)) { $mime[] = sprintf( 'Content-Type: %s; name="%s"%s', $type, $this->encodeHeader($this->secureHeader($name)), - $this->LE + static::LE ); } else { $mime[] = sprintf( 'Content-Type: %s%s', $type, - $this->LE + static::LE ); } // RFC1341 part 5 says 7bit is assumed if not specified if ('7bit' != $encoding) { - $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE); + $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, static::LE); } if ('inline' == $disposition) { - $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE); + $mime[] = sprintf('Content-ID: <%s>%s', $cid, static::LE); } // If a filename contains any of these chars, it should be quoted, @@ -2512,7 +2512,7 @@ class PHPMailer 'Content-Disposition: %s; filename="%s"%s', $disposition, $encoded_name, - $this->LE . $this->LE + static::LE . static::LE ); } else { if (!empty($encoded_name)) { @@ -2520,18 +2520,18 @@ class PHPMailer 'Content-Disposition: %s; filename=%s%s', $disposition, $encoded_name, - $this->LE . $this->LE + static::LE . static::LE ); } else { $mime[] = sprintf( 'Content-Disposition: %s%s', $disposition, - $this->LE . $this->LE + static::LE . static::LE ); } } } else { - $mime[] = $this->LE; + $mime[] = static::LE; } // Encode as string attachment @@ -2540,18 +2540,18 @@ class PHPMailer if ($this->isError()) { return ''; } - $mime[] = $this->LE; + $mime[] = static::LE; } else { $mime[] = $this->encodeFile($path, $encoding); if ($this->isError()) { return ''; } - $mime[] = $this->LE; + $mime[] = static::LE; } } } - $mime[] = sprintf('--%s--%s', $boundary, $this->LE); + $mime[] = sprintf('--%s--%s', $boundary, static::LE); return implode('', $mime); } @@ -2593,14 +2593,14 @@ class PHPMailer $encoded = ''; switch (strtolower($encoding)) { case 'base64': - $encoded = chunk_split(base64_encode($str), 76, $this->LE); + $encoded = chunk_split(base64_encode($str), 76, static::LE); break; case '7bit': case '8bit': $encoded = $this->fixEOL($str); // Make sure it ends with a line break - if (substr($encoded, -(strlen($this->LE))) != $this->LE) { - $encoded .= $this->LE; + if (substr($encoded, -(strlen(static::LE))) != static::LE) { + $encoded .= static::LE; } break; case 'binary': @@ -2673,11 +2673,11 @@ class PHPMailer $encoding = 'Q'; $encoded = $this->encodeQ($str, $position); $encoded = $this->wrapText($encoded, $maxlen, true); - $encoded = str_replace('=' . self::CRLF, "\n", trim($encoded)); + $encoded = str_replace('=' . static::LE, "\n", trim($encoded)); } $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . "?$encoding?\\1?=", $encoded); - $encoded = trim(str_replace("\n", $this->LE, $encoded)); + $encoded = trim(str_replace("\n", static::LE, $encoded)); return $encoded; } @@ -2723,7 +2723,7 @@ class PHPMailer $end = '?='; $encoded = ''; if (is_null($linebreak)) { - $linebreak = $this->LE; + $linebreak = static::LE; } $mb_length = mb_strlen($str, $this->CharSet); @@ -3183,7 +3183,7 @@ class PHPMailer /** * Ensure consistent line endings in a string. - * Changes every end of line from CRLF, CR or LF to $this->LE. + * Changes every end of line from LE, CR or LF to static::LE. * @access public * @param string $str String to fixEOL * @return string @@ -3193,8 +3193,8 @@ class PHPMailer // Normalise to \n $nstr = str_replace(["\r\n", "\r"], "\n", $str); // Now convert LE as needed - if ("\n" !== $this->LE) { - $nstr = str_replace("\n", $this->LE, $nstr); + if ("\n" !== static::LE) { + $nstr = str_replace("\n", static::LE, $nstr); } return $nstr; } @@ -3300,12 +3300,12 @@ class PHPMailer } } $this->isHTML(true); - // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better + // Convert all message body line breaks to LE, makes quoted-printable encoding work much better $this->Body = $this->normalizeBreaks($message); $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced)); if (!$this->alternativeExists()) { $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . - self::CRLF . self::CRLF; + static::LE . static::LE; } return $this->Body; } @@ -3558,10 +3558,10 @@ class PHPMailer /** * Normalize line breaks in a string. - * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format. - * Defaults to CRLF (for message bodies) and preserves consecutive breaks. + * Converts UNIX LF, Mac CR and Windows LE line breaks into a single line break format. + * Defaults to LE (for message bodies) and preserves consecutive breaks. * @param string $text - * @param string $breaktype What kind of line break to use, defaults to CRLF + * @param string $breaktype What kind of line break to use, defaults to LE * @return string * @access public * @static @@ -3656,7 +3656,7 @@ class PHPMailer foreach ($lines as $key => $line) { //If the header is missing a :, skip it as it's invalid //This is likely to happen because the explode() above will also split - //on the trailing CRLF, leaving an empty line + //on the trailing LE, leaving an empty line if (strpos($line, ':') === false) { continue; } @@ -3710,7 +3710,7 @@ class PHPMailer $DKIMquery = 'dns/txt'; // Query method $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone) $subject_header = "Subject: $subject"; - $headers = explode($this->LE, $headers_line); + $headers = explode(static::LE, $headers_line); $from_header = ''; $to_header = ''; $date_header = ''; @@ -3783,7 +3783,7 @@ class PHPMailer */ public static function hasLineLongerThanMax($str) { - //+2 to include CRLF line break for a 1000 total + //+2 to include LE line break for a 1000 total return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str); } diff --git a/src/POP3.php b/src/POP3.php index a37d2a2a..e4864c10 100644 --- a/src/POP3.php +++ b/src/POP3.php @@ -127,7 +127,7 @@ class POP3 /** * Line break constant */ - const CRLF = "\r\n"; + const LE = "\r\n"; /** * Simple static wrapper for all-in-one POP before SMTP @@ -280,11 +280,11 @@ class POP3 } // Send the Username - $this->sendString("USER $username" . self::CRLF); + $this->sendString("USER $username" . static::LE); $pop3_response = $this->getResponse(); if ($this->checkResponse($pop3_response)) { // Send the Password - $this->sendString("PASS $password" . self::CRLF); + $this->sendString("PASS $password" . static::LE); $pop3_response = $this->getResponse(); if ($this->checkResponse($pop3_response)) { return true; diff --git a/src/SMTP.php b/src/SMTP.php index 8b902873..158646b9 100644 --- a/src/SMTP.php +++ b/src/SMTP.php @@ -38,7 +38,7 @@ class SMTP * SMTP line break constant. * @var string */ - const CRLF = "\r\n"; + const LE = "\r\n"; /** * The SMTP port to use if one is not specified. @@ -342,7 +342,7 @@ class SMTP * @see hello() * @param string $username The user name * @param string $password The password - * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2) + * @param string $authtype The auth type (CRAM-MD5, PLAIN, LOGIN, XOAUTH2) * @param OAuth $OAuth An optional OAuth instance for XOAUTH2 authentication * @return bool True if successfully authenticated. * @access public @@ -374,7 +374,15 @@ class SMTP self::DEBUG_LOWLEVEL ); + //If we have requested a specific auth type, check the server supports it before trying others + if (!in_array($authtype, $this->server_caps['AUTH'])) { + $this->edebug('Requested auth method not available: ' . $authtype, self::DEBUG_LOWLEVEL); + $authtype = null; + } + if (empty($authtype)) { + //If no auth mechanism is specified, attempt to use these, in this order + //Try CRAM-MD5 first as it's more secure than the others foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2') as $method) { if (in_array($method, $this->server_caps['AUTH'])) { $authtype = $method; @@ -387,11 +395,6 @@ class SMTP } $this->edebug('Auth method selected: '.$authtype, self::DEBUG_LOWLEVEL); } - - if (!in_array($authtype, $this->server_caps['AUTH'])) { - $this->setError("The requested authentication method \"$authtype\" is not supported by the server"); - return false; - } } elseif (empty($authtype)) { $authtype = 'LOGIN'; } @@ -423,19 +426,6 @@ class SMTP return false; } break; - case 'XOAUTH2': - //If the OAuth Instance is not set. Can be a case when PHPMailer is used - //instead of PHPMailerOAuth - if (is_null($OAuth)) { - return false; - } - $oauth = $OAuth->getOauth64(); - - // Start authentication - if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { - return false; - } - break; case 'CRAM-MD5': // Start authentication if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) { @@ -449,6 +439,18 @@ class SMTP // send encoded credentials return $this->sendCommand('Username', base64_encode($response), 235); + case 'XOAUTH2': + //The OAuth instance must be set up prior to requesting auth. + if (is_null($OAuth)) { + return false; + } + $oauth = $OAuth->getOauth64(); + + // Start authentication + if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) { + return false; + } + break; default: $this->setError("Authentication method \"$authtype\" is not supported"); return false; @@ -541,7 +543,7 @@ class SMTP * finializing the mail transaction. $msg_data is the message * that is to be send with the headers. Each header needs to be * on a single line followed by a with the message headers - * and the message body being separated by and additional . + * and the message body being separated by an additional . * Implements rfc 821: DATA * @param string $msg_data Message data to send * @access public @@ -555,7 +557,7 @@ class SMTP } /* The server is ready to accept data! - * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF) + * According to rfc821 we should not send more than 1000 characters on a single line (including the LE) * so we will break the data up into lines by \r and/or \n then if needed we will break each of those into * smaller lines to fit within the limit. * We will also look for lines that start with a '.' and prepend an additional '.'. @@ -612,7 +614,7 @@ class SMTP if (!empty($line_out) and $line_out[0] == '.') { $line_out = '.' . $line_out; } - $this->client_send($line_out . self::CRLF); + $this->client_send($line_out . static::LE); } } @@ -794,7 +796,7 @@ class SMTP $this->setError("Command '$command' contained line breaks"); return false; } - $this->client_send($commandstring . self::CRLF); + $this->client_send($commandstring . static::LE); $this->last_reply = $this->get_lines(); // Fetch SMTP code and possible error code explanation diff --git a/test/phpmailerTest.php b/test/phpmailerTest.php index c21ff46a..16001952 100644 --- a/test/phpmailerTest.php +++ b/test/phpmailerTest.php @@ -1277,11 +1277,11 @@ EOT; */ public function testLongBody() { - $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::CRLF, 2); - $badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 1) . PHPMailer::CRLF, 2); + $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::LE, 2); + $badlen = str_repeat(str_repeat('1', PHPMailer::MAX_LINE_LENGTH + 1) . PHPMailer::LE, 2); $this->Mail->Body = "This message contains lines that are too long.". - PHPMailer::CRLF . $oklen . $badlen . $oklen; + PHPMailer::LE . $oklen . $badlen . $oklen; $this->assertTrue( PHPMailer::hasLineLongerThanMax($this->Mail->Body), 'Test content does not contain long lines!' @@ -1305,10 +1305,10 @@ EOT; */ public function testShortBody() { - $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::CRLF, 10); + $oklen = str_repeat(str_repeat('0', PHPMailer::MAX_LINE_LENGTH) . PHPMailer::LE, 10); $this->Mail->Body = "This message does not contain lines that are too long.". - PHPMailer::CRLF . $oklen; + PHPMailer::LE . $oklen; $this->assertFalse( PHPMailer::hasLineLongerThanMax($this->Mail->Body), 'Test content contains long lines!' @@ -1931,22 +1931,14 @@ EOT; ); //Line break normalization - $eol = $this->Mail->LE; + $eol = PHPMailer::LE; $b1 = "1\r2\r3\r"; $b2 = "1\n2\n3\n"; $b3 = "1\r\n2\r3\n"; - $this->Mail->LE = "\n"; - $t1 = "1{$this->Mail->LE}2{$this->Mail->LE}3{$this->Mail->LE}"; + $t1 = "1{$eol}2{$eol}3{$eol}"; $this->assertEquals($this->Mail->fixEOL($b1), $t1, 'Failed to normalize line breaks (1)'); $this->assertEquals($this->Mail->fixEOL($b2), $t1, 'Failed to normalize line breaks (2)'); $this->assertEquals($this->Mail->fixEOL($b3), $t1, 'Failed to normalize line breaks (3)'); - $this->Mail->LE = "\r\n"; - $t1 = "1{$this->Mail->LE}2{$this->Mail->LE}3{$this->Mail->LE}"; - $this->assertEquals($this->Mail->fixEOL($b1), $t1, 'Failed to normalize line breaks (4)'); - $this->assertEquals($this->Mail->fixEOL($b2), $t1, 'Failed to normalize line breaks (5)'); - $this->assertEquals($this->Mail->fixEOL($b3), $t1, 'Failed to normalize line breaks (6)'); - $this->Mail->LE = $eol; - } public function testBadSMTP()