Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option novalidatecert to connect(); closes #63 #94

Closed
wants to merge 10 commits into from
4 changes: 4 additions & 0 deletions docs/book/read.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
27 changes: 8 additions & 19 deletions src/Protocol/Imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ class Imap
*/
const TIMEOUT_CONNECTION = 30;

/**
* socket to imap server
* @var resource|null
*/
protected $socket;

/**
* counter for request tag
* @var int
Expand All @@ -34,13 +28,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->setNoValidateCert($novalidatecert);

if ($host) {
$this->connect($host, $port, $ssl);
}
Expand Down Expand Up @@ -87,15 +84,7 @@ public function connect($host, $port = null, $ssl = false)
}
}

ErrorHandler::start();
$this->socket = fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION);
$error = ErrorHandler::stop();
if (! $this->socket) {
throw new Exception\RuntimeException(sprintf(
'cannot connect to host %s',
($error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : '')
), 0, $error);
}
$this->setSocket($host, $port);

if (! $this->assumedNextLine('* OK')) {
throw new Exception\RuntimeException('host doesn\'t allow connection');
Expand Down
27 changes: 8 additions & 19 deletions src/Protocol/Pop3.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ class Pop3
*/
public $hasTop = null;

/**
* socket to pop3
* @var null|resource
*/
protected $socket;

/**
* greeting timestamp for apop
* @var null|string
Expand All @@ -40,12 +34,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->setNoValidateCert($novalidatecert);

if ($host) {
$this->connect($host, $port, $ssl);
}
Expand Down Expand Up @@ -92,15 +89,7 @@ public function connect($host, $port = null, $ssl = false)
}
}

ErrorHandler::start();
$this->socket = fsockopen($host, $port, $errno, $errstr, self::TIMEOUT_CONNECTION);
$error = ErrorHandler::stop();
if (! $this->socket) {
throw new Exception\RuntimeException(sprintf(
'cannot connect to host %s',
($error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : '')
), 0, $error);
}
$this->setSocket($host, $port);

$welcome = $this->readResponse();

Expand Down
76 changes: 76 additions & 0 deletions src/Protocol/ProtocolTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
*/
trait ProtocolTrait
{
/**
* If set to true, do not validate the SSL certificate
* @var null|bool
*/
protected $novalidatecert;

public function getCryptoMethod()
{
// Allow the best TLS version(s) we can
Expand All @@ -27,4 +33,74 @@ public function getCryptoMethod()

return $cryptoMethod;
}

/**
* Do not validate SSL certificate
*
* @param bool $novalidatecert Set to true to disable certificate validation
*
* @return Imap|Pop3
*/
public function setNoValidateCert(bool $novalidatecert)
{
$this->novalidatecert = $novalidatecert;
return $this;
}

/**
* Should we validate SSL certificate?
*
* @return bool
*/
public function validateCert()
{
return ! $this->novalidatecert;
}

/**
* Prepare socket options
*
* @return array
*/
protected function prepareSocketOptions()
trasher marked this conversation as resolved.
Show resolved Hide resolved
{
return $this->novalidatecert
? [
'ssl' => [
'verify_peer_name' => false,
'verify_peer' => false,
]
] : [];
}

/**
* Setup connection socket
*
* @param string $host hostname or IP address of IMAP server
* @param int|null $port of IMAP server, default is 143 (993 for ssl)
*
* @return void
*/
protected function setSocket($host, $port)
trasher marked this conversation as resolved.
Show resolved Hide resolved
{
$socketOptions = [];

trasher marked this conversation as resolved.
Show resolved Hide resolved
ErrorHandler::start();
$this->socket = stream_socket_client(
$host . ":" . $port,
$errno,
$errstr,
self::TIMEOUT_CONNECTION,
STREAM_CLIENT_CONNECT,
stream_context_create($this->prepareSocketOptions())
);
$error = ErrorHandler::stop();
trasher marked this conversation as resolved.
Show resolved Hide resolved

if (! $this->socket) {
throw new Exception\RuntimeException(sprintf(
'cannot connect to host %s',
($error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : '')
), 0, $error);
}
}
}
5 changes: 5 additions & 0 deletions src/Storage/Imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -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((bool)$params->novalidatecert);
}
trasher marked this conversation as resolved.
Show resolved Hide resolved

$this->protocol->connect($host, $port, $ssl);
if (! $this->protocol->login($params->user, $password)) {
throw new Exception\RuntimeException('cannot login, user or password wrong');
Expand Down
5 changes: 5 additions & 0 deletions src/Storage/Pop3.php
Original file line number Diff line number Diff line change
Expand Up @@ -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((bool)$params->novalidatecert);
}

$this->protocol->connect($host, $port, $ssl);
$this->protocol->login($params->user, $password);
}
Expand Down