From 4b7ff8e98c0208273a25d84e1f0322cad5bce2bf Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 13 Sep 2018 12:59:59 +0200 Subject: Protect HSTS code for no-feature-settings build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under the hood we use QSettings to store HSTS policies. Qt configured with 'no feature settings' would fail to build then. For such builds, we fall back to in-memory only HSTS cache. Change-Id: I6df551d8c6c96d982080a51ce6b1bdce71d04b9f Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/access/access.pri | 14 ++++++++++---- src/network/access/qhsts.cpp | 19 ++++++++++++++++++- src/network/access/qhsts_p.h | 8 +++++--- src/network/access/qhstsstore_p.h | 2 ++ src/network/access/qnetworkaccessmanager.cpp | 13 +++++++++++++ src/network/access/qnetworkaccessmanager_p.h | 7 ++++++- 6 files changed, 54 insertions(+), 9 deletions(-) (limited to 'src/network') diff --git a/src/network/access/access.pri b/src/network/access/access.pri index a129beda15..ec0273377f 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -24,8 +24,7 @@ HEADERS += \ access/qabstractnetworkcache.h \ access/qnetworkfile_p.h \ access/qhsts_p.h \ - access/qhstspolicy.h \ - access/qhstsstore_p.h + access/qhstspolicy.h SOURCES += \ access/qnetworkaccessauthenticationmanager.cpp \ @@ -45,8 +44,7 @@ SOURCES += \ access/qabstractnetworkcache.cpp \ access/qnetworkfile.cpp \ access/qhsts.cpp \ - access/qhstspolicy.cpp \ - access/qhstsstore.cpp + access/qhstspolicy.cpp qtConfig(ftp) { HEADERS += \ @@ -66,6 +64,14 @@ qtConfig(networkdiskcache) { SOURCES += access/qnetworkdiskcache.cpp } +qtConfig(settings) { + HEADERS += \ + access/qhstsstore_p.h + + SOURCES += \ + access/qhstsstore.cpp +} + mac: LIBS_PRIVATE += -framework Security include($$PWD/../../3rdparty/zlib_dependency.pri) diff --git a/src/network/access/qhsts.cpp b/src/network/access/qhsts.cpp index 43a8a3663e..af913ca015 100644 --- a/src/network/access/qhsts.cpp +++ b/src/network/access/qhsts.cpp @@ -37,13 +37,16 @@ ** ****************************************************************************/ -#include "qhstsstore_p.h" #include "qhsts_p.h" #include "QtCore/private/qipaddress_p.h" #include "QtCore/qvector.h" #include "QtCore/qlist.h" +#if QT_CONFIG(settings) +#include "qhstsstore_p.h" +#endif // QT_CONFIG(settings) + QT_BEGIN_NAMESPACE static bool is_valid_domain_name(const QString &host) @@ -83,8 +86,10 @@ void QHstsCache::updateFromHeaders(const QList> &h QHstsHeaderParser parser; if (parser.parse(headers)) { updateKnownHost(url.host(), parser.expirationDate(), parser.includeSubDomains()); +#if QT_CONFIG(settings) if (hstsStore) hstsStore->synchronize(); +#endif // QT_CONFIG(settings) } } @@ -93,12 +98,14 @@ void QHstsCache::updateFromPolicies(const QVector &policies) for (const auto &policy : policies) updateKnownHost(policy.host(), policy.expiry(), policy.includesSubDomains()); +#if QT_CONFIG(settings) if (hstsStore && policies.size()) { // These policies are coming either from store or from QNAM's setter // function. As a result we can notice expired or new policies, time // to sync ... hstsStore->synchronize(); } +#endif // QT_CONFIG(settings) } void QHstsCache::updateKnownHost(const QUrl &url, const QDateTime &expires, @@ -108,8 +115,10 @@ void QHstsCache::updateKnownHost(const QUrl &url, const QDateTime &expires, return; updateKnownHost(url.host(), expires, includeSubDomains); +#if QT_CONFIG(settings) if (hstsStore) hstsStore->synchronize(); +#endif // QT_CONFIG(settings) } void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires, @@ -137,8 +146,10 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires, } knownHosts.insert(pos, {hostName, newPolicy}); +#if QT_CONFIG(settings) if (hstsStore) hstsStore->addToObserved(newPolicy); +#endif // QT_CONFIG(settings) return; } @@ -149,8 +160,10 @@ void QHstsCache::updateKnownHost(const QString &host, const QDateTime &expires, else return; +#if QT_CONFIG(settings) if (hstsStore) hstsStore->addToObserved(newPolicy); +#endif // QT_CONFIG(settings) } bool QHstsCache::isKnownHost(const QUrl &url) const @@ -187,10 +200,12 @@ bool QHstsCache::isKnownHost(const QUrl &url) const if (pos != knownHosts.end()) { if (pos->second.isExpired()) { knownHosts.erase(pos); +#if QT_CONFIG(settings) if (hstsStore) { // Inform our store that this policy has expired. hstsStore->addToObserved(pos->second); } +#endif // QT_CONFIG(settings) } else if (!superDomainMatch || pos->second.includesSubDomains()) { return true; } @@ -221,6 +236,7 @@ QVector QHstsCache::policies() const return values; } +#if QT_CONFIG(settings) void QHstsCache::setStore(QHstsStore *store) { // Caller retains ownership of store, which must outlive this cache. @@ -248,6 +264,7 @@ void QHstsCache::setStore(QHstsStore *store) updateFromPolicies(restored); } } +#endif // QT_CONFIG(settings) // The parser is quite simple: 'nextToken' knowns exactly what kind of tokens // are valid and it will return false if something else was found; then diff --git a/src/network/access/qhsts_p.h b/src/network/access/qhsts_p.h index bc8708341d..c219d9eab5 100644 --- a/src/network/access/qhsts_p.h +++ b/src/network/access/qhsts_p.h @@ -69,8 +69,6 @@ QT_BEGIN_NAMESPACE template class QList; template class QVector; -class QHstsStore; - class Q_AUTOTEST_EXPORT QHstsCache { public: @@ -85,7 +83,9 @@ public: QVector policies() const; - void setStore(QHstsStore *store); +#if QT_CONFIG(settings) + void setStore(class QHstsStore *store); +#endif // QT_CONFIG(settings) private: @@ -119,7 +119,9 @@ private: }; mutable std::map knownHosts; +#if QT_CONFIG(settings) QHstsStore *hstsStore = nullptr; +#endif // QT_CONFIG(settings) }; class Q_AUTOTEST_EXPORT QHstsHeaderParser diff --git a/src/network/access/qhstsstore_p.h b/src/network/access/qhstsstore_p.h index 13042839c4..e82596b250 100644 --- a/src/network/access/qhstsstore_p.h +++ b/src/network/access/qhstsstore_p.h @@ -53,6 +53,8 @@ #include +QT_REQUIRE_CONFIG(settings); + #include #include diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 96e3f92db1..a2649fe77c 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -48,6 +48,10 @@ #include "qhstspolicy.h" #include "qhsts_p.h" +#if QT_CONFIG(settings) +#include "qhstsstore_p.h" +#endif // QT_CONFIG(settings) + #include "QtNetwork/qnetworksession.h" #include "QtNetwork/private/qsharednetworksession_p.h" @@ -760,9 +764,14 @@ bool QNetworkAccessManager::isStrictTransportSecurityEnabled() const void QNetworkAccessManager::enableStrictTransportSecurityStore(bool enabled, const QString &storeDir) { +#if QT_CONFIG(settings) Q_D(QNetworkAccessManager); d->stsStore.reset(enabled ? new QHstsStore(storeDir) : nullptr); d->stsCache.setStore(d->stsStore.data()); +#else + Q_UNUSED(enabled) Q_UNUSED(storeDir) + qWarning("HSTS permanent store requires the feature 'settings' enabled"); +#endif // QT_CONFIG(settings) } /*! @@ -776,8 +785,12 @@ void QNetworkAccessManager::enableStrictTransportSecurityStore(bool enabled, con bool QNetworkAccessManager::isStrictTransportSecurityStoreEnabled() const { +#if QT_CONFIG(settings) Q_D(const QNetworkAccessManager); return bool(d->stsStore.data()); +#else + return false; +#endif // QT_CONFIG(settings) } /*! diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h index ffed24a314..5cab4928e4 100644 --- a/src/network/access/qnetworkaccessmanager_p.h +++ b/src/network/access/qnetworkaccessmanager_p.h @@ -56,7 +56,6 @@ #include "qnetworkaccesscache_p.h" #include "qnetworkaccessbackend_p.h" #include "qnetworkrequest.h" -#include "qhstsstore_p.h" #include "qhsts_p.h" #include "private/qobject_p.h" #include "QtNetwork/qnetworkproxy.h" @@ -66,6 +65,10 @@ #include "QtNetwork/qnetworkconfigmanager.h" #endif +#if QT_CONFIG(settings) +#include "qhstsstore_p.h" +#endif // QT_CONFIG(settings) + QT_BEGIN_NAMESPACE class QAuthenticator; @@ -215,7 +218,9 @@ public: Q_AUTOTEST_EXPORT static void clearConnectionCache(QNetworkAccessManager *manager); QHstsCache stsCache; +#if QT_CONFIG(settings) QScopedPointer stsStore; +#endif // QT_CONFIG(settings) bool stsEnabled = false; #ifndef QT_NO_BEARERMANAGEMENT -- cgit v1.2.3 From 6948bf20a73d09e867fd7c2d89052237d94b7d6a Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Tue, 11 Sep 2018 20:35:13 +0300 Subject: QSslContext: Use 0 instead of TLS_MAX_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the SSL_CTX_set_max_proto_version manpage [1]: > Setting the minimum or maximum version to 0, will enable protocol > versions down to the lowest version, or up to the highest version > supported by the library, respectively. This should make it possible to use Qt Network with older versions of libssl than it was compiled against. In particular, use with 1.1.0 when compiled against 1.1.1. Also, one of OpenSSL developers is suggesting to remove TLS_MAX_VERSION from the public header in the future [2]. [1] https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_max_proto_version.html#DESCRIPTION [2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908567#59 Change-Id: Ie76054b917daa8e54d5c0156e848dbaca7bb8a82 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/ssl/qsslcontext_openssl11.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/network') diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp index 5c68ed41db..4fb33cb0a4 100644 --- a/src/network/ssl/qsslcontext_openssl11.cpp +++ b/src/network/ssl/qsslcontext_openssl11.cpp @@ -124,20 +124,20 @@ init_context: case QSsl::TlsV1SslV3: case QSsl::AnyProtocol: minVersion = SSL3_VERSION; - maxVersion = TLS_MAX_VERSION; + maxVersion = 0; break; case QSsl::SecureProtocols: case QSsl::TlsV1_0OrLater: minVersion = TLS1_VERSION; - maxVersion = TLS_MAX_VERSION; + maxVersion = 0; break; case QSsl::TlsV1_1OrLater: minVersion = TLS1_1_VERSION; - maxVersion = TLS_MAX_VERSION; + maxVersion = 0; break; case QSsl::TlsV1_2OrLater: minVersion = TLS1_2_VERSION; - maxVersion = TLS_MAX_VERSION; + maxVersion = 0; break; case QSsl::SslV2: // This protocol is not supported by OpenSSL 1.1 and we handle -- cgit v1.2.3 From b26cd68bf61346273a5a03bbc1e60a7cdffa4f0d Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 19 Sep 2018 13:31:18 +0200 Subject: Modernize the "datestring" feature Change-Id: I2236a456fe3758d9054b22e36fe6316f3522d533 Reviewed-by: Lars Knoll Reviewed-by: Edward Welbourne --- src/network/access/qftp.cpp | 4 ++-- src/network/access/qnetworkaccessftpbackend.cpp | 2 +- src/network/access/qnetworkrequest.cpp | 6 +++--- src/network/ssl/qsslcertificate.cpp | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/network') diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 719e3536b4..feece4ebaf 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -525,7 +525,7 @@ static void _q_parseUnixDir(const QStringList &tokens, const QString &userName, // Resolve the modification date by parsing all possible formats QDateTime dateTime; int n = 0; -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) do { dateTime = QLocale::c().toDateTime(dateString, formats.at(n++)); } while (n < formats.size() && (!dateTime.isValid())); @@ -600,7 +600,7 @@ static void _q_parseDosDir(const QStringList &tokens, const QString &userName, Q info->setWritable(info->isFile()); QDateTime dateTime; -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) dateTime = QLocale::c().toDateTime(tokens.at(1), QLatin1String("MM-dd-yy hh:mmAP")); if (dateTime.date().year() < 1971) { dateTime.setDate(QDate(dateTime.date().year() + 100, diff --git a/src/network/access/qnetworkaccessftpbackend.cpp b/src/network/access/qnetworkaccessftpbackend.cpp index c5404e4221..bc44a78a9a 100644 --- a/src/network/access/qnetworkaccessftpbackend.cpp +++ b/src/network/access/qnetworkaccessftpbackend.cpp @@ -370,7 +370,7 @@ void QNetworkAccessFtpBackend::ftpRawCommandReply(int code, const QString &text) if (id == sizeId) { // reply to the size command setHeader(QNetworkRequest::ContentLengthHeader, text.toLongLong()); -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) } else if (id == mdtmId) { QDateTime dt = QDateTime::fromString(text, QLatin1String("yyyyMMddHHmmss")); setHeader(QNetworkRequest::LastModifiedHeader, dt); diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 2fc50a66de..4cb93805dc 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -47,7 +47,7 @@ #include "QtCore/qdatetime.h" #include -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) # include #endif @@ -1159,7 +1159,7 @@ QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value) int pos = value.indexOf(','); QDateTime dt; -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) if (pos == -1) { // no comma -> asctime(3) format dt = QDateTime::fromString(QString::fromLatin1(value), Qt::TextDate); @@ -1186,7 +1186,7 @@ QDateTime QNetworkHeadersPrivate::fromHttpDate(const QByteArray &value) dt = c.toDateTime(sansWeekday, QLatin1String("dd-MMM-yy hh:mm:ss 'GMT'")); } } -#endif // QT_NO_DATESTRING +#endif // datestring if (dt.isValid()) dt.setTimeSpec(Qt::UTC); diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 6433b84e80..9ddcb70b1d 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -699,7 +699,7 @@ QDebug operator<<(QDebug debug, const QSslCertificate &certificate) << ", " << certificate.issuerInfo(QSslCertificate::Organization) << ", " << certificate.subjectInfo(QSslCertificate::Organization) << ", " << certificate.subjectAlternativeNames() -#ifndef QT_NO_DATESTRING +#if QT_CONFIG(datestring) << ", " << certificate.effectiveDate() << ", " << certificate.expiryDate() #endif -- cgit v1.2.3 From f99e956d65058e22780d99832987edad16f6d077 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 20 Sep 2018 14:26:23 +0200 Subject: Add QT_REQUIRE_CONFIG(ssl) to pre-shared key authenticator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it's done (albeit in old-style there) in other public QSsl-classes. Task-number: QTBUG-70604 Change-Id: If3cd9da0e8f8378fd29a80215cd889e459aa7bce Reviewed-by: Mårten Nordheim Reviewed-by: Edward Welbourne --- src/network/ssl/qsslpresharedkeyauthenticator.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/network') diff --git a/src/network/ssl/qsslpresharedkeyauthenticator.h b/src/network/ssl/qsslpresharedkeyauthenticator.h index a012ff489a..74ab888000 100644 --- a/src/network/ssl/qsslpresharedkeyauthenticator.h +++ b/src/network/ssl/qsslpresharedkeyauthenticator.h @@ -45,6 +45,8 @@ #include #include +QT_REQUIRE_CONFIG(ssl); + QT_BEGIN_NAMESPACE class QSslPreSharedKeyAuthenticatorPrivate; -- cgit v1.2.3