summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKurt Pattyn <pattyn.kurt@gmail.com>2014-02-12 15:17:58 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-15 14:40:02 +0100
commit45eadd663ff22df46fadf03c45db7e058e71e476 (patch)
tree896959f43e107cd446b3e948a295e0a7661d4f47
parentabb6912c11dc322718724eb11e70617d8428b6f5 (diff)
downloadqtwebsockets-45eadd663ff22df46fadf03c45db7e058e71e476.tar.gz
Add user configurable mask generation
Created a QMaskGenerator abstract base class to serve as a basis for user specific mask generators. Added the possibility to override the default mask generation in QWebSocket. Change-Id: Iaa02b44193f854d103b5f352617789175fe61f89 Reviewed-by: Kurt Pattyn <pattyn.kurt@gmail.com>
-rw-r--r--src/websockets/qdefaultmaskgenerator_p.cpp68
-rw-r--r--src/websockets/qdefaultmaskgenerator_p.h75
-rw-r--r--src/websockets/qmaskgenerator.cpp91
-rw-r--r--src/websockets/qmaskgenerator.h64
-rw-r--r--src/websockets/qwebsocket.cpp32
-rw-r--r--src/websockets/qwebsocket.h3
-rw-r--r--src/websockets/qwebsocket_p.cpp47
-rw-r--r--src/websockets/qwebsocket_p.h8
-rw-r--r--src/websockets/websockets.pro12
-rw-r--r--tests/auto/auto.pro3
-rw-r--r--tests/auto/qdefaultmaskgenerator/qdefaultmaskgenerator.pro14
-rw-r--r--tests/auto/qdefaultmaskgenerator/tst_defaultmaskgenerator.cpp158
12 files changed, 553 insertions, 22 deletions
diff --git a/src/websockets/qdefaultmaskgenerator_p.cpp b/src/websockets/qdefaultmaskgenerator_p.cpp
new file mode 100644
index 0000000..2d8b1a2
--- /dev/null
+++ b/src/websockets/qdefaultmaskgenerator_p.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdefaultmaskgenerator_p.h"
+#include <QDateTime>
+#include <limits>
+
+QT_BEGIN_NAMESPACE
+
+QDefaultMaskGenerator::QDefaultMaskGenerator(QObject *parent) :
+ QMaskGenerator(parent)
+{
+}
+
+QDefaultMaskGenerator::~QDefaultMaskGenerator()
+{
+}
+
+bool QDefaultMaskGenerator::seed()
+{
+ qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
+ return true;
+}
+
+quint32 QDefaultMaskGenerator::nextMask()
+{
+ return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
+}
+
+QT_END_NAMESPACE
diff --git a/src/websockets/qdefaultmaskgenerator_p.h b/src/websockets/qdefaultmaskgenerator_p.h
new file mode 100644
index 0000000..5050a4a
--- /dev/null
+++ b/src/websockets/qdefaultmaskgenerator_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDEFAULTMASKGENERATOR_P_H
+#define QDEFAULTMASKGENERATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWebSockets/qmaskgenerator.h>
+
+QT_BEGIN_NAMESPACE
+class QObject;
+
+class Q_AUTOTEST_EXPORT QDefaultMaskGenerator : public QMaskGenerator
+{
+ Q_DISABLE_COPY(QDefaultMaskGenerator)
+
+public:
+ explicit QDefaultMaskGenerator(QObject *parent = 0);
+ virtual ~QDefaultMaskGenerator();
+
+ bool seed() Q_DECL_NOEXCEPT Q_DECL_OVERRIDE;
+ quint32 nextMask() Q_DECL_NOEXCEPT Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDEFAULTMASKGENERATOR_P_H
diff --git a/src/websockets/qmaskgenerator.cpp b/src/websockets/qmaskgenerator.cpp
new file mode 100644
index 0000000..9c678b5
--- /dev/null
+++ b/src/websockets/qmaskgenerator.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QMaskGenerator
+ 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
+ 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}.
+ By default QWebSocket 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.
+*/
+
+/*!
+ \fn bool QMaskGenerator::seed()
+
+ 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.
+*/
+
+/*!
+ \fn quint32 QMaskGenerator::nextMask()
+
+ Returns a new random 32-bit mask. The randomness depends on the RNG used to created the
+ mask.
+*/
+
+#include "qmaskgenerator.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Creates a new QMaskGenerator object.
+ */
+QMaskGenerator::QMaskGenerator(QObject *parent) :
+ QObject(parent)
+{
+}
+
+/*!
+ Destroys the QMaskGenerator object.
+ */
+QMaskGenerator::~QMaskGenerator()
+{}
+
+QT_END_NAMESPACE
diff --git a/src/websockets/qmaskgenerator.h b/src/websockets/qmaskgenerator.h
new file mode 100644
index 0000000..00cadba
--- /dev/null
+++ b/src/websockets/qmaskgenerator.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebSockets module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMASKGENERATOR_H
+#define QMASKGENERATOR_H
+
+#include <QObject>
+#include "QtWebSockets/qwebsockets_global.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_WEBSOCKETS_EXPORT QMaskGenerator : public QObject
+{
+ Q_DISABLE_COPY(QMaskGenerator)
+
+public:
+ explicit QMaskGenerator(QObject *parent = Q_NULLPTR);
+ virtual ~QMaskGenerator();
+
+ virtual bool seed() = 0;
+ virtual quint32 nextMask() = 0;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMASKGENERATOR_H
diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index 0a0c420..ca8ae08 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -57,7 +57,17 @@
\l {http://tools.ietf.org/html/rfc6455#page-39} {extensions} and
\l {http://tools.ietf.org/html/rfc6455#page-12} {subprotocols}.
- QWebSocket only supports version 13 of the WebSocket protocol, as outlined in RFC 6455.
+ QWebSocket only supports version 13 of the WebSocket protocol, as outlined in
+ \l {http://tools.ietf.org/html/rfc6455}{RFC 6455}.
+
+ \warning To generate masks, this implementation of WebSockets uses the cryptographically
+ insecure qrand() function.
+ For more information about the importance of good masking,
+ see \l {http://w2spconf.com/2011/papers/websocket.pdf}.
+ 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.
\sa QAbstractSocket, QTcpSocket
@@ -621,6 +631,26 @@ void QWebSocket::setProxy(const QNetworkProxy &networkProxy)
#endif
/*!
+ Sets the generator to use for creating masks to \a maskGenerator.
+ The default QWebSocket generator can be reset by supplying a \e Q_NULLPTR.
+ The mask generator can be changed at any time, even while the connection is open.
+ */
+void QWebSocket::setMaskGenerator(const QMaskGenerator *maskGenerator)
+{
+ Q_D(QWebSocket);
+ d->setMaskGenerator(maskGenerator);
+}
+
+/*!
+ Returns the mask generator that is currently used by this QWebSocket.
+ */
+const QMaskGenerator *QWebSocket::maskGenerator() const
+{
+ Q_D(const QWebSocket);
+ return d->maskGenerator();
+}
+
+/*!
Returns the size in bytes of the readbuffer that is used by the socket.
*/
qint64 QWebSocket::readBufferSize() const
diff --git a/src/websockets/qwebsocket.h b/src/websockets/qwebsocket.h
index 660b3a3..bb9f2db 100644
--- a/src/websockets/qwebsocket.h
+++ b/src/websockets/qwebsocket.h
@@ -57,6 +57,7 @@ QT_BEGIN_NAMESPACE
class QTcpSocket;
class QWebSocketPrivate;
+class QMaskGenerator;
class Q_WEBSOCKETS_EXPORT QWebSocket : public QObject
{
@@ -85,6 +86,8 @@ public:
QNetworkProxy proxy() const;
void setProxy(const QNetworkProxy &networkProxy);
#endif
+ void setMaskGenerator(const QMaskGenerator *maskGenerator);
+ const QMaskGenerator *maskGenerator() const;
qint64 readBufferSize() const;
void setReadBufferSize(qint64 size);
diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp
index 338e581..bff060f 100644
--- a/src/websockets/qwebsocket_p.cpp
+++ b/src/websockets/qwebsocket_p.cpp
@@ -44,6 +44,7 @@
#include "qwebsocketprotocol_p.h"
#include "qwebsockethandshakerequest_p.h"
#include "qwebsockethandshakeresponse_p.h"
+#include "qdefaultmaskgenerator_p.h"
#include <QtCore/QUrl>
#include <QtNetwork/QAuthenticator>
@@ -109,7 +110,9 @@ QWebSocketPrivate::QWebSocketPrivate(const QString &origin, QWebSocketProtocol::
m_closeReason(),
m_pingTimer(),
m_dataProcessor(),
- m_configuration()
+ m_configuration(),
+ m_pMaskGenerator(&m_defaultMaskGenerator),
+ m_defaultMaskGenerator()
{
}
@@ -139,7 +142,9 @@ QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol:
m_closeReason(),
m_pingTimer(),
m_dataProcessor(),
- m_configuration()
+ m_configuration(),
+ m_pMaskGenerator(&m_defaultMaskGenerator),
+ m_defaultMaskGenerator()
{
}
@@ -149,8 +154,9 @@ QWebSocketPrivate::QWebSocketPrivate(QTcpSocket *pTcpSocket, QWebSocketProtocol:
void QWebSocketPrivate::init()
{
Q_ASSERT(q_ptr);
- //TODO: need a better randomizer
- qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
+ Q_ASSERT(m_pMaskGenerator);
+
+ m_pMaskGenerator->seed();
if (m_pSocket) {
makeConnections(m_pSocket.data());
@@ -762,20 +768,11 @@ qint64 QWebSocketPrivate::doWriteFrames(const QByteArray &data, bool isBinary)
}
/*!
- * \internal
- */
-quint32 QWebSocketPrivate::generateRandomNumber() const
-{
- //TODO: need a better randomizer
- return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
-}
-
-/*!
\internal
*/
quint32 QWebSocketPrivate::generateMaskingKey() const
{
- return generateRandomNumber();
+ return m_pMaskGenerator->nextMask();
}
/*!
@@ -786,7 +783,7 @@ QByteArray QWebSocketPrivate::generateKey() const
QByteArray key;
for (int i = 0; i < 4; ++i) {
- const quint32 tmp = generateRandomNumber();
+ const quint32 tmp = m_pMaskGenerator->nextMask();
key.append(static_cast<const char *>(static_cast<const void *>(&tmp)), sizeof(quint32));
}
@@ -1235,6 +1232,26 @@ void QWebSocketPrivate::setProxy(const QNetworkProxy &networkProxy)
/*!
\internal
*/
+void QWebSocketPrivate::setMaskGenerator(const QMaskGenerator *maskGenerator)
+{
+ if (!maskGenerator)
+ m_pMaskGenerator = &m_defaultMaskGenerator;
+ else if (maskGenerator != m_pMaskGenerator)
+ m_pMaskGenerator = const_cast<QMaskGenerator *>(maskGenerator);
+}
+
+/*!
+ \internal
+ */
+const QMaskGenerator *QWebSocketPrivate::maskGenerator() const
+{
+ Q_ASSERT(m_pMaskGenerator);
+ return m_pMaskGenerator;
+}
+
+/*!
+ \internal
+ */
qint64 QWebSocketPrivate::readBufferSize() const
{
return m_readBufferSize;
diff --git a/src/websockets/qwebsocket_p.h b/src/websockets/qwebsocket_p.h
index 3bd9918..c1128c5 100644
--- a/src/websockets/qwebsocket_p.h
+++ b/src/websockets/qwebsocket_p.h
@@ -68,6 +68,7 @@
#include "qwebsocketprotocol.h"
#include "qwebsocketdataprocessor_p.h"
+#include "qdefaultmaskgenerator_p.h"
QT_BEGIN_NAMESPACE
@@ -75,6 +76,7 @@ class QWebSocketHandshakeRequest;
class QWebSocketHandshakeResponse;
class QTcpSocket;
class QWebSocket;
+class QMaskGenerator;
struct QWebSocketConfiguration
{
@@ -122,6 +124,8 @@ public:
QNetworkProxy proxy() const;
void setProxy(const QNetworkProxy &networkProxy);
#endif
+ void setMaskGenerator(const QMaskGenerator *maskGenerator);
+ const QMaskGenerator *maskGenerator() const;
qint64 readBufferSize() const;
void resume();
void setPauseMode(QAbstractSocket::PauseModes pauseMode);
@@ -195,7 +199,6 @@ private:
quint32 generateMaskingKey() const;
QByteArray generateKey() const;
- quint32 generateRandomNumber() const;
qint64 writeFrames(const QList<QByteArray> &frames) Q_REQUIRED_RESULT;
qint64 writeFrame(const QByteArray &frame) Q_REQUIRED_RESULT;
@@ -226,6 +229,9 @@ private:
QWebSocketDataProcessor m_dataProcessor;
QWebSocketConfiguration m_configuration;
+ QMaskGenerator *m_pMaskGenerator;
+ QDefaultMaskGenerator m_defaultMaskGenerator;
+
friend class QWebSocketServerPrivate;
};
diff --git a/src/websockets/websockets.pro b/src/websockets/websockets.pro
index 04bee8e..99e84b6 100644
--- a/src/websockets/websockets.pro
+++ b/src/websockets/websockets.pro
@@ -1,7 +1,7 @@
load(qt_build_config)
TARGET = QtWebSockets
-QT = core network core-private
+QT = core network core-private sql
TEMPLATE = lib
@@ -17,7 +17,8 @@ PUBLIC_HEADERS += \
$$PWD/qwebsocket.h \
$$PWD/qwebsocketserver.h \
$$PWD/qwebsocketprotocol.h \
- $$PWD/qwebsocketcorsauthenticator.h
+ $$PWD/qwebsocketcorsauthenticator.h \
+ $$PWD/qmaskgenerator.h
PRIVATE_HEADERS += \
$$PWD/qwebsocket_p.h \
@@ -27,7 +28,8 @@ PRIVATE_HEADERS += \
$$PWD/qwebsockethandshakeresponse_p.h \
$$PWD/qwebsocketdataprocessor_p.h \
$$PWD/qwebsocketcorsauthenticator_p.h \
- $$PWD/qwebsocketframe_p.h
+ $$PWD/qwebsocketframe_p.h \
+ $$PWD/qdefaultmaskgenerator_p.h
SOURCES += \
$$PWD/qwebsocket.cpp \
@@ -39,7 +41,9 @@ SOURCES += \
$$PWD/qwebsockethandshakeresponse.cpp \
$$PWD/qwebsocketdataprocessor.cpp \
$$PWD/qwebsocketcorsauthenticator.cpp \
- $$PWD/qwebsocketframe.cpp
+ $$PWD/qwebsocketframe.cpp \
+ $$PWD/qmaskgenerator.cpp \
+ $$PWD/qdefaultmaskgenerator_p.cpp
contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
SOURCES += $$PWD/qsslserver.cpp
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 34b232b..31900a4 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -7,7 +7,8 @@ contains(QT_CONFIG, private_tests): SUBDIRS += \
websocketprotocol \
dataprocessor \
websocketframe \
- handshakerequest
+ handshakerequest \
+ qdefaultmaskgenerator
SUBDIRS += \
qwebsocket \
diff --git a/tests/auto/qdefaultmaskgenerator/qdefaultmaskgenerator.pro b/tests/auto/qdefaultmaskgenerator/qdefaultmaskgenerator.pro
new file mode 100644
index 0000000..1ddccb3
--- /dev/null
+++ b/tests/auto/qdefaultmaskgenerator/qdefaultmaskgenerator.pro
@@ -0,0 +1,14 @@
+CONFIG += console
+CONFIG += testcase c++11
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+TARGET = tst_defaultmaskgenerator
+
+QT = core testlib websockets websockets-private
+
+SOURCES += tst_defaultmaskgenerator.cpp
+
+requires(contains(QT_CONFIG, private_tests))
+DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/qdefaultmaskgenerator/tst_defaultmaskgenerator.cpp b/tests/auto/qdefaultmaskgenerator/tst_defaultmaskgenerator.cpp
new file mode 100644
index 0000000..46e6d61
--- /dev/null
+++ b/tests/auto/qdefaultmaskgenerator/tst_defaultmaskgenerator.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QtTest/qtestcase.h>
+#include <QtTest/QSignalSpy>
+#include <QtCore/QBuffer>
+#include <QtCore/QByteArray>
+#include <QtCore/QDebug>
+
+#include "private/qdefaultmaskgenerator_p.h"
+
+QT_USE_NAMESPACE
+
+class tst_QDefaultMaskGenerator : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QDefaultMaskGenerator();
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+ void tst_randomnessWithoutSeed();
+ void tst_randomnessWithSeed();
+
+private:
+};
+
+
+
+tst_QDefaultMaskGenerator::tst_QDefaultMaskGenerator()
+{
+}
+
+void tst_QDefaultMaskGenerator::initTestCase()
+{
+}
+
+void tst_QDefaultMaskGenerator::cleanupTestCase()
+{
+}
+
+void tst_QDefaultMaskGenerator::init()
+{
+}
+
+void tst_QDefaultMaskGenerator::cleanup()
+{
+}
+
+void tst_QDefaultMaskGenerator::tst_randomnessWithoutSeed()
+{
+ //generate two series of data, and see if they differ
+ {
+ QDefaultMaskGenerator generator;
+
+ QVector<quint32> series1, series2;
+ for (int i = 0; i < 1000; ++i)
+ series1 << generator.nextMask();
+ for (int i = 0; i < 1000; ++i)
+ series2 << generator.nextMask();
+
+ QVERIFY(series1 != series2);
+ }
+}
+
+void tst_QDefaultMaskGenerator::tst_randomnessWithSeed()
+{
+ //generate two series of data, and see if they differ
+ //the generator is seeded
+ {
+ QDefaultMaskGenerator generator;
+ generator.seed();
+
+ QVector<quint32> series1, series2;
+ for (int i = 0; i < 1000; ++i)
+ series1 << generator.nextMask();
+ for (int i = 0; i < 1000; ++i)
+ series2 << generator.nextMask();
+
+ QVERIFY(series1 != series2);
+ }
+ //generates two series of data with 2 distinct generators
+ //both generators are seeded
+ {
+ QDefaultMaskGenerator generator1, generator2;
+ generator1.seed();
+ generator2.seed();
+
+ QVector<quint32> series1, series2;
+ for (int i = 0; i < 1000; ++i) {
+ series1 << generator1.nextMask();
+ series2 << generator2.nextMask();
+ }
+
+ QVERIFY(series1 != series2);
+ }
+ //generates two series of data with 2 distinct generators
+ //only one of the two is seeded
+ {
+ QDefaultMaskGenerator generator1, generator2;
+ generator1.seed();
+
+ QVector<quint32> series1, series2;
+ for (int i = 0; i < 1000; ++i) {
+ series1 << generator1.nextMask();
+ series2 << generator2.nextMask();
+ }
+
+ QVERIFY(series1 != series2);
+ }
+}
+
+QTEST_MAIN(tst_QDefaultMaskGenerator)
+
+#include "tst_defaultmaskgenerator.moc"