summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/network/ssl/qsslsocket.cpp26
-rw-r--r--src/network/ssl/qsslsocket_p.h1
-rw-r--r--tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp99
3 files changed, 82 insertions, 44 deletions
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 068dfb9f2d..a6c86837ea 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -460,6 +460,9 @@ void QSslSocket::connectToHostEncrypted(const QString &hostName, quint16 port, O
return;
}
+ if (!d->verifyProtocolSupported("QSslSocket::connectToHostEncrypted:"))
+ return;
+
d->init();
d->autoStartHandshake = true;
d->initialized = true;
@@ -1607,6 +1610,8 @@ bool QSslSocket::waitForEncrypted(int msecs)
return false;
if (d->mode == UnencryptedMode && !d->autoStartHandshake)
return false;
+ if (!d->verifyProtocolSupported("QSslSocket::waitForEncrypted:"))
+ return false;
QElapsedTimer stopWatch;
stopWatch.start();
@@ -1856,6 +1861,10 @@ void QSslSocket::startClientEncryption()
d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
return;
}
+
+ if (!d->verifyProtocolSupported("QSslSocket::startClientEncryption:"))
+ return;
+
#ifdef QSSLSOCKET_DEBUG
qCDebug(lcSsl) << "QSslSocket::startClientEncryption()";
#endif
@@ -1899,6 +1908,9 @@ void QSslSocket::startServerEncryption()
d->setErrorAndEmit(QAbstractSocket::SslInternalError, tr("TLS initialization failed"));
return;
}
+ if (!d->verifyProtocolSupported("QSslSocket::startServerEncryption"))
+ return;
+
d->mode = SslServerMode;
emit modeChanged(d->mode);
d->startServerEncryption();
@@ -2133,6 +2145,20 @@ void QSslSocketPrivate::init()
/*!
\internal
*/
+bool QSslSocketPrivate::verifyProtocolSupported(const char *where)
+{
+ if (configuration.protocol == QSsl::SslV2 || configuration.protocol == QSsl::SslV3) {
+ qCWarning(lcSsl) << where << "Attempted to use an unsupported protocol.";
+ setErrorAndEmit(QAbstractSocket::SslInvalidUserDataError,
+ QSslSocket::tr("Attempted to use an unsupported protocol."));
+ return false;
+ }
+ return true;
+}
+
+/*!
+ \internal
+*/
QList<QSslCipher> QSslSocketPrivate::defaultCiphers()
{
QSslSocketPrivate::ensureInitialized();
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 2f394f013b..5115613695 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -97,6 +97,7 @@ public:
virtual ~QSslSocketPrivate();
void init();
+ bool verifyProtocolSupported(const char *where);
bool initialized;
QSslSocket::SslMode mode;
diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
index 0523f2591f..184f07a48e 100644
--- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
+++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp
@@ -245,8 +245,8 @@ private slots:
void signatureAlgorithm();
#endif
- void deprecatedProtocols_data();
- void deprecatedProtocols();
+ void disabledProtocols_data();
+ void disabledProtocols();
void setEmptyDefaultConfiguration(); // this test should be last
@@ -4051,60 +4051,71 @@ void tst_QSslSocket::forwardReadChannelFinished()
#endif // QT_NO_OPENSSL
-void tst_QSslSocket::deprecatedProtocols_data()
+void tst_QSslSocket::disabledProtocols_data()
{
- QTest::addColumn<QSsl::SslProtocol>("protocol");
- QTest::addColumn<bool>("succeeds");
- QTest::newRow("SecureProtocols") << QSsl::SecureProtocols << true;
- QTest::newRow("SslV2") << QSsl::SslV2 << false;
- QTest::newRow("SslV3") << QSsl::SslV3 << false;
+ QTest::addColumn<QSsl::SslProtocol>("disabledProtocol");
+ QTest::newRow("SslV2") << QSsl::SslV2;
+ QTest::newRow("SslV3") << QSsl::SslV3;
}
-void tst_QSslSocket::deprecatedProtocols()
+void tst_QSslSocket::disabledProtocols()
{
- QFETCH_GLOBAL(bool, setProxy);
+ QFETCH_GLOBAL(const bool, setProxy);
if (setProxy)
- QSKIP("This test does not work under a proxy");
-
- QFETCH(QSsl::SslProtocol, protocol);
- QFETCH(bool, succeeds);
-
- QSslSocket socket;
- socket.setProtocol(protocol);
-
- QSignalSpy connectedSpy(&socket, &QSslSocket::connected);
- QVERIFY(connectedSpy.isValid());
-
- QSignalSpy encryptedSpy(&socket, &QSslSocket::encrypted);
- QVERIFY(encryptedSpy.isValid());
+ return;
- QSignalSpy errorSpy(&socket, QOverload<QAbstractSocket::SocketError>::of(&QSslSocket::error));
- QVERIFY(errorSpy.isValid());
+ QFETCH(const QSsl::SslProtocol, disabledProtocol);
+ const int timeoutMS = 500;
+ // Test a client socket.
+ {
+ // 0. connectToHostEncrypted: client-side, non-blocking API, error is discovered
+ // early, preventing any real connection from ever starting.
+ QSslSocket socket;
+ socket.setProtocol(disabledProtocol);
+ QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
+ socket.connectToHostEncrypted(QStringLiteral("doesnotmatter.org"), 1010);
+ QCOMPARE(socket.error(), QAbstractSocket::SslInvalidUserDataError);
+ QCOMPARE(socket.state(), QAbstractSocket::UnconnectedState);
+ }
+ {
+ // 1. startClientEncryption: client-side, non blocking API, but wants a socket in
+ // the 'connected' state (otherwise just returns false not setting any error code).
+ SslServer server;
+ QVERIFY(server.listen());
- connect(&socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
- &socket, QOverload<>::of(&QSslSocket::ignoreSslErrors));
+ QSslSocket socket;
+ QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
- SslServer server;
- QVERIFY(server.listen());
+ socket.connectToHost(server.serverAddress(), server.serverPort());
+ QVERIFY(socket.waitForConnected(timeoutMS));
- socket.connectToHost(server.serverAddress(), server.serverPort());
+ socket.setProtocol(disabledProtocol);
+ socket.startClientEncryption();
+ QCOMPARE(socket.error(), QAbstractSocket::SslInvalidUserDataError);
+ }
+ {
+ // 2. waitForEncrypted: client-side, blocking API plus requires from us
+ // to call ... connectToHostEncrypted(), which will notice an error and
+ // will prevent any connect at all. Nothing to test.
+ }
- // Can't use waitForConnected / waitForEncrypted as they wait forever,
- // so do this asynchronously via QTRY_ macros (QTBUG-72179)
- QTRY_COMPARE(connectedSpy.size(), 1);
- QCOMPARE(encryptedSpy.size(), 0);
- QCOMPARE(errorSpy.size(), 0);
+ // Test a server side, relatively simple: server does not connect, it listens/accepts
+ // and then calls startServerEncryption() (which must fall).
+ {
+ SslServer server;
+ server.protocol = disabledProtocol;
+ QVERIFY(server.listen());
- socket.startClientEncryption();
+ QTestEventLoop loop;
+ connect(&server, &SslServer::socketError, [&loop](QAbstractSocket::SocketError)
+ {loop.exitLoop();});
- if (succeeds) {
- QTRY_COMPARE(encryptedSpy.size(), 1);
- QCOMPARE(errorSpy.size(), 0);
- } else {
- // The various backends differ in the errors fired here (QTBUG-72196),
- // so just check that we did get an error (and we're not encrypted)
- QTRY_VERIFY(errorSpy.size() > 0);
- QCOMPARE(encryptedSpy.size(), 0);
+ QTcpSocket client;
+ client.connectToHost(server.serverAddress(), server.serverPort());
+ loop.enterLoopMSecs(timeoutMS);
+ QVERIFY(!loop.timeout());
+ QVERIFY(server.socket);
+ QCOMPARE(server.socket->error(), QAbstractSocket::SslInvalidUserDataError);
}
}