mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-26 13:08:48 +03:00
Add option to only send encrypted messages to verified devices
fixes #636
This commit is contained in:
parent
760f675792
commit
25e7a985b8
5 changed files with 127 additions and 48 deletions
|
@ -3542,7 +3542,7 @@ Cache::roomMembers(const std::string &room_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, std::optional<UserKeyCache>>
|
std::map<std::string, std::optional<UserKeyCache>>
|
||||||
Cache::getMembersWithKeys(const std::string &room_id)
|
Cache::getMembersWithKeys(const std::string &room_id, bool verified_only)
|
||||||
{
|
{
|
||||||
std::string_view keys;
|
std::string_view keys;
|
||||||
|
|
||||||
|
@ -3559,9 +3559,50 @@ Cache::getMembersWithKeys(const std::string &room_id)
|
||||||
auto res = keysDb.get(txn, user_id, keys);
|
auto res = keysDb.get(txn, user_id, keys);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
auto k = json::parse(keys).get<UserKeyCache>();
|
||||||
|
if (verified_only) {
|
||||||
|
auto verif = verificationStatus(std::string(user_id));
|
||||||
|
if (verif.user_verified == crypto::Trust::Verified ||
|
||||||
|
!verif.verified_devices.empty()) {
|
||||||
|
auto keyCopy = k;
|
||||||
|
keyCopy.device_keys.clear();
|
||||||
|
|
||||||
|
std::copy_if(
|
||||||
|
k.device_keys.begin(),
|
||||||
|
k.device_keys.end(),
|
||||||
|
std::inserter(keyCopy.device_keys,
|
||||||
|
keyCopy.device_keys.end()),
|
||||||
|
[&verif](const auto &key) {
|
||||||
|
auto curve25519 = key.second.keys.find(
|
||||||
|
"curve25519:" + key.first);
|
||||||
|
if (curve25519 == key.second.keys.end())
|
||||||
|
return false;
|
||||||
|
if (auto t =
|
||||||
|
verif.verified_device_keys.find(
|
||||||
|
curve25519->second);
|
||||||
|
t ==
|
||||||
|
verif.verified_device_keys.end() ||
|
||||||
|
t->second != crypto::Trust::Verified)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return key.first ==
|
||||||
|
key.second.device_id &&
|
||||||
|
std::find(
|
||||||
|
verif.verified_devices.begin(),
|
||||||
|
verif.verified_devices.end(),
|
||||||
|
key.first) !=
|
||||||
|
verif.verified_devices.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!keyCopy.device_keys.empty())
|
||||||
members[std::string(user_id)] =
|
members[std::string(user_id)] =
|
||||||
json::parse(keys).get<UserKeyCache>();
|
std::move(keyCopy);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
members[std::string(user_id)] = std::move(k);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!verified_only)
|
||||||
members[std::string(user_id)] = {};
|
members[std::string(user_id)] = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,8 @@ public:
|
||||||
// user cache stores user keys
|
// user cache stores user keys
|
||||||
std::optional<UserKeyCache> userKeys(const std::string &user_id);
|
std::optional<UserKeyCache> userKeys(const std::string &user_id);
|
||||||
std::map<std::string, std::optional<UserKeyCache>> getMembersWithKeys(
|
std::map<std::string, std::optional<UserKeyCache>> getMembersWithKeys(
|
||||||
const std::string &room_id);
|
const std::string &room_id,
|
||||||
|
bool verified_only);
|
||||||
void updateUserKeys(const std::string &sync_token,
|
void updateUserKeys(const std::string &sync_token,
|
||||||
const mtx::responses::QueryKeys &keyQuery);
|
const mtx::responses::QueryKeys &keyQuery);
|
||||||
void markUserKeysOutOfDate(lmdb::txn &txn,
|
void markUserKeysOutOfDate(lmdb::txn &txn,
|
||||||
|
|
|
@ -524,7 +524,8 @@ encrypt_group_message(const std::string &room_id, const std::string &device_id,
|
||||||
|
|
||||||
auto own_user_id = http::client()->user_id().to_string();
|
auto own_user_id = http::client()->user_id().to_string();
|
||||||
|
|
||||||
auto members = cache::client()->getMembersWithKeys(room_id);
|
auto members = cache::client()->getMembersWithKeys(
|
||||||
|
room_id, UserSettings::instance()->onlyShareKeysWithVerifiedUsers());
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::string>> sendSessionTo;
|
std::map<std::string, std::vector<std::string>> sendSessionTo;
|
||||||
mtx::crypto::OutboundGroupSessionPtr session = nullptr;
|
mtx::crypto::OutboundGroupSessionPtr session = nullptr;
|
||||||
|
|
|
@ -90,8 +90,6 @@ UserSettings::load(std::optional<QString> profile)
|
||||||
decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool();
|
decryptSidebar_ = settings.value("user/decrypt_sidebar", true).toBool();
|
||||||
privacyScreen_ = settings.value("user/privacy_screen", false).toBool();
|
privacyScreen_ = settings.value("user/privacy_screen", false).toBool();
|
||||||
privacyScreenTimeout_ = settings.value("user/privacy_screen_timeout", 0).toInt();
|
privacyScreenTimeout_ = settings.value("user/privacy_screen_timeout", 0).toInt();
|
||||||
shareKeysWithTrustedUsers_ =
|
|
||||||
settings.value("user/automatically_share_keys_with_trusted_users", false).toBool();
|
|
||||||
mobileMode_ = settings.value("user/mobile_mode", false).toBool();
|
mobileMode_ = settings.value("user/mobile_mode", false).toBool();
|
||||||
emojiFont_ = settings.value("user/emoji_font_family", "default").toString();
|
emojiFont_ = settings.value("user/emoji_font_family", "default").toString();
|
||||||
baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble();
|
baseFontSize_ = settings.value("user/font_size", QFont().pointSizeF()).toDouble();
|
||||||
|
@ -123,6 +121,12 @@ UserSettings::load(std::optional<QString> profile)
|
||||||
userId_ = settings.value(prefix + "auth/user_id", "").toString();
|
userId_ = settings.value(prefix + "auth/user_id", "").toString();
|
||||||
deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
|
deviceId_ = settings.value(prefix + "auth/device_id", "").toString();
|
||||||
|
|
||||||
|
shareKeysWithTrustedUsers_ =
|
||||||
|
settings.value(prefix + "user/automatically_share_keys_with_trusted_users", false)
|
||||||
|
.toBool();
|
||||||
|
onlyShareKeysWithVerifiedUsers_ =
|
||||||
|
settings.value(prefix + "user/only_share_keys_with_verified_users", false).toBool();
|
||||||
|
|
||||||
disableCertificateValidation_ =
|
disableCertificateValidation_ =
|
||||||
settings.value("disable_certificate_validation", false).toBool();
|
settings.value("disable_certificate_validation", false).toBool();
|
||||||
|
|
||||||
|
@ -401,6 +405,17 @@ UserSettings::setUseStunServer(bool useStunServer)
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserSettings::setOnlyShareKeysWithVerifiedUsers(bool shareKeys)
|
||||||
|
{
|
||||||
|
if (shareKeys == onlyShareKeysWithVerifiedUsers_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
onlyShareKeysWithVerifiedUsers_ = shareKeys;
|
||||||
|
emit onlyShareKeysWithVerifiedUsersChanged(shareKeys);
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
UserSettings::setShareKeysWithTrustedUsers(bool shareKeys)
|
UserSettings::setShareKeysWithTrustedUsers(bool shareKeys)
|
||||||
{
|
{
|
||||||
|
@ -610,8 +625,6 @@ UserSettings::save()
|
||||||
settings.setValue("decrypt_sidebar", decryptSidebar_);
|
settings.setValue("decrypt_sidebar", decryptSidebar_);
|
||||||
settings.setValue("privacy_screen", privacyScreen_);
|
settings.setValue("privacy_screen", privacyScreen_);
|
||||||
settings.setValue("privacy_screen_timeout", privacyScreenTimeout_);
|
settings.setValue("privacy_screen_timeout", privacyScreenTimeout_);
|
||||||
settings.setValue("automatically_share_keys_with_trusted_users",
|
|
||||||
shareKeysWithTrustedUsers_);
|
|
||||||
settings.setValue("mobile_mode", mobileMode_);
|
settings.setValue("mobile_mode", mobileMode_);
|
||||||
settings.setValue("font_size", baseFontSize_);
|
settings.setValue("font_size", baseFontSize_);
|
||||||
settings.setValue("typing_notifications", typingNotifications_);
|
settings.setValue("typing_notifications", typingNotifications_);
|
||||||
|
@ -650,6 +663,11 @@ UserSettings::save()
|
||||||
settings.setValue(prefix + "auth/user_id", userId_);
|
settings.setValue(prefix + "auth/user_id", userId_);
|
||||||
settings.setValue(prefix + "auth/device_id", deviceId_);
|
settings.setValue(prefix + "auth/device_id", deviceId_);
|
||||||
|
|
||||||
|
settings.setValue(prefix + "user/automatically_share_keys_with_trusted_users",
|
||||||
|
shareKeysWithTrustedUsers_);
|
||||||
|
settings.setValue(prefix + "user/only_share_keys_with_verified_users",
|
||||||
|
onlyShareKeysWithVerifiedUsers_);
|
||||||
|
|
||||||
settings.setValue("disable_certificate_validation", disableCertificateValidation_);
|
settings.setValue("disable_certificate_validation", disableCertificateValidation_);
|
||||||
|
|
||||||
settings.sync();
|
settings.sync();
|
||||||
|
@ -708,6 +726,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
||||||
avatarCircles_ = new Toggle{this};
|
avatarCircles_ = new Toggle{this};
|
||||||
decryptSidebar_ = new Toggle(this);
|
decryptSidebar_ = new Toggle(this);
|
||||||
privacyScreen_ = new Toggle{this};
|
privacyScreen_ = new Toggle{this};
|
||||||
|
onlyShareKeysWithVerifiedUsers_ = new Toggle(this);
|
||||||
shareKeysWithTrustedUsers_ = new Toggle(this);
|
shareKeysWithTrustedUsers_ = new Toggle(this);
|
||||||
groupViewToggle_ = new Toggle{this};
|
groupViewToggle_ = new Toggle{this};
|
||||||
timelineButtonsToggle_ = new Toggle{this};
|
timelineButtonsToggle_ = new Toggle{this};
|
||||||
|
@ -738,6 +757,7 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
||||||
avatarCircles_->setChecked(settings_->avatarCircles());
|
avatarCircles_->setChecked(settings_->avatarCircles());
|
||||||
decryptSidebar_->setChecked(settings_->decryptSidebar());
|
decryptSidebar_->setChecked(settings_->decryptSidebar());
|
||||||
privacyScreen_->setChecked(settings_->privacyScreen());
|
privacyScreen_->setChecked(settings_->privacyScreen());
|
||||||
|
onlyShareKeysWithVerifiedUsers_->setChecked(settings_->onlyShareKeysWithVerifiedUsers());
|
||||||
shareKeysWithTrustedUsers_->setChecked(settings_->shareKeysWithTrustedUsers());
|
shareKeysWithTrustedUsers_->setChecked(settings_->shareKeysWithTrustedUsers());
|
||||||
groupViewToggle_->setChecked(settings_->groupView());
|
groupViewToggle_->setChecked(settings_->groupView());
|
||||||
timelineButtonsToggle_->setChecked(settings_->buttonsInTimeline());
|
timelineButtonsToggle_->setChecked(settings_->buttonsInTimeline());
|
||||||
|
@ -1008,10 +1028,14 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
||||||
formLayout_->addRow(new HorizontalLine{this});
|
formLayout_->addRow(new HorizontalLine{this});
|
||||||
boxWrap(tr("Device ID"), deviceIdValue_);
|
boxWrap(tr("Device ID"), deviceIdValue_);
|
||||||
boxWrap(tr("Device Fingerprint"), deviceFingerprintValue_);
|
boxWrap(tr("Device Fingerprint"), deviceFingerprintValue_);
|
||||||
boxWrap(
|
boxWrap(tr("Send encrypted messages to verified users only"),
|
||||||
tr("Share keys with verified users and devices"),
|
onlyShareKeysWithVerifiedUsers_,
|
||||||
|
tr("Requires a user to be verified to send encrypted messages to them. This "
|
||||||
|
"improves safety but makes E2EE more tedious."));
|
||||||
|
boxWrap(tr("Share keys with verified users and devices"),
|
||||||
shareKeysWithTrustedUsers_,
|
shareKeysWithTrustedUsers_,
|
||||||
tr("Automatically replies to key requests from other users, if they are verified."));
|
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."));
|
||||||
formLayout_->addRow(new HorizontalLine{this});
|
formLayout_->addRow(new HorizontalLine{this});
|
||||||
formLayout_->addRow(sessionKeysLabel, sessionKeysLayout);
|
formLayout_->addRow(sessionKeysLabel, sessionKeysLayout);
|
||||||
formLayout_->addRow(crossSigningKeysLabel, crossSigningKeysLayout);
|
formLayout_->addRow(crossSigningKeysLabel, crossSigningKeysLayout);
|
||||||
|
@ -1179,6 +1203,10 @@ UserSettingsPage::UserSettingsPage(QSharedPointer<UserSettings> settings, QWidge
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(onlyShareKeysWithVerifiedUsers_, &Toggle::toggled, this, [this](bool enabled) {
|
||||||
|
settings_->setOnlyShareKeysWithVerifiedUsers(enabled);
|
||||||
|
});
|
||||||
|
|
||||||
connect(shareKeysWithTrustedUsers_, &Toggle::toggled, this, [this](bool enabled) {
|
connect(shareKeysWithTrustedUsers_, &Toggle::toggled, this, [this](bool enabled) {
|
||||||
settings_->setShareKeysWithTrustedUsers(enabled);
|
settings_->setShareKeysWithTrustedUsers(enabled);
|
||||||
});
|
});
|
||||||
|
@ -1271,6 +1299,7 @@ UserSettingsPage::showEvent(QShowEvent *)
|
||||||
groupViewToggle_->setState(settings_->groupView());
|
groupViewToggle_->setState(settings_->groupView());
|
||||||
decryptSidebar_->setState(settings_->decryptSidebar());
|
decryptSidebar_->setState(settings_->decryptSidebar());
|
||||||
privacyScreen_->setState(settings_->privacyScreen());
|
privacyScreen_->setState(settings_->privacyScreen());
|
||||||
|
onlyShareKeysWithVerifiedUsers_->setState(settings_->onlyShareKeysWithVerifiedUsers());
|
||||||
shareKeysWithTrustedUsers_->setState(settings_->shareKeysWithTrustedUsers());
|
shareKeysWithTrustedUsers_->setState(settings_->shareKeysWithTrustedUsers());
|
||||||
avatarCircles_->setState(settings_->avatarCircles());
|
avatarCircles_->setState(settings_->avatarCircles());
|
||||||
typingNotifications_->setState(settings_->typingNotifications());
|
typingNotifications_->setState(settings_->typingNotifications());
|
||||||
|
|
|
@ -88,6 +88,8 @@ class UserSettings : public QObject
|
||||||
setScreenShareHideCursor NOTIFY screenShareHideCursorChanged)
|
setScreenShareHideCursor NOTIFY screenShareHideCursorChanged)
|
||||||
Q_PROPERTY(
|
Q_PROPERTY(
|
||||||
bool useStunServer READ useStunServer WRITE setUseStunServer NOTIFY useStunServerChanged)
|
bool useStunServer READ useStunServer WRITE setUseStunServer NOTIFY useStunServerChanged)
|
||||||
|
Q_PROPERTY(bool onlyShareKeysWithVerifiedUsers READ onlyShareKeysWithVerifiedUsers WRITE
|
||||||
|
setOnlyShareKeysWithVerifiedUsers NOTIFY onlyShareKeysWithVerifiedUsersChanged)
|
||||||
Q_PROPERTY(bool shareKeysWithTrustedUsers READ shareKeysWithTrustedUsers WRITE
|
Q_PROPERTY(bool shareKeysWithTrustedUsers READ shareKeysWithTrustedUsers WRITE
|
||||||
setShareKeysWithTrustedUsers NOTIFY shareKeysWithTrustedUsersChanged)
|
setShareKeysWithTrustedUsers NOTIFY shareKeysWithTrustedUsersChanged)
|
||||||
Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
|
Q_PROPERTY(QString profile READ profile WRITE setProfile NOTIFY profileChanged)
|
||||||
|
@ -152,6 +154,7 @@ public:
|
||||||
void setScreenShareRemoteVideo(bool state);
|
void setScreenShareRemoteVideo(bool state);
|
||||||
void setScreenShareHideCursor(bool state);
|
void setScreenShareHideCursor(bool state);
|
||||||
void setUseStunServer(bool state);
|
void setUseStunServer(bool state);
|
||||||
|
void setOnlyShareKeysWithVerifiedUsers(bool state);
|
||||||
void setShareKeysWithTrustedUsers(bool state);
|
void setShareKeysWithTrustedUsers(bool state);
|
||||||
void setProfile(QString profile);
|
void setProfile(QString profile);
|
||||||
void setUserId(QString userId);
|
void setUserId(QString userId);
|
||||||
|
@ -208,6 +211,7 @@ public:
|
||||||
bool screenShareHideCursor() const { return screenShareHideCursor_; }
|
bool screenShareHideCursor() const { return screenShareHideCursor_; }
|
||||||
bool useStunServer() const { return useStunServer_; }
|
bool useStunServer() const { return useStunServer_; }
|
||||||
bool shareKeysWithTrustedUsers() const { return shareKeysWithTrustedUsers_; }
|
bool shareKeysWithTrustedUsers() const { return shareKeysWithTrustedUsers_; }
|
||||||
|
bool onlyShareKeysWithVerifiedUsers() const { return onlyShareKeysWithVerifiedUsers_; }
|
||||||
QString profile() const { return profile_; }
|
QString profile() const { return profile_; }
|
||||||
QString userId() const { return userId_; }
|
QString userId() const { return userId_; }
|
||||||
QString accessToken() const { return accessToken_; }
|
QString accessToken() const { return accessToken_; }
|
||||||
|
@ -252,6 +256,7 @@ signals:
|
||||||
void screenShareRemoteVideoChanged(bool state);
|
void screenShareRemoteVideoChanged(bool state);
|
||||||
void screenShareHideCursorChanged(bool state);
|
void screenShareHideCursorChanged(bool state);
|
||||||
void useStunServerChanged(bool state);
|
void useStunServerChanged(bool state);
|
||||||
|
void onlyShareKeysWithVerifiedUsersChanged(bool state);
|
||||||
void shareKeysWithTrustedUsersChanged(bool state);
|
void shareKeysWithTrustedUsersChanged(bool state);
|
||||||
void profileChanged(QString profile);
|
void profileChanged(QString profile);
|
||||||
void userIdChanged(QString userId);
|
void userIdChanged(QString userId);
|
||||||
|
@ -284,6 +289,7 @@ private:
|
||||||
bool privacyScreen_;
|
bool privacyScreen_;
|
||||||
int privacyScreenTimeout_;
|
int privacyScreenTimeout_;
|
||||||
bool shareKeysWithTrustedUsers_;
|
bool shareKeysWithTrustedUsers_;
|
||||||
|
bool onlyShareKeysWithVerifiedUsers_;
|
||||||
bool mobileMode_;
|
bool mobileMode_;
|
||||||
int timelineMaxWidth_;
|
int timelineMaxWidth_;
|
||||||
int roomListWidth_;
|
int roomListWidth_;
|
||||||
|
@ -372,6 +378,7 @@ private:
|
||||||
Toggle *privacyScreen_;
|
Toggle *privacyScreen_;
|
||||||
QSpinBox *privacyScreenTimeout_;
|
QSpinBox *privacyScreenTimeout_;
|
||||||
Toggle *shareKeysWithTrustedUsers_;
|
Toggle *shareKeysWithTrustedUsers_;
|
||||||
|
Toggle *onlyShareKeysWithVerifiedUsers_;
|
||||||
Toggle *mobileMode_;
|
Toggle *mobileMode_;
|
||||||
QLabel *deviceFingerprintValue_;
|
QLabel *deviceFingerprintValue_;
|
||||||
QLabel *deviceIdValue_;
|
QLabel *deviceIdValue_;
|
||||||
|
|
Loading…
Reference in a new issue