diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-12-03 15:40:53 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2018-12-21 03:28:47 +0000 |
commit | 3e1758e35d14e6ee16e30ae2f6f6bd92d29d57f0 (patch) | |
tree | 8bd5e17931e4088bbd7eaecb2a6785fbb98d4190 /tests | |
parent | 50d53533e5ab1923865a9f80cb8b093ab477ae81 (diff) |
QSsl: do not wait for 'connected'/'encrypted' if a protocol is disabled
since we'll refuse to continue with a handshake, failing in initSslContext()
on a disabled protocol versions. Then, functions like waitForEncrypted,
connectToHostEncrypted, startServerEncryption and startClientEncryption
should either bail out early (who needs a TCP connection which we'll
abort anyway?) or bail out whenever we can, as soon as a disabled protocol
was found in a configuration. This change also makes the behavior
of different back-ends consistent, since it's a general code-path
that reports the same SslInvalidUserData error. Update auto-test to
... actually test what it claims it tests.
Task-number: QTBUG-72196
Task-number: QTBUG-72179
Change-Id: I548468993410f10c07ce5773b78f38132be8e3e0
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 99 |
1 files changed, 55 insertions, 44 deletions
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); } } |