summaryrefslogtreecommitdiffstats
path: root/src/network/kernel/qdnslookup.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-04-19 09:41:40 -0700
committerThiago Macieira <thiago.macieira@intel.com>2024-05-08 21:13:45 -0700
commit503fd609881fb220ac5abe7da2fe367efd90ed4b (patch)
tree0a4efedaf0508a308166d861d689572c6f9b569c /src/network/kernel/qdnslookup.cpp
parentf2f00b2a4632aaeb58e6cdae7faef9e0bafaff49 (diff)
QDnsLookup: add the ability to tell if the reply was authenticated
This is implemented for DNS-over-TLS and for the native Unix resolver, because I can find no way to get the state of the reply on Windows with the WinDNS.h API. Change-Id: I455fe22ef4ad4b2f9b01fffd17c7bc022ded2363 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/kernel/qdnslookup.cpp')
-rw-r--r--src/network/kernel/qdnslookup.cpp55
1 files changed, 53 insertions, 2 deletions
diff --git a/src/network/kernel/qdnslookup.cpp b/src/network/kernel/qdnslookup.cpp
index 9a35bd3365..a3ebbe04db 100644
--- a/src/network/kernel/qdnslookup.cpp
+++ b/src/network/kernel/qdnslookup.cpp
@@ -168,7 +168,7 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
name, or the host name associated with an IP address you should use
QHostInfo instead.
- \section1 DNS-over-TLS
+ \section1 DNS-over-TLS and Authentic Data
QDnsLookup supports DNS-over-TLS (DoT, as specified by \l{RFC 7858}) on
some platforms. That currently includes all Unix platforms where regular
@@ -182,6 +182,27 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
server being connected to. Clients may use setSslConfiguration() to impose
additional restrictions and sslConfiguration() to obtain information after
the query is complete.
+
+ QDnsLookup will request DNS servers queried over TLS to perform
+ authentication on the data they return. If they confirm the data is valid,
+ the \l authenticData property will be set to true. QDnsLookup does not
+ verify the integrity of the data by itself, so applications should only
+ trust this property on servers they have confirmed through other means to
+ be trustworthy.
+
+ \section2 Authentic Data without TLS
+
+ QDnsLookup request Authentic Data for any server set with setNameserver(),
+ even if TLS encryption is not required. This is useful when querying a
+ caching nameserver on the same host as the application or on a trusted
+ network. Though similar to the TLS case, the application is responsible for
+ determining if the server it chose to use is trustworthy, and if the
+ unencrypted connection cannot be tampered with.
+
+ QDnsLookup obeys the system configuration to request Authentic Data on the
+ default nameserver (that is, if setNameserver() is not called). This is
+ currently only supported on Linux systems using glibc 2.31 or later. On any
+ other systems, QDnsLookup will ignore the AD bit in the query header.
*/
/*!
@@ -419,6 +440,28 @@ QDnsLookup::~QDnsLookup()
}
/*!
+ \since 6.8
+ \property QDnsLookup::authenticData
+ \brief whether the reply was authenticated by the resolver.
+
+ QDnsLookup does not perform the authentication itself. Instead, it trusts
+ the name server that was queried to perform the authentication and report
+ it. The application is responsible for determining if any servers it
+ configured with setNameserver() are trustworthy; if no server was set,
+ QDnsLookup obeys system configuration on whether responses should be
+ trusted.
+
+ This property may be set even if error() indicates a resolver error
+ occurred.
+
+ \sa setNameserver(), nameserverProtocol()
+*/
+bool QDnsLookup::isAuthenticData() const
+{
+ return d_func()->reply.authenticData;
+}
+
+/*!
\property QDnsLookup::error
\brief the type of error that occurred if the DNS lookup failed, or NoError.
*/
@@ -1308,6 +1351,7 @@ inline QDebug operator<<(QDebug &d, QDnsLookupRunnable *r)
#if QT_CONFIG(ssl)
static constexpr std::chrono::milliseconds DnsOverTlsConnectTimeout(15'000);
static constexpr std::chrono::milliseconds DnsOverTlsTimeout(120'000);
+static constexpr quint8 DnsAuthenticDataBit = 0x20;
static int makeReplyErrorFromSocket(QDnsLookupReply *reply, const QAbstractSocket *socket)
{
@@ -1334,6 +1378,9 @@ bool QDnsLookupRunnable::sendDnsOverTls(QDnsLookupReply *reply, QSpan<unsigned c
socket.setProtocolTag("domain-s"_L1);
# endif
+ // Request the name server attempt to authenticate the reply.
+ query[3] |= DnsAuthenticDataBit;
+
do {
quint16 size = qToBigEndian<quint16>(query.size());
QDeadlineTimer timeout(DnsOverTlsTimeout);
@@ -1363,8 +1410,12 @@ bool QDnsLookupRunnable::sendDnsOverTls(QDnsLookupReply *reply, QSpan<unsigned c
// the maximum allocation is small.
size = qFromBigEndian(size);
response.resize(size);
- if (waitForBytes(response.data(), size))
+ if (waitForBytes(response.data(), size)) {
+ // check if the AD bit is set; we'll trust it over TLS requests
+ if (size >= 4)
+ reply->authenticData = response[3] & DnsAuthenticDataBit;
return true;
+ }
} while (false);
// handle errors