/** * Starts a TLS connection. * * @return boolean True on success, PEAR_Error on failure. */ function _startTLS() { $res = $this->_doCmd('STARTTLS'); if (is_a($res, 'PEAR_Error')) { return $res; } if (!stream_socket_enable_crypto($this->_sock->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { return $this->_pear->raiseError('Failed to establish TLS connection', 2); } $this->_debug('STARTTLS negotiation successful'); // The server should be sending a CAPABILITY response after // negotiating TLS. Read it, and ignore if it doesn't. // Unfortunately old Cyrus versions are broken and don't send a // CAPABILITY response, thus we would wait here forever. Parse the // Cyrus version and work around this broken behavior. if (!preg_match('/^CYRUS TIMSIEVED V([0-9.]+)/', $this->_capability['implementation'], $matches) || version_compare($matches[1], '2.3.10', '>=')) { $this->_doCmd(); } // Query the server capabilities again now that we are under // encryption. $res = $this->_cmdCapability(); if (is_a($res, 'PEAR_Error')) { return $this->_pear->raiseError('Failed to connect, server said: ' . $res->getMessage(), 2); } return true; }