summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube/rcube_imap_generic.php
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2014-06-16 14:13:58 +0200
committerAleksander Machniak <alec@alec.pl>2014-06-16 14:13:58 +0200
commit109bcce470b789dac498d0fba8fb9673b988f867 (patch)
tree2e7d1ece8c4d5d31034d13dc079cc76fa0e4e19b /program/lib/Roundcube/rcube_imap_generic.php
parenteb82b35df9807d0e002b9fd676692d51d007b319 (diff)
Add config option to specify IMAP connection socket parameters - imap_conn_options (#1489948)
Diffstat (limited to 'program/lib/Roundcube/rcube_imap_generic.php')
-rw-r--r--program/lib/Roundcube/rcube_imap_generic.php181
1 files changed, 103 insertions, 78 deletions
diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php
index e4c9b7eb8..5aaad0a00 100644
--- a/program/lib/Roundcube/rcube_imap_generic.php
+++ b/program/lib/Roundcube/rcube_imap_generic.php
@@ -723,110 +723,38 @@ class rcube_imap_generic
// configure
$this->set_prefs($options);
- $auth_method = $this->prefs['auth_type'];
- $result = false;
-
- // initialize connection
- $this->error = '';
- $this->errornum = self::ERROR_OK;
- $this->selected = null;
- $this->user = $user;
$this->host = $host;
+ $this->user = $user;
$this->logged = false;
+ $this->selected = null;
// check input
if (empty($host)) {
$this->setError(self::ERROR_BAD, "Empty host");
return false;
}
+
if (empty($user)) {
$this->setError(self::ERROR_NO, "Empty user");
return false;
}
+
if (empty($password)) {
$this->setError(self::ERROR_NO, "Empty password");
return false;
}
- if (!$this->prefs['port']) {
- $this->prefs['port'] = 143;
- }
- // check for SSL
- if ($this->prefs['ssl_mode'] && $this->prefs['ssl_mode'] != 'tls') {
- $host = $this->prefs['ssl_mode'] . '://' . $host;
- }
-
- if ($this->prefs['timeout'] <= 0) {
- $this->prefs['timeout'] = max(0, intval(ini_get('default_socket_timeout')));
- }
-
// Connect
- $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']);
-
- if (!$this->fp) {
- if (!$errstr) {
- $errstr = "Unknown reason (fsockopen() function disabled?)";
- }
- $this->setError(self::ERROR_BAD, sprintf("Could not connect to %s:%d: %s", $host, $this->prefs['port'], $errstr));
- return false;
- }
-
- if ($this->prefs['timeout'] > 0) {
- stream_set_timeout($this->fp, $this->prefs['timeout']);
- }
-
- $line = trim(fgets($this->fp, 8192));
-
- if ($this->_debug) {
- // set connection identifier for debug output
- preg_match('/#([0-9]+)/', (string)$this->fp, $m);
- $this->resourceid = strtoupper(substr(md5($m[1].$this->user.microtime()), 0, 4));
-
- if ($line)
- $this->debug('S: '. $line);
- }
-
- // Connected to wrong port or connection error?
- if (!preg_match('/^\* (OK|PREAUTH)/i', $line)) {
- if ($line)
- $error = sprintf("Wrong startup greeting (%s:%d): %s", $host, $this->prefs['port'], $line);
- else
- $error = sprintf("Empty startup greeting (%s:%d)", $host, $this->prefs['port']);
-
- $this->setError(self::ERROR_BAD, $error);
- $this->closeConnection();
+ if (!$this->_connect($host)) {
return false;
}
- // RFC3501 [7.1] optional CAPABILITY response
- if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
- $this->parseCapability($matches[1], true);
- }
-
- // TLS connection
- if ($this->prefs['ssl_mode'] == 'tls' && $this->getCapability('STARTTLS')) {
- $res = $this->execute('STARTTLS');
-
- if ($res[0] != self::ERROR_OK) {
- $this->closeConnection();
- return false;
- }
-
- if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
- $this->setError(self::ERROR_BAD, "Unable to negotiate TLS");
- $this->closeConnection();
- return false;
- }
-
- // Now we're secure, capabilities need to be reread
- $this->clearCapability();
- }
-
// Send ID info
if (!empty($this->prefs['ident']) && $this->getCapability('ID')) {
$this->id($this->prefs['ident']);
}
+ $auth_method = $this->prefs['auth_type'];
$auth_methods = array();
$result = null;
@@ -901,6 +829,103 @@ class rcube_imap_generic
}
/**
+ * Connects to IMAP server.
+ *
+ * @param string $host Server hostname or IP
+ *
+ * @return bool True on success, False on failure
+ */
+ protected function _connect($host)
+ {
+ // initialize connection
+ $this->error = '';
+ $this->errornum = self::ERROR_OK;
+
+ if (!$this->prefs['port']) {
+ $this->prefs['port'] = 143;
+ }
+
+ // check for SSL
+ if ($this->prefs['ssl_mode'] && $this->prefs['ssl_mode'] != 'tls') {
+ $host = $this->prefs['ssl_mode'] . '://' . $host;
+ }
+
+ if ($this->prefs['timeout'] <= 0) {
+ $this->prefs['timeout'] = max(0, intval(ini_get('default_socket_timeout')));
+ }
+
+ if (!empty($this->prefs['socket_options'])) {
+ $context = stream_context_create($this->prefs['socket_options']);
+ $this->fp = stream_socket_client($host . ':' . $this->prefs['port'], $errno, $errstr,
+ $this->prefs['timeout'], STREAM_CLIENT_CONNECT, $context);
+ }
+ else {
+ $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']);
+ }
+
+ if (!$this->fp) {
+ $this->setError(self::ERROR_BAD, sprintf("Could not connect to %s:%d: %s",
+ $host, $this->prefs['port'], $errstr ?: "Unknown reason"));
+
+ return false;
+ }
+
+ if ($this->prefs['timeout'] > 0) {
+ stream_set_timeout($this->fp, $this->prefs['timeout']);
+ }
+
+ $line = trim(fgets($this->fp, 8192));
+
+ if ($this->_debug) {
+ // set connection identifier for debug output
+ preg_match('/#([0-9]+)/', (string) $this->fp, $m);
+ $this->resourceid = strtoupper(substr(md5($m[1].$this->user.microtime()), 0, 4));
+
+ if ($line) {
+ $this->debug('S: '. $line);
+ }
+ }
+
+ // Connected to wrong port or connection error?
+ if (!preg_match('/^\* (OK|PREAUTH)/i', $line)) {
+ if ($line)
+ $error = sprintf("Wrong startup greeting (%s:%d): %s", $host, $this->prefs['port'], $line);
+ else
+ $error = sprintf("Empty startup greeting (%s:%d)", $host, $this->prefs['port']);
+
+ $this->setError(self::ERROR_BAD, $error);
+ $this->closeConnection();
+ return false;
+ }
+
+ // RFC3501 [7.1] optional CAPABILITY response
+ if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
+ $this->parseCapability($matches[1], true);
+ }
+
+ // TLS connection
+ if ($this->prefs['ssl_mode'] == 'tls' && $this->getCapability('STARTTLS')) {
+ $res = $this->execute('STARTTLS');
+
+ if ($res[0] != self::ERROR_OK) {
+ $this->closeConnection();
+ return false;
+ }
+
+ if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+ $this->setError(self::ERROR_BAD, "Unable to negotiate TLS");
+ $this->closeConnection();
+ return false;
+ }
+
+ // Now we're secure, capabilities need to be reread
+ $this->clearCapability();
+ }
+
+ return true;
+ }
+
+ /**
* Initializes environment
*/
protected function set_prefs($prefs)