aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/connection.cpp2
-rw-r--r--lib/converters.h18
-rw-r--r--lib/keyverificationsession.cpp22
-rw-r--r--lib/keyverificationsession.h3
-rw-r--r--lib/networkaccessmanager.cpp13
-rw-r--r--lib/util.h2
6 files changed, 39 insertions, 21 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index 5003f40c..8ca76ceb 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -380,7 +380,7 @@ public:
{
qCDebug(MAIN) << "Saving access token to keychain for" << q->userId();
auto job = new QKeychain::WritePasswordJob(qAppName());
- job->setAutoDelete(false);
+ job->setAutoDelete(true);
job->setKey(q->userId());
job->setBinaryData(data->accessToken());
job->start();
diff --git a/lib/converters.h b/lib/converters.h
index 688f7bbd..0fb36320 100644
--- a/lib/converters.h
+++ b/lib/converters.h
@@ -37,7 +37,6 @@ struct JsonObjectUnpacker {
// fromJson<T, QJsonObject> specialisation instead of specialising
// the entire JsonConverter; if a different type of JSON value is needed
// (e.g., an array), specialising JsonConverter is inevitable
- static T load(QJsonValueRef jvr) { return fromJson<T>(QJsonValue(jvr)); }
static T load(const QJsonValue& jv) { return fromJson<T>(jv.toObject()); }
static T load(const QJsonDocument& jd) { return fromJson<T>(jd.object()); }
};
@@ -228,7 +227,7 @@ QString flagToJsonString(FlagT v, const FlagStringValuesT& flagValues)
return {};
}
-// JsonConverter<> specialisations
+// Specialisations
template<>
inline bool fromJson(const QJsonValue& jv) { return jv.toBool(); }
@@ -248,7 +247,7 @@ inline qint64 fromJson(const QJsonValue& jv) { return qint64(jv.toDouble()); }
template <>
inline QString fromJson(const QJsonValue& jv) { return jv.toString(); }
-//! Use fromJson<QString> and use toLatin1()/toUtf8()/... to make QByteArray
+//! Use fromJson<QString> and then toLatin1()/toUtf8()/... to make QByteArray
//!
//! QJsonValue can only convert to QString and there's ambiguity whether
//! conversion to QByteArray should use (fast but very limited) toLatin1() or
@@ -348,8 +347,12 @@ struct JsonArrayConverter {
{
VectorT vect;
vect.reserve(typename VectorT::size_type(ja.size()));
- for (const auto& i : ja)
- vect.push_back(fromJson<T>(i));
+ // NB: Make sure to pass QJsonValue to fromJson<> so that it could
+ // hit the correct overload and not fall back to the generic fromJson
+ // that treats everything as an object. See also the explanation in
+ // the commit introducing these lines.
+ for (const QJsonValue v : ja)
+ vect.push_back(fromJson<T>(v));
return vect;
}
static auto load(const QJsonValue& jv) { return load(jv.toArray()); }
@@ -401,8 +404,11 @@ struct HashMapFromJson {
static void fillFrom(const QJsonObject& jo, HashMapT& h)
{
h.reserve(h.size() + jo.size());
+ // NB: the QJsonValue cast below is for the same reason as in
+ // JsonArrayConverter
for (auto it = jo.begin(); it != jo.end(); ++it)
- h[it.key()] = fromJson<typename HashMapT::mapped_type>(it.value());
+ h[it.key()] = fromJson<typename HashMapT::mapped_type>(
+ QJsonValue(it.value()));
}
};
diff --git a/lib/keyverificationsession.cpp b/lib/keyverificationsession.cpp
index cc4428d7..3f76eac1 100644
--- a/lib/keyverificationsession.cpp
+++ b/lib/keyverificationsession.cpp
@@ -256,6 +256,10 @@ void KeyVerificationSession::sendMac()
mac),
m_encrypted);
setState (macReceived ? DONE : WAITINGFORMAC);
+ m_verified = true;
+ if (!m_pendingEdKeyId.isEmpty()) {
+ trustKeys();
+ }
}
void KeyVerificationSession::sendDone()
@@ -313,9 +317,10 @@ void KeyVerificationSession::sendStartSas()
{
startSentByUs = true;
KeyVerificationStartEvent event(m_transactionId, m_connection->deviceId());
- m_startEvent = QJsonDocument(event.contentJson()).toJson(QJsonDocument::Compact);
- m_connection->sendToDevice(m_remoteUserId, m_remoteDeviceId,
- std::move(event), m_encrypted);
+ m_startEvent =
+ QJsonDocument(event.contentJson()).toJson(QJsonDocument::Compact);
+ m_connection->sendToDevice(m_remoteUserId, m_remoteDeviceId, event,
+ m_encrypted);
setState(WAITINGFORACCEPT);
}
@@ -370,7 +375,16 @@ void KeyVerificationSession::handleMac(const KeyVerificationMacEvent& event)
return;
}
- m_connection->database()->setSessionVerified(edKeyId);
+ m_pendingEdKeyId = edKeyId;
+
+ if (m_verified) {
+ trustKeys();
+ }
+}
+
+void KeyVerificationSession::trustKeys()
+{
+ m_connection->database()->setSessionVerified(m_pendingEdKeyId);
emit m_connection->sessionVerified(m_remoteUserId, m_remoteDeviceId);
macReceived = true;
diff --git a/lib/keyverificationsession.h b/lib/keyverificationsession.h
index 9cac1184..32a91cfc 100644
--- a/lib/keyverificationsession.h
+++ b/lib/keyverificationsession.h
@@ -131,6 +131,8 @@ private:
bool macReceived = false;
bool m_encrypted;
QStringList m_remoteSupportedMethods;
+ bool m_verified = false;
+ QString m_pendingEdKeyId{};
void handleReady(const KeyVerificationReadyEvent& event);
void handleStart(const KeyVerificationStartEvent& event);
@@ -141,6 +143,7 @@ private:
void setError(Error error);
static QString errorToString(Error error);
static Error stringToError(const QString& error);
+ void trustKeys();
QByteArray macInfo(bool verifying, const QString& key = "KEY_IDS"_ls);
QString calculateMac(const QString& input, bool verifying, const QString& keyId= "KEY_IDS"_ls);
diff --git a/lib/networkaccessmanager.cpp b/lib/networkaccessmanager.cpp
index 38ab07cc..78be89bd 100644
--- a/lib/networkaccessmanager.cpp
+++ b/lib/networkaccessmanager.cpp
@@ -9,7 +9,6 @@
#include "mxcreply.h"
#include <QtCore/QCoreApplication>
-#include <QtCore/QThreadStorage>
#include <QtCore/QSettings>
#include <QtNetwork/QNetworkReply>
@@ -50,9 +49,8 @@ QList<QSslError> NetworkAccessManager::ignoredSslErrors() const
void NetworkAccessManager::ignoreSslErrors(bool ignore) const
{
if (ignore) {
- connect(this, &QNetworkAccessManager::sslErrors, this, [](QNetworkReply *reply, const QList<QSslError> &errors) {
- reply->ignoreSslErrors();
- });
+ connect(this, &QNetworkAccessManager::sslErrors, this,
+ [](QNetworkReply* reply) { reply->ignoreSslErrors(); });
} else {
disconnect(this, &QNetworkAccessManager::sslErrors, this, nullptr);
}
@@ -70,11 +68,8 @@ void NetworkAccessManager::clearIgnoredSslErrors()
NetworkAccessManager* NetworkAccessManager::instance()
{
- static QThreadStorage<NetworkAccessManager*> storage;
- if(!storage.hasLocalData()) {
- storage.setLocalData(new NetworkAccessManager());
- }
- return storage.localData();
+ thread_local NetworkAccessManager nam;
+ return &nam;
}
QNetworkReply* NetworkAccessManager::createRequest(
diff --git a/lib/util.h b/lib/util.h
index 1cb1c0e1..9efda5d1 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -160,7 +160,7 @@ template <typename ImplType, typename TypeToDelete = ImplType, typename... ArgTs
inline ImplPtr<ImplType, TypeToDelete> makeImpl(ArgTs&&... args)
{
return ImplPtr<ImplType, TypeToDelete> {
- new ImplType(std::forward<ArgTs>(args)...),
+ new ImplType{std::forward<ArgTs>(args)...},
[](TypeToDelete* impl) { delete impl; }
};
}