Skip to content

Commit

Permalink
SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) (
Browse files Browse the repository at this point in the history
…#74)

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

Issue with non-blocking streams on establishing STARTTLS encryption

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

Beware of infinite loop

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

do it in a for loop

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

more details in STARTTLS failed errormessage

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

keep backwards-compatibility to PHP5.4 by creating a method for array_filter parameter <mode>
change detailied error-message from combining string to sprintf() function
change usleep timing according to attempts
adding error_handler on every attempt

* SMTP: STARTTLS failed (code: 220, response: 2.0.0 Ready to start TLS) #68

changed new method name

* Update Net/SMTP.php

Co-authored-by: Jon Parise <jon@indelible.org>

* Update Net/SMTP.php

Co-authored-by: Jon Parise <jon@indelible.org>

* Update Net/SMTP.php

---------

Co-authored-by: Jon Parise <jon@indelible.org>
  • Loading branch information
schengawegga and jparise committed Oct 20, 2023
1 parent cfd963d commit d7b3f6a
Showing 1 changed file with 85 additions and 10 deletions.
95 changes: 85 additions & 10 deletions Net/SMTP.php
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ public function command($command, $valid)
*/
public function getResponse()
{
return array($this->code, join("\n", $this->arguments));
return array($this->code, implode("\n", $this->arguments));
}

/**
Expand Down Expand Up @@ -623,23 +623,77 @@ public function starttls()
/* STREAM_CRYPTO_METHOD_TLS_ANY_CLIENT constant does not exist
* and STREAM_CRYPTO_METHOD_SSLv23_CLIENT constant is
* inconsistent across PHP versions. */
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT
| @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
| @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
$crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;

if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
$crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
}

if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
$crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
}

if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) {
$crypto_method |= @STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
}
}
if (PEAR::isError($result = $this->socket->enableCrypto(true, $crypto_method))) {
return $result;
} elseif ($result !== true) {
return PEAR::raiseError('STARTTLS failed');

for ($attempts = 1; $attempts < 15; $attempts++) {
if(PEAR::isError(
$result = $this->socket->enableCrypto(
true, $crypto_method)
)
) {
return $result;
}
if ($this->socket->isBlocking() !== true) {
usleep($attempts);
}
if ($result !== 0) {
break;
}
}


if ($result !== true) {
$last_error = error_get_last();
$crypto_types_arr = $this->getDefinedConstantsKeyFilter(
'STREAM_CRYPTO_METHOD_'
);
$error_types_arr = $this->getDefinedConstantsKeyFilter(
'E_'
);

$resultErrorString = "STARTTLS failed ";
//{enableCrypto: false;
$resultErrorString .= "{enableCrypto: %s; ";
//crypto_method: STREAM_CRYPTO_METHOD_TLS_CLIENT (3);
$resultErrorString .= "crypto_method: %s (%s); ";
//attempts: 1;
$resultErrorString .= "attempts: %d; ";
//E_ERROR (1): ErrorMessage}
$resultErrorString .= "%s (%s): %s}";

return PEAR::raiseError(
sprintf(
$resultErrorString,
var_export($result, true),
array_search($crypto_method, $crypto_types_arr),
var_export($crypto_method, true),
$attempts,
array_search($last_error['type'], $error_types_arr),
$last_error['type'],
$last_error['message']
)
);
}

/* Send EHLO again to recieve the AUTH string from the
* SMTP server. */
$this->negotiate();
} else {
return false;
}

return true;
}

Expand Down Expand Up @@ -1475,4 +1529,25 @@ public function identifySender()
{
return true;
}

/**
* Backwards-compatibility method.
* array_filter alternative in PHP5.4 for using
* key filter because array_filter mode parameter
* is only available since PHP5.6.
*
* @param string $filter The string to filter
* @return array Filtered constants array.
*/
private function getDefinedConstantsKeyFilter($filter) {
$constants_filtered = array();
$filter_length = strlen($filter);
$constants = get_defined_constants();
foreach ($constants as $key=>$value){
if (substr($key, 0, $filter_length) == $filter) {
$constants_filtered[$key] = $value;
}
}
return $constants_filtered;
}
}

0 comments on commit d7b3f6a

Please sign in to comment.