From c8b88105471b407cc6e010c9cc079390e4bca2e4 Mon Sep 17 00:00:00 2001 From: Jeremy Lainé Date: Fri, 4 Jun 2010 16:55:21 +0000 Subject: convert DOS end of lines --- source/server/QXmppClientServer.cpp | 294 +++++------ source/server/QXmppClientServer.h | 168 +++---- source/server/QXmppServer.cpp | 836 ++++++++++++++++---------------- source/server/QXmppServer.h | 196 ++++---- source/server/QXmppServerConnection.cpp | 330 ++++++------- source/server/QXmppServerConnection.h | 230 ++++----- 6 files changed, 1027 insertions(+), 1027 deletions(-) (limited to 'source/server') diff --git a/source/server/QXmppClientServer.cpp b/source/server/QXmppClientServer.cpp index b52d1734..9afb463b 100644 --- a/source/server/QXmppClientServer.cpp +++ b/source/server/QXmppClientServer.cpp @@ -1,147 +1,147 @@ -/* - * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya - * - * Authors: - * Manjeet Dahiya - * Sjors Gielen - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - - -#include "QXmppClientServer.h" -#include "QXmppLogger.h" -#include "QXmppStream.h" -#include "QXmppMessage.h" -#include "QXmppUtils.h" - -#define QXMPPCLIENTSERVER_DEBUG - -#define ASSERT_CONNECT(a, b, c, d) \ - { bool check = connect(a, b, c, d); \ - Q_ASSERT( check ); } - -/** - * @brief Creates a QXmppClientServer object. - * - * This class is meant to service client connections as a server. This class - * is only directly used by QXmppServer. If you want to listen to clients, use - * that class, and not this one. - * - * @param socket Server socket (must be nonzero and connected) - * @param data Server data to start parsing - * @param parent QObject parent of this object - */ -QXmppClientServer::QXmppClientServer(QSslSocket *socket, - const QByteArray &data, QObject *parent) -: QObject(parent) -, m_logger(0) -, m_stream(0) -{ - Q_ASSERT( socket->state() == QAbstractSocket::ConnectedState ); - - m_logger = QXmppLogger::getLogger(); - //m_stream = new QXmppStream(this); - //m_stream->setSocket( socket ); - - ASSERT_CONNECT(m_stream, SIGNAL(messageReceived(const QXmppMessage&)), - this, SIGNAL(messageReceived(const QXmppMessage&))); - - ASSERT_CONNECT(m_stream, SIGNAL(disconnected()), - this, SIGNAL(disconnected())); - - ASSERT_CONNECT(m_stream, SIGNAL(xmppConnected()), - this, SIGNAL(connected())); - - ASSERT_CONNECT(m_stream, SIGNAL(error(QXmppClientServer::Error)), - this, SIGNAL(error(QXmppClientServer::Error))); -} - -/// Destructor, destroys the QXmppClientServer object. -/// - -QXmppClientServer::~QXmppClientServer() -{ -} - -/// After successfully connecting to the server use this function to send -/// stanzas to the server. This function can solely be used to send various kind -/// of stanzas to the server. QXmppPacket is a parent class of all the stanzas -/// QXmppMessage, QXmppPresence, QXmppIq, QXmppBind, QXmppRosterIq, QXmppSession -/// and QXmppVCard. -/// -/// Following code snippet illustrates how to send a message using this function: -/// \code -/// QXmppMessage message(from, to, message); -/// client.sendPacket(message); -/// \endcode -/// -/// \param packet A valid XMPP stanza. It can be an iq, a message or a presence stanza. -/// - -void QXmppClientServer::sendPacket(const QXmppPacket& packet) -{ - Q_ASSERT( m_stream != 0 ); - m_stream->sendPacket(packet); -} - -/// Disconnects the client and the current presence of client changes to -/// QXmppPresence::Unavailable and statatus text changes to "Logged out". -/// -/// \note Make sure that the clientPresence is changed to -/// QXmppPresence::Available, if you are again calling connectToServer() after -/// calling the disconnect() function. -/// - -void QXmppClientServer::disconnect() -{ - Q_ASSERT( m_stream != 0 ); - m_stream->disconnect(); -} - -/// Returns the socket error if QXmppClientServer::Error is QXmppClientServer::SocketError. -/// -/// \return QAbstractSocket::SocketError -/// - -QAbstractSocket::SocketError QXmppClientServer::getSocketError() -{ - return m_stream->getSocketError(); -} - -/// Returns the XMPP stream error if QXmppClientServer::Error is QXmppClientServer::XmppStreamError. -/// -/// \return QXmppClientServer::Error::Condition -/// - -QXmppStanza::Error::Condition QXmppClientServer::getXmppStreamError() -{ - return m_stream->getXmppStreamError(); -} - -/// Return the QXmppLogger associated with the client. - -QXmppLogger *QXmppClientServer::logger() -{ - return m_logger; -} - -void QXmppClientServer::setLogger(QXmppLogger *logger) -{ - m_logger = logger; -} - +/* + * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya + * + * Authors: + * Manjeet Dahiya + * Sjors Gielen + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + + +#include "QXmppClientServer.h" +#include "QXmppLogger.h" +#include "QXmppStream.h" +#include "QXmppMessage.h" +#include "QXmppUtils.h" + +#define QXMPPCLIENTSERVER_DEBUG + +#define ASSERT_CONNECT(a, b, c, d) \ + { bool check = connect(a, b, c, d); \ + Q_ASSERT( check ); } + +/** + * @brief Creates a QXmppClientServer object. + * + * This class is meant to service client connections as a server. This class + * is only directly used by QXmppServer. If you want to listen to clients, use + * that class, and not this one. + * + * @param socket Server socket (must be nonzero and connected) + * @param data Server data to start parsing + * @param parent QObject parent of this object + */ +QXmppClientServer::QXmppClientServer(QSslSocket *socket, + const QByteArray &data, QObject *parent) +: QObject(parent) +, m_logger(0) +, m_stream(0) +{ + Q_ASSERT( socket->state() == QAbstractSocket::ConnectedState ); + + m_logger = QXmppLogger::getLogger(); + //m_stream = new QXmppStream(this); + //m_stream->setSocket( socket ); + + ASSERT_CONNECT(m_stream, SIGNAL(messageReceived(const QXmppMessage&)), + this, SIGNAL(messageReceived(const QXmppMessage&))); + + ASSERT_CONNECT(m_stream, SIGNAL(disconnected()), + this, SIGNAL(disconnected())); + + ASSERT_CONNECT(m_stream, SIGNAL(xmppConnected()), + this, SIGNAL(connected())); + + ASSERT_CONNECT(m_stream, SIGNAL(error(QXmppClientServer::Error)), + this, SIGNAL(error(QXmppClientServer::Error))); +} + +/// Destructor, destroys the QXmppClientServer object. +/// + +QXmppClientServer::~QXmppClientServer() +{ +} + +/// After successfully connecting to the server use this function to send +/// stanzas to the server. This function can solely be used to send various kind +/// of stanzas to the server. QXmppPacket is a parent class of all the stanzas +/// QXmppMessage, QXmppPresence, QXmppIq, QXmppBind, QXmppRosterIq, QXmppSession +/// and QXmppVCard. +/// +/// Following code snippet illustrates how to send a message using this function: +/// \code +/// QXmppMessage message(from, to, message); +/// client.sendPacket(message); +/// \endcode +/// +/// \param packet A valid XMPP stanza. It can be an iq, a message or a presence stanza. +/// + +void QXmppClientServer::sendPacket(const QXmppPacket& packet) +{ + Q_ASSERT( m_stream != 0 ); + m_stream->sendPacket(packet); +} + +/// Disconnects the client and the current presence of client changes to +/// QXmppPresence::Unavailable and statatus text changes to "Logged out". +/// +/// \note Make sure that the clientPresence is changed to +/// QXmppPresence::Available, if you are again calling connectToServer() after +/// calling the disconnect() function. +/// + +void QXmppClientServer::disconnect() +{ + Q_ASSERT( m_stream != 0 ); + m_stream->disconnect(); +} + +/// Returns the socket error if QXmppClientServer::Error is QXmppClientServer::SocketError. +/// +/// \return QAbstractSocket::SocketError +/// + +QAbstractSocket::SocketError QXmppClientServer::getSocketError() +{ + return m_stream->getSocketError(); +} + +/// Returns the XMPP stream error if QXmppClientServer::Error is QXmppClientServer::XmppStreamError. +/// +/// \return QXmppClientServer::Error::Condition +/// + +QXmppStanza::Error::Condition QXmppClientServer::getXmppStreamError() +{ + return m_stream->getXmppStreamError(); +} + +/// Return the QXmppLogger associated with the client. + +QXmppLogger *QXmppClientServer::logger() +{ + return m_logger; +} + +void QXmppClientServer::setLogger(QXmppLogger *logger) +{ + m_logger = logger; +} + diff --git a/source/server/QXmppClientServer.h b/source/server/QXmppClientServer.h index a976b00d..ba2b8df8 100644 --- a/source/server/QXmppClientServer.h +++ b/source/server/QXmppClientServer.h @@ -1,84 +1,84 @@ -/* - * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya - * - * Authors: - * Manjeet Dahiya - * Sjors Gielen - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#ifndef QXMPPCLIENTSERVER_H -#define QXMPPCLIENTSERVER_H - -#include -#include - -#include "QXmppClient.h" - -/** - * @brief The QXmppClientServer receives connections from clients. - */ - -class QXmppClientServer : public QObject -{ - Q_OBJECT - -public: - QXmppClientServer(QSslSocket *serverSocket, - const QByteArray &parseData = QByteArray(), QObject *parent = 0); - ~QXmppClientServer(); - - void disconnect(); - -signals: - - /// This signal is emitted when the XMPP connection disconnects. - /// - void disconnected(); - - /// This signal is emitted when the XMPP connection encounters any error. - /// The QXmppClient::Error parameter specifies the type of error occured. - /// It could be due to TCP socket or the xml stream or the stanza. - /// Depending upon the type of error occured use the respective get function to - /// know the error. - void error(QXmppClient::Error); - - /// Notifies that an XMPP message stanza is received. The QXmppMessage - /// parameter contains the details of the message sent to this client. - /// In other words whenever someone sends you a message this signal is - /// emitted. - void messageReceived(const QXmppMessage&); - -public: - QAbstractSocket::SocketError getSocketError(); - - QXmppStanza::Error::Condition getXmppStreamError(); - - QXmppLogger *logger(); - void setLogger(QXmppLogger *logger); - -public slots: - void sendPacket(const QXmppPacket&); - -private: - QXmppLogger* m_logger; - QXmppStream* m_stream; ///< Pointer to QXmppStream object, a wrapper over - ///< TCP socket and XMPP protocol -}; - -#endif // QXMPPCLIENT_H +/* + * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya + * + * Authors: + * Manjeet Dahiya + * Sjors Gielen + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPCLIENTSERVER_H +#define QXMPPCLIENTSERVER_H + +#include +#include + +#include "QXmppClient.h" + +/** + * @brief The QXmppClientServer receives connections from clients. + */ + +class QXmppClientServer : public QObject +{ + Q_OBJECT + +public: + QXmppClientServer(QSslSocket *serverSocket, + const QByteArray &parseData = QByteArray(), QObject *parent = 0); + ~QXmppClientServer(); + + void disconnect(); + +signals: + + /// This signal is emitted when the XMPP connection disconnects. + /// + void disconnected(); + + /// This signal is emitted when the XMPP connection encounters any error. + /// The QXmppClient::Error parameter specifies the type of error occured. + /// It could be due to TCP socket or the xml stream or the stanza. + /// Depending upon the type of error occured use the respective get function to + /// know the error. + void error(QXmppClient::Error); + + /// Notifies that an XMPP message stanza is received. The QXmppMessage + /// parameter contains the details of the message sent to this client. + /// In other words whenever someone sends you a message this signal is + /// emitted. + void messageReceived(const QXmppMessage&); + +public: + QAbstractSocket::SocketError getSocketError(); + + QXmppStanza::Error::Condition getXmppStreamError(); + + QXmppLogger *logger(); + void setLogger(QXmppLogger *logger); + +public slots: + void sendPacket(const QXmppPacket&); + +private: + QXmppLogger* m_logger; + QXmppStream* m_stream; ///< Pointer to QXmppStream object, a wrapper over + ///< TCP socket and XMPP protocol +}; + +#endif // QXMPPCLIENT_H diff --git a/source/server/QXmppServer.cpp b/source/server/QXmppServer.cpp index 07c21119..9d7fd89e 100644 --- a/source/server/QXmppServer.cpp +++ b/source/server/QXmppServer.cpp @@ -1,418 +1,418 @@ -/* - * Copyright (C) 2010 Sjors Gielen - * - * Author: - * Sjors Gielen - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#include - -#include "QXmppServer.h" -#include "QXmppServerConnection.h" -#include "QXmppClientServer.h" - -#define QXMPPSERVER_DEBUG - -#define ASSERT_CONNECT(a, b, c, d) \ - { bool check = connect(a, b, c, d); \ - Q_ASSERT( check ); } - -const QByteArray XMPP_STANDARD_SERVER_STREAM_START = ""; -const QByteArray XMPP_STANDARD_CLIENT_STREAM_START = ""; -const QByteArray XMPP_STANDARD_POLICY_STREAM_ERROR = "" - "" - "" - "Clients of your type are not allowed to connect to this port." - "" - ""; -const QByteArray XMPP_STANDARD_INVALIDNS_STREAM_ERROR = "" - "" - ""; -const QByteArray XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR = "" - "" - ""; -const QByteArray XMPP_STANDARD_END_STREAM = ""; - -QXmppServer::QXmppServer(bool acceptsServers, bool acceptsClients, QObject *parent) -: QTcpServer(parent) -, m_logger(0) -, m_localCertificate(QByteArray()) -, m_privateKey(QSslKey()) -, m_acceptsClients(acceptsClients) -, m_acceptsServers(acceptsServers) -{ - m_logger = QXmppLogger::getLogger(); -} - -QXmppServer::~QXmppServer() -{ - for( int i = 0; i < m_unknownClients.size(); ++i ) - { - closeSocket( m_unknownClients[i] ); - } - m_unknownClients.clear(); - Q_ASSERT( m_streamReaders.isEmpty() ); - Q_ASSERT( m_cache.isEmpty() ); - - for( int i = 0; i < m_clientConnections.size(); ++i ) - { - delete m_clientConnections[i]; - } - - for( int i = 0; i < m_serverConnections.size(); ++i ) - { - delete m_serverConnections[i]; - } -} - -bool QXmppServer::acceptsClients() const -{ - return m_acceptsClients; -} - -bool QXmppServer::acceptsServers() const -{ - return m_acceptsServers; -} - -void QXmppServer::addCaCertificates( const QList &certificates ) -{ - m_certificates.append( certificates ); -} - -void QXmppServer::addCaCertificates( const QSslCertificate &certificate ) -{ - m_certificates.append( certificate ); -} - -void QXmppServer::closeSocket( QSslSocket *socket ) -{ - forgetSocket( socket ); - delete socket; -} - -/** - * @brief Determine the socket type of this socket. - * - * This method determines whether the connecting peer is a client on the network, or - * another server. To do this, it analyses the 'xmlns' attribute to the - * <stream:stream> start tag. - */ -void QXmppServer::determineSocketType() -{ - QSslSocket *socket = static_cast(sender()); - Q_ASSERT( socket != 0 ); - - Q_ASSERT( m_unknownClients.contains( socket ) ); - Q_ASSERT( m_streamReaders. contains( socket ) ); - Q_ASSERT( m_cache. contains( socket ) ); - QXmlStreamReader *reader = m_streamReaders.value( socket ); - - // Previous errors should already be handled here - Q_ASSERT( !reader->hasError() ); - - QByteArray data = socket->readAll(); - m_cache[socket].append( data ); - reader->addData( data ); - - bool isStartStream = false; - QXmlStreamNamespaceDeclarations xmlns; - while( !reader->atEnd() ) - { - QXmlStreamReader::TokenType type = reader->readNext(); - if( type == QXmlStreamReader::StartElement ) - { - xmlns = reader->namespaceDeclarations(); - if( reader->qualifiedName() == "stream:stream" ) - { - // Got the start of a stream! -#ifdef QXMPPSERVER_DEBUG - qDebug() << "Got the start of a stream."; -#endif - isStartStream = true; - } - else - { - qWarning() << "Received another start element than stream:stream" - << reader->qualifiedName(); - socket->write( XMPP_STANDARD_SERVER_STREAM_START ); - socket->write( XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR ); - socket->write( XMPP_STANDARD_END_STREAM ); - socket->flush(); - closeSocket( socket ); - return; - } - } - else if( !isStartStream && type != QXmlStreamReader::StartDocument ) - { - qWarning() << "Received XML data before start of stream: " - << reader->qualifiedName() - << "type: " << type - << "error: " << reader->errorString(); - if( type == 1 && tryOtherProtocol( socket ) ) - { - // Apparantly, the socket wasn't speaking XMPP. - // tryOtherProtocol() has returned another message, now close - socket->flush(); - closeSocket( socket ); - return; - } - else if( reader->hasError() && reader->error() != - QXmlStreamReader::PrematureEndOfDocumentError ) - { - socket->write( XMPP_STANDARD_SERVER_STREAM_START ); - if( reader->qualifiedName() == "stream:stream" ) - { - socket->write( XMPP_STANDARD_INVALIDNS_STREAM_ERROR ); - } - else - { - socket->write( XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR ); - } - socket->write( XMPP_STANDARD_END_STREAM ); - socket->flush(); - closeSocket( socket ); - return; - } - } - } - - if( !isStartStream ) - { - // Didn't find a stream:stream yet, return immediately. - return; - } - - bool containsServerXmlns; - bool containsClientXmlns; - for(int i = 0; i < xmlns.size(); ++i ) - { -#ifdef QXMPPSERVER_DEBUG - qDebug() << "XMLNS prefix=" << xmlns.at(i).prefix() << "; namespaceUri=" - << xmlns.at(i).namespaceUri(); -#endif - if( xmlns.at(i).prefix().isEmpty() ) - { - if( xmlns.at(i).namespaceUri() == "jabber:client" ) - { - containsClientXmlns = true; - } - else if( xmlns.at(i).namespaceUri() == "jabber:server" ) - { - containsServerXmlns = true; - } - else - { - qWarning() << "Didn't find proper XML namespace in stream."; - socket->write( XMPP_STANDARD_SERVER_STREAM_START ); - socket->write( XMPP_STANDARD_INVALIDNS_STREAM_ERROR ); - socket->write( XMPP_STANDARD_END_STREAM ); - socket->flush(); - closeSocket( socket ); - return; - } - } - } - - Q_ASSERT( containsServerXmlns || containsClientXmlns ); - - if( containsServerXmlns ) - { -#ifdef QXMPPSERVER_DEBUG - qDebug() << "It's a server socket!"; -#endif - - if( !m_acceptsServers ) - { - // send a stream error - socket->write( XMPP_STANDARD_SERVER_STREAM_START ); - socket->write( XMPP_STANDARD_POLICY_STREAM_ERROR ); - socket->write( XMPP_STANDARD_END_STREAM ); - socket->flush(); - closeSocket( socket ); - return; - } - - QByteArray pastData = m_cache[socket]; - forgetSocket( socket ); - - socket->addCaCertificates( m_certificates ); - socket->setLocalCertificate( m_localCertificate ); - socket->setPrivateKey( m_privateKey ); - socket->setProtocol( QSsl::AnyProtocol ); - - QXmppServerConnection *sc = new QXmppServerConnection( socket, pastData ); - sc->setLogger( m_logger ); - m_serverConnections.append( sc ); - } - else if( containsClientXmlns ) - { -#ifdef QXMPPSERVER_DEBUG - qDebug() << "It's a client socket!"; -#endif - - if( !m_acceptsClients ) - { - // send a stream error - socket->write( XMPP_STANDARD_CLIENT_STREAM_START ); - socket->write( XMPP_STANDARD_POLICY_STREAM_ERROR ); - socket->write( XMPP_STANDARD_END_STREAM ); - socket->flush(); - closeSocket( socket ); - return; - } - - QByteArray pastData = m_cache[socket]; - forgetSocket( socket ); - - QXmppClientServer *cs = new QXmppClientServer( socket, pastData ); - cs->setLogger( m_logger ); - m_clientConnections.append( cs ); - } -} - -void QXmppServer::forgetSocket( QSslSocket *socket ) -{ - Q_ASSERT( m_unknownClients.contains( socket ) ); - Q_ASSERT( m_streamReaders. contains( socket ) ); - Q_ASSERT( m_cache. contains( socket ) ); - - socket->disconnect( this, 0 ); - - QXmlStreamReader *reader = m_streamReaders.value( socket ); - m_unknownClients.removeAll( socket ); - m_streamReaders.remove( socket ); - m_cache.remove( socket ); - delete reader; -} - -void QXmppServer::incomingConnection( int socketDescriptor ) -{ - QSslSocket *socket = new QSslSocket; - if( socket->setSocketDescriptor( socketDescriptor ) ) - { - ASSERT_CONNECT( socket, SIGNAL( readyRead() ), - this, SLOT( determineSocketType() ) ); - - m_unknownClients.append( socket ); - m_streamReaders.insert( socket, new QXmlStreamReader() ); - m_cache.insert( socket, "" ); - emit unknownClientConnected( socket ); - return; - } - - delete socket; - qWarning() << "setSocketDescriptor failed"; -} - -QXmppLogger *QXmppServer::logger() -{ - return m_logger; -} - -void QXmppServer::setAcceptsClients( bool acceptsClients ) -{ - m_acceptsClients = acceptsClients; -} - -void QXmppServer::setAcceptsServers( bool acceptsServers ) -{ - m_acceptsServers = acceptsServers; -} - -void QXmppServer::setLocalCertificate( const QSslCertificate &localCertificate ) -{ - m_localCertificate = localCertificate; -} - -void QXmppServer::setLogger(QXmppLogger *logger) -{ - m_logger = logger; -} - -void QXmppServer::setPrivateKey( const QSslKey &privateKey ) -{ - m_privateKey = privateKey; -} - -/** - * @brief Try to detect another protocol on our server line - * - * Sometimes, a client erroneously connects to the wrong port. For example, a - * browser or IRC client might end up on our socket. The XML parser will - * likely give an error then - here we check if the other side is speaking the - * incorrect protocol. This will, of course, never work in protocols where the - * server starts sending and the client waits indefinitely. - * - * This method should only write a message to the socket and return true if - * a protocol was recognised; the socket will be flushed and closed elsewhere. - * - * Recognised protocols: http (first line ends with HTTP/x.y), irc (first line - * starts with NICK) - */ -bool QXmppServer::tryOtherProtocol( QSslSocket *socket ) -{ - Q_ASSERT( m_cache. contains( socket ) ); - QByteArray &cache = m_cache[socket]; - - int newline = cache.indexOf( "\n" ); - int carrret = cache.indexOf( "\r" ); - newline = ( carrret < newline && carrret != -1 ) ? carrret : newline; - QByteArray firstLine = cache.mid( 0, newline ); - - // Discover IRC - if( firstLine.startsWith( "NICK " ) ) - { - QByteArray nick = firstLine.mid( 5, newline - 5 ); - socket->write( ":xmppd 001 " + nick + " :Welcome to XMPP IRC\r\n" ); - socket->write( ":xmppd 002 " + nick + " :Your host is an XMPP IRC daemon\r\n" ); - socket->write( ":xmppd 375 " + nick + " :- XMPP IRC Daemon Message of the Day -\r\n" ); - socket->write( ":xmppd 372 " + nick + " :- This server is not an IRC server! It is\r\n" ); - socket->write( ":xmppd 372 " + nick + " :- an XMPP server. Please use an XMPP client\r\n" ); - socket->write( ":xmppd 372 " + nick + " :- to connect to it.\r\n" ); - socket->write( ":xmppd 376 " + nick + " :End of /MOTD command.\r\n" ); - socket->write( ":" + nick + " QUIT :Not an XMPP client.\r\n" ); - socket->write( "ERROR :Closing Link: Not an XMPP client.\r\n" ); - return true; - } - - // Discover HTTP - QByteArray httpVer = firstLine.right(8); - if( httpVer.startsWith( "HTTP/" ) ) - { - socket->write( "HTTP/1.0 200 OK\r\n" ); - socket->write( "Content-Type: text/html; charset=UTF-8\r\n" ); - socket->write( "Server: xmppd\r\n" ); - socket->write( "\r\n" ); - socket->write( "Not a webserver\r\n" ); - socket->write( "You are connecting to an XMPP server as if it were" ); - socket->write( " a webserver. Please use an XMPP client to connect to " ); - socket->write( "it.\r\n" ); - return true; - } - - return false; -} +/* + * Copyright (C) 2010 Sjors Gielen + * + * Author: + * Sjors Gielen + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#include + +#include "QXmppServer.h" +#include "QXmppServerConnection.h" +#include "QXmppClientServer.h" + +#define QXMPPSERVER_DEBUG + +#define ASSERT_CONNECT(a, b, c, d) \ + { bool check = connect(a, b, c, d); \ + Q_ASSERT( check ); } + +const QByteArray XMPP_STANDARD_SERVER_STREAM_START = ""; +const QByteArray XMPP_STANDARD_CLIENT_STREAM_START = ""; +const QByteArray XMPP_STANDARD_POLICY_STREAM_ERROR = "" + "" + "" + "Clients of your type are not allowed to connect to this port." + "" + ""; +const QByteArray XMPP_STANDARD_INVALIDNS_STREAM_ERROR = "" + "" + ""; +const QByteArray XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR = "" + "" + ""; +const QByteArray XMPP_STANDARD_END_STREAM = ""; + +QXmppServer::QXmppServer(bool acceptsServers, bool acceptsClients, QObject *parent) +: QTcpServer(parent) +, m_logger(0) +, m_localCertificate(QByteArray()) +, m_privateKey(QSslKey()) +, m_acceptsClients(acceptsClients) +, m_acceptsServers(acceptsServers) +{ + m_logger = QXmppLogger::getLogger(); +} + +QXmppServer::~QXmppServer() +{ + for( int i = 0; i < m_unknownClients.size(); ++i ) + { + closeSocket( m_unknownClients[i] ); + } + m_unknownClients.clear(); + Q_ASSERT( m_streamReaders.isEmpty() ); + Q_ASSERT( m_cache.isEmpty() ); + + for( int i = 0; i < m_clientConnections.size(); ++i ) + { + delete m_clientConnections[i]; + } + + for( int i = 0; i < m_serverConnections.size(); ++i ) + { + delete m_serverConnections[i]; + } +} + +bool QXmppServer::acceptsClients() const +{ + return m_acceptsClients; +} + +bool QXmppServer::acceptsServers() const +{ + return m_acceptsServers; +} + +void QXmppServer::addCaCertificates( const QList &certificates ) +{ + m_certificates.append( certificates ); +} + +void QXmppServer::addCaCertificates( const QSslCertificate &certificate ) +{ + m_certificates.append( certificate ); +} + +void QXmppServer::closeSocket( QSslSocket *socket ) +{ + forgetSocket( socket ); + delete socket; +} + +/** + * @brief Determine the socket type of this socket. + * + * This method determines whether the connecting peer is a client on the network, or + * another server. To do this, it analyses the 'xmlns' attribute to the + * <stream:stream> start tag. + */ +void QXmppServer::determineSocketType() +{ + QSslSocket *socket = static_cast(sender()); + Q_ASSERT( socket != 0 ); + + Q_ASSERT( m_unknownClients.contains( socket ) ); + Q_ASSERT( m_streamReaders. contains( socket ) ); + Q_ASSERT( m_cache. contains( socket ) ); + QXmlStreamReader *reader = m_streamReaders.value( socket ); + + // Previous errors should already be handled here + Q_ASSERT( !reader->hasError() ); + + QByteArray data = socket->readAll(); + m_cache[socket].append( data ); + reader->addData( data ); + + bool isStartStream = false; + QXmlStreamNamespaceDeclarations xmlns; + while( !reader->atEnd() ) + { + QXmlStreamReader::TokenType type = reader->readNext(); + if( type == QXmlStreamReader::StartElement ) + { + xmlns = reader->namespaceDeclarations(); + if( reader->qualifiedName() == "stream:stream" ) + { + // Got the start of a stream! +#ifdef QXMPPSERVER_DEBUG + qDebug() << "Got the start of a stream."; +#endif + isStartStream = true; + } + else + { + qWarning() << "Received another start element than stream:stream" + << reader->qualifiedName(); + socket->write( XMPP_STANDARD_SERVER_STREAM_START ); + socket->write( XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR ); + socket->write( XMPP_STANDARD_END_STREAM ); + socket->flush(); + closeSocket( socket ); + return; + } + } + else if( !isStartStream && type != QXmlStreamReader::StartDocument ) + { + qWarning() << "Received XML data before start of stream: " + << reader->qualifiedName() + << "type: " << type + << "error: " << reader->errorString(); + if( type == 1 && tryOtherProtocol( socket ) ) + { + // Apparantly, the socket wasn't speaking XMPP. + // tryOtherProtocol() has returned another message, now close + socket->flush(); + closeSocket( socket ); + return; + } + else if( reader->hasError() && reader->error() != + QXmlStreamReader::PrematureEndOfDocumentError ) + { + socket->write( XMPP_STANDARD_SERVER_STREAM_START ); + if( reader->qualifiedName() == "stream:stream" ) + { + socket->write( XMPP_STANDARD_INVALIDNS_STREAM_ERROR ); + } + else + { + socket->write( XMPP_STANDARD_NOTWELLFORMED_STREAM_ERROR ); + } + socket->write( XMPP_STANDARD_END_STREAM ); + socket->flush(); + closeSocket( socket ); + return; + } + } + } + + if( !isStartStream ) + { + // Didn't find a stream:stream yet, return immediately. + return; + } + + bool containsServerXmlns; + bool containsClientXmlns; + for(int i = 0; i < xmlns.size(); ++i ) + { +#ifdef QXMPPSERVER_DEBUG + qDebug() << "XMLNS prefix=" << xmlns.at(i).prefix() << "; namespaceUri=" + << xmlns.at(i).namespaceUri(); +#endif + if( xmlns.at(i).prefix().isEmpty() ) + { + if( xmlns.at(i).namespaceUri() == "jabber:client" ) + { + containsClientXmlns = true; + } + else if( xmlns.at(i).namespaceUri() == "jabber:server" ) + { + containsServerXmlns = true; + } + else + { + qWarning() << "Didn't find proper XML namespace in stream."; + socket->write( XMPP_STANDARD_SERVER_STREAM_START ); + socket->write( XMPP_STANDARD_INVALIDNS_STREAM_ERROR ); + socket->write( XMPP_STANDARD_END_STREAM ); + socket->flush(); + closeSocket( socket ); + return; + } + } + } + + Q_ASSERT( containsServerXmlns || containsClientXmlns ); + + if( containsServerXmlns ) + { +#ifdef QXMPPSERVER_DEBUG + qDebug() << "It's a server socket!"; +#endif + + if( !m_acceptsServers ) + { + // send a stream error + socket->write( XMPP_STANDARD_SERVER_STREAM_START ); + socket->write( XMPP_STANDARD_POLICY_STREAM_ERROR ); + socket->write( XMPP_STANDARD_END_STREAM ); + socket->flush(); + closeSocket( socket ); + return; + } + + QByteArray pastData = m_cache[socket]; + forgetSocket( socket ); + + socket->addCaCertificates( m_certificates ); + socket->setLocalCertificate( m_localCertificate ); + socket->setPrivateKey( m_privateKey ); + socket->setProtocol( QSsl::AnyProtocol ); + + QXmppServerConnection *sc = new QXmppServerConnection( socket, pastData ); + sc->setLogger( m_logger ); + m_serverConnections.append( sc ); + } + else if( containsClientXmlns ) + { +#ifdef QXMPPSERVER_DEBUG + qDebug() << "It's a client socket!"; +#endif + + if( !m_acceptsClients ) + { + // send a stream error + socket->write( XMPP_STANDARD_CLIENT_STREAM_START ); + socket->write( XMPP_STANDARD_POLICY_STREAM_ERROR ); + socket->write( XMPP_STANDARD_END_STREAM ); + socket->flush(); + closeSocket( socket ); + return; + } + + QByteArray pastData = m_cache[socket]; + forgetSocket( socket ); + + QXmppClientServer *cs = new QXmppClientServer( socket, pastData ); + cs->setLogger( m_logger ); + m_clientConnections.append( cs ); + } +} + +void QXmppServer::forgetSocket( QSslSocket *socket ) +{ + Q_ASSERT( m_unknownClients.contains( socket ) ); + Q_ASSERT( m_streamReaders. contains( socket ) ); + Q_ASSERT( m_cache. contains( socket ) ); + + socket->disconnect( this, 0 ); + + QXmlStreamReader *reader = m_streamReaders.value( socket ); + m_unknownClients.removeAll( socket ); + m_streamReaders.remove( socket ); + m_cache.remove( socket ); + delete reader; +} + +void QXmppServer::incomingConnection( int socketDescriptor ) +{ + QSslSocket *socket = new QSslSocket; + if( socket->setSocketDescriptor( socketDescriptor ) ) + { + ASSERT_CONNECT( socket, SIGNAL( readyRead() ), + this, SLOT( determineSocketType() ) ); + + m_unknownClients.append( socket ); + m_streamReaders.insert( socket, new QXmlStreamReader() ); + m_cache.insert( socket, "" ); + emit unknownClientConnected( socket ); + return; + } + + delete socket; + qWarning() << "setSocketDescriptor failed"; +} + +QXmppLogger *QXmppServer::logger() +{ + return m_logger; +} + +void QXmppServer::setAcceptsClients( bool acceptsClients ) +{ + m_acceptsClients = acceptsClients; +} + +void QXmppServer::setAcceptsServers( bool acceptsServers ) +{ + m_acceptsServers = acceptsServers; +} + +void QXmppServer::setLocalCertificate( const QSslCertificate &localCertificate ) +{ + m_localCertificate = localCertificate; +} + +void QXmppServer::setLogger(QXmppLogger *logger) +{ + m_logger = logger; +} + +void QXmppServer::setPrivateKey( const QSslKey &privateKey ) +{ + m_privateKey = privateKey; +} + +/** + * @brief Try to detect another protocol on our server line + * + * Sometimes, a client erroneously connects to the wrong port. For example, a + * browser or IRC client might end up on our socket. The XML parser will + * likely give an error then - here we check if the other side is speaking the + * incorrect protocol. This will, of course, never work in protocols where the + * server starts sending and the client waits indefinitely. + * + * This method should only write a message to the socket and return true if + * a protocol was recognised; the socket will be flushed and closed elsewhere. + * + * Recognised protocols: http (first line ends with HTTP/x.y), irc (first line + * starts with NICK) + */ +bool QXmppServer::tryOtherProtocol( QSslSocket *socket ) +{ + Q_ASSERT( m_cache. contains( socket ) ); + QByteArray &cache = m_cache[socket]; + + int newline = cache.indexOf( "\n" ); + int carrret = cache.indexOf( "\r" ); + newline = ( carrret < newline && carrret != -1 ) ? carrret : newline; + QByteArray firstLine = cache.mid( 0, newline ); + + // Discover IRC + if( firstLine.startsWith( "NICK " ) ) + { + QByteArray nick = firstLine.mid( 5, newline - 5 ); + socket->write( ":xmppd 001 " + nick + " :Welcome to XMPP IRC\r\n" ); + socket->write( ":xmppd 002 " + nick + " :Your host is an XMPP IRC daemon\r\n" ); + socket->write( ":xmppd 375 " + nick + " :- XMPP IRC Daemon Message of the Day -\r\n" ); + socket->write( ":xmppd 372 " + nick + " :- This server is not an IRC server! It is\r\n" ); + socket->write( ":xmppd 372 " + nick + " :- an XMPP server. Please use an XMPP client\r\n" ); + socket->write( ":xmppd 372 " + nick + " :- to connect to it.\r\n" ); + socket->write( ":xmppd 376 " + nick + " :End of /MOTD command.\r\n" ); + socket->write( ":" + nick + " QUIT :Not an XMPP client.\r\n" ); + socket->write( "ERROR :Closing Link: Not an XMPP client.\r\n" ); + return true; + } + + // Discover HTTP + QByteArray httpVer = firstLine.right(8); + if( httpVer.startsWith( "HTTP/" ) ) + { + socket->write( "HTTP/1.0 200 OK\r\n" ); + socket->write( "Content-Type: text/html; charset=UTF-8\r\n" ); + socket->write( "Server: xmppd\r\n" ); + socket->write( "\r\n" ); + socket->write( "Not a webserver\r\n" ); + socket->write( "You are connecting to an XMPP server as if it were" ); + socket->write( " a webserver. Please use an XMPP client to connect to " ); + socket->write( "it.\r\n" ); + return true; + } + + return false; +} diff --git a/source/server/QXmppServer.h b/source/server/QXmppServer.h index 910cee92..06c8ab03 100644 --- a/source/server/QXmppServer.h +++ b/source/server/QXmppServer.h @@ -1,98 +1,98 @@ -/* - * Copyright (C) 2010 Sjors Gielen, Rob ten Berge - * - * Authors: - * Sjors Gielen - * Rob ten Berge - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#ifndef QXMPPSERVER_H -#define QXMPPSERVER_H - -#include -#include -#include -#include -#include - -#include "QXmppConfiguration.h" -#include "QXmppPresence.h" -#include "QXmppClient.h" -#include "QXmppLogger.h" - -class QXmppServerConnection; -class QXmppClientServer; - -/** @brief The QXmppServer class is the server class of QXmpp. - * - * This class listens on a TCP port and accepts clients and/or servers (depending on - * its configuration). It proceeds to create a QXmppServerConnection class if the - * other peer is a server, or a QXmppClientServer class if the other peer is a client. - */ - -class QXmppServer : public QTcpServer -{ - Q_OBJECT - -public: - QXmppServer(bool acceptsClients, bool acceptsServers, QObject *parent = 0); - ~QXmppServer(); - - QXmppLogger *logger(); - void setLogger(QXmppLogger *logger); - - void setAcceptsClients( bool acceptsClients ); - void setAcceptsServers( bool acceptsServers ); - bool acceptsClients() const; - bool acceptsServers() const; - - void addCaCertificates( const QList &certificates ); - void addCaCertificates( const QSslCertificate &certificate ); - void setLocalCertificate( const QSslCertificate &localCertificate ); - void setPrivateKey( const QSslKey &privateKey ); - -signals: - void unknownClientConnected( QSslSocket *client ); - void serverConnected( QXmppServerConnection *server ); - void clientConnected( QXmppClientServer *client ); - -private slots: - void determineSocketType(); - void forgetSocket( QSslSocket *socket ); - void closeSocket( QSslSocket *socket ); - bool tryOtherProtocol( QSslSocket *socket ); - -private: - QList m_serverConnections; - QList m_clientConnections; - QList m_unknownClients; - QHash m_streamReaders; - QHash m_cache; - - QXmppLogger* m_logger; - QList m_certificates; - QSslCertificate m_localCertificate; - QSslKey m_privateKey; - bool m_acceptsClients; - bool m_acceptsServers; - - void incomingConnection(int socketDescriptor); -}; - -#endif // QXMPPCLIENT_H +/* + * Copyright (C) 2010 Sjors Gielen, Rob ten Berge + * + * Authors: + * Sjors Gielen + * Rob ten Berge + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPSERVER_H +#define QXMPPSERVER_H + +#include +#include +#include +#include +#include + +#include "QXmppConfiguration.h" +#include "QXmppPresence.h" +#include "QXmppClient.h" +#include "QXmppLogger.h" + +class QXmppServerConnection; +class QXmppClientServer; + +/** @brief The QXmppServer class is the server class of QXmpp. + * + * This class listens on a TCP port and accepts clients and/or servers (depending on + * its configuration). It proceeds to create a QXmppServerConnection class if the + * other peer is a server, or a QXmppClientServer class if the other peer is a client. + */ + +class QXmppServer : public QTcpServer +{ + Q_OBJECT + +public: + QXmppServer(bool acceptsClients, bool acceptsServers, QObject *parent = 0); + ~QXmppServer(); + + QXmppLogger *logger(); + void setLogger(QXmppLogger *logger); + + void setAcceptsClients( bool acceptsClients ); + void setAcceptsServers( bool acceptsServers ); + bool acceptsClients() const; + bool acceptsServers() const; + + void addCaCertificates( const QList &certificates ); + void addCaCertificates( const QSslCertificate &certificate ); + void setLocalCertificate( const QSslCertificate &localCertificate ); + void setPrivateKey( const QSslKey &privateKey ); + +signals: + void unknownClientConnected( QSslSocket *client ); + void serverConnected( QXmppServerConnection *server ); + void clientConnected( QXmppClientServer *client ); + +private slots: + void determineSocketType(); + void forgetSocket( QSslSocket *socket ); + void closeSocket( QSslSocket *socket ); + bool tryOtherProtocol( QSslSocket *socket ); + +private: + QList m_serverConnections; + QList m_clientConnections; + QList m_unknownClients; + QHash m_streamReaders; + QHash m_cache; + + QXmppLogger* m_logger; + QList m_certificates; + QSslCertificate m_localCertificate; + QSslKey m_privateKey; + bool m_acceptsClients; + bool m_acceptsServers; + + void incomingConnection(int socketDescriptor); +}; + +#endif // QXMPPCLIENT_H diff --git a/source/server/QXmppServerConnection.cpp b/source/server/QXmppServerConnection.cpp index 1bf98cce..2a688482 100644 --- a/source/server/QXmppServerConnection.cpp +++ b/source/server/QXmppServerConnection.cpp @@ -1,165 +1,165 @@ -/* - * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya - * - * Authors: - * Manjeet Dahiya - * Sjors Gielen - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - - -#include "QXmppServerConnection.h" -#include "QXmppLogger.h" -#include "QXmppStream.h" -#include "QXmppMessage.h" -#include "QXmppUtils.h" - -#define QXMPPSERVERCONNECTION_DEBUG - -#define ASSERT_CONNECT(a, b, c, d) \ - { bool check = connect(a, b, c, d); \ - Q_ASSERT( check ); } - -/** - * @brief Creates a QXmppServerConnection object. - * - * This class is meant for server to server connections, both initiated by this - * server (in which case the connectToHost method should be used), and - * initiated by other servers (in which case a QSslSocket should be given to - * this class). To listen to incoming connections, use QXmppServer. - * - * @param socket Server socket if nonzero, ignored if zero - * @param data Server data to start parsing, only if server socket nonzero - * @param parent QObject parent of this object - */ -QXmppServerConnection::QXmppServerConnection(QSslSocket *socket, - const QByteArray &data, QObject *parent) -: QObject(parent) -, m_logger(0) -, m_stream(0) -{ - Q_ASSERT( socket == 0 || socket->state() == QAbstractSocket::ConnectedState ); - - m_logger = QXmppLogger::getLogger(); - //m_stream = new QXmppStream(this); - //m_stream->setSocket( socket ); - - ASSERT_CONNECT(m_stream, SIGNAL(messageReceived(const QXmppMessage&)), - this, SIGNAL(messageReceived(const QXmppMessage&))); - - ASSERT_CONNECT(m_stream, SIGNAL(disconnected()), - this, SIGNAL(disconnected())); - - ASSERT_CONNECT(m_stream, SIGNAL(xmppConnected()), - this, SIGNAL(connected())); - - ASSERT_CONNECT(m_stream, SIGNAL(error(QXmppServerConnection::Error)), - this, SIGNAL(error(QXmppServerConnection::Error))); -} - -/// Destructor, destroys the QXmppServerConnection object. -/// - -QXmppServerConnection::~QXmppServerConnection() -{ -} - -/** - * @brief Attempts to connect to another XMPP server. - * - * @param host Hostname of the XMPP server where connection has to be made - * (e.g. "jabber.org" and "talk.google.com"). It can also be an IP address in - * the form of a string (e.g. "192.168.1.25"). - * @param domain Domain name of the other side e.g. "gmail.com", "jabber.org". - * @param port Port number at which the XMPP server is listening. The default - * value is 5269. - */ -void QXmppServerConnection::connectToServer(const QString& host, const QString& domain, - int port) -{ - disconnect(); - //m_stream->connect( host, domain, port ); -} - -/// After successfully connecting to the server use this function to send -/// stanzas to the server. This function can solely be used to send various kind -/// of stanzas to the server. QXmppPacket is a parent class of all the stanzas -/// QXmppMessage, QXmppPresence, QXmppIq, QXmppBind, QXmppRosterIq, QXmppSession -/// and QXmppVCard. -/// -/// Following code snippet illustrates how to send a message using this function: -/// \code -/// QXmppMessage message(from, to, message); -/// client.sendPacket(message); -/// \endcode -/// -/// \param packet A valid XMPP stanza. It can be an iq, a message or a presence stanza. -/// - -void QXmppServerConnection::sendPacket(const QXmppPacket& packet) -{ - Q_ASSERT( m_stream != 0 ); - m_stream->sendPacket(packet); -} - -/// Disconnects the client and the current presence of client changes to -/// QXmppPresence::Unavailable and statatus text changes to "Logged out". -/// -/// \note Make sure that the clientPresence is changed to -/// QXmppPresence::Available, if you are again calling connectToServer() after -/// calling the disconnect() function. -/// - -void QXmppServerConnection::disconnect() -{ - Q_ASSERT( m_stream != 0 ); - m_stream->disconnect(); -} - -/// Returns the socket error if QXmppServerConnection::Error is QXmppServerConnection::SocketError. -/// -/// \return QAbstractSocket::SocketError -/// - -QAbstractSocket::SocketError QXmppServerConnection::getSocketError() -{ - return m_stream->getSocketError(); -} - -/// Returns the XMPP stream error if QXmppServerConnection::Error is QXmppServerConnection::XmppStreamError. -/// -/// \return QXmppServerConnection::Error::Condition -/// - -QXmppStanza::Error::Condition QXmppServerConnection::getXmppStreamError() -{ - return m_stream->getXmppStreamError(); -} - -/// Return the QXmppLogger associated with the client. - -QXmppLogger *QXmppServerConnection::logger() -{ - return m_logger; -} - -void QXmppServerConnection::setLogger(QXmppLogger *logger) -{ - m_logger = logger; -} - +/* + * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya + * + * Authors: + * Manjeet Dahiya + * Sjors Gielen + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + + +#include "QXmppServerConnection.h" +#include "QXmppLogger.h" +#include "QXmppStream.h" +#include "QXmppMessage.h" +#include "QXmppUtils.h" + +#define QXMPPSERVERCONNECTION_DEBUG + +#define ASSERT_CONNECT(a, b, c, d) \ + { bool check = connect(a, b, c, d); \ + Q_ASSERT( check ); } + +/** + * @brief Creates a QXmppServerConnection object. + * + * This class is meant for server to server connections, both initiated by this + * server (in which case the connectToHost method should be used), and + * initiated by other servers (in which case a QSslSocket should be given to + * this class). To listen to incoming connections, use QXmppServer. + * + * @param socket Server socket if nonzero, ignored if zero + * @param data Server data to start parsing, only if server socket nonzero + * @param parent QObject parent of this object + */ +QXmppServerConnection::QXmppServerConnection(QSslSocket *socket, + const QByteArray &data, QObject *parent) +: QObject(parent) +, m_logger(0) +, m_stream(0) +{ + Q_ASSERT( socket == 0 || socket->state() == QAbstractSocket::ConnectedState ); + + m_logger = QXmppLogger::getLogger(); + //m_stream = new QXmppStream(this); + //m_stream->setSocket( socket ); + + ASSERT_CONNECT(m_stream, SIGNAL(messageReceived(const QXmppMessage&)), + this, SIGNAL(messageReceived(const QXmppMessage&))); + + ASSERT_CONNECT(m_stream, SIGNAL(disconnected()), + this, SIGNAL(disconnected())); + + ASSERT_CONNECT(m_stream, SIGNAL(xmppConnected()), + this, SIGNAL(connected())); + + ASSERT_CONNECT(m_stream, SIGNAL(error(QXmppServerConnection::Error)), + this, SIGNAL(error(QXmppServerConnection::Error))); +} + +/// Destructor, destroys the QXmppServerConnection object. +/// + +QXmppServerConnection::~QXmppServerConnection() +{ +} + +/** + * @brief Attempts to connect to another XMPP server. + * + * @param host Hostname of the XMPP server where connection has to be made + * (e.g. "jabber.org" and "talk.google.com"). It can also be an IP address in + * the form of a string (e.g. "192.168.1.25"). + * @param domain Domain name of the other side e.g. "gmail.com", "jabber.org". + * @param port Port number at which the XMPP server is listening. The default + * value is 5269. + */ +void QXmppServerConnection::connectToServer(const QString& host, const QString& domain, + int port) +{ + disconnect(); + //m_stream->connect( host, domain, port ); +} + +/// After successfully connecting to the server use this function to send +/// stanzas to the server. This function can solely be used to send various kind +/// of stanzas to the server. QXmppPacket is a parent class of all the stanzas +/// QXmppMessage, QXmppPresence, QXmppIq, QXmppBind, QXmppRosterIq, QXmppSession +/// and QXmppVCard. +/// +/// Following code snippet illustrates how to send a message using this function: +/// \code +/// QXmppMessage message(from, to, message); +/// client.sendPacket(message); +/// \endcode +/// +/// \param packet A valid XMPP stanza. It can be an iq, a message or a presence stanza. +/// + +void QXmppServerConnection::sendPacket(const QXmppPacket& packet) +{ + Q_ASSERT( m_stream != 0 ); + m_stream->sendPacket(packet); +} + +/// Disconnects the client and the current presence of client changes to +/// QXmppPresence::Unavailable and statatus text changes to "Logged out". +/// +/// \note Make sure that the clientPresence is changed to +/// QXmppPresence::Available, if you are again calling connectToServer() after +/// calling the disconnect() function. +/// + +void QXmppServerConnection::disconnect() +{ + Q_ASSERT( m_stream != 0 ); + m_stream->disconnect(); +} + +/// Returns the socket error if QXmppServerConnection::Error is QXmppServerConnection::SocketError. +/// +/// \return QAbstractSocket::SocketError +/// + +QAbstractSocket::SocketError QXmppServerConnection::getSocketError() +{ + return m_stream->getSocketError(); +} + +/// Returns the XMPP stream error if QXmppServerConnection::Error is QXmppServerConnection::XmppStreamError. +/// +/// \return QXmppServerConnection::Error::Condition +/// + +QXmppStanza::Error::Condition QXmppServerConnection::getXmppStreamError() +{ + return m_stream->getXmppStreamError(); +} + +/// Return the QXmppLogger associated with the client. + +QXmppLogger *QXmppServerConnection::logger() +{ + return m_logger; +} + +void QXmppServerConnection::setLogger(QXmppLogger *logger) +{ + m_logger = logger; +} + diff --git a/source/server/QXmppServerConnection.h b/source/server/QXmppServerConnection.h index d0acfe20..c948064f 100644 --- a/source/server/QXmppServerConnection.h +++ b/source/server/QXmppServerConnection.h @@ -1,115 +1,115 @@ -/* - * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya - * - * Authors: - * Manjeet Dahiya - * Sjors Gielen - * - * Source: - * http://code.google.com/p/qxmpp - * - * This file is a part of QXmpp library. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - */ - -#ifndef QXMPPSERVERCONNECTION_H -#define QXMPPSERVERCONNECTION_H - -#include -#include - -#include "QXmppClient.h" - -/** - * @brief The QXmppServerConnection class handles connections to other servers. - */ - -class QXmppServerConnection : public QObject -{ - Q_OBJECT - -public: - // should probably be moved to QXmppStream - enum Error - { - SocketError, ///< Error due to TCP socket - KeepAliveError, ///< Error due to no response to a keep alive - XmppStreamError, ///< Error due to XML stream - }; - - QXmppServerConnection(QSslSocket *serverSocket = 0, - const QByteArray &parseData = QByteArray(), QObject *parent = 0); - ~QXmppServerConnection(); - void connectToServer(const QString& host, - const QString& domain, - int port = 5269); - void disconnect(); - -signals: - - /// This signal is emitted when the client connects sucessfully to the XMPP - /// server i.e. when a successful XMPP connection is established. - /// XMPP Connection involves following sequential steps: - /// - TCP socket connection - /// - Client sends start stream - /// - Server sends start stream - /// - TLS negotiation (encryption) - /// - Authentication - /// - Resource binding - /// - Session establishment - /// - /// After all these steps a successful XMPP connection is established and - /// connected() signal is emitted. - /// - /// After the connected() signal is emitted QXmpp will send the roster request - /// to the server. On receiving the roster, QXmpp will emit - /// QXmppRoster::rosterReceived(). After this signal, QXmppRoster object gets - /// populated and you can use getRoster() to get the handle of QXmppRoster object. - /// - void connected(); - - /// This signal is emitted when the XMPP connection disconnects. - /// - void disconnected(); - - /// This signal is emitted when the XMPP connection encounters any error. - /// The QXmppClient::Error parameter specifies the type of error occured. - /// It could be due to TCP socket or the xml stream or the stanza. - /// Depending upon the type of error occured use the respective get function to - /// know the error. - void error(QXmppClient::Error); - - /// Notifies that an XMPP message stanza is received. The QXmppMessage - /// parameter contains the details of the message sent to this client. - /// In other words whenever someone sends you a message this signal is - /// emitted. - void messageReceived(const QXmppMessage&); - -public: - QAbstractSocket::SocketError getSocketError(); - - QXmppStanza::Error::Condition getXmppStreamError(); - - QXmppLogger *logger(); - void setLogger(QXmppLogger *logger); - -public slots: - void sendPacket(const QXmppPacket&); - -private: - QXmppLogger* m_logger; - QXmppStream* m_stream; ///< Pointer to QXmppStream object, a wrapper over - ///< TCP socket and XMPP protocol -}; - -#endif // QXMPPCLIENT_H +/* + * Copyright (C) 2010 Sjors Gielen, Manjeet Dahiya + * + * Authors: + * Manjeet Dahiya + * Sjors Gielen + * + * Source: + * http://code.google.com/p/qxmpp + * + * This file is a part of QXmpp library. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + */ + +#ifndef QXMPPSERVERCONNECTION_H +#define QXMPPSERVERCONNECTION_H + +#include +#include + +#include "QXmppClient.h" + +/** + * @brief The QXmppServerConnection class handles connections to other servers. + */ + +class QXmppServerConnection : public QObject +{ + Q_OBJECT + +public: + // should probably be moved to QXmppStream + enum Error + { + SocketError, ///< Error due to TCP socket + KeepAliveError, ///< Error due to no response to a keep alive + XmppStreamError, ///< Error due to XML stream + }; + + QXmppServerConnection(QSslSocket *serverSocket = 0, + const QByteArray &parseData = QByteArray(), QObject *parent = 0); + ~QXmppServerConnection(); + void connectToServer(const QString& host, + const QString& domain, + int port = 5269); + void disconnect(); + +signals: + + /// This signal is emitted when the client connects sucessfully to the XMPP + /// server i.e. when a successful XMPP connection is established. + /// XMPP Connection involves following sequential steps: + /// - TCP socket connection + /// - Client sends start stream + /// - Server sends start stream + /// - TLS negotiation (encryption) + /// - Authentication + /// - Resource binding + /// - Session establishment + /// + /// After all these steps a successful XMPP connection is established and + /// connected() signal is emitted. + /// + /// After the connected() signal is emitted QXmpp will send the roster request + /// to the server. On receiving the roster, QXmpp will emit + /// QXmppRoster::rosterReceived(). After this signal, QXmppRoster object gets + /// populated and you can use getRoster() to get the handle of QXmppRoster object. + /// + void connected(); + + /// This signal is emitted when the XMPP connection disconnects. + /// + void disconnected(); + + /// This signal is emitted when the XMPP connection encounters any error. + /// The QXmppClient::Error parameter specifies the type of error occured. + /// It could be due to TCP socket or the xml stream or the stanza. + /// Depending upon the type of error occured use the respective get function to + /// know the error. + void error(QXmppClient::Error); + + /// Notifies that an XMPP message stanza is received. The QXmppMessage + /// parameter contains the details of the message sent to this client. + /// In other words whenever someone sends you a message this signal is + /// emitted. + void messageReceived(const QXmppMessage&); + +public: + QAbstractSocket::SocketError getSocketError(); + + QXmppStanza::Error::Condition getXmppStreamError(); + + QXmppLogger *logger(); + void setLogger(QXmppLogger *logger); + +public slots: + void sendPacket(const QXmppPacket&); + +private: + QXmppLogger* m_logger; + QXmppStream* m_stream; ///< Pointer to QXmppStream object, a wrapper over + ///< TCP socket and XMPP protocol +}; + +#endif // QXMPPCLIENT_H -- cgit v1.2.3