Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qhstsstore.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qhstsstore_p.h"
5#include "qhstspolicy.h"
6
7#include "qstandardpaths.h"
8#include "qdatastream.h"
9#include "qbytearray.h"
10#include "qdatetime.h"
11#include "qvariant.h"
12#include "qstring.h"
13#include "qdir.h"
14
15#include <utility>
16
18
19using namespace Qt::StringLiterals;
20
22{
23 const QByteArray hostNameAsHex(hostName.toUtf8().toHex());
24 return QString::fromLatin1(hostNameAsHex);
25}
26
28{
29 const QByteArray hostNameAsUtf8(QByteArray::fromHex(key.toLatin1()));
30 return QString::fromUtf8(hostNameAsUtf8);
31}
32
34 : store(absoluteFilePath(dirName), QSettings::IniFormat)
35{
36 // Disable fallbacks, we do not want to use anything but our own ini file.
37 store.setFallbacksEnabled(false);
38}
39
44
45QList<QHstsPolicy> QHstsStore::readPolicies()
46{
47 // This function only attempts to read policies, making no decision about
48 // expired policies. It's up to a user (QHstsCache) to mark these policies
49 // for deletion and sync the store later. But we immediately remove keys/values
50 // (if the store isWritable) for the policies that we fail to read.
51 QList<QHstsPolicy> policies;
52
53 beginHstsGroups();
54
55 const QStringList keys = store.childKeys();
56 for (const auto &key : keys) {
57 QHstsPolicy restoredPolicy;
58 if (deserializePolicy(key, restoredPolicy)) {
59 restoredPolicy.setHost(settings_key_to_host_name(key));
60 policies.push_back(std::move(restoredPolicy));
61 } else if (isWritable()) {
62 evictPolicy(key);
63 }
64 }
65
66 endHstsGroups();
67
68 return policies;
69}
70
72{
73 observedPolicies.push_back(policy);
74}
75
77{
78 if (!isWritable())
79 return;
80
81 if (observedPolicies.size()) {
82 beginHstsGroups();
83 for (const QHstsPolicy &policy : std::as_const(observedPolicies)) {
85 // If we fail to write a new, updated policy, we also remove the old one.
86 if (policy.isExpired() || !serializePolicy(key, policy))
87 evictPolicy(key);
88 }
89 observedPolicies.clear();
90 endHstsGroups();
91 }
92
93 store.sync();
94}
95
97{
98 return store.isWritable();
99}
100
102{
104 : dirName);
105 return dir.absoluteFilePath("hstsstore"_L1);
106}
107
108void QHstsStore::beginHstsGroups()
109{
110 store.beginGroup("StrictTransportSecurity"_L1);
111 store.beginGroup("Policies"_L1);
112}
113
114void QHstsStore::endHstsGroups()
115{
116 store.endGroup();
117 store.endGroup();
118}
119
120bool QHstsStore::deserializePolicy(const QString &key, QHstsPolicy &policy)
121{
122 Q_ASSERT(store.contains(key));
123
124 const QVariant data(store.value(key));
125 if (data.isNull() || !data.canConvert<QByteArray>())
126 return false;
127
128 const QByteArray serializedData(data.toByteArray());
129 QDataStream streamer(serializedData);
130 qint64 expiryInMS = 0;
131 streamer >> expiryInMS;
132 if (streamer.status() != QDataStream::Ok)
133 return false;
134 bool includesSubDomains = false;
135 streamer >> includesSubDomains;
136 if (streamer.status() != QDataStream::Ok)
137 return false;
138
139 policy.setExpiry(QDateTime::fromMSecsSinceEpoch(expiryInMS));
140 policy.setIncludesSubDomains(includesSubDomains);
141
142 return true;
143}
144
145bool QHstsStore::serializePolicy(const QString &key, const QHstsPolicy &policy)
146{
147 Q_ASSERT(store.isWritable());
148
149 QByteArray serializedData;
150 QDataStream streamer(&serializedData, QIODevice::WriteOnly);
151 streamer << policy.expiry().toMSecsSinceEpoch();
152 streamer << policy.includesSubDomains();
153
154 if (streamer.status() != QDataStream::Ok)
155 return false;
156
157 store.setValue(key, serializedData);
158 return true;
159}
160
161void QHstsStore::evictPolicy(const QString &key)
162{
163 Q_ASSERT(store.isWritable());
164 if (store.contains(key))
165 store.remove(key);
166}
167
\inmodule QtCore
Definition qbytearray.h:57
static QByteArray fromHex(const QByteArray &hexEncoded)
Returns a decoded copy of the hex encoded array hexEncoded.
QByteArray toHex(char separator='\0') const
Returns a hex encoded copy of the byte array.
\inmodule QtCore\reentrant
Definition qdatastream.h:46
static QDateTime fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone)
\inmodule QtCore
Definition qdir.h:20
The QHstsPolicy class specifies that a host supports HTTP Strict Transport Security policy (HSTS).
Definition qhstspolicy.h:19
void setHost(const QString &host, QUrl::ParsingMode mode=QUrl::DecodedMode)
Sets a host, host data is interpreted according to mode parameter.
QHstsStore(const QString &dirName)
bool isWritable() const
void synchronize()
void addToObserved(const QHstsPolicy &policy)
QList< QHstsPolicy > readPolicies()
static QString absoluteFilePath(const QString &dirName)
qsizetype size() const noexcept
Definition qlist.h:397
void push_back(parameter_type t)
Definition qlist.h:675
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qsettings.h:30
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
bool contains(QAnyStringView key) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(QAnyStringView key, const QVariant &value)
Sets the value of setting key to value.
void remove(QAnyStringView key)
Removes the setting key and any sub-settings of key.
QVariant value(QAnyStringView key, const QVariant &defaultValue) const
Returns the value for setting key.
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object.
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
bool isWritable() const
Returns true if settings can be written using this QSettings object; returns false otherwise.
void beginGroup(QAnyStringView prefix)
Appends prefix to the current group.
void setFallbacksEnabled(bool b)
Sets whether fallbacks are enabled to b.
static QString writableLocation(StandardLocation type)
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5871
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QByteArray toUtf8() const &
Definition qstring.h:634
\inmodule QtCore
Definition qvariant.h:65
Combined button and popup list for selecting options.
static QString settings_key_to_host_name(const QString &key)
static QString host_name_to_settings_key(const QString &hostName)
GLuint64 key
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static QString absoluteFilePath(const Options *options, const QString &relativeFileName)
Definition main.cpp:1902
long long qint64
Definition qtypes.h:60
QStringList keys
QString dir
[11]
QSizePolicy policy