From 7b46aa2a6e4fdb71632128a94b6645613631d8d4 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Wed, 16 Dec 2020 22:10:09 +0100 Subject: Store secrets in keychain --- src/Cache.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) (limited to 'src/Cache.cpp') 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 #include #include -#include #include +#include + #include #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 +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 +secret(const std::string &name) +{ + return instance_->secret(name); +} } // namespace cache -- cgit 1.5.1