From 4a92e525c57a743510b035ebf3a0bad067542c2a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 14 Apr 2014 18:00:32 +0200 Subject: [PATCH] Add STARTTLS support to SMTPMailSender --- .../files/lib/system/io/RemoteFile.class.php | 22 +++++++++++++ .../lib/system/mail/SMTPMailSender.class.php | 32 +++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/wcfsetup/install/files/lib/system/io/RemoteFile.class.php b/wcfsetup/install/files/lib/system/io/RemoteFile.class.php index 415cc8d325..4ff441d42c 100644 --- a/wcfsetup/install/files/lib/system/io/RemoteFile.class.php +++ b/wcfsetup/install/files/lib/system/io/RemoteFile.class.php @@ -72,4 +72,26 @@ class RemoteFile extends File { public function getErrorDesc() { return $this->errorDesc; } + + /** + * Switches TLS support for this connection. + * Usually used in combination with 'STARTTLS' + * + * @param boolean $enable Whether TLS support should be enabled + * @return boolean True on success, false otherwise + */ + public function setTLS($enable) { + if (!$this->hasTLSSupport()) return false; + + return stream_socket_enable_crypto($this->resource, $enable, STREAM_CRYPTO_METHOD_TLS_CLIENT); + } + + /** + * Returns whether TLS support is available. + * + * @return boolean + */ + public function hasTLSSupport() { + return function_exists('stream_socket_enable_crypto'); + } } diff --git a/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php b/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php index 772903b191..52b7ed03a9 100644 --- a/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php +++ b/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php @@ -7,7 +7,7 @@ use wcf\util\StringUtil; /** * Sends a Mail with a connection to a smtp server. * - * @author Alexander Ebert + * @author Tim Duesterhus, Alexander Ebert * @copyright 2001-2014 WoltLab GmbH * @license GNU Lesser General Public License * @package com.woltlab.wcf @@ -74,8 +74,35 @@ class SMTPMailSender extends MailSender { // send ehlo $this->write('EHLO '.$host); - $this->getSMTPStatus(); + $extensions = explode(Mail::$lineEnding, $this->read()); + $this->getSMTPStatus(array_shift($extensions)); if ($this->statusCode == 250) { + $extensions = array_map(function($element) { + return strtolower(substr($element, 4)); + }, $extensions); + + if ($this->connection->hasTLSSupport() && in_array('starttls', $extensions)) { + $this->write('STARTTLS'); + $this->getSMTPStatus(); + + if ($this->statusCode != 220) { + throw new SystemException($this->formatError("cannot enable STARTTLS, though '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."' advertised it")); + } + + if (!$this->connection->setTLS(true)) { + throw new SystemException('enabling TLS failed'); + } + + // repeat EHLO + $this->write('EHLO '.$host); + $extensions = explode(Mail::$lineEnding, $this->read()); + $this->getSMTPStatus(array_shift($extensions)); + + if ($this->statusCode != 250) { + throw new SystemException($this->formatError("could not EHLO after enabling STARTTLS at '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."'")); + } + } + // do authentication if (MAIL_SMTP_USER != '' || MAIL_SMTP_PASSWORD != '') { $this->auth(); @@ -237,6 +264,7 @@ class SMTPMailSender extends MailSender { $result .= $read; if (substr($read, 3, 1) == " ") break; } + return $result; } -- 2.20.1