mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-02 07:15:27 +08:00
qt 6.6.0 clean
This commit is contained in:
@ -14,7 +14,7 @@ if (QT_FEATURE_private_tests)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# add_subdirectory(selftest) # special case not ported
|
||||
# add_subdirectory(selftest) # TODO: not ported
|
||||
add_subdirectory(access)
|
||||
add_subdirectory(kernel)
|
||||
add_subdirectory(ssl)
|
||||
|
@ -751,7 +751,7 @@ public:
|
||||
cache.remove(url);
|
||||
if (QRandomGenerator::global()->bounded(5) == 1)
|
||||
cache.clear();
|
||||
sleep(0);
|
||||
sleep(std::chrono::seconds{0});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8140,7 +8140,7 @@ class Qtbug25280Server : public MiniHttpServer
|
||||
public:
|
||||
Qtbug25280Server(QByteArray qba) : MiniHttpServer(qba, false) {}
|
||||
QSet<QTcpSocket*> receivedSockets;
|
||||
virtual void reply()
|
||||
void reply() override
|
||||
{
|
||||
// Save sockets in a list
|
||||
receivedSockets.insert((QTcpSocket*)sender());
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
if(NOT INTEGRITY)
|
||||
if(QT_FEATURE_dnslookup AND (QT_FEATURE_libresolv OR WIN32))
|
||||
add_subdirectory(qdnslookup)
|
||||
add_subdirectory(qdnslookup_appless)
|
||||
endif()
|
||||
|
@ -12,3 +12,8 @@ qt_internal_add_test(tst_qdnslookup
|
||||
Qt::Network
|
||||
Qt::TestPrivate
|
||||
)
|
||||
|
||||
qt_internal_extend_target(tst_qdnslookup CONDITION WIN32
|
||||
LIBRARIES
|
||||
iphlpapi
|
||||
)
|
||||
|
@ -8,7 +8,18 @@
|
||||
#include <QtTest/private/qpropertytesthelper_p.h>
|
||||
|
||||
#include <QtNetwork/QDnsLookup>
|
||||
|
||||
#include <QtCore/QRandomGenerator>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include <QtNetwork/QNetworkDatagram>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
# include <QtCore/QFile>
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <iphlpapi.h>
|
||||
#endif
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
static const int Timeout = 15000; // 15s
|
||||
@ -29,6 +40,8 @@ public slots:
|
||||
void initTestCase();
|
||||
|
||||
private slots:
|
||||
void lookupLocalhost();
|
||||
void lookupRoot();
|
||||
void lookup_data();
|
||||
void lookup();
|
||||
void lookupIdn_data() { lookup_data(); }
|
||||
@ -36,10 +49,125 @@ private slots:
|
||||
|
||||
void lookupReuse();
|
||||
void lookupAbortRetry();
|
||||
void setNameserverLoopback();
|
||||
void setNameserver_data();
|
||||
void setNameserver();
|
||||
void bindingsAndProperties();
|
||||
void automatedBindings();
|
||||
};
|
||||
|
||||
static constexpr qsizetype HeaderSize = 6 * sizeof(quint16);
|
||||
static const char preparedDnsQuery[] =
|
||||
// header
|
||||
"\x00\x00" // transaction ID, we'll replace
|
||||
"\x01\x20" // flags
|
||||
"\x00\x01" // qdcount
|
||||
"\x00\x00" // ancount
|
||||
"\x00\x00" // nscount
|
||||
"\x00\x00" // arcount
|
||||
// query:
|
||||
"\x00\x00\x06\x00\x01" // <root domain> IN SOA
|
||||
;
|
||||
|
||||
static QList<QHostAddress> systemNameservers()
|
||||
{
|
||||
QList<QHostAddress> result;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
ULONG infosize = 0;
|
||||
DWORD r = GetNetworkParams(nullptr, &infosize);
|
||||
auto buffer = std::make_unique<uchar[]>(infosize);
|
||||
auto info = new (buffer.get()) FIXED_INFO;
|
||||
r = GetNetworkParams(info, &infosize);
|
||||
if (r == NO_ERROR) {
|
||||
for (PIP_ADDR_STRING ptr = &info->DnsServerList; ptr; ptr = ptr->Next) {
|
||||
QLatin1StringView addr(ptr->IpAddress.String);
|
||||
result.emplaceBack(addr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
QFile f("/etc/resolv.conf");
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
return result;
|
||||
|
||||
while (!f.atEnd()) {
|
||||
static const char command[] = "nameserver";
|
||||
QByteArray line = f.readLine().simplified();
|
||||
if (!line.startsWith(command))
|
||||
continue;
|
||||
|
||||
QString addr = QLatin1StringView(line).mid(sizeof(command));
|
||||
result.emplaceBack(addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static QList<QHostAddress> globalPublicNameservers()
|
||||
{
|
||||
const char *const candidates[] = {
|
||||
// Google's dns.google
|
||||
"8.8.8.8", "2001:4860:4860::8888",
|
||||
//"8.8.4.4", "2001:4860:4860::8844",
|
||||
|
||||
// CloudFare's one.one.one.one
|
||||
"1.1.1.1", "2606:4700:4700::1111",
|
||||
//"1.0.0.1", "2606:4700:4700::1001",
|
||||
|
||||
// Quad9's dns9
|
||||
//"9.9.9.9", "2620:fe::9",
|
||||
};
|
||||
|
||||
QList<QHostAddress> result;
|
||||
QRandomGenerator &rng = *QRandomGenerator::system();
|
||||
for (auto name : candidates) {
|
||||
// check the candidates for reachability
|
||||
QHostAddress addr{QLatin1StringView(name)};
|
||||
quint16 id = quint16(rng());
|
||||
QByteArray data(preparedDnsQuery, sizeof(preparedDnsQuery));
|
||||
char *ptr = data.data();
|
||||
qToBigEndian(id, ptr);
|
||||
|
||||
QUdpSocket socket;
|
||||
socket.connectToHost(addr, 53);
|
||||
if (socket.waitForConnected(1))
|
||||
socket.write(data);
|
||||
|
||||
if (!socket.waitForReadyRead(1000)) {
|
||||
qDebug() << addr << "discarded:" << socket.errorString();
|
||||
continue;
|
||||
}
|
||||
|
||||
QNetworkDatagram dgram = socket.receiveDatagram();
|
||||
if (!dgram.isValid()) {
|
||||
qDebug() << addr << "discarded:" << socket.errorString();
|
||||
continue;
|
||||
}
|
||||
|
||||
data = dgram.data();
|
||||
ptr = data.data();
|
||||
if (data.size() < HeaderSize) {
|
||||
qDebug() << addr << "discarded: reply too small";
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ok = qFromBigEndian<quint16>(ptr) == id
|
||||
&& (ptr[2] & 0x80) // is a reply
|
||||
&& (ptr[3] & 0xf) == 0 // rcode NOERROR
|
||||
&& qFromBigEndian<quint16>(ptr + 4) == 1 // qdcount
|
||||
&& qFromBigEndian<quint16>(ptr + 6) >= 1; // ancount
|
||||
if (!ok) {
|
||||
qDebug() << addr << "discarded: invalid reply";
|
||||
continue;
|
||||
}
|
||||
|
||||
result.emplaceBack(std::move(addr));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::initTestCase()
|
||||
{
|
||||
if (qgetenv("QTEST_ENVIRONMENT") == "ci")
|
||||
@ -82,6 +210,39 @@ QStringList tst_QDnsLookup::domainNameListAlternatives(const QString &input)
|
||||
return alternatives;
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookupLocalhost()
|
||||
{
|
||||
QDnsLookup lookup(QDnsLookup::Type::A, u"localhost"_s);
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
QCOMPARE(lookup.error(), QDnsLookup::NoError);
|
||||
|
||||
QList<QDnsHostAddressRecord> hosts = lookup.hostAddressRecords();
|
||||
QCOMPARE(hosts.size(), 1);
|
||||
QCOMPARE(hosts.at(0).value(), QHostAddress::LocalHost);
|
||||
QVERIFY2(hosts.at(0).name().startsWith(lookup.name()),
|
||||
qPrintable(hosts.at(0).name()));
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookupRoot()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
QSKIP("This test fails on Windows as it seems to treat the lookup as a local one.");
|
||||
#else
|
||||
QDnsLookup lookup(QDnsLookup::Type::NS, u""_s);
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
QCOMPARE(lookup.error(), QDnsLookup::NoError);
|
||||
|
||||
const QList<QDnsDomainNameRecord> servers = lookup.nameServerRecords();
|
||||
QVERIFY(!servers.isEmpty());
|
||||
for (const QDnsDomainNameRecord &ns : servers) {
|
||||
QCOMPARE(ns.name(), QString());
|
||||
QVERIFY(ns.value().endsWith(".root-servers.net"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::lookup_data()
|
||||
{
|
||||
QTest::addColumn<int>("type");
|
||||
@ -95,22 +256,18 @@ void tst_QDnsLookup::lookup_data()
|
||||
QTest::addColumn<QString>("srv");
|
||||
QTest::addColumn<QString>("txt");
|
||||
|
||||
QTest::newRow("a-empty") << int(QDnsLookup::A) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << ""<< "" << "";
|
||||
QTest::newRow("a-notfound") << int(QDnsLookup::A) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("a-single") << int(QDnsLookup::A) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("a-multi") << int(QDnsLookup::A) << "a-multi" << int(QDnsLookup::NoError) << "" << "192.0.2.1;192.0.2.2;192.0.2.3" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("aaaa-empty") << int(QDnsLookup::AAAA) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("aaaa-notfound") << int(QDnsLookup::AAAA) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("aaaa-single") << int(QDnsLookup::AAAA) << "aaaa-single" << int(QDnsLookup::NoError) << "" << "2001:db8::1" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("aaaa-multi") << int(QDnsLookup::AAAA) << "aaaa-multi" << int(QDnsLookup::NoError) << "" << "2001:db8::1;2001:db8::2;2001:db8::3" << "" << "" << "" << "" << "";
|
||||
|
||||
QTest::newRow("any-empty") << int(QDnsLookup::ANY) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("any-notfound") << int(QDnsLookup::ANY) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("any-a-single") << int(QDnsLookup::ANY) << "a-single" << int(QDnsLookup::NoError) << "" << "192.0.2.1" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("any-a-plus-aaaa") << int(QDnsLookup::ANY) << "a-plus-aaaa" << int(QDnsLookup::NoError) << "" << "198.51.100.1;2001:db8::1:1" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("any-multi") << int(QDnsLookup::ANY) << "multi" << int(QDnsLookup::NoError) << "" << "198.51.100.1;198.51.100.2;198.51.100.3;2001:db8::1:1;2001:db8::1:2" << "" << "" << "" << "" << "";
|
||||
|
||||
QTest::newRow("mx-empty") << int(QDnsLookup::MX) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("mx-notfound") << int(QDnsLookup::MX) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("mx-single") << int(QDnsLookup::MX) << "mx-single" << int(QDnsLookup::NoError) << "" << "" << "10 multi" << "" << "" << "" << "";
|
||||
QTest::newRow("mx-single-cname") << int(QDnsLookup::MX) << "mx-single-cname" << int(QDnsLookup::NoError) << "" << "" << "10 cname" << "" << "" << "" << "";
|
||||
@ -119,12 +276,10 @@ void tst_QDnsLookup::lookup_data()
|
||||
<< "10 multi;10 a-single|"
|
||||
"10 a-single;10 multi" << "" << "" << "" << "";
|
||||
|
||||
QTest::newRow("ns-empty") << int(QDnsLookup::NS) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("ns-notfound") << int(QDnsLookup::NS) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("ns-single") << int(QDnsLookup::NS) << "ns-single" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net." << "" << "" << "";
|
||||
QTest::newRow("ns-multi") << int(QDnsLookup::NS) << "ns-multi" << int(QDnsLookup::NoError) << "" << "" << "" << "ns11.cloudns.net.;ns12.cloudns.net." << "" << "" << "";
|
||||
|
||||
QTest::newRow("ptr-empty") << int(QDnsLookup::PTR) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("ptr-notfound") << int(QDnsLookup::PTR) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
#if 0
|
||||
// temporarily disabled since the new hosting provider can't insert
|
||||
@ -132,7 +287,6 @@ void tst_QDnsLookup::lookup_data()
|
||||
QTest::newRow("ptr-single") << int(QDnsLookup::PTR) << "ptr-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "a-single" << "" << "";
|
||||
#endif
|
||||
|
||||
QTest::newRow("srv-empty") << int(QDnsLookup::SRV) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("srv-notfound") << int(QDnsLookup::SRV) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("srv-single") << int(QDnsLookup::SRV) << "_echo._tcp.srv-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "5 0 7 multi" << "";
|
||||
QTest::newRow("srv-prio") << int(QDnsLookup::SRV) << "_echo._tcp.srv-prio" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "1 0 7 multi;2 0 7 a-plus-aaaa" << "";
|
||||
@ -143,7 +297,6 @@ void tst_QDnsLookup::lookup_data()
|
||||
<< "1 50 7 multi;2 50 7 a-single;2 50 7 aaaa-single;3 50 7 a-multi|"
|
||||
"1 50 7 multi;2 50 7 aaaa-single;2 50 7 a-single;3 50 7 a-multi" << "";
|
||||
|
||||
QTest::newRow("txt-empty") << int(QDnsLookup::TXT) << "" << int(QDnsLookup::InvalidRequestError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("txt-notfound") << int(QDnsLookup::TXT) << "invalid.invalid" << int(QDnsLookup::NotFoundError) << "" << "" << "" << "" << "" << "" << "";
|
||||
QTest::newRow("txt-single") << int(QDnsLookup::TXT) << "txt-single" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << "" << "Hello";
|
||||
QTest::newRow("txt-multi-onerr") << int(QDnsLookup::TXT) << "txt-multi-onerr" << int(QDnsLookup::NoError) << "" << "" << "" << "" << "" << ""
|
||||
@ -181,11 +334,6 @@ void tst_QDnsLookup::lookup()
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
if (lookup.errorString() == QStringLiteral("Not yet supported on Android"))
|
||||
QEXPECT_FAIL("", "Not yet supported on Android", Abort);
|
||||
#endif
|
||||
|
||||
auto extraErrorMsg = [&] () {
|
||||
QString result;
|
||||
QTextStream str(&result);
|
||||
@ -209,7 +357,8 @@ void tst_QDnsLookup::lookup()
|
||||
};
|
||||
|
||||
if (!dnsServersMustWork && (lookup.error() == QDnsLookup::ServerFailureError
|
||||
|| lookup.error() == QDnsLookup::ServerRefusedError)) {
|
||||
|| lookup.error() == QDnsLookup::ServerRefusedError
|
||||
|| lookup.error() == QDnsLookup::TimeoutError)) {
|
||||
// It's not a QDnsLookup problem if the server refuses to answer the query.
|
||||
// This happens for queries of type ANY through Dnsmasq, for example.
|
||||
qWarning("Server refused or was unable to answer query; %s", extraErrorMsg().constData());
|
||||
@ -217,7 +366,6 @@ void tst_QDnsLookup::lookup()
|
||||
}
|
||||
|
||||
QVERIFY2(int(lookup.error()) == error, extraErrorMsg());
|
||||
|
||||
if (error == QDnsLookup::NoError)
|
||||
QVERIFY(lookup.errorString().isEmpty());
|
||||
QCOMPARE(int(lookup.type()), type);
|
||||
@ -317,11 +465,6 @@ void tst_QDnsLookup::lookupReuse()
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
if (lookup.errorString() == QStringLiteral("Not yet supported on Android"))
|
||||
QEXPECT_FAIL("", "Not yet supported on Android", Abort);
|
||||
#endif
|
||||
|
||||
QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError));
|
||||
QVERIFY(!lookup.hostAddressRecords().isEmpty());
|
||||
QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("a-single"));
|
||||
@ -358,17 +501,98 @@ void tst_QDnsLookup::lookupAbortRetry()
|
||||
lookup.lookup();
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
if (lookup.errorString() == QStringLiteral("Not yet supported on Android"))
|
||||
QEXPECT_FAIL("", "Not yet supported on Android", Abort);
|
||||
#endif
|
||||
|
||||
QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError));
|
||||
QVERIFY(!lookup.hostAddressRecords().isEmpty());
|
||||
QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("aaaa-single"));
|
||||
QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("2001:db8::1"));
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::setNameserverLoopback()
|
||||
{
|
||||
#ifdef Q_OS_WIN
|
||||
// Windows doesn't like sending DNS requests to ports other than 53, so
|
||||
// let's try it first.
|
||||
constexpr quint16 DesiredPort = 53;
|
||||
#else
|
||||
// Trying to bind to port 53 will fail on Unix systems unless this test is
|
||||
// run as root, so we try mDNS's port (to help decoding in a packet capture).
|
||||
constexpr quint16 DesiredPort = 5353; // mDNS
|
||||
#endif
|
||||
// random loopback address so multiple copies of this test can run
|
||||
QHostAddress desiredAddress(0x7f000000 | QRandomGenerator::system()->bounded(0xffffff));
|
||||
|
||||
QUdpSocket server;
|
||||
if (!server.bind(desiredAddress, DesiredPort)) {
|
||||
// port in use, try a random one
|
||||
server.bind(QHostAddress::LocalHost, 0);
|
||||
}
|
||||
QCOMPARE(server.state(), QUdpSocket::BoundState);
|
||||
|
||||
QDnsLookup lookup(QDnsLookup::Type::A, u"somelabel.somedomain"_s);
|
||||
QSignalSpy spy(&lookup, SIGNAL(finished()));
|
||||
lookup.setNameserver(server.localAddress(), server.localPort());
|
||||
|
||||
// QDnsLookup is threaded, so we can answer on the main thread
|
||||
QObject::connect(&server, &QUdpSocket::readyRead,
|
||||
&QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
|
||||
QObject::connect(&lookup, &QDnsLookup::finished,
|
||||
&QTestEventLoop::instance(), &QTestEventLoop::exitLoop);
|
||||
lookup.lookup();
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
QVERIFY2(spy.isEmpty(), qPrintable(lookup.errorString()));
|
||||
|
||||
QNetworkDatagram dgram = server.receiveDatagram();
|
||||
QByteArray data = dgram.data();
|
||||
QCOMPARE_GT(data.size(), HeaderSize);
|
||||
|
||||
quint8 opcode = (quint8(data.at(2)) >> 3) & 0xF;
|
||||
QCOMPARE(opcode, 0); // standard query
|
||||
|
||||
// send an NXDOMAIN reply to release the lookup thread
|
||||
QByteArray reply = data;
|
||||
reply[2] = 0x80; // header->qr = true;
|
||||
reply[3] = 3; // header->rcode = NXDOMAIN;
|
||||
server.writeDatagram(dgram.makeReply(reply));
|
||||
server.close();
|
||||
|
||||
// now check that the QDnsLookup finished
|
||||
QTestEventLoop::instance().enterLoop(5);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
QCOMPARE(spy.size(), 1);
|
||||
QCOMPARE(lookup.error(), QDnsLookup::NotFoundError);
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::setNameserver_data()
|
||||
{
|
||||
static QList<QHostAddress> servers = systemNameservers() + globalPublicNameservers();
|
||||
QTest::addColumn<QHostAddress>("server");
|
||||
|
||||
if (servers.isEmpty()) {
|
||||
QSKIP("No reachable DNS servers were found");
|
||||
} else {
|
||||
for (const QHostAddress &h : std::as_const(servers))
|
||||
QTest::addRow("%s", qUtf8Printable(h.toString())) << h;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::setNameserver()
|
||||
{
|
||||
QFETCH(QHostAddress, server);
|
||||
QDnsLookup lookup;
|
||||
lookup.setNameserver(server);
|
||||
|
||||
lookup.setType(QDnsLookup::Type::A);
|
||||
lookup.setName(domainName("a-single"));
|
||||
lookup.lookup();
|
||||
|
||||
QTRY_VERIFY_WITH_TIMEOUT(lookup.isFinished(), Timeout);
|
||||
QCOMPARE(int(lookup.error()), int(QDnsLookup::NoError));
|
||||
QVERIFY(!lookup.hostAddressRecords().isEmpty());
|
||||
QCOMPARE(lookup.hostAddressRecords().first().name(), domainName("a-single"));
|
||||
QCOMPARE(lookup.hostAddressRecords().first().value(), QHostAddress("192.0.2.1"));
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::bindingsAndProperties()
|
||||
{
|
||||
QDnsLookup lookup;
|
||||
@ -401,14 +625,23 @@ void tst_QDnsLookup::bindingsAndProperties()
|
||||
QProperty<QHostAddress> nameserverProp;
|
||||
lookup.bindableNameserver().setBinding(Qt::makePropertyBinding(nameserverProp));
|
||||
const QSignalSpy nameserverChangeSpy(&lookup, &QDnsLookup::nameserverChanged);
|
||||
const QSignalSpy nameserverPortChangeSpy(&lookup, &QDnsLookup::nameserverPortChanged);
|
||||
|
||||
nameserverProp = QHostAddress::LocalHost;
|
||||
QCOMPARE(nameserverChangeSpy.size(), 1);
|
||||
QCOMPARE(nameserverPortChangeSpy.size(), 0);
|
||||
QCOMPARE(lookup.nameserver(), QHostAddress::LocalHost);
|
||||
|
||||
nameserverProp.setBinding(lookup.bindableNameserver().makeBinding());
|
||||
lookup.setNameserver(QHostAddress::Any);
|
||||
QCOMPARE(nameserverProp.value(), QHostAddress::Any);
|
||||
QCOMPARE(nameserverChangeSpy.size(), 2);
|
||||
QCOMPARE(nameserverPortChangeSpy.size(), 0);
|
||||
|
||||
lookup.setNameserver(QHostAddress::LocalHostIPv6, 10053);
|
||||
QCOMPARE(nameserverProp.value(), QHostAddress::LocalHostIPv6);
|
||||
QCOMPARE(nameserverChangeSpy.size(), 3);
|
||||
QCOMPARE(nameserverPortChangeSpy.size(), 1);
|
||||
}
|
||||
|
||||
void tst_QDnsLookup::automatedBindings()
|
||||
@ -434,6 +667,13 @@ void tst_QDnsLookup::automatedBindings()
|
||||
qDebug("Failed property test for QDnsLookup::nameserver");
|
||||
return;
|
||||
}
|
||||
|
||||
QTestPrivate::testReadWritePropertyBasics(lookup, quint16(123), quint16(456),
|
||||
"nameserverPort");
|
||||
if (QTest::currentTestFailed()) {
|
||||
qDebug("Failed property test for QDnsLookup::nameserverPort");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QDnsLookup)
|
||||
|
@ -703,6 +703,7 @@ void tst_QHostAddress::classification()
|
||||
bool isUniqueLocalAddress = (result == UniqueLocalAddress);
|
||||
bool isMulticast = (result == MulticastAddress);
|
||||
bool isBroadcast = (result == BroadcastAddress);
|
||||
bool isPrivateUse = (result == PrivateNetworkAddress || result == UniqueLocalAddress);
|
||||
|
||||
QCOMPARE(address.isLoopback(), isLoopback);
|
||||
QCOMPARE(address.isGlobal(), isGlobal);
|
||||
@ -711,6 +712,7 @@ void tst_QHostAddress::classification()
|
||||
QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress);
|
||||
QCOMPARE(address.isMulticast(), isMulticast);
|
||||
QCOMPARE(address.isBroadcast(), isBroadcast);
|
||||
QCOMPARE(address.isPrivateUse(), isPrivateUse);
|
||||
}
|
||||
|
||||
void tst_QHostAddress::convertv4v6_data()
|
||||
|
@ -502,6 +502,7 @@ protected:
|
||||
inline void run() override
|
||||
{
|
||||
QHostInfo info = QHostInfo::fromName("a-single" TEST_DOMAIN);
|
||||
QCOMPARE(info.errorString(), "Unknown error"); // no error
|
||||
QCOMPARE(info.error(), QHostInfo::NoError);
|
||||
QVERIFY(info.addresses().size() > 0);
|
||||
QCOMPARE(info.addresses().at(0).toString(), QString("192.0.2.1"));
|
||||
|
@ -9,6 +9,6 @@ qt_internal_add_test(tst_qnetworkinterface
|
||||
SOURCES
|
||||
tst_qnetworkinterface.cpp
|
||||
LIBRARIES
|
||||
Qt::Network
|
||||
Qt::NetworkPrivate
|
||||
QT_TEST_SERVER_LIST "apache2"
|
||||
)
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include <qudpsocket.h>
|
||||
#include "../../../network-settings.h"
|
||||
|
||||
#include <private/qtnetwork-config_p.h>
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress)
|
||||
|
||||
class tst_QNetworkInterface : public QObject
|
||||
@ -49,14 +51,13 @@ tst_QNetworkInterface::~tst_QNetworkInterface()
|
||||
|
||||
bool tst_QNetworkInterface::isIPv6Working()
|
||||
{
|
||||
// Version without following cannot get IPV6 information
|
||||
#if !defined(QT_NO_GETIFADDRS) && !defined(QT_NO_IPV6IFNAME)
|
||||
QUdpSocket socket;
|
||||
socket.connectToHost(QHostAddress::LocalHostIPv6, 1234);
|
||||
return socket.state() == QAbstractSocket::ConnectedState || socket.waitForConnected(100);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
// QNetworkInterface may be unable to detect IPv6 addresses even if they
|
||||
// are there, due to limitations of the implementation.
|
||||
if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows ||
|
||||
QT_CONFIG(linux_netlink) || (QT_CONFIG(getifaddrs) && QT_CONFIG(ipv6ifname))) {
|
||||
return QtNetworkSettings::hasIPv6();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void tst_QNetworkInterface::initTestCase()
|
||||
|
@ -1,7 +1,6 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
# add_subdirectory(test) # special case remove
|
||||
add_subdirectory(socketprocess)
|
||||
qt_internal_add_test(tst_qlocalsocket
|
||||
SOURCES
|
||||
|
@ -459,7 +459,7 @@ public:
|
||||
protected:
|
||||
void run() override
|
||||
{
|
||||
sleep(2);
|
||||
sleep(std::chrono::seconds{2});
|
||||
|
||||
QTcpSocket socket;
|
||||
socket.connectToHost(host, port);
|
||||
|
@ -562,7 +562,7 @@ void tst_QTcpSocket::bind()
|
||||
|
||||
std::unique_ptr<QTcpSocket> socket(newSocket());
|
||||
quint16 boundPort;
|
||||
qintptr fd;
|
||||
qintptr fd = 0;
|
||||
|
||||
if (successExpected) {
|
||||
bool randomPort = port == -1;
|
||||
|
@ -121,6 +121,7 @@ private:
|
||||
QList<QHostAddress> allAddresses;
|
||||
QHostAddress multicastGroup4, multicastGroup6;
|
||||
QList<QHostAddress> linklocalMulticastGroups;
|
||||
QNetworkInterface ifaceWithIPv6;
|
||||
QUdpSocket *m_asyncSender;
|
||||
QUdpSocket *m_asyncReceiver;
|
||||
};
|
||||
@ -171,26 +172,7 @@ QNetworkInterface tst_QUdpSocket::interfaceForGroup(const QHostAddress &multicas
|
||||
if (!scope.isEmpty())
|
||||
return QNetworkInterface::interfaceFromName(scope);
|
||||
|
||||
static QNetworkInterface ipv6if = [&]() {
|
||||
// find any link local address in the allAddress list
|
||||
for (const QHostAddress &addr: std::as_const(allAddresses)) {
|
||||
if (addr.isLoopback())
|
||||
continue;
|
||||
|
||||
QString scope = addr.scopeId();
|
||||
if (!scope.isEmpty()) {
|
||||
QNetworkInterface iface = QNetworkInterface::interfaceFromName(scope);
|
||||
qDebug() << "Will bind IPv6 sockets to" << iface;
|
||||
return iface;
|
||||
}
|
||||
}
|
||||
|
||||
qWarning("interfaceForGroup(%s) could not find any link-local IPv6 address! "
|
||||
"Make sure this test is behind a check of QtNetworkSettings::hasIPv6().",
|
||||
qUtf8Printable(multicastGroup.toString()));
|
||||
return QNetworkInterface();
|
||||
}();
|
||||
return ipv6if;
|
||||
return ifaceWithIPv6;
|
||||
}
|
||||
|
||||
bool tst_QUdpSocket::shouldWorkaroundLinuxKernelBug()
|
||||
@ -275,9 +257,16 @@ void tst_QUdpSocket::initTestCase()
|
||||
continue;
|
||||
llbase.setScopeId(scope);
|
||||
linklocalMulticastGroups << llbase;
|
||||
if (!ifaceWithIPv6.isValid()) {
|
||||
// Remember the first interface we've found that has IPv6 so we can
|
||||
// bind non-link-local sockets to it (the first is least likely to
|
||||
// be some weird virtual interface).
|
||||
ifaceWithIPv6 = QNetworkInterface::interfaceFromName(scope);
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Will use multicast groups" << multicastGroup4 << multicastGroup6 << linklocalMulticastGroups;
|
||||
qDebug() << "Will bind IPv6 sockets to" << ifaceWithIPv6;
|
||||
|
||||
m_workaroundLinuxKernelBug = shouldWorkaroundLinuxKernelBug();
|
||||
if (QTestPrivate::isRunningArmOnX86())
|
||||
|
@ -26,6 +26,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace
|
||||
@ -127,8 +129,8 @@ private:
|
||||
DtlsPtr clientCrypto;
|
||||
|
||||
QTestEventLoop testLoop;
|
||||
const int handshakeTimeoutMS = 5000;
|
||||
const int dataExchangeTimeoutMS = 1000;
|
||||
static constexpr auto HandshakeTimeout = 5s;
|
||||
static constexpr auto DataExchangeTimeout = 1s;
|
||||
|
||||
const QByteArray presharedKey = "DEADBEEFDEADBEEF";
|
||||
QString certDirPath;
|
||||
@ -413,7 +415,7 @@ void tst_QDtls::handshake()
|
||||
QDTLS_VERIFY_NO_ERROR(clientCrypto);
|
||||
QCOMPARE(clientCrypto->handshakeState(), QDtls::HandshakeInProgress);
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
@ -473,7 +475,7 @@ void tst_QDtls::handshakeWithRetransmission()
|
||||
// client will re-transmit in 1s., the first part of 'ServerHello' to be
|
||||
// dropped, the client then will re-transmit after another 2 s. Thus it's ~3.
|
||||
// We err on safe side and double our (already quite generous) 5s.
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS * 2);
|
||||
testLoop.enterLoop(HandshakeTimeout * 2);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
|
||||
@ -496,7 +498,7 @@ void tst_QDtls::sessionCipher()
|
||||
QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, hostName));
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
|
||||
@ -559,7 +561,7 @@ void tst_QDtls::cipherPreferences()
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
QDTLS_VERIFY_NO_ERROR(clientCrypto);
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
|
||||
@ -634,7 +636,7 @@ void tst_QDtls::protocolVersionMatching()
|
||||
QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
if (works) {
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(serverCrypto);
|
||||
@ -669,7 +671,7 @@ void tst_QDtls::verificationErrors()
|
||||
// Now we are ready for handshake:
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QDTLS_VERIFY_NO_ERROR(serverCrypto);
|
||||
@ -739,7 +741,7 @@ void tst_QDtls::presetExpectedErrors()
|
||||
QVERIFY(clientCrypto->setPeer(serverAddress, serverPort));
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
@ -826,7 +828,7 @@ void tst_QDtls::verifyServerCertificate()
|
||||
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
if (serverKey.isNull() && !serverCerts.isEmpty()) {
|
||||
@ -956,7 +958,7 @@ void tst_QDtls::verifyClientCertificate()
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
QDTLS_VERIFY_NO_ERROR(clientCrypto);
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
serverConfig = serverCrypto->dtlsConfiguration();
|
||||
|
||||
@ -1003,7 +1005,7 @@ void tst_QDtls::blacklistedCerificate()
|
||||
QVERIFY(clientCrypto->setPeer(serverAddress, serverPort, name));
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QCOMPARE(clientCrypto->handshakeState(), QDtls::PeerVerificationFailed);
|
||||
QCOMPARE(clientCrypto->dtlsError(), QDtlsError::PeerVerificationError);
|
||||
@ -1055,7 +1057,7 @@ void tst_QDtls::readWriteEncrypted()
|
||||
QCOMPARE(clientCrypto->dtlsError(), QDtlsError::InvalidOperation);
|
||||
|
||||
// 1.2 Finish the handshake:
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
|
||||
@ -1073,7 +1075,7 @@ void tst_QDtls::readWriteEncrypted()
|
||||
QVERIFY(clientBytesWritten > 0);
|
||||
|
||||
// 5. Exchange client/server messages:
|
||||
testLoop.enterLoopMSecs(dataExchangeTimeoutMS);
|
||||
testLoop.enterLoop(DataExchangeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
QCOMPARE(serverExpectedPlainText, serverReceivedPlainText);
|
||||
@ -1091,7 +1093,7 @@ void tst_QDtls::readWriteEncrypted()
|
||||
QCOMPARE(crypto->handshakeState(), QDtls::HandshakeNotStarted);
|
||||
QVERIFY(!crypto->isConnectionEncrypted());
|
||||
// 8. Receive this read notification and handle it:
|
||||
testLoop.enterLoopMSecs(dataExchangeTimeoutMS);
|
||||
testLoop.enterLoop(DataExchangeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
DtlsPtr &peerCrypto = serverSideShutdown ? clientCrypto : serverCrypto;
|
||||
@ -1116,7 +1118,7 @@ void tst_QDtls::datagramFragmentation()
|
||||
|
||||
QVERIFY(clientCrypto->doHandshake(&clientSocket));
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
|
||||
QDTLS_VERIFY_HANDSHAKE_SUCCESS(clientCrypto);
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#define STOP_ON_FAILURE \
|
||||
@ -76,7 +78,7 @@ private:
|
||||
quint16 serverPort = 0;
|
||||
|
||||
QTestEventLoop testLoop;
|
||||
int handshakeTimeoutMS = 500;
|
||||
static constexpr auto HandshakeTimeout = 500ms;
|
||||
|
||||
QDtlsClientVerifier listener;
|
||||
using HandshakePtr = QSharedPointer<QDtls>;
|
||||
@ -327,7 +329,7 @@ void tst_QDtlsCookie::verifyMultipleClients()
|
||||
|
||||
clientsToAdd = clientsToWait = 100;
|
||||
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS * clientsToWait);
|
||||
testLoop.enterLoop(HandshakeTimeout * clientsToWait);
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QVERIFY(clientsToWait == 0);
|
||||
}
|
||||
@ -351,7 +353,7 @@ void tst_QDtlsCookie::receiveMessage(QUdpSocket *socket, QByteArray *message,
|
||||
Q_ASSERT(socket && message);
|
||||
|
||||
if (socket->pendingDatagramSize() <= 0)
|
||||
testLoop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
testLoop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!testLoop.timeout());
|
||||
QVERIFY(socket->pendingDatagramSize());
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
// NOTE: the word 'subject' in the code below means the subject of a status request,
|
||||
// so in general it's our peer's certificate we are asking about.
|
||||
|
||||
@ -386,7 +388,7 @@ private:
|
||||
void (QSslSocket::*tlsErrorsSignal)(const QList<QSslError> &) = &QSslSocket::sslErrors;
|
||||
void (QTestEventLoop::*exitLoopSlot)() = &QTestEventLoop::exitLoop;
|
||||
|
||||
const int handshakeTimeoutMS = 500;
|
||||
static constexpr auto HandshakeTimeout = 500ms;
|
||||
QTestEventLoop loop;
|
||||
|
||||
std::vector<QSslError::SslError> ocspErrorCodes = {QSslError::OcspNoResponseFound,
|
||||
@ -462,7 +464,7 @@ void tst_QOcsp::connectSelfSigned()
|
||||
auto roots = clientConfig.caCertificates();
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QCOMPARE_SINGLE_ERROR(clientSocket, expectedError);
|
||||
@ -478,7 +480,7 @@ void tst_QOcsp::connectSelfSigned()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket);
|
||||
|
||||
@ -543,7 +545,7 @@ void tst_QOcsp::badStatus()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QCOMPARE_SINGLE_ERROR(clientSocket, expectedError.error());
|
||||
@ -574,7 +576,7 @@ void tst_QOcsp::multipleSingleResponses()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(responderChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QCOMPARE_SINGLE_ERROR(clientSocket, expectedError);
|
||||
@ -594,7 +596,7 @@ void tst_QOcsp::malformedResponse()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(serverChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QCOMPARE(clientSocket.error(), QAbstractSocket::SslHandshakeFailedError);
|
||||
@ -633,7 +635,7 @@ void tst_QOcsp::expiredResponse()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QCOMPARE_SINGLE_ERROR(clientSocket, expectedError);
|
||||
@ -664,7 +666,7 @@ void tst_QOcsp::noNextUpdate()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY_HANDSHAKE_WITHOUT_ERRORS(clientSocket);
|
||||
}
|
||||
@ -710,7 +712,7 @@ void tst_QOcsp::wrongCertificateInResponse()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, issuerToChain(subjectChain), server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QVERIFY(containsError(clientSocket.sslHandshakeErrors(), expectedError));
|
||||
@ -735,7 +737,7 @@ void tst_QOcsp::untrustedResponder()
|
||||
QSslSocket clientSocket;
|
||||
setupOcspClient(clientSocket, {}, server.peerVerifyName());
|
||||
clientSocket.connectToHostEncrypted(server.hostName(), server.serverPort());
|
||||
loop.enterLoopMSecs(handshakeTimeoutMS);
|
||||
loop.enterLoop(HandshakeTimeout);
|
||||
|
||||
QVERIFY(!clientSocket.isEncrypted());
|
||||
QVERIFY(containsError(clientSocket.sslHandshakeErrors(), expectedError));
|
||||
|
@ -102,7 +102,31 @@ private slots:
|
||||
#endif // QT_CONFIG(ssl)
|
||||
private:
|
||||
QString testDataDir;
|
||||
bool isNonOpenSslTls = false;
|
||||
|
||||
enum class TLSBackend {
|
||||
OpenSSL,
|
||||
Schannel,
|
||||
SecureTransport,
|
||||
CertOnly,
|
||||
Unknown,
|
||||
};
|
||||
static TLSBackend currentBackend()
|
||||
{
|
||||
static TLSBackend activeBackend = []() {
|
||||
using namespace Qt::StringLiterals;
|
||||
const QString active = QSslSocket::activeBackend();
|
||||
if (active == "openssl"_L1)
|
||||
return TLSBackend::OpenSSL;
|
||||
if (active == "schannel")
|
||||
return TLSBackend::Schannel;
|
||||
if (active == "securetransport")
|
||||
return TLSBackend::SecureTransport;
|
||||
if (active == "cert-only")
|
||||
return TLSBackend::CertOnly;
|
||||
return TLSBackend::Unknown;
|
||||
}();
|
||||
return activeBackend;
|
||||
}
|
||||
};
|
||||
|
||||
void tst_QSslCertificate::initTestCase()
|
||||
@ -113,8 +137,6 @@ void tst_QSslCertificate::initTestCase()
|
||||
if (!testDataDir.endsWith(QLatin1String("/")))
|
||||
testDataDir += QLatin1String("/");
|
||||
|
||||
isNonOpenSslTls = QSslSocket::activeBackend() != QStringLiteral("openssl");
|
||||
|
||||
QDir dir(testDataDir + "certificates");
|
||||
const QFileInfoList fileInfoList = dir.entryInfoList(QDir::Files | QDir::Readable);
|
||||
QRegularExpression rxCert(QLatin1String("^.+\\.(pem|der)$"));
|
||||
@ -451,7 +473,7 @@ void tst_QSslCertificate::subjectInfoToString()
|
||||
QVERIFY(testInfo(QSslCertificate::DistinguishedNameQualifier, QString()));
|
||||
QVERIFY(testInfo(QSslCertificate::SerialNumber, QString()));
|
||||
// TODO: check why generic code does not handle this!
|
||||
if (!isNonOpenSslTls)
|
||||
if (currentBackend() == TLSBackend::OpenSSL)
|
||||
QVERIFY(testInfo(QSslCertificate::EmailAddress, QStringLiteral("ababic@trolltech.com")));
|
||||
}
|
||||
|
||||
@ -463,9 +485,8 @@ void tst_QSslCertificate::subjectIssuerDisplayName_data()
|
||||
QTest::addRow("CommonName") << QStringLiteral("more-certificates/cert-cn.pem") << QStringLiteral("YOUR name");
|
||||
QTest::addRow("OrganizationName") << QStringLiteral("more-certificates/cert-on.pem") << QStringLiteral("R&D");
|
||||
QTest::addRow("OrganizationUnitName") << QStringLiteral("more-certificates/cert-oun.pem") << QStringLiteral("Foundations");
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QTest::addRow("NoSubjectName") << QStringLiteral("more-certificates/cert-noname.pem") << QString();
|
||||
#endif
|
||||
if (currentBackend() == TLSBackend::OpenSSL)
|
||||
QTest::addRow("NoSubjectName") << QStringLiteral("more-certificates/cert-noname.pem") << QString();
|
||||
}
|
||||
|
||||
void tst_QSslCertificate::subjectIssuerDisplayName()
|
||||
@ -875,7 +896,7 @@ void tst_QSslCertificate::task256066toPem()
|
||||
|
||||
void tst_QSslCertificate::nulInCN()
|
||||
{
|
||||
if (isNonOpenSslTls)
|
||||
if (currentBackend() != TLSBackend::OpenSSL)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
|
||||
QList<QSslCertificate> certList =
|
||||
@ -895,7 +916,7 @@ void tst_QSslCertificate::nulInCN()
|
||||
void tst_QSslCertificate::nulInSan()
|
||||
{
|
||||
|
||||
if (isNonOpenSslTls)
|
||||
if (currentBackend() != TLSBackend::OpenSSL)
|
||||
QSKIP("Generic QSslCertificatePrivate fails this test");
|
||||
|
||||
QList<QSslCertificate> certList =
|
||||
@ -962,7 +983,7 @@ void tst_QSslCertificate::selfsignedCertificates()
|
||||
|
||||
void tst_QSslCertificate::toText()
|
||||
{
|
||||
if (isNonOpenSslTls)
|
||||
if (currentBackend() != TLSBackend::OpenSSL)
|
||||
QSKIP("QSslCertificate::toText is not implemented on platforms which do not use openssl");
|
||||
|
||||
QList<QSslCertificate> certList =
|
||||
@ -1012,7 +1033,7 @@ void tst_QSslCertificate::subjectAndIssuerAttributes()
|
||||
|
||||
QByteArray shortName("1.3.6.1.4.1.311.60.2.1.3");
|
||||
#if !defined(QT_NO_OPENSSL) && defined(SN_jurisdictionCountryName)
|
||||
if (!isNonOpenSslTls)
|
||||
if (currentBackend() == TLSBackend::OpenSSL)
|
||||
shortName = SN_jurisdictionCountryName;
|
||||
#endif
|
||||
attributes = certList[0].subjectInfoAttributes();
|
||||
@ -1021,8 +1042,8 @@ void tst_QSslCertificate::subjectAndIssuerAttributes()
|
||||
|
||||
void tst_QSslCertificate::verify()
|
||||
{
|
||||
if (isNonOpenSslTls)
|
||||
QSKIP("Not implemented in SecureTransport or Schannel");
|
||||
if (currentBackend() != TLSBackend::OpenSSL)
|
||||
QSKIP("Only implemented for OpenSSL");
|
||||
|
||||
QList<QSslError> errors;
|
||||
QList<QSslCertificate> toVerify;
|
||||
@ -1363,9 +1384,8 @@ void tst_QSslCertificate::pkcs12()
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_OPENSSL) && OPENSSL_VERSION_MAJOR >= 3
|
||||
QSKIP("leaf.p12 is using RC2, which is disabled by default in OpenSSL v >= 3");
|
||||
#endif
|
||||
if (currentBackend() == TLSBackend::OpenSSL && QSslSocket::sslLibraryVersionNumber() >= 0x30000000L)
|
||||
QSKIP("leaf.p12 is using RC2, which is disabled by default in OpenSSL v >= 3");
|
||||
|
||||
QFile f(testDataDir + QLatin1String("pkcs12/leaf.p12"));
|
||||
bool ok = f.open(QIODevice::ReadOnly);
|
||||
@ -1375,8 +1395,8 @@ void tst_QSslCertificate::pkcs12()
|
||||
QSslCertificate cert;
|
||||
QList<QSslCertificate> caCerts;
|
||||
|
||||
if (isNonOpenSslTls)
|
||||
QEXPECT_FAIL("", "pkcs12 imports are only supported when openssl is used", Abort); // TODO?
|
||||
if (currentBackend() != TLSBackend::OpenSSL)
|
||||
QEXPECT_FAIL("", "pkcs12 imports are not available with the current TLS backend", Abort); // TODO?
|
||||
|
||||
ok = QSslCertificate::importPkcs12(&f, &key, &cert, &caCerts);
|
||||
QVERIFY(ok);
|
||||
@ -1408,7 +1428,8 @@ void tst_QSslCertificate::pkcs12()
|
||||
QFile nocert(testDataDir + QLatin1String("pkcs12/leaf-nokey.p12"));
|
||||
ok = nocert.open(QIODevice::ReadOnly);
|
||||
QVERIFY(ok);
|
||||
QTest::ignoreMessage(QtWarningMsg, "Unable to convert private key");
|
||||
if (currentBackend() == TLSBackend::OpenSSL)
|
||||
QTest::ignoreMessage(QtWarningMsg, "Unable to convert private key");
|
||||
ok = QSslCertificate::importPkcs12(&nocert, &key, &cert, &caCerts);
|
||||
QVERIFY(!ok);
|
||||
nocert.close();
|
||||
|
@ -43,6 +43,8 @@
|
||||
#include "private/qsslsocket_p.h"
|
||||
#include "private/qsslconfiguration_p.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
// make these enum values available without causing deprecation warnings:
|
||||
@ -2840,7 +2842,7 @@ void tst_QSslSocket::closeWhileEmittingSocketError()
|
||||
// Make sure we have some data buffered so that close will try to flush:
|
||||
clientSocket.write(QByteArray(1000000, Qt::Uninitialized));
|
||||
|
||||
QTestEventLoop::instance().enterLoopMSecs(1000);
|
||||
QTestEventLoop::instance().enterLoop(1s);
|
||||
QVERIFY(!QTestEventLoop::instance().timeout());
|
||||
|
||||
QCOMPARE(socketErrorSpy.size(), 1);
|
||||
@ -3100,7 +3102,14 @@ void tst_QSslSocket::blacklistedCertificates()
|
||||
QList<QSslError> sslErrors = receiver->sslHandshakeErrors();
|
||||
QVERIFY(sslErrors.size() > 0);
|
||||
// there are more errors (self signed cert and hostname mismatch), but we only care about the blacklist error
|
||||
QCOMPARE(sslErrors.at(0).error(), QSslError::CertificateBlacklisted);
|
||||
std::optional<QSslError> blacklistedError;
|
||||
for (const QSslError &error : sslErrors) {
|
||||
if (error.error() == QSslError::CertificateBlacklisted) {
|
||||
blacklistedError = error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY2(blacklistedError, "CertificateBlacklisted error not found!");
|
||||
}
|
||||
|
||||
void tst_QSslSocket::versionAccessors()
|
||||
@ -4577,7 +4586,7 @@ void tst_QSslSocket::unsupportedProtocols()
|
||||
return;
|
||||
|
||||
QFETCH(const QSsl::SslProtocol, unsupportedProtocol);
|
||||
const int timeoutMS = 500;
|
||||
constexpr auto timeout = 500ms;
|
||||
// Test a client socket.
|
||||
{
|
||||
// 0. connectToHostEncrypted: client-side, non-blocking API, error is discovered
|
||||
@ -4599,7 +4608,7 @@ void tst_QSslSocket::unsupportedProtocols()
|
||||
QCOMPARE(socket.error(), QAbstractSocket::UnknownSocketError);
|
||||
|
||||
socket.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
QVERIFY(socket.waitForConnected(timeoutMS));
|
||||
QVERIFY(socket.waitForConnected(int(timeout.count())));
|
||||
|
||||
socket.setProtocol(unsupportedProtocol);
|
||||
socket.startClientEncryption();
|
||||
@ -4624,7 +4633,7 @@ void tst_QSslSocket::unsupportedProtocols()
|
||||
|
||||
QTcpSocket client;
|
||||
client.connectToHost(QHostAddress::LocalHost, server.serverPort());
|
||||
loop.enterLoopMSecs(timeoutMS);
|
||||
loop.enterLoop(timeout);
|
||||
QVERIFY(!loop.timeout());
|
||||
QVERIFY(server.socket);
|
||||
QCOMPARE(server.socket->error(), QAbstractSocket::SslInvalidUserDataError);
|
||||
@ -4731,7 +4740,7 @@ void tst_QSslSocket::alertMissingCertificate()
|
||||
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
|
||||
connect(&server, &SslServer::socketError, earlyQuitter);
|
||||
|
||||
runner.enterLoopMSecs(1000);
|
||||
runner.enterLoop(1s);
|
||||
|
||||
if (clientSocket.isEncrypted()) {
|
||||
// When using TLS 1.3 the client side thinks it is connected very
|
||||
@ -4739,7 +4748,7 @@ void tst_QSslSocket::alertMissingCertificate()
|
||||
// inevitable disconnect.
|
||||
QCOMPARE(clientSocket.sessionProtocol(), QSsl::TlsV1_3);
|
||||
connect(&clientSocket, &QSslSocket::disconnected, &runner, &QTestEventLoop::exitLoop);
|
||||
runner.enterLoopMSecs(10000);
|
||||
runner.enterLoop(10s);
|
||||
}
|
||||
|
||||
QVERIFY(serverSpy.size() > 0);
|
||||
@ -4794,7 +4803,7 @@ void tst_QSslSocket::alertInvalidCertificate()
|
||||
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
|
||||
connect(&server, &SslServer::socketError, earlyQuitter);
|
||||
|
||||
runner.enterLoopMSecs(1000);
|
||||
runner.enterLoop(1s);
|
||||
|
||||
QVERIFY(serverSpy.size() > 0);
|
||||
QVERIFY(clientSpy.size() > 0);
|
||||
@ -4922,7 +4931,7 @@ void tst_QSslSocket::selfSignedCertificates()
|
||||
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
|
||||
connect(&server, &SslServer::socketError, earlyQuitter);
|
||||
|
||||
runner.enterLoopMSecs(1000);
|
||||
runner.enterLoop(1s);
|
||||
|
||||
if (clientKnown) {
|
||||
QCOMPARE(serverSpy.size(), 0);
|
||||
@ -5060,7 +5069,7 @@ void tst_QSslSocket::pskHandshake()
|
||||
connect(&clientSocket, &QAbstractSocket::errorOccurred, earlyQuitter);
|
||||
connect(&server, &SslServer::socketError, earlyQuitter);
|
||||
|
||||
runner.enterLoopMSecs(1000);
|
||||
runner.enterLoop(1s);
|
||||
|
||||
if (pskRight) {
|
||||
QCOMPARE(serverSpy.size(), 0);
|
||||
|
Reference in New Issue
Block a user