mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Allow downloading keys from key backup
This commit is contained in:
parent
e5dea361c0
commit
56db0dbc7d
15 changed files with 342 additions and 34 deletions
|
@ -381,7 +381,7 @@ if(USE_BUNDLED_MTXCLIENT)
|
|||
FetchContent_Declare(
|
||||
MatrixClient
|
||||
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
|
||||
GIT_TAG deb51ef1d6df870098069312f0a1999550e1eb85
|
||||
GIT_TAG 513196f520733e2f70576168aff7aaf16e0df180
|
||||
)
|
||||
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
|
||||
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")
|
||||
|
|
|
@ -163,7 +163,7 @@ modules:
|
|||
buildsystem: cmake-ninja
|
||||
name: mtxclient
|
||||
sources:
|
||||
- commit: deb51ef1d6df870098069312f0a1999550e1eb85
|
||||
- commit: 513196f520733e2f70576168aff7aaf16e0df180
|
||||
type: git
|
||||
url: https://github.com/Nheko-Reborn/mtxclient.git
|
||||
- config-opts:
|
||||
|
|
|
@ -39,7 +39,7 @@ Image {
|
|||
case Crypto.TOFU:
|
||||
return qsTr("Encrypted by an unverified device, but you have trusted that user so far.");
|
||||
default:
|
||||
return qsTr("Encrypted by an unverified device");
|
||||
return qsTr("Encrypted by an unverified device or the key is from an untrusted source like the key backup.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ static const std::string SECRET("secret");
|
|||
static const std::string_view NEXT_BATCH_KEY("next_batch");
|
||||
static const std::string_view OLM_ACCOUNT_KEY("olm_account");
|
||||
static const std::string_view CACHE_FORMAT_VERSION_KEY("cache_format_version");
|
||||
static const std::string_view CURRENT_ONLINE_BACKUP_VERSION("current_online_backup_version");
|
||||
|
||||
constexpr size_t MAX_RESTORED_MESSAGES = 30'000;
|
||||
|
||||
|
@ -723,6 +724,36 @@ Cache::restoreOlmAccount()
|
|||
return std::string(pickled.data(), pickled.size());
|
||||
}
|
||||
|
||||
void
|
||||
Cache::saveBackupVersion(const OnlineBackupVersion &data)
|
||||
{
|
||||
auto txn = lmdb::txn::begin(env_);
|
||||
syncStateDb_.put(txn, CURRENT_ONLINE_BACKUP_VERSION, nlohmann::json(data).dump());
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
void
|
||||
Cache::deleteBackupVersion()
|
||||
{
|
||||
auto txn = lmdb::txn::begin(env_);
|
||||
syncStateDb_.del(txn, CURRENT_ONLINE_BACKUP_VERSION);
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
std::optional<OnlineBackupVersion>
|
||||
Cache::backupVersion()
|
||||
{
|
||||
try {
|
||||
auto txn = ro_txn(env_);
|
||||
std::string_view v;
|
||||
syncStateDb_.get(txn, CURRENT_ONLINE_BACKUP_VERSION, v);
|
||||
|
||||
return nlohmann::json::parse(v).get<OnlineBackupVersion>();
|
||||
} catch (...) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Cache::storeSecret(const std::string name, const std::string secret)
|
||||
{
|
||||
|
@ -4114,6 +4145,20 @@ from_json(const json &j, VerificationCache &info)
|
|||
info.device_blocked = j.at("device_blocked").get<std::set<std::string>>();
|
||||
}
|
||||
|
||||
void
|
||||
to_json(json &j, const OnlineBackupVersion &info)
|
||||
{
|
||||
j["v"] = info.version;
|
||||
j["a"] = info.algorithm;
|
||||
}
|
||||
|
||||
void
|
||||
from_json(const json &j, OnlineBackupVersion &info)
|
||||
{
|
||||
info.version = j.at("v").get<std::string>();
|
||||
info.algorithm = j.at("a").get<std::string>();
|
||||
}
|
||||
|
||||
std::optional<VerificationCache>
|
||||
Cache::verificationCache(const std::string &user_id, lmdb::txn &txn)
|
||||
{
|
||||
|
@ -4461,6 +4506,7 @@ to_json(nlohmann::json &obj, const GroupSessionData &msg)
|
|||
{
|
||||
obj["message_index"] = msg.message_index;
|
||||
obj["ts"] = msg.timestamp;
|
||||
obj["trust"] = msg.trusted;
|
||||
|
||||
obj["sender_claimed_ed25519_key"] = msg.sender_claimed_ed25519_key;
|
||||
obj["forwarding_curve25519_key_chain"] = msg.forwarding_curve25519_key_chain;
|
||||
|
@ -4475,6 +4521,7 @@ from_json(const nlohmann::json &obj, GroupSessionData &msg)
|
|||
{
|
||||
msg.message_index = obj.at("message_index");
|
||||
msg.timestamp = obj.value("ts", 0ULL);
|
||||
msg.trusted = obj.value("trust", true);
|
||||
|
||||
msg.sender_claimed_ed25519_key = obj.value("sender_claimed_ed25519_key", "");
|
||||
msg.forwarding_curve25519_key_chain =
|
||||
|
|
|
@ -47,6 +47,11 @@ struct GroupSessionData
|
|||
uint64_t message_index = 0;
|
||||
uint64_t timestamp = 0;
|
||||
|
||||
// If we got the session via key sharing or forwarding, we can usually trust it.
|
||||
// If it came from asymmetric key backup, it is not trusted.
|
||||
// TODO(Nico): What about forwards? They might come from key backup?
|
||||
bool trusted = true;
|
||||
|
||||
std::string sender_claimed_ed25519_key;
|
||||
std::vector<std::string> forwarding_curve25519_key_chain;
|
||||
|
||||
|
@ -83,6 +88,13 @@ from_json(const nlohmann::json &obj, DevicePublicKeys &msg);
|
|||
//! Represents a unique megolm session identifier.
|
||||
struct MegolmSessionIndex
|
||||
{
|
||||
MegolmSessionIndex() = default;
|
||||
MegolmSessionIndex(std::string room_id_, const mtx::events::msg::Encrypted &e)
|
||||
: room_id(std::move(room_id_))
|
||||
, session_id(e.session_id)
|
||||
, sender_key(e.sender_key)
|
||||
{}
|
||||
|
||||
//! The room in which this session exists.
|
||||
std::string room_id;
|
||||
//! The session_id of the megolm session.
|
||||
|
@ -167,3 +179,16 @@ void
|
|||
to_json(nlohmann::json &j, const VerificationCache &info);
|
||||
void
|
||||
from_json(const nlohmann::json &j, VerificationCache &info);
|
||||
|
||||
struct OnlineBackupVersion
|
||||
{
|
||||
//! the version of the online backup currently enabled
|
||||
std::string version;
|
||||
//! the algorithm used by the backup
|
||||
std::string algorithm;
|
||||
};
|
||||
|
||||
void
|
||||
to_json(nlohmann::json &j, const OnlineBackupVersion &info);
|
||||
void
|
||||
from_json(const nlohmann::json &j, OnlineBackupVersion &info);
|
||||
|
|
|
@ -287,6 +287,10 @@ public:
|
|||
void saveOlmAccount(const std::string &pickled);
|
||||
std::string restoreOlmAccount();
|
||||
|
||||
void saveBackupVersion(const OnlineBackupVersion &data);
|
||||
void deleteBackupVersion();
|
||||
std::optional<OnlineBackupVersion> backupVersion();
|
||||
|
||||
void storeSecret(const std::string name, const std::string secret);
|
||||
void deleteSecret(const std::string name);
|
||||
std::optional<std::string> secret(const std::string name);
|
||||
|
|
100
src/ChatPage.cpp
100
src/ChatPage.cpp
|
@ -385,6 +385,7 @@ ChatPage::bootstrap(QString userid, QString homeserver, QString token)
|
|||
}
|
||||
|
||||
getProfileInfo();
|
||||
getBackupVersion();
|
||||
tryInitialSync();
|
||||
}
|
||||
|
||||
|
@ -418,6 +419,7 @@ ChatPage::loadStateFromCache()
|
|||
nhlog::crypto()->info("curve25519: {}", olm::client()->identity_keys().curve25519);
|
||||
|
||||
getProfileInfo();
|
||||
getBackupVersion();
|
||||
|
||||
emit contentLoaded();
|
||||
|
||||
|
@ -974,6 +976,104 @@ ChatPage::getProfileInfo()
|
|||
});
|
||||
}
|
||||
|
||||
void
|
||||
ChatPage::getBackupVersion()
|
||||
{
|
||||
if (!UserSettings::instance()->useOnlineKeyBackup()) {
|
||||
nhlog::crypto()->info("Online key backup disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
http::client()->backup_version(
|
||||
[this](const mtx::responses::backup::BackupVersion &res, mtx::http::RequestErr err) {
|
||||
if (err) {
|
||||
nhlog::net()->warn("Failed to retrieve backup version");
|
||||
if (err->status_code == 404)
|
||||
cache::client()->deleteBackupVersion();
|
||||
return;
|
||||
}
|
||||
|
||||
// switch to UI thread for secrets stuff
|
||||
QTimer::singleShot(0, this, [this, res] {
|
||||
auto auth_data = nlohmann::json::parse(res.auth_data);
|
||||
|
||||
if (res.algorithm == "m.megolm_backup.v1.curve25519-aes-sha2") {
|
||||
auto key =
|
||||
cache::secret(mtx::secret_storage::secrets::megolm_backup_v1);
|
||||
if (!key) {
|
||||
nhlog::crypto()->info("No key for online key backup.");
|
||||
cache::client()->deleteBackupVersion();
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace mtx::crypto;
|
||||
auto pubkey = CURVE25519_public_key_from_private(
|
||||
to_binary_buf(base642bin(*key)));
|
||||
|
||||
if (auth_data["public_key"].get<std::string>() != pubkey) {
|
||||
nhlog::crypto()->info(
|
||||
"Our backup key {} does not match the one "
|
||||
"used in the online backup {}",
|
||||
pubkey,
|
||||
auth_data["public_key"]);
|
||||
cache::client()->deleteBackupVersion();
|
||||
return;
|
||||
}
|
||||
|
||||
nhlog::crypto()->info("Using online key backup.");
|
||||
OnlineBackupVersion data{};
|
||||
data.algorithm = res.algorithm;
|
||||
data.version = res.version;
|
||||
cache::client()->saveBackupVersion(data);
|
||||
|
||||
// We really don't need to add our signature.
|
||||
// if (!auth_data["signatures"]
|
||||
// [http::client()->user_id().to_string()]
|
||||
// .contains("ed25519:" +
|
||||
// http::client()->device_id())) {
|
||||
// // add our signature
|
||||
// // This is not strictly necessary, but some Element
|
||||
// // clients rely on it. We assume the master_key
|
||||
// signature
|
||||
// // already exists and add our device signature just to
|
||||
// be
|
||||
// // safe, even though just the master signature is
|
||||
// enough,
|
||||
// // if cross-signing is used.
|
||||
// auto signatures = auth_data["signatures"];
|
||||
// auth_data.erase("signatures");
|
||||
// auth_data.erase("unsigned");
|
||||
// signatures[http::client()->user_id().to_string()]
|
||||
// ["ed25519:" + http::client()->device_id()] =
|
||||
// olm::client()->sign_message(auth_data.dump());
|
||||
// auth_data["signatures"] = signatures;
|
||||
|
||||
// auto copy = res;
|
||||
// copy.auth_data = auth_data.dump();
|
||||
// http::client()->update_backup_version(
|
||||
// res.version, copy, [](mtx::http::RequestErr e) {
|
||||
// if (e) {
|
||||
// nhlog::crypto()->error(
|
||||
// "Failed to update online backup "
|
||||
// "signatures: {} - {}",
|
||||
// mtx::errors::to_string(
|
||||
// e->matrix_error.errcode),
|
||||
// e->matrix_error.error);
|
||||
// } else {
|
||||
// nhlog::crypto()->info(
|
||||
// "Updated key backup signatures");
|
||||
// }
|
||||
// });
|
||||
//}
|
||||
} else {
|
||||
nhlog::crypto()->info("Unsupported key backup algorithm: {}",
|
||||
res.algorithm);
|
||||
cache::client()->deleteBackupVersion();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
ChatPage::initiateLogout()
|
||||
{
|
||||
|
|
|
@ -182,6 +182,7 @@ private:
|
|||
void trySync();
|
||||
void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts);
|
||||
void getProfileInfo();
|
||||
void getBackupVersion();
|
||||
|
||||
//! Check if the given room is currently open.
|
||||
bool isRoomActive(const QString &room_id);
|
||||
|
|
|
@ -130,26 +130,29 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
|
||||
trayIcon_->setVisible(userSettings_->tray());
|
||||
|
||||
if (hasActiveUser()) {
|
||||
QString token = userSettings_->accessToken();
|
||||
QString home_server = userSettings_->homeserver();
|
||||
QString user_id = userSettings_->userId();
|
||||
QString device_id = userSettings_->deviceId();
|
||||
// load cache on event loop
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
if (hasActiveUser()) {
|
||||
QString token = userSettings_->accessToken();
|
||||
QString home_server = userSettings_->homeserver();
|
||||
QString user_id = userSettings_->userId();
|
||||
QString device_id = userSettings_->deviceId();
|
||||
|
||||
http::client()->set_access_token(token.toStdString());
|
||||
http::client()->set_server(home_server.toStdString());
|
||||
http::client()->set_device_id(device_id.toStdString());
|
||||
http::client()->set_access_token(token.toStdString());
|
||||
http::client()->set_server(home_server.toStdString());
|
||||
http::client()->set_device_id(device_id.toStdString());
|
||||
|
||||
try {
|
||||
using namespace mtx::identifiers;
|
||||
http::client()->set_user(parse<User>(user_id.toStdString()));
|
||||
} catch (const std::invalid_argument &) {
|
||||
nhlog::ui()->critical("bootstrapped with invalid user_id: {}",
|
||||
user_id.toStdString());
|
||||
try {
|
||||
using namespace mtx::identifiers;
|
||||
http::client()->set_user(parse<User>(user_id.toStdString()));
|
||||
} catch (const std::invalid_argument &) {
|
||||
nhlog::ui()->critical("bootstrapped with invalid user_id: {}",
|
||||
user_id.toStdString());
|
||||
}
|
||||
|
||||
showChatPage();
|
||||
}
|
||||
|
||||
showChatPage();
|
||||
}
|
||||
});
|
||||
|
||||
if (loadJdenticonPlugin()) {
|
||||
nhlog::ui()->info("loaded jdenticon.");
|
||||
|
|
104
src/Olm.cpp
104
src/Olm.cpp
|
@ -833,6 +833,8 @@ import_inbound_megolm_session(
|
|||
data.forwarding_curve25519_key_chain =
|
||||
roomKey.content.forwarding_curve25519_key_chain;
|
||||
data.sender_claimed_ed25519_key = roomKey.content.sender_claimed_ed25519_key;
|
||||
// may have come from online key backup, so we can't trust it...
|
||||
data.trusted = false;
|
||||
|
||||
cache::saveInboundMegolmSession(index, std::move(megolm_session), data);
|
||||
} catch (const lmdb::error &e) {
|
||||
|
@ -856,6 +858,97 @@ mark_keys_as_published()
|
|||
cache::saveOlmAccount(olm::client()->save(STORAGE_SECRET_KEY));
|
||||
}
|
||||
|
||||
void
|
||||
lookup_keybackup(const std::string room, const std::string session_id)
|
||||
{
|
||||
if (!UserSettings::instance()->useOnlineKeyBackup()) {
|
||||
// Online key backup disabled
|
||||
return;
|
||||
}
|
||||
|
||||
auto backupVersion = cache::client()->backupVersion();
|
||||
if (!backupVersion) {
|
||||
// no trusted OKB
|
||||
return;
|
||||
}
|
||||
|
||||
using namespace mtx::crypto;
|
||||
|
||||
auto decryptedSecret = cache::secret(mtx::secret_storage::secrets::megolm_backup_v1);
|
||||
if (!decryptedSecret) {
|
||||
// no backup key available
|
||||
return;
|
||||
}
|
||||
auto sessionDecryptionKey = to_binary_buf(base642bin(*decryptedSecret));
|
||||
|
||||
http::client()->room_keys(
|
||||
backupVersion->version,
|
||||
room,
|
||||
session_id,
|
||||
[room, session_id, sessionDecryptionKey](const mtx::responses::backup::SessionBackup &bk,
|
||||
mtx::http::RequestErr err) {
|
||||
if (err) {
|
||||
if (err->status_code != 404)
|
||||
nhlog::crypto()->error(
|
||||
"Failed to dowload key {}:{}: {} - {}",
|
||||
room,
|
||||
session_id,
|
||||
mtx::errors::to_string(err->matrix_error.errcode),
|
||||
err->matrix_error.error);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
auto session = decrypt_session(bk.session_data, sessionDecryptionKey);
|
||||
|
||||
if (session.algorithm != mtx::crypto::MEGOLM_ALGO)
|
||||
// don't know this algorithm
|
||||
return;
|
||||
|
||||
MegolmSessionIndex index;
|
||||
index.room_id = room;
|
||||
index.session_id = session_id;
|
||||
index.sender_key = session.sender_key;
|
||||
|
||||
GroupSessionData data{};
|
||||
data.forwarding_curve25519_key_chain =
|
||||
session.forwarding_curve25519_key_chain;
|
||||
data.sender_claimed_ed25519_key = session.sender_claimed_keys["ed25519"];
|
||||
// online key backup can't be trusted, because anyone can upload to it.
|
||||
data.trusted = false;
|
||||
|
||||
auto megolm_session =
|
||||
olm::client()->import_inbound_group_session(session.session_key);
|
||||
|
||||
if (!cache::inboundMegolmSessionExists(index) ||
|
||||
olm_inbound_group_session_first_known_index(megolm_session.get()) <
|
||||
olm_inbound_group_session_first_known_index(
|
||||
cache::getInboundMegolmSession(index).get())) {
|
||||
cache::saveInboundMegolmSession(
|
||||
index, std::move(megolm_session), data);
|
||||
|
||||
nhlog::crypto()->info("imported inbound megolm session "
|
||||
"from key backup ({}, {})",
|
||||
room,
|
||||
session_id);
|
||||
|
||||
// call on UI thread
|
||||
QTimer::singleShot(0, ChatPage::instance(), [index] {
|
||||
ChatPage::instance()->receivedSessionKey(
|
||||
index.room_id, index.session_id);
|
||||
});
|
||||
}
|
||||
} catch (const lmdb::error &e) {
|
||||
nhlog::crypto()->critical("failed to save inbound megolm session: {}",
|
||||
e.what());
|
||||
return;
|
||||
} catch (const mtx::crypto::olm_exception &e) {
|
||||
nhlog::crypto()->critical("failed to import inbound megolm session: {}",
|
||||
e.what());
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
send_key_request_for(mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> e,
|
||||
const std::string &request_id,
|
||||
|
@ -898,6 +991,8 @@ send_key_request_for(mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> e,
|
|||
e.sender,
|
||||
e.content.device_id);
|
||||
});
|
||||
|
||||
// http::client()->room_keys
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1095,12 +1190,15 @@ decryptEvent(const MegolmSessionIndex &index,
|
|||
}
|
||||
|
||||
crypto::Trust
|
||||
calculate_trust(const std::string &user_id, const std::string &curve25519)
|
||||
calculate_trust(const std::string &user_id, const MegolmSessionIndex &index)
|
||||
{
|
||||
auto status = cache::client()->verificationStatus(user_id);
|
||||
auto megolmData = cache::client()->getMegolmSessionData(index);
|
||||
crypto::Trust trustlevel = crypto::Trust::Unverified;
|
||||
if (status.verified_device_keys.count(curve25519))
|
||||
trustlevel = status.verified_device_keys.at(curve25519);
|
||||
|
||||
if (megolmData && megolmData->trusted &&
|
||||
status.verified_device_keys.count(index.sender_key))
|
||||
trustlevel = status.verified_device_keys.at(index.sender_key);
|
||||
|
||||
return trustlevel;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,8 @@ create_inbound_megolm_session(const mtx::events::DeviceEvent<mtx::events::msg::R
|
|||
void
|
||||
import_inbound_megolm_session(
|
||||
const mtx::events::DeviceEvent<mtx::events::msg::ForwardedRoomKey> &roomKey);
|
||||
void
|
||||
lookup_keybackup(const std::string room, const std::string session_id);
|
||||
|
||||
nlohmann::json
|
||||
handle_pre_key_olm_message(const std::string &sender,
|
||||
|
@ -87,7 +89,7 @@ decryptEvent(const MegolmSessionIndex &index,
|
|||
const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &event,
|
||||
bool dont_write_db = false);
|
||||
crypto::Trust
|
||||
calculate_trust(const std::string &user_id, const std::string &curve25519);
|
||||
calculate_trust(const std::string &user_id, const MegolmSessionIndex &index);
|
||||
|
||||
void
|
||||
mark_keys_as_published();
|
||||
|
|
|
@ -124,6 +124,7 @@ UserSettings::load(std::optional<QString> profile)
|
|||
.toBool();
|
||||
onlyShareKeysWithVerifiedUsers_ =
|
||||
settings.value(prefix + "user/only_share_keys_with_verified_users", false).toBool();
|
||||
useOnlineKeyBackup_ = settings.value(prefix + "user/online_key_backup", true).toBool();
|
||||
|
||||
disableCertificateValidation_ =
|
||||
settings.value("disable_certificate_validation", false).toBool();
|
||||
|
@ -425,6 +426,17 @@ UserSettings::setShareKeysWithTrustedUsers(bool shareKeys)
|
|||
save();
|
||||
}
|
||||
|
||||
void
|
||||
UserSettings::setUseOnlineKeyBackup(bool useBackup)
|
||||
{
|
||||
if (useBackup == useOnlineKeyBackup_)
|
||||
return;
|
||||
|
||||
useOnlineKeyBackup_ = useBackup;
|
||||
emit useOnlineKeyBackupChanged(useBackup);
|
||||
save();
|
||||
}
|
||||
|
||||
void
|
||||
UserSettings::setRingtone(QString ringtone)
|
||||
{
|
||||
|
@ -664,6 +676,7 @@ UserSettings::save()
|
|||
shareKeysWithTrustedUsers_);
|
||||
settings.setValue(prefix + "user/only_share_keys_with_verified_users",
|
||||
onlyShareKeysWithVerifiedUsers_);
|
||||
settings.setValue(prefix + "user/online_key_backup", useOnlineKeyBackup_);
|
||||
|
||||
settings.setValue("disable_certificate_validation", disableCertificateValidation_);
|
||||
|
||||
|
@ -725,6 +738,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
privacyScreen_ = new Toggle{this};
|
||||
onlyShareKeysWithVerifiedUsers_ = new Toggle(this);
|
||||
shareKeysWithTrustedUsers_ = new Toggle(this);
|
||||
useOnlineKeyBackup_ = new Toggle(this);
|
||||
groupViewToggle_ = new Toggle{this};
|
||||
timelineButtonsToggle_ = new Toggle{this};
|
||||
typingNotifications_ = new Toggle{this};
|
||||
|
@ -756,6 +770,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
privacyScreen_->setChecked(settings_->privacyScreen());
|
||||
onlyShareKeysWithVerifiedUsers_->setChecked(settings_->onlyShareKeysWithVerifiedUsers());
|
||||
shareKeysWithTrustedUsers_->setChecked(settings_->shareKeysWithTrustedUsers());
|
||||
useOnlineKeyBackup_->setChecked(settings_->useOnlineKeyBackup());
|
||||
groupViewToggle_->setChecked(settings_->groupView());
|
||||
timelineButtonsToggle_->setChecked(settings_->buttonsInTimeline());
|
||||
typingNotifications_->setChecked(settings_->typingNotifications());
|
||||
|
@ -1033,6 +1048,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
shareKeysWithTrustedUsers_,
|
||||
tr("Automatically replies to key requests from other users, if they are verified, "
|
||||
"even if that device shouldn't have access to those keys otherwise."));
|
||||
boxWrap(tr("Online Key Backup"),
|
||||
useOnlineKeyBackup_,
|
||||
tr("Download message encryption keys from and upload to the encrypted online key "
|
||||
"backup."));
|
||||
formLayout_->addRow(new HorizontalLine{this});
|
||||
formLayout_->addRow(sessionKeysLabel, sessionKeysLayout);
|
||||
formLayout_->addRow(crossSigningKeysLabel, crossSigningKeysLayout);
|
||||
|
@ -1208,6 +1227,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
|||
settings_->setShareKeysWithTrustedUsers(enabled);
|
||||
});
|
||||
|
||||
connect(useOnlineKeyBackup_, &Toggle::toggled, this, [this](bool enabled) {
|
||||
settings_->setUseOnlineKeyBackup(enabled);
|
||||
});
|
||||
|
||||
connect(avatarCircles_, &Toggle::toggled, this, [this](bool enabled) {
|
||||
settings_->setAvatarCircles(enabled);
|
||||
});
|
||||
|
@ -1298,6 +1321,7 @@ UserSettingsPage::showEvent(QShowEvent *)
|
|||
privacyScreen_->setState(settings_->privacyScreen());
|
||||
onlyShareKeysWithVerifiedUsers_->setState(settings_->onlyShareKeysWithVerifiedUsers());
|
||||
shareKeysWithTrustedUsers_->setState(settings_->shareKeysWithTrustedUsers());
|
||||
useOnlineKeyBackup_->setState(settings_->useOnlineKeyBackup());
|
||||
avatarCircles_->setState(settings_->avatarCircles());
|
||||
typingNotifications_->setState(settings_->typingNotifications());
|
||||
sortByImportance_->setState(settings_->sortByImportance());
|
||||
|
|
|
@ -93,6 +93,8 @@ class UserSettings : public QObject
|
|||
setOnlyShareKeysWithVerifiedUsers NOTIFY onlyShareKeysWithVerifiedUsersChanged)
|
||||
Q_PROPERTY(bool shareKeysWithTrustedUsers READ shareKeysWithTrustedUsers WRITE
|
||||
setShareKeysWithTrustedUsers NOTIFY shareKeysWithTrustedUsersChanged)
|
||||
Q_PROPERTY(bool useOnlineKeyBackup READ useOnlineKeyBackup WRITE setUseOnlineKeyBackup
|
||||
NOTIFY useOnlineKeyBackupChanged)
|
||||
Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
|
||||
Q_PROPERTY(QString userId READ userId WRITE setUserId NOTIFY userIdChanged)
|
||||
Q_PROPERTY(
|
||||
|
@ -159,6 +161,7 @@ public:
|
|||
void setUseStunServer(bool state);
|
||||
void setOnlyShareKeysWithVerifiedUsers(bool state);
|
||||
void setShareKeysWithTrustedUsers(bool state);
|
||||
void setUseOnlineKeyBackup(bool state);
|
||||
void setProfile(QString profile);
|
||||
void setUserId(QString userId);
|
||||
void setAccessToken(QString accessToken);
|
||||
|
@ -215,6 +218,7 @@ public:
|
|||
bool useStunServer() const { return useStunServer_; }
|
||||
bool shareKeysWithTrustedUsers() const { return shareKeysWithTrustedUsers_; }
|
||||
bool onlyShareKeysWithVerifiedUsers() const { return onlyShareKeysWithVerifiedUsers_; }
|
||||
bool useOnlineKeyBackup() const { return useOnlineKeyBackup_; }
|
||||
QString profile() const { return profile_; }
|
||||
QString userId() const { return userId_; }
|
||||
QString accessToken() const { return accessToken_; }
|
||||
|
@ -261,6 +265,7 @@ signals:
|
|||
void useStunServerChanged(bool state);
|
||||
void onlyShareKeysWithVerifiedUsersChanged(bool state);
|
||||
void shareKeysWithTrustedUsersChanged(bool state);
|
||||
void useOnlineKeyBackupChanged(bool state);
|
||||
void profileChanged(QString profile);
|
||||
void userIdChanged(QString userId);
|
||||
void accessTokenChanged(QString accessToken);
|
||||
|
@ -293,6 +298,7 @@ private:
|
|||
int privacyScreenTimeout_;
|
||||
bool shareKeysWithTrustedUsers_;
|
||||
bool onlyShareKeysWithVerifiedUsers_;
|
||||
bool useOnlineKeyBackup_;
|
||||
bool mobileMode_;
|
||||
int timelineMaxWidth_;
|
||||
int roomListWidth_;
|
||||
|
@ -384,6 +390,7 @@ private:
|
|||
QSpinBox *privacyScreenTimeout_;
|
||||
Toggle *shareKeysWithTrustedUsers_;
|
||||
Toggle *onlyShareKeysWithVerifiedUsers_;
|
||||
Toggle *useOnlineKeyBackup_;
|
||||
Toggle *mobileMode_;
|
||||
QLabel *deviceFingerprintValue_;
|
||||
QLabel *deviceIdValue_;
|
||||
|
|
|
@ -643,10 +643,7 @@ EventStore::decryptEvent(const IdIndex &idx,
|
|||
if (auto cachedEvent = decryptedEvents_.object(idx))
|
||||
return cachedEvent;
|
||||
|
||||
MegolmSessionIndex index;
|
||||
index.room_id = room_id_;
|
||||
index.session_id = e.content.session_id;
|
||||
index.sender_key = e.content.sender_key;
|
||||
MegolmSessionIndex index(room_id_, e.content);
|
||||
|
||||
auto asCacheEntry = [&idx](olm::DecryptionResult &&event) {
|
||||
auto event_ptr = new olm::DecryptionResult(std::move(event));
|
||||
|
@ -726,6 +723,7 @@ EventStore::requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::E
|
|||
qint64 delay = manual ? 60 : (60 * 10);
|
||||
if (r.requested_at + delay < QDateTime::currentSecsSinceEpoch()) {
|
||||
r.requested_at = QDateTime::currentSecsSinceEpoch();
|
||||
olm::lookup_keybackup(room_id_, ev.content.session_id);
|
||||
olm::send_key_request_for(copy, r.request_id);
|
||||
}
|
||||
} else {
|
||||
|
@ -733,6 +731,7 @@ EventStore::requestSession(const mtx::events::EncryptedEvent<mtx::events::msg::E
|
|||
request.request_id = "key_request." + http::client()->generate_txn_id();
|
||||
request.requested_at = QDateTime::currentSecsSinceEpoch();
|
||||
request.events.push_back(copy);
|
||||
olm::lookup_keybackup(room_id_, ev.content.session_id);
|
||||
olm::send_key_request_for(copy, request.request_id);
|
||||
pending_key_requests[ev.content.session_id] = request;
|
||||
}
|
||||
|
|
|
@ -641,8 +641,9 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r
|
|||
if (auto encrypted =
|
||||
std::get_if<mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(
|
||||
&*encrypted_event)) {
|
||||
return olm::calculate_trust(encrypted->sender,
|
||||
encrypted->content.sender_key);
|
||||
return olm::calculate_trust(
|
||||
encrypted->sender,
|
||||
MegolmSessionIndex(room_id_.toStdString(), encrypted->content));
|
||||
}
|
||||
}
|
||||
return crypto::Trust::Unverified;
|
||||
|
@ -840,10 +841,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline)
|
|||
|
||||
for (auto e : timeline.events) {
|
||||
if (auto encryptedEvent = std::get_if<EncryptedEvent<msg::Encrypted>>(&e)) {
|
||||
MegolmSessionIndex index;
|
||||
index.room_id = room_id_.toStdString();
|
||||
index.session_id = encryptedEvent->content.session_id;
|
||||
index.sender_key = encryptedEvent->content.sender_key;
|
||||
MegolmSessionIndex index(room_id_.toStdString(), encryptedEvent->content);
|
||||
|
||||
auto result = olm::decryptEvent(index, *encryptedEvent);
|
||||
if (result.event)
|
||||
|
|
Loading…
Reference in a new issue