/** * Connects to the server and upgrades to TLS connection if possible * * @return void */ public function connect() { // Figure out where we need to connect to $server = $this->getServer(); try { // Get a connection to server $this->_stream = $this->getStream($server); $this->_logger->debug('Connection made'); // Set the stream to blocking mode $this->_stream->setBlocking(true); $this->_logger->debug('Blocking enabled'); // Attempt to send the stream start $this->startStream(); $this->_logger->debug('Wait for response from server'); // Now we will expect to get a stream tag back from the server. Not // sure if we're supposed to do anything with it, so we'll just drop // it for now. May contain the features the server supports. $response = $this->waitForServer('stream:stream'); $this->_logger->debug('Received: ' . $response); // If the response from the server does contain a features tag, don't // bother querying server to get it. // TODO - Xpath would probably be more sensible for this, but for // now this'll work. if (strpos($response->asXml(), '<stream:features') === false) { // Server should now send back a features tag telling us what // features it supports. If it tells us to start tls then we will // need to change to a secure connection. It will also tell us what // authentication methods it supports. // // Note we check for a "features" tag rather than stream:features // because it is namespaced. $response = $this->waitForServer('features'); $this->_logger->debug('Received: ' . $response); } // Set mechanisms based on that tag $this->setMechanisms($response); // If there was a starttls tag in there, and this connection has SSL // enabled, then we should tell the server that we will start up tls as // well. if (preg_match("/<starttls xmlns=('|\")urn:ietf:params:xml:ns:xmpp-tls('|\")>(<required\\/>)?<\\/starttls>/", $response->asXML()) != 0 && $this->_ssl === true) { $this->_logger->debug('Informing server we will start TLS'); $message = "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"; $this->_stream->send($message); // Wait to get the proceed message back from the server $response = $this->waitForServer('proceed'); $this->_logger->debug('Received: ' . $response->asXML()); // Once we have the proceed signal from the server, we should turn // on TLS on the stream and send the opening stream tag again. $this->_stream->setTLS(true); $this->_logger->debug('Enabled TLS'); // Now we need to start a new stream again. $this->startStream(); // Server should now respond with start of stream and list of // features $response = $this->waitForServer('stream:stream'); $this->_logger->debug('Received: ' . $response); // Set mechanisms based on that tag $this->setMechanisms($response); } } catch (Stream_Exception $e) { // A Stream Exception occured. Catch it and rethrow it as an Xmpp // Exception. throw new Xmpp_Exception('Failed to connect: ' . $e->getMessage()); } return true; }