aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Pudeyev <oleg@bsdpower.com>2012-02-10 20:52:36 -0500
committerOleg Pudeyev <oleg@bsdpower.com>2012-02-10 20:52:36 -0500
commitd6bc77375a00e0879ffd3077901fc154dcdedfe2 (patch)
tree4797e1a9e7837bf8bc327558346cf6050874a739
parent95ac995be8cdf0b7acf1aa7a03064bae4fab00b9 (diff)
parent237ddf9d22e0aeccad5e1db022de3a890871849f (diff)
downloadforums-d6bc77375a00e0879ffd3077901fc154dcdedfe2.tar
forums-d6bc77375a00e0879ffd3077901fc154dcdedfe2.tar.gz
forums-d6bc77375a00e0879ffd3077901fc154dcdedfe2.tar.bz2
forums-d6bc77375a00e0879ffd3077901fc154dcdedfe2.tar.xz
forums-d6bc77375a00e0879ffd3077901fc154dcdedfe2.zip
Merge remote-tracking branch 'bantu/ticket/10076' into develop
* bantu/ticket/10076: [ticket/10076] STARTTLS support for SMTP via smtp_class. [ticket/10076] Move EHLO/HELO code into its own method.
-rw-r--r--phpBB/includes/functions_messenger.php113
1 files changed, 93 insertions, 20 deletions
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index 13d9b6a5cb..f4e49b1b18 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -1136,6 +1136,7 @@ class smtp_class
{
var $server_response = '';
var $socket = 0;
+ protected $socket_tls = false;
var $responses = array();
var $commands = array();
var $numeric_response_code = 0;
@@ -1286,30 +1287,29 @@ class smtp_class
}
}
- // Try EHLO first
- $this->server_send("EHLO {$local_host}");
- if ($err_msg = $this->server_parse('250', __LINE__))
+ $hello_result = $this->hello($local_host);
+ if (!is_null($hello_result))
{
- // a 503 response code means that we're already authenticated
- if ($this->numeric_response_code == 503)
- {
- return false;
- }
-
- // If EHLO fails, we try HELO
- $this->server_send("HELO {$local_host}");
- if ($err_msg = $this->server_parse('250', __LINE__))
- {
- return ($this->numeric_response_code == 503) ? false : $err_msg;
- }
+ return $hello_result;
}
- foreach ($this->responses as $response)
+ // SMTP STARTTLS (RFC 3207)
+ if (!$this->socket_tls)
{
- $response = explode(' ', $response);
- $response_code = $response[0];
- unset($response[0]);
- $this->commands[$response_code] = implode(' ', $response);
+ $this->socket_tls = $this->starttls();
+
+ if ($this->socket_tls)
+ {
+ // Switched to TLS
+ // RFC 3207: "The client MUST discard any knowledge obtained from the server, [...]"
+ // So say hello again
+ $hello_result = $this->hello($local_host);
+
+ if (!is_null($hello_result))
+ {
+ return $hello_result;
+ }
+ }
}
// If we are not authenticated yet, something might be wrong if no username and passwd passed
@@ -1356,6 +1356,79 @@ class smtp_class
}
/**
+ * SMTP EHLO/HELO
+ *
+ * @return mixed Null if the authentication process is supposed to continue
+ * False if already authenticated
+ * Error message (string) otherwise
+ */
+ protected function hello($hostname)
+ {
+ // Try EHLO first
+ $this->server_send("EHLO $hostname");
+ if ($err_msg = $this->server_parse('250', __LINE__))
+ {
+ // a 503 response code means that we're already authenticated
+ if ($this->numeric_response_code == 503)
+ {
+ return false;
+ }
+
+ // If EHLO fails, we try HELO
+ $this->server_send("HELO $hostname");
+ if ($err_msg = $this->server_parse('250', __LINE__))
+ {
+ return ($this->numeric_response_code == 503) ? false : $err_msg;
+ }
+ }
+
+ foreach ($this->responses as $response)
+ {
+ $response = explode(' ', $response);
+ $response_code = $response[0];
+ unset($response[0]);
+ $this->commands[$response_code] = implode(' ', $response);
+ }
+ }
+
+ /**
+ * SMTP STARTTLS (RFC 3207)
+ *
+ * @return bool Returns true if TLS was started
+ * Otherwise false
+ */
+ protected function starttls()
+ {
+ if (!function_exists('stream_socket_enable_crypto'))
+ {
+ return false;
+ }
+
+ if (!isset($this->commands['STARTTLS']))
+ {
+ return false;
+ }
+
+ $this->server_send('STARTTLS');
+
+ if ($err_msg = $this->server_parse('220', __LINE__))
+ {
+ return false;
+ }
+
+ $result = false;
+ $stream_meta = stream_get_meta_data($this->socket);
+
+ if (socket_set_blocking($this->socket, 1));
+ {
+ $result = stream_socket_enable_crypto($this->socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
+ socket_set_blocking($this->socket, (int) $stream_meta['blocked']);
+ }
+
+ return $result;
+ }
+
+ /**
* Pop before smtp authentication
*/
function pop_before_smtp($hostname, $username, $password)