summary refs log tree commit diff
path: root/src/Cache.cpp
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2020-12-16 22:10:09 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2020-12-16 22:10:09 +0100
commit7b46aa2a6e4fdb71632128a94b6645613631d8d4 (patch)
treedb6a8ee2e6d741399614aa98addbd1da0dea9371 /src/Cache.cpp
parentFix black cat emoji (diff)
downloadnheko-7b46aa2a6e4fdb71632128a94b6645613631d8d4.tar.xz
Store secrets in keychain
Diffstat (limited to '')
-rw-r--r--src/Cache.cpp94
1 files changed, 93 insertions, 1 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp

index 05c2e486..9da0d87d 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp
@@ -24,9 +24,10 @@ #include <QFile> #include <QHash> #include <QMap> -#include <QSettings> #include <QStandardPaths> +#include <qt5keychain/keychain.h> + #include <mtx/responses/common.hpp> #include "Cache.h" @@ -569,6 +570,64 @@ Cache::restoreOlmAccount() return std::string(pickled.data(), pickled.size()); } +void +Cache::storeSecret(const std::string &name, const std::string &secret) +{ + QKeychain::WritePasswordJob job(QCoreApplication::applicationName()); + job.setAutoDelete(false); + job.setInsecureFallback(true); + job.setKey(QString::fromStdString(name)); + job.setTextData(QString::fromStdString(secret)); + QEventLoop loop; + job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.start(); + loop.exec(); + + if (job.error()) { + nhlog::db()->warn( + "Storing secret '{}' failed: {}", name, job.errorString().toStdString()); + } else { + emit secretChanged(name); + } +} + +void +Cache::deleteSecret(const std::string &name) +{ + QKeychain::DeletePasswordJob job(QCoreApplication::applicationName()); + job.setAutoDelete(false); + job.setInsecureFallback(true); + job.setKey(QString::fromStdString(name)); + QEventLoop loop; + job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.start(); + loop.exec(); + + emit secretChanged(name); +} + +std::optional<std::string> +Cache::secret(const std::string &name) +{ + QKeychain::ReadPasswordJob job(QCoreApplication::applicationName()); + job.setAutoDelete(false); + job.setInsecureFallback(true); + job.setKey(QString::fromStdString(name)); + QEventLoop loop; + job.connect(&job, &QKeychain::Job::finished, &loop, &QEventLoop::quit); + job.start(); + loop.exec(); + + const QString secret = job.textData(); + if (job.error()) { + nhlog::db()->debug( + "Restoring secret '{}' failed: {}", name, job.errorString().toStdString()); + return std::nullopt; + } + + return secret.toStdString(); +} + // // Media Management // @@ -726,10 +785,32 @@ void Cache::deleteData() { // TODO: We need to remove the env_ while not accepting new requests. + lmdb::dbi_close(env_, syncStateDb_); + lmdb::dbi_close(env_, roomsDb_); + lmdb::dbi_close(env_, invitesDb_); + lmdb::dbi_close(env_, mediaDb_); + lmdb::dbi_close(env_, readReceiptsDb_); + lmdb::dbi_close(env_, notificationsDb_); + + lmdb::dbi_close(env_, devicesDb_); + lmdb::dbi_close(env_, deviceKeysDb_); + + lmdb::dbi_close(env_, inboundMegolmSessionDb_); + lmdb::dbi_close(env_, outboundMegolmSessionDb_); + + env_.close(); + + verification_storage.status.clear(); + if (!cacheDirectory_.isEmpty()) { QDir(cacheDirectory_).removeRecursively(); nhlog::db()->info("deleted cache files from disk"); } + + deleteSecret(mtx::secret_storage::secrets::megolm_backup_v1); + deleteSecret(mtx::secret_storage::secrets::cross_signing_master); + deleteSecret(mtx::secret_storage::secrets::cross_signing_user_signing); + deleteSecret(mtx::secret_storage::secrets::cross_signing_self_signing); } //! migrates db to the current format @@ -4262,4 +4343,15 @@ restoreOlmAccount() { return instance_->restoreOlmAccount(); } + +void +storeSecret(const std::string &name, const std::string &secret) +{ + instance_->storeSecret(name, secret); +} +std::optional<std::string> +secret(const std::string &name) +{ + return instance_->secret(name); +} } // namespace cache