diff options
author | Sergio Ahumada <sahumada@blackberry.com> | 2014-03-13 14:50:03 +0100 |
---|---|---|
committer | Sergio Ahumada <sahumada@blackberry.com> | 2014-03-13 14:50:05 +0100 |
commit | 974fd5f831cf9abfbd900c49ab6c21fb04ef62da (patch) | |
tree | 235666b5d896d5c86db5325215720425b5508ffa /src | |
parent | e677361e300a7747a500c3879217727a53aae245 (diff) | |
parent | d4ac9f51f6d18a05016e3d61c06eace27501f589 (diff) | |
download | qtwebsockets-974fd5f831cf9abfbd900c49ab6c21fb04ef62da.tar.gz |
Merge remote-tracking branch 'origin/stable' into dev
Change-Id: I0ee590f834200c488498315e66acf7cd046d43ad
Diffstat (limited to 'src')
-rw-r--r-- | src/websockets/doc/qtwebsockets.qdocconf | 4 | ||||
-rw-r--r-- | src/websockets/doc/src/index.qdoc | 9 | ||||
-rw-r--r-- | src/websockets/doc/src/qtwebsockets-module.qdoc | 6 | ||||
-rw-r--r-- | src/websockets/qdefaultmaskgenerator_p.cpp | 41 | ||||
-rw-r--r-- | src/websockets/qmaskgenerator.cpp | 8 | ||||
-rw-r--r-- | src/websockets/qsslserver.cpp | 41 | ||||
-rw-r--r-- | src/websockets/qsslserver_p.h | 2 | ||||
-rw-r--r-- | src/websockets/qwebsocket.cpp | 4 | ||||
-rw-r--r-- | src/websockets/qwebsocket_p.cpp | 2 | ||||
-rw-r--r-- | src/websockets/qwebsockethandshakeresponse.cpp | 2 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver.cpp | 7 | ||||
-rw-r--r-- | src/websockets/qwebsocketserver_p.cpp | 18 |
12 files changed, 131 insertions, 13 deletions
diff --git a/src/websockets/doc/qtwebsockets.qdocconf b/src/websockets/doc/qtwebsockets.qdocconf index 434c9f2..7822edc 100644 --- a/src/websockets/doc/qtwebsockets.qdocconf +++ b/src/websockets/doc/qtwebsockets.qdocconf @@ -40,11 +40,11 @@ tagfile = ../../../doc/qtwebsockets/ depends += qtcore qtnetwork qtdoc -headerdirs += .. +headerdirs += .. \ ../../imports sourcedirs += .. \ - src + src \ ../../imports diff --git a/src/websockets/doc/src/index.qdoc b/src/websockets/doc/src/index.qdoc index f85380b..2961ef3 100644 --- a/src/websockets/doc/src/index.qdoc +++ b/src/websockets/doc/src/index.qdoc @@ -50,10 +50,15 @@ QT += websockets \endcode - \section1 Related information + \section1 Reference documentation \list \li \l{Qt WebSockets C++ Classes}{C++ Classes} - \li \l{Qt WebSockets Examples}{Examples} \li \l{Qt WebSockets QML Types}{QML Types} \endlist + + \section1 Examples + + The module provides the following examples as a guide to using + the API. + \l{Qt WebSockets Examples}{Examples} */ diff --git a/src/websockets/doc/src/qtwebsockets-module.qdoc b/src/websockets/doc/src/qtwebsockets-module.qdoc index c4dea41..02d31d1 100644 --- a/src/websockets/doc/src/qtwebsockets-module.qdoc +++ b/src/websockets/doc/src/qtwebsockets-module.qdoc @@ -29,6 +29,7 @@ \title Qt WebSockets C++ Classes \ingroup modules \qtvariable websockets + \since 5.3 \brief List of C++ classes that provide WebSockets communication. To use these classes in your application, use the following include @@ -52,4 +53,9 @@ \brief List of QML types that provide WebSockets communication. \annotatedlist websockets-qml + + The QML types are accessed by using: + \code + import QtWebSockets 1.0 + \endcode */ diff --git a/src/websockets/qdefaultmaskgenerator_p.cpp b/src/websockets/qdefaultmaskgenerator_p.cpp index 814e04d..da166ac 100644 --- a/src/websockets/qdefaultmaskgenerator_p.cpp +++ b/src/websockets/qdefaultmaskgenerator_p.cpp @@ -38,6 +38,26 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +/*! + \class QDefaultMaskGenerator + + \inmodule QtWebSockets + + \brief The QDefaultMaskGenerator class provides the default mask generator for QtWebSockets. + + The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455} + requires that all communication from client to server must be masked. This is to prevent + malicious scripts to attack bad behaving proxies. + For more information about the importance of good masking, + see \l {http://w2spconf.com/2011/papers/websocket.pdf}. + The default mask generator uses the cryptographically insecure qrand() function. + The best measure against attacks mentioned in the document above, + is to use QWebSocket over a secure connection (\e wss://). + In general, always be careful to not have 3rd party script access to + a QWebSocket in your application. + + \internal +*/ #include "qdefaultmaskgenerator_p.h" #include <QDateTime> @@ -45,21 +65,42 @@ QT_BEGIN_NAMESPACE +/*! + Constructs a new QDefaultMaskGenerator with the given \a parent. + + \internal +*/ QDefaultMaskGenerator::QDefaultMaskGenerator(QObject *parent) : QMaskGenerator(parent) { } +/*! + Destroys the QDefaultMaskGenerator object. + + \internal +*/ QDefaultMaskGenerator::~QDefaultMaskGenerator() { } +/*! + Seeds the QDefaultMaskGenerator using qsrand(). + When seed() is not called, no seed is used at all. + + \internal +*/ bool QDefaultMaskGenerator::seed() { qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch())); return true; } +/*! + Generates a new random mask using the insecure qrand() method. + + \internal +*/ quint32 QDefaultMaskGenerator::nextMask() { return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max()); diff --git a/src/websockets/qmaskgenerator.cpp b/src/websockets/qmaskgenerator.cpp index aa78f77..04f5e1e 100644 --- a/src/websockets/qmaskgenerator.cpp +++ b/src/websockets/qmaskgenerator.cpp @@ -41,7 +41,10 @@ /*! \class QMaskGenerator - The QMaskGenerator class provides an abstract base for custom 32-bit mask generators. + + \inmodule QtWebSockets + + \brief The QMaskGenerator class provides an abstract base for custom 32-bit mask generators. The WebSockets specification as outlined in {http://tools.ietf.org/html/rfc6455}{RFC 6455} requires that all communication from client to server must be masked. This is to prevent @@ -61,6 +64,7 @@ Initializes the QMaskGenerator by seeding the randomizer. When seed() is not called, it depends on the specific implementation of a subclass if a default seed is used or no seed is used at all. + Returns \e true if seeding succeeds, otherwise false. */ /*! @@ -75,7 +79,7 @@ QT_BEGIN_NAMESPACE /*! - Creates a new QMaskGenerator object. + Creates a new QMaskGenerator object with the given optional QObject \a parent. */ QMaskGenerator::QMaskGenerator(QObject *parent) : QObject(parent) diff --git a/src/websockets/qsslserver.cpp b/src/websockets/qsslserver.cpp index d1add19..e5faded 100644 --- a/src/websockets/qsslserver.cpp +++ b/src/websockets/qsslserver.cpp @@ -39,6 +39,16 @@ ** ****************************************************************************/ +/*! + \class QSslServer + + \inmodule QtWebSockets + + \brief Implements a secure TCP server over SSL. + + \internal +*/ + #include "qsslserver_p.h" #include <QtNetwork/QSslSocket> @@ -46,26 +56,57 @@ QT_BEGIN_NAMESPACE +/*! + Constructs a new QSslServer with the given \a parent. + + \internal +*/ QSslServer::QSslServer(QObject *parent) : QTcpServer(parent), m_sslConfiguration(QSslConfiguration::defaultConfiguration()) { } +/*! + Destroys the QSslServer. + + All open connections are closed. + + \internal +*/ QSslServer::~QSslServer() { } +/*! + Sets the \a sslConfiguration to use. + + \sa QSslSocket::setSslConfiguration() + + \internal +*/ void QSslServer::setSslConfiguration(const QSslConfiguration &sslConfiguration) { m_sslConfiguration = sslConfiguration; } +/*! + Returns the current ssl configuration. + + \internal +*/ QSslConfiguration QSslServer::sslConfiguration() const { return m_sslConfiguration; } +/*! + Called when a new connection is established. + + Converts \a socket to a QSslSocket. + + \internal +*/ void QSslServer::incomingConnection(qintptr socket) { QSslSocket *pSslSocket = new QSslSocket(); diff --git a/src/websockets/qsslserver_p.h b/src/websockets/qsslserver_p.h index 12da3c5..12b9369 100644 --- a/src/websockets/qsslserver_p.h +++ b/src/websockets/qsslserver_p.h @@ -55,7 +55,7 @@ class QSslServer : public QTcpServer Q_DISABLE_COPY(QSslServer) public: - QSslServer(QObject *parent = Q_NULLPTR); + explicit QSslServer(QObject *parent = Q_NULLPTR); virtual ~QSslServer(); void setSslConfiguration(const QSslConfiguration &sslConfiguration); diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp index 707d459..85b45c0 100644 --- a/src/websockets/qwebsocket.cpp +++ b/src/websockets/qwebsocket.cpp @@ -60,6 +60,10 @@ QWebSocket only supports version 13 of the WebSocket protocol, as outlined in \l {http://tools.ietf.org/html/rfc6455}{RFC 6455}. + \note Some proxies do not understand certain HTTP headers used during a web socket handshake. + In that case, non-secure web socket connections fail. The best way to mitigate against + this problem is to use web sockets over a secure connection. + \warning To generate masks, this implementation of WebSockets uses the cryptographically insecure qrand() function. For more information about the importance of good masking, diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index be589db..c51ba38 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -92,7 +92,7 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol:: QObjectPrivate(), q_ptr(pWebSocket), m_pSocket(), - m_errorString(QWebSocket::tr("Unknown error")), + m_errorString(), m_version(version), m_resourceName(), m_requestUrl(), diff --git a/src/websockets/qwebsockethandshakeresponse.cpp b/src/websockets/qwebsockethandshakeresponse.cpp index d244000..aa9a881 100644 --- a/src/websockets/qwebsockethandshakeresponse.cpp +++ b/src/websockets/qwebsockethandshakeresponse.cpp @@ -207,7 +207,7 @@ QString QWebSocketHandshakeResponse::getHandshakeResponse( if (Q_UNLIKELY(!m_canUpgrade)) { response << QStringLiteral("HTTP/1.1 400 Bad Request"); QStringList versions; - Q_FOREACH (QWebSocketProtocol::Version version, supportedVersions) + Q_FOREACH (const QWebSocketProtocol::Version &version, supportedVersions) versions << QString::number(static_cast<int>(version)); response << QStringLiteral("Sec-WebSocket-Version: ") % versions.join(QStringLiteral(", ")); diff --git a/src/websockets/qwebsocketserver.cpp b/src/websockets/qwebsocketserver.cpp index 0645947..884f422 100644 --- a/src/websockets/qwebsocketserver.cpp +++ b/src/websockets/qwebsocketserver.cpp @@ -70,6 +70,13 @@ \l {http://tools.ietf.org/html/rfc6455#page-39} {extensions} and \l {http://tools.ietf.org/html/rfc6455#page-12} {subprotocols}. + \note When working with self-signed certificates, FireFox currently has a + \l {https://bugzilla.mozilla.org/show_bug.cgi?id=594502} {bug} that prevents it to + connect to a secure websocket server. To work around this problem, first browse to the + secure websocket server using https. FireFox will indicate that the certificate is invalid. + From here on, the certificate can be added to the exceptions. After this, the secure websockets + connection should work. + QWebSocketServer only supports version 13 of the WebSocket protocol, as outlined in RFC 6455. \sa echoserver.html diff --git a/src/websockets/qwebsocketserver_p.cpp b/src/websockets/qwebsocketserver_p.cpp index a43e75a..f349dc2 100644 --- a/src/websockets/qwebsocketserver_p.cpp +++ b/src/websockets/qwebsocketserver_p.cpp @@ -94,7 +94,8 @@ void QWebSocketServerPrivate::init() m_pTcpServer = pSslServer; if (Q_LIKELY(m_pTcpServer)) { QObjectPrivate::connect(pSslServer, &QSslServer::newEncryptedConnection, - this, &QWebSocketServerPrivate::onNewConnection); + this, &QWebSocketServerPrivate::onNewConnection, + Qt::QueuedConnection); QObject::connect(pSslServer, &QSslServer::peerVerifyError, q_ptr, &QWebSocketServer::peerVerifyError); QObject::connect(pSslServer, &QSslServer::sslErrors, @@ -414,13 +415,22 @@ void QWebSocketServerPrivate::handshakeReceived() qWarning() << QWebSocketServer::tr("Sender is not a QTcpSocket. This is a Qt bug!!!"); return; } + //When using Google Chrome the handshake in received in two parts. + //Therefore, the readyRead signal is emitted twice. + //This is a guard against the BEAST attack. + //See: https://www.imperialviolet.org/2012/01/15/beastfollowup.html + //For Safari, the handshake is delivered at once + //FIXME: For FireFox, the readyRead signal is never emitted + //This is a bug in FireFox (see https://bugzilla.mozilla.org/show_bug.cgi?id=594502) + if (!pTcpSocket->canReadLine()) { + return; + } + disconnect(pTcpSocket, &QTcpSocket::readyRead, + this, &QWebSocketServerPrivate::handshakeReceived); Q_Q(QWebSocketServer); bool success = false; bool isSecure = false; - disconnect(pTcpSocket, &QTcpSocket::readyRead, - this, &QWebSocketServerPrivate::handshakeReceived); - if (m_pendingConnections.length() >= maxPendingConnections()) { pTcpSocket->close(); pTcpSocket->deleteLater(); |