From 27b814063485fbfbc461e2a153fc71d2b5c57dcc Mon Sep 17 00:00:00 2001 From: abulhol Date: Fri, 18 Oct 2019 12:41:59 +0200 Subject: [PATCH] Add option novalidatecert to connect(); closes #63 Signed-off-by: Johan Cwiklinski --- docs/book/read.md | 4 ++++ src/Protocol/Imap.php | 48 ++++++++++++++++++++++++++++++++++++++----- src/Protocol/Pop3.php | 48 ++++++++++++++++++++++++++++++++++++++----- src/Storage/Imap.php | 5 +++++ src/Storage/Pop3.php | 5 +++++ 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/docs/book/read.md b/docs/book/read.md index 2619cd1c..4b94e9f6 100644 --- a/docs/book/read.md +++ b/docs/book/read.md @@ -117,6 +117,10 @@ $mail = new Pop3([ ]); ``` +If you are connecting to a mail server with a self-signed certificate and want to +skip the SSL verification, you can also pass an additional argument `novalidatecert` +with the value `true`. + Both constructors throw `Laminas\Mail\Exception` or `Laminas\Mail\Protocol\Exception` (extends `Laminas\Mail\Exception`) for connection errors, depending on the type of error encountered. diff --git a/src/Protocol/Imap.php b/src/Protocol/Imap.php index eb2515c4..227d9356 100644 --- a/src/Protocol/Imap.php +++ b/src/Protocol/Imap.php @@ -19,6 +19,12 @@ class Imap */ const TIMEOUT_CONNECTION = 30; + /** + * If set to true, do not validate the SSL certificate + * @var null|bool + */ + protected $novalidatecert; + /** * socket to imap server * @var resource|null @@ -34,13 +40,16 @@ class Imap /** * Public constructor * - * @param string $host hostname or IP address of IMAP server, if given connect() is called - * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl) - * @param bool $ssl use ssl? 'SSL', 'TLS' or false + * @param string $host hostname or IP address of IMAP server, if given connect() is called + * @param int|null $port port of IMAP server, null for default (143 or 993 for ssl) + * @param bool $ssl use ssl? 'SSL', 'TLS' or false + * @param bool $novalidatecert set to true to skip SSL certificate validation * @throws \Laminas\Mail\Protocol\Exception\ExceptionInterface */ - public function __construct($host = '', $port = null, $ssl = false) + public function __construct($host = '', $port = null, $ssl = false, $novalidatecert = false) { + $this->novalidatecert = $novalidatecert; + if ($host) { $this->connect($host, $port, $ssl); } @@ -54,6 +63,14 @@ public function __destruct() $this->logout(); } + public function setNoValidateCert($novalidatecert) + { + + if (is_bool($novalidatecert)) { + $this->novalidatecert = $novalidatecert; + } + } + /** * Open connection to IMAP server * @@ -87,8 +104,29 @@ public function connect($host, $port = null, $ssl = false) } } + $socket_options = []; + + if ($this->novalidatecert) { + $socket_options = [ + 'ssl' => [ + 'verify_peer_name' => false, + 'verify_peer' => false, + ] + ]; + } + + $socket_context = stream_context_create($socket_options); + ErrorHandler::start(); - $this->socket = fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION); + $this->socket = stream_socket_client( + $host . ":" . $port, + $errno, + $errstr, + self::TIMEOUT_CONNECTION, + STREAM_CLIENT_CONNECT, + $socket_context + ); + $error = ErrorHandler::stop(); if (! $this->socket) { throw new Exception\RuntimeException(sprintf( diff --git a/src/Protocol/Pop3.php b/src/Protocol/Pop3.php index 342644bc..8f07fd37 100644 --- a/src/Protocol/Pop3.php +++ b/src/Protocol/Pop3.php @@ -25,6 +25,12 @@ class Pop3 */ public $hasTop = null; + /** + * If set to true, do not validate the SSL certificate + * @var null|bool + */ + protected $novalidatecert; + /** * socket to pop3 * @var null|resource @@ -40,12 +46,15 @@ class Pop3 /** * Public constructor * - * @param string $host hostname or IP address of POP3 server, if given connect() is called - * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl) - * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false + * @param string $host hostname or IP address of POP3 server, if given connect() is called + * @param int|null $port port of POP3 server, null for default (110 or 995 for ssl) + * @param bool|string $ssl use ssl? 'SSL', 'TLS' or false + * @param bool $novalidatecert set to true to skip SSL certificate validation */ - public function __construct($host = '', $port = null, $ssl = false) + public function __construct($host = '', $port = null, $ssl = false, $novalidatecert = false) { + $this->novalidatecert = $novalidatecert; + if ($host) { $this->connect($host, $port, $ssl); } @@ -59,6 +68,14 @@ public function __destruct() $this->logout(); } + public function setNoValidateCert($novalidatecert) + { + + if (is_bool($novalidatecert)) { + $this->novalidatecert = $novalidatecert; + } + } + /** * Open connection to POP3 server * @@ -92,8 +109,29 @@ public function connect($host, $port = null, $ssl = false) } } + $socket_options = []; + + if ($this->novalidatecert) { + $socket_options = [ + 'ssl' => [ + 'verify_peer_name' => false, + 'verify_peer' => false, + ] + ]; + } + + $socket_context = stream_context_create($socket_options); + ErrorHandler::start(); - $this->socket = fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION); + $this->socket = stream_socket_client( + $host . ":" . $port, + $errno, + $errstr, + self::TIMEOUT_CONNECTION, + STREAM_CLIENT_CONNECT, + $socket_context + ); + $error = ErrorHandler::stop(); if (! $this->socket) { throw new Exception\RuntimeException(sprintf( diff --git a/src/Storage/Imap.php b/src/Storage/Imap.php index 029e950e..b842f9c5 100644 --- a/src/Storage/Imap.php +++ b/src/Storage/Imap.php @@ -213,6 +213,11 @@ public function __construct($params) $ssl = isset($params->ssl) ? $params->ssl : false; $this->protocol = new Protocol\Imap(); + + if (isset($params->novalidatecert)) { + $this->protocol->setNoValidateCert(true); + } + $this->protocol->connect($host, $port, $ssl); if (! $this->protocol->login($params->user, $password)) { throw new Exception\RuntimeException('cannot login, user or password wrong'); diff --git a/src/Storage/Pop3.php b/src/Storage/Pop3.php index 7e799ae9..4e51836d 100644 --- a/src/Storage/Pop3.php +++ b/src/Storage/Pop3.php @@ -146,6 +146,11 @@ public function __construct($params) $ssl = isset($params->ssl) ? $params->ssl : false; $this->protocol = new Protocol\Pop3(); + + if (isset($params->novalidatecert)) { + $this->protocol->setNoValidateCert($params->novalidatecert); + } + $this->protocol->connect($host, $port, $ssl); $this->protocol->login($params->user, $password); }