summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/websockets/qdefaultmaskgenerator_p.cpp18
-rw-r--r--src/websockets/qmaskgenerator.cpp2
-rw-r--r--src/websockets/qwebsocket.cpp4
-rw-r--r--tests/auto/qml/qml.pro3
-rw-r--r--tests/auto/websockets/qwebsocketserver/qwebsocketserver.pro1
-rw-r--r--tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp57
-rw-r--r--tests/auto/websockets/websockets.pro3
8 files changed, 70 insertions, 20 deletions
diff --git a/.qmake.conf b/.qmake.conf
index cf1e4e0..08b8470 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -3,4 +3,4 @@ load(qt_build_config)
CONFIG += warning_clean
DEFINES += QT_NO_FOREACH
-MODULE_VERSION = 5.9.2
+MODULE_VERSION = 5.10.0
diff --git a/src/websockets/qdefaultmaskgenerator_p.cpp b/src/websockets/qdefaultmaskgenerator_p.cpp
index 1035e8f..7dc0cee 100644
--- a/src/websockets/qdefaultmaskgenerator_p.cpp
+++ b/src/websockets/qdefaultmaskgenerator_p.cpp
@@ -48,7 +48,7 @@
malicious scripts to attack bad behaving proxies.
For more information about the importance of good masking,
see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
- The default mask generator uses the cryptographically insecure qrand() function.
+ The default mask generator uses the reasonably secure QRandomGenerator::get32() 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
@@ -58,8 +58,7 @@
*/
#include "qdefaultmaskgenerator_p.h"
-#include <QDateTime>
-#include <limits>
+#include <QRandomGenerator>
QT_BEGIN_NAMESPACE
@@ -83,25 +82,26 @@ QDefaultMaskGenerator::~QDefaultMaskGenerator()
}
/*!
- Seeds the QDefaultMaskGenerator using qsrand().
- When seed() is not called, no seed is used at all.
-
\internal
*/
bool QDefaultMaskGenerator::seed() Q_DECL_NOEXCEPT
{
- qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch()));
return true;
}
/*!
- Generates a new random mask using the insecure qrand() method.
+ Generates a new random mask using the insecure QRandomGenerator::get32() method.
\internal
*/
quint32 QDefaultMaskGenerator::nextMask() Q_DECL_NOEXCEPT
{
- return quint32((double(qrand()) / RAND_MAX) * std::numeric_limits<quint32>::max());
+ quint32 value = QRandomGenerator::get32();
+ while (Q_UNLIKELY(value == 0)) {
+ // a mask of zero has a special meaning
+ value = QRandomGenerator::get32();
+ }
+ return value;
}
QT_END_NAMESPACE
diff --git a/src/websockets/qmaskgenerator.cpp b/src/websockets/qmaskgenerator.cpp
index 064ada2..56d1223 100644
--- a/src/websockets/qmaskgenerator.cpp
+++ b/src/websockets/qmaskgenerator.cpp
@@ -50,7 +50,7 @@
malicious scripts from attacking badly behaving proxies.
For more information about the importance of good masking,
see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
- By default QWebSocket uses the cryptographically insecure qrand() function.
+ By default QWebSocket uses the reasonably secure QRandomGenerator::get32() 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
diff --git a/src/websockets/qwebsocket.cpp b/src/websockets/qwebsocket.cpp
index ba343e4..30bb39d 100644
--- a/src/websockets/qwebsocket.cpp
+++ b/src/websockets/qwebsocket.cpp
@@ -63,8 +63,8 @@
In that case, non-secure WebSocket connections fail. The best way to mitigate against
this problem is to use WebSocket over a secure connection.
- \warning To generate masks, this implementation of WebSockets uses the cryptographically
- insecure qrand() function.
+ \warning To generate masks, this implementation of WebSockets uses the reasonably
+ secure QRandomGenerator::get32() function.
For more information about the importance of good masking,
see \l {"Talking to Yourself for Fun and Profit" by Lin-Shung Huang et al}.
The best measure against attacks mentioned in the document above,
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 2d2fde4..8951c55 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -1,6 +1,3 @@
TEMPLATE = subdirs
!uikit: SUBDIRS += qmlwebsockets qmlwebsockets_compat
-
-# QTBUG-60268
-boot2qt: SUBDIRS -= qmlwebsockets_compat
diff --git a/tests/auto/websockets/qwebsocketserver/qwebsocketserver.pro b/tests/auto/websockets/qwebsocketserver/qwebsocketserver.pro
index e166f50..178fd88 100644
--- a/tests/auto/websockets/qwebsocketserver/qwebsocketserver.pro
+++ b/tests/auto/websockets/qwebsocketserver/qwebsocketserver.pro
@@ -12,3 +12,4 @@ SOURCES += tst_qwebsocketserver.cpp
RESOURCES += $$PWD/../shared/qwebsocketshared.qrc
+boot2qt: DEFINES += SHOULD_CHECK_SYSCALL_SUPPORT
diff --git a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
index 82e2013..8f3e293 100644
--- a/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
+++ b/tests/auto/websockets/qwebsocketserver/tst_qwebsocketserver.cpp
@@ -112,9 +112,15 @@ private Q_SLOTS:
void tst_serverDestroyedWhileSocketConnected();
void tst_scheme(); // qtbug-55927
void tst_handleConnection();
+
+private:
+ bool m_shouldSkipUnsupportedIpv6Test;
+#ifdef SHOULD_CHECK_SYSCALL_SUPPORT
+ bool ipv6GetsockoptionMissing(int level, int optname);
+#endif
};
-tst_QWebSocketServer::tst_QWebSocketServer()
+tst_QWebSocketServer::tst_QWebSocketServer() : m_shouldSkipUnsupportedIpv6Test(false)
{
}
@@ -132,8 +138,42 @@ void tst_QWebSocketServer::init()
#endif
}
+#ifdef SHOULD_CHECK_SYSCALL_SUPPORT
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <unistd.h>
+
+bool tst_QWebSocketServer::ipv6GetsockoptionMissing(int level, int optname)
+{
+ int testSocket;
+
+ testSocket = socket(PF_INET6, SOCK_STREAM, 0);
+
+ // If we can't test here, assume it's not missing
+ if (testSocket == -1)
+ return false;
+
+ bool result = false;
+ if (getsockopt(testSocket, level, optname, nullptr, 0) == -1) {
+ if (errno == EOPNOTSUPP) {
+ result = true;
+ }
+ }
+
+ close(testSocket);
+ return result;
+}
+
+#endif //SHOULD_CHECK_SYSCALL_SUPPORT
+
void tst_QWebSocketServer::initTestCase()
{
+#ifdef SHOULD_CHECK_SYSCALL_SUPPORT
+ // Qemu does not have required support for IPV6 socket options.
+ // If this is detected, skip the test
+ m_shouldSkipUnsupportedIpv6Test = ipv6GetsockoptionMissing(SOL_IPV6, IPV6_V6ONLY);
+#endif
}
void tst_QWebSocketServer::cleanupTestCase()
@@ -283,6 +323,9 @@ void tst_QWebSocketServer::tst_listening()
void tst_QWebSocketServer::tst_connectivity()
{
+ if (m_shouldSkipUnsupportedIpv6Test)
+ QSKIP("Syscalls needed for ipv6 sockoptions missing functionality");
+
QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
QSignalSpy serverConnectionSpy(&server, SIGNAL(newConnection()));
QSignalSpy serverErrorSpy(&server,
@@ -325,6 +368,9 @@ void tst_QWebSocketServer::tst_connectivity()
void tst_QWebSocketServer::tst_preSharedKey()
{
+ if (m_shouldSkipUnsupportedIpv6Test)
+ QSKIP("Syscalls needed for ipv6 sockoptions missing functionality");
+
#ifndef QT_NO_OPENSSL
QWebSocketServer server(QString(), QWebSocketServer::SecureMode);
@@ -403,6 +449,9 @@ void tst_QWebSocketServer::tst_preSharedKey()
void tst_QWebSocketServer::tst_maxPendingConnections()
{
+ if (m_shouldSkipUnsupportedIpv6Test)
+ QSKIP("Syscalls needed for ipv6 sockoptions missing functionality");
+
//tests if maximum connections are respected
//also checks if there are no side-effects like signals that are unexpectedly thrown
QWebSocketServer server(QString(), QWebSocketServer::NonSecureMode);
@@ -481,6 +530,9 @@ void tst_QWebSocketServer::tst_maxPendingConnections()
void tst_QWebSocketServer::tst_serverDestroyedWhileSocketConnected()
{
+ if (m_shouldSkipUnsupportedIpv6Test)
+ QSKIP("Syscalls needed for ipv6 sockoptions missing functionality");
+
QWebSocketServer * server = new QWebSocketServer(QString(), QWebSocketServer::NonSecureMode);
QSignalSpy serverConnectionSpy(server, SIGNAL(newConnection()));
QSignalSpy corsAuthenticationSpy(server,
@@ -515,6 +567,9 @@ void tst_QWebSocketServer::tst_serverDestroyedWhileSocketConnected()
void tst_QWebSocketServer::tst_scheme()
{
+ if (m_shouldSkipUnsupportedIpv6Test)
+ QSKIP("Syscalls needed for ipv6 sockoptions missing functionality");
+
QWebSocketServer plainServer(QString(), QWebSocketServer::NonSecureMode);
QSignalSpy plainServerConnectionSpy(&plainServer, SIGNAL(newConnection()));
diff --git a/tests/auto/websockets/websockets.pro b/tests/auto/websockets/websockets.pro
index 4b7ee4e..b000229 100644
--- a/tests/auto/websockets/websockets.pro
+++ b/tests/auto/websockets/websockets.pro
@@ -14,6 +14,3 @@ qtConfig(private_tests): SUBDIRS += \
SUBDIRS += \
qwebsocket \
qwebsocketserver
-
-# QTBUG-60268
-boot2qt: SUBDIRS -= qwebsocketserver