Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@ All notable changes to this project will be documented in this file, in reverse

- [#95](https://github.com/laminas/laminas-mail/pull/95) adds the methods `setHeaderLocator(Laminas\Mail\Header\HeaderLocatorInterface $locator)` and `getHeaderLocator(): Laminas\Mail\Header\HeaderLocatorInterface` to the `Laminas\Mail\Headers` implementation. Users are encouraged to use these when providing custom header implementations in order to prepare for a 3.0 release. **The value of `getHeaderLocator()` will now be used as the default mechanism for resolving header names to header classes.**

- [#94](https://github.com/laminas/laminas-mail/pull/94) adds the "novalidatecert" option for POP3 and IMAP connections. When toggled true, you can connect to servers using self-signed certificates.
- [#94](https://github.com/laminas/laminas-mail/pull/94) and [#99](https://github.com/laminas/laminas-mail/pull/99) add the "novalidatecert" option for each of the POP3, IMAP, and SMTP protocol implementations. When toggled true, you can connect to servers using self-signed certificates.

### Changed

- [#95](https://github.com/laminas/laminas-mail/pull/95) bumps the minimum supported PHP version to 7.1.

### Deprecated

- [#99](https://github.com/laminas/laminas-mail/pull/99) deprecates the `Laminas\Mail\Protocol\AbstractProtocol::_connect()` method, as it is no longer used internally.

- [#95](https://github.com/laminas/laminas-mail/pull/95) deprecates `Laminas\Mail\Header\HeaderLoader` in favor of the new `Laminas\Mail\Header\HeaderLocator` class. The class will be removed in version 3.0.0.

- [#95](https://github.com/laminas/laminas-mail/pull/95) deprecates the `Headers::getPluginClassLoader()` and `Headers::setPluginClassLoader()` methods, in favor of the new `setHeaderLocator()` and `getHeaderLocator()` methods. These methods will be removed in version 3.0.0, and laminas-loader `PluginClassLocator` instances will no longer be supported. Please update your code to use the new `HeaderLocatorInterface` instead.
Expand Down
6 changes: 4 additions & 2 deletions src/Protocol/AbstractProtocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ abstract class AbstractProtocol

/**
* Socket connection resource
* @var resource
* @var null|resource
*/
protected $socket;

Expand Down Expand Up @@ -194,13 +194,15 @@ protected function _addLog($value)
*
* An example $remote string may be 'tcp://mail.example.com:25' or 'ssh://hostname.com:2222'
*
* @deprecated Since 1.12.0. Implementations should use the ProtocolTrait::setupSocket() method instead.
* @todo Remove for 3.0.0.
* @param string $remote Remote
* @throws Exception\RuntimeException
* @return bool
*/
protected function _connect($remote)
{
// @codingStandardsIgnoreEnd
// @codingStandardsIgnoreEnd
$errorNum = 0;
$errorStr = '';

Expand Down
10 changes: 8 additions & 2 deletions src/Protocol/Imap.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class Imap
*/
const TIMEOUT_CONNECTION = 30;

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

/**
* counter for request tag
* @var int
Expand Down Expand Up @@ -60,6 +65,7 @@ public function __destruct()
*/
public function connect($host, $port = null, $ssl = false)
{
$transport = 'tcp';
$isTls = false;

if ($ssl) {
Expand All @@ -68,7 +74,7 @@ public function connect($host, $port = null, $ssl = false)

switch ($ssl) {
case 'ssl':
$host = 'ssl://' . $host;
$transport = 'ssl';
if (! $port) {
$port = 993;
}
Expand All @@ -82,7 +88,7 @@ public function connect($host, $port = null, $ssl = false)
}
}

$this->setupSocket($host, $port, self::TIMEOUT_CONNECTION);
$this->socket = $this->setupSocket($transport, $host, $port, self::TIMEOUT_CONNECTION);

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

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

/**
* greeting timestamp for apop
* @var null|string
Expand Down Expand Up @@ -67,6 +72,7 @@ public function __destruct()
*/
public function connect($host, $port = null, $ssl = false)
{
$transport = 'tcp';
$isTls = false;

if ($ssl) {
Expand All @@ -75,7 +81,7 @@ public function connect($host, $port = null, $ssl = false)

switch ($ssl) {
case 'ssl':
$host = 'ssl://' . $host;
$transport = 'ssl';
if (! $port) {
$port = 995;
}
Expand All @@ -89,7 +95,7 @@ public function connect($host, $port = null, $ssl = false)
}
}

$this->setupSocket($host, $port, self::TIMEOUT_CONNECTION);
$this->socket = $this->setupSocket($transport, $host, $port, self::TIMEOUT_CONNECTION);

$welcome = $this->readResponse();

Expand Down
36 changes: 24 additions & 12 deletions src/Protocol/ProtocolTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ trait ProtocolTrait
*/
protected $novalidatecert;

public function getCryptoMethod()

public function getCryptoMethod(): int
{
// Allow the best TLS version(s) we can
$cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
Expand All @@ -39,8 +40,9 @@ public function getCryptoMethod()
/**
* Do not validate SSL certificate
*
* @todo Update to return self when minimum supported PHP version is 7.4+
* @param bool $novalidatecert Set to true to disable certificate validation
* @return self
* @return $this
*/
public function setNoValidateCert(bool $novalidatecert)
{
Expand All @@ -53,7 +55,7 @@ public function setNoValidateCert(bool $novalidatecert)
*
* @return bool
*/
public function validateCert()
public function validateCert(): bool
{
return ! $this->novalidatecert;
}
Expand All @@ -63,7 +65,7 @@ public function validateCert()
*
* @return array
*/
private function prepareSocketOptions()
private function prepareSocketOptions(): array
{
return $this->novalidatecert
? [
Expand All @@ -81,14 +83,18 @@ private function prepareSocketOptions()
* @param string $host hostname or IP address of IMAP server
* @param int|null $port of IMAP server, default is 143 (993 for ssl)
* @param int $timeout timeout in seconds for initiating session
* @return void
* @return resource The socket created.
* @throws Exception\RuntimeException If unable to connect to host.
*/
protected function setupSocket($host, $port, $timeout)
{
protected function setupSocket(
string $transport,
string $host,
?int $port,
int $timeout
) {
ErrorHandler::start();
$this->socket = stream_socket_client(
$host . ":" . $port,
$socket = stream_socket_client(
sprintf('%s://%s:%d', $transport, $host, $port),
$errno,
$errstr,
$timeout,
Expand All @@ -97,11 +103,17 @@ protected function setupSocket($host, $port, $timeout)
);
$error = ErrorHandler::stop();

if (! $this->socket) {
if (! $socket) {
throw new Exception\RuntimeException(sprintf(
'cannot connect to host %s',
($error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : '')
'cannot connect to host%s',
$error ? sprintf('; error = %s (errno = %d )', $error->getMessage(), $error->getCode()) : ''
), 0, $error);
}

if (false === stream_set_timeout($socket, $timeout)) {
throw new Exception\RuntimeException('Could not set stream timeout');
}

return $socket;
}
}
13 changes: 11 additions & 2 deletions src/Protocol/Smtp.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ public function __construct($host = '127.0.0.1', $port = null, array $config = n
}
}

if (array_key_exists('novalidatecert', $config)) {
$this->setNoValidateCert($config['novalidatecert']);
}

parent::__construct($host, $port);
}

Expand Down Expand Up @@ -183,10 +187,15 @@ public function useCompleteQuit()
*/
public function connect()
{
return $this->_connect($this->transport . '://' . $this->host . ':' . $this->port);
$this->socket = $this->setupSocket(
$this->transport,
$this->host,
$this->port,
self::TIMEOUT_CONNECTION
);
return true;
}


/**
* Initiate HELO/EHLO sequence and set flag to indicate valid smtp session
*
Expand Down