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/access') 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 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 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/network/access') 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); -- cgit v1.2.3