diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/connection.cpp | 2 | ||||
-rw-r--r-- | lib/converters.h | 18 | ||||
-rw-r--r-- | lib/keyverificationsession.cpp | 22 | ||||
-rw-r--r-- | lib/keyverificationsession.h | 3 | ||||
-rw-r--r-- | lib/networkaccessmanager.cpp | 13 | ||||
-rw-r--r-- | lib/util.h | 2 |
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( @@ -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; } }; } |