Hi
Right now, Roundcube supports TLS, but there is no way to enforce IMAP and SMTP server certificate validation. This is very infortunate, since it means RoundCube has no way to detect trivial MiM attacks using a self-signed certificate.
Let us look at the SMTP side. Connexion handle is obtained in program/lib/Roundcube/rcube_smtp.php: $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
Net_SMTP allows a stream context options to be provided, and this stream context options can be used to enforce CA valdation. It would work like this:
$opts = array( 'ssl' => array( 'verify_peer' => TRUE, 'verify_depth' => 5, 'cafile' => '/path/to_ca_file', ), ); $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host, false, 0, $opts);
I would like to contribute such a change. Obviously, ca_file must be available as a config option (what name?). Is there any comment on the approach?
I have not looked at the IMAP side: I use imapproxy for connexion caching, and therefore Roundcube is not in charge of TLS.
On 11/24/2013 06:20 AM, Emmanuel Dreyfus wrote:
Net_SMTP allows a stream context options to be provided, and this stream context options can be used to enforce CA valdation. It would work like this:
$opts = array( 'ssl' => array( 'verify_peer' => TRUE, 'verify_depth' => 5, 'cafile' => '/path/to_ca_file', ), ); $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host, false, 0, $opts);
I would like to contribute such a change. Obviously, ca_file must be available as a config option (what name?). Is there any comment on the approach?
I propose to add 'smtp_conn_options' option where you could specify the whole options array as above. In comments we should provide an example and link to http://us1.php.net/manual/en/context.ssl.php
I have not looked at the IMAP side: I use imapproxy for connexion caching, and therefore Roundcube is not in charge of TLS.
rcube_imap_generic class does not use stream_context_create() so we'd need more changes here, but that should be quite simple change as the code is already in Net_Socket.
A.L.E.C alec@alec.pl wrote:
I propose to add 'smtp_conn_options' option where you could specify the whole options array as above. In comments we should provide an example and link to http://us1.php.net/manual/en/context.ssl.php
Here is the patch to do it. It took me some time to discover that certificate validation does not work with socket timeout set to 0. Hence, while there, I fixed smtp_timeout that was not honoured.
--- program/include/rcube_smtp.php.orig +++ program/include/rcube_smtp.php @@ -70,8 +70,9 @@ 'smtp_auth_pw' => $RCMAIL->config->get('smtp_auth_pw'), 'smtp_auth_type' => $RCMAIL->config->get('smtp_auth_type'), 'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'), 'smtp_timeout' => $RCMAIL->config->get('smtp_timeout'),
'smtp_conn_options' => $RCMAIL->config->get('smtp_conn_options'),
'smtp_auth_callbacks' => array(),
));
$smtp_host = rcube_parse_host($CONFIG['smtp_server']);
@@ -106,9 +107,13 @@
// IDNA Support
$smtp_host = rcube_idn_to_ascii($smtp_host);
if (!empty($CONFIG['smtp_conn_options'])) {
$this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host, false, 0, $CONFIG['smtp_conn_options']);
} else {
$this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
}
if ($RCMAIL->config->get('smtp_debug')) $this->conn->setDebug(true, array($this, 'debug_handler'));
@@ -135,9 +140,9 @@ } }
// try to connect to server and exit on failure
$result = $this->conn->connect($CONFIG['smtp_timeout']);
if (PEAR::isError($result)) { $this->response[] = "Connection failed: ".$result->getMessage(); $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code));
--- config/main.inc.php.dist.orig +++ config/main.inc.php.dist
// SMTP connection timeout, in seconds. Default: 0 (no limit) $rcmail_config['smtp_timeout'] = 0;
+// SMTP socket contect options +// See http://us1.php.net/manual/en/context.ssl.php +// The example below enable server certificate validation, and +// requires $rcmail_config['smtp_timeout'] to be non zero. +// $rcmail_config['smtp_conn_options'] = array( +// 'ssl' => array( +// 'verify_peer' => TRUE, +// 'verify_depth => 3, +// 'cafile' => '/etc/openssl/certs/ca.crt', +// ), +// );
// ---------------------------------- // SYSTEM // ----------------------------------
On 01/18/2014 06:23 AM, Emmanuel Dreyfus wrote:
Here is the patch to do it. It took me some time to discover that certificate validation does not work with socket timeout set to 0. Hence, while there, I fixed smtp_timeout that was not honoured.
Implemented in 357f9c831a7b1d01a6f7dfd40f44f77acde15a54. Thanks.
Hi
No reply on that message? Any chance the patch gets checked in?
Emmanuel Dreyfus manu@netbsd.org wrote:
A.L.E.C alec@alec.pl wrote:
I propose to add 'smtp_conn_options' option where you could specify the whole options array as above. In comments we should provide an example and link to http://us1.php.net/manual/en/context.ssl.php
Here is the patch to do it. It took me some time to discover that certificate validation does not work with socket timeout set to 0. Hence, while there, I fixed smtp_timeout that was not honoured.
--- program/include/rcube_smtp.php.orig +++ program/include/rcube_smtp.php @@ -70,8 +70,9 @@ 'smtp_auth_pw' => $RCMAIL->config->get('smtp_auth_pw'), 'smtp_auth_type' => $RCMAIL->config->get('smtp_auth_type'), 'smtp_helo_host' => $RCMAIL->config->get('smtp_helo_host'), 'smtp_timeout' => $RCMAIL->config->get('smtp_timeout'),
'smtp_conn_options' => $RCMAIL->config->get('smtp_conn_options'), 'smtp_auth_callbacks' => array(),
));
$smtp_host = rcube_parse_host($CONFIG['smtp_server']);
@@ -106,9 +107,13 @@
// IDNA Support $smtp_host = rcube_idn_to_ascii($smtp_host);
- $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
- if (!empty($CONFIG['smtp_conn_options'])) {
$this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host,
false, 0, $CONFIG['smtp_conn_options']);
} else {
$this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
}
if ($RCMAIL->config->get('smtp_debug')) $this->conn->setDebug(true, array($this, 'debug_handler'));
@@ -135,9 +140,9 @@ } }
// try to connect to server and exit on failure
- $result = $this->conn->connect($smtp_timeout);
$result = $this->conn->connect($CONFIG['smtp_timeout']);
if (PEAR::isError($result)) { $this->response[] = "Connection failed: ".$result->getMessage(); $this->error = array('label' => 'smtpconnerror', 'vars' =>
array('code' => $this->conn->_code));
--- config/main.inc.php.dist.orig +++ config/main.inc.php.dist
// SMTP connection timeout, in seconds. Default: 0 (no limit) $rcmail_config['smtp_timeout'] = 0;
+// SMTP socket contect options +// See http://us1.php.net/manual/en/context.ssl.php +// The example below enable server certificate validation, and +// requires $rcmail_config['smtp_timeout'] to be non zero. +// $rcmail_config['smtp_conn_options'] = array( +// 'ssl' => array( +// 'verify_peer' => TRUE, +// 'verify_depth => 3, +// 'cafile' => '/etc/openssl/certs/ca.crt', +// ), +// );
// ---------------------------------- // SYSTEM // ----------------------------------