From 25e7bde7bcfb1fbacd1b3a489cac20171a4ff116 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 25 Mar 2020 18:38:12 +0000 Subject: [PATCH 1/2] Add a flag to control whether cross-signing signatures are trusted Fixes: https://github.com/vector-im/riot-web/issues/12616 --- res/css/_components.scss | 1 + src/MatrixClientPeg.js | 3 +++ src/components/views/rooms/MemberTile.js | 7 +++++++ .../settings/tabs/user/SecurityUserSettingsTab.js | 3 +++ src/i18n/strings/en_EN.json | 2 ++ src/settings/Settings.js | 11 +++++++++++ 6 files changed, 27 insertions(+) diff --git a/res/css/_components.scss b/res/css/_components.scss index 6890a1ffd1..b959b1f1cd 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -186,6 +186,7 @@ @import "./views/settings/_AvatarSetting.scss"; @import "./views/settings/_CrossSigningPanel.scss"; @import "./views/settings/_DevicesPanel.scss"; +@import "./views/settings/_E2eAdvancedPanel.scss"; @import "./views/settings/_EmailAddresses.scss"; @import "./views/settings/_IntegrationManager.scss"; @import "./views/settings/_KeyBackupPanel.scss"; diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js index 98fcc85d60..21f05b9759 100644 --- a/src/MatrixClientPeg.js +++ b/src/MatrixClientPeg.js @@ -148,6 +148,9 @@ class _MatrixClientPeg { // check that we have a version of the js-sdk which includes initCrypto if (!SettingsStore.getValue("lowBandwidth") && this.matrixClient.initCrypto) { await this.matrixClient.initCrypto(); + this.matrixClient.setCryptoTrustCrossSignedDevices( + !SettingsStore.getValue('e2ee.manuallyVerifyAllSessions'), + ); StorageManager.setCryptoInitialised(true); } } catch (e) { diff --git a/src/components/views/rooms/MemberTile.js b/src/components/views/rooms/MemberTile.js index 1f1d8389b1..a0e900b5fc 100644 --- a/src/components/views/rooms/MemberTile.js +++ b/src/components/views/rooms/MemberTile.js @@ -65,6 +65,7 @@ export default createReactClass({ }); if (isRoomEncrypted) { cli.on("userTrustStatusChanged", this.onUserTrustStatusChanged); + cli.on("deviceVerificationChanged", this.onDeviceVerificationChanged); this.updateE2EStatus(); } else { // Listen for room to become encrypted @@ -88,6 +89,7 @@ export default createReactClass({ if (cli) { cli.removeListener("RoomState.events", this.onRoomStateEvents); cli.removeListener("userTrustStatusChanged", this.onUserTrustStatusChanged); + cli.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged); } }, @@ -110,6 +112,11 @@ export default createReactClass({ this.updateE2EStatus(); }, + onDeviceVerificationChanged: function(userId, deviceId, deviceInfo) { + if (userId !== this.props.member.userId) return; + this.updateE2EStatus(); + }, + updateE2EStatus: async function() { const cli = MatrixClientPeg.get(); const { userId } = this.props.member; diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index 2e35a6bf6f..3dca6e2490 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -281,6 +281,8 @@ export default class SecurityUserSettingsTab extends React.Component { ); } + const E2eAdvancedPanel = sdk.getComponent('views.settings.E2eAdvancedPanel'); + return (
{_t("Security & Privacy")}
@@ -311,6 +313,7 @@ export default class SecurityUserSettingsTab extends React.Component {
{this._renderIgnoredUsers()} {this._renderManageInvites()} + ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 57b39309b0..3602134f08 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -432,6 +432,7 @@ "Enable message search in encrypted rooms": "Enable message search in encrypted rooms", "Keep secret storage passphrase in memory for this session": "Keep secret storage passphrase in memory for this session", "How fast should messages be downloaded.": "How fast should messages be downloaded.", + "Manually verify all remote sessions": "Manually verify all remote sessions", "Collecting app version information": "Collecting app version information", "Collecting logs": "Collecting logs", "Uploading report": "Uploading report", @@ -598,6 +599,7 @@ "Public Name": "Public Name", "Last seen": "Last seen", "Failed to set display name": "Failed to set display name", + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.", "Disable Notifications": "Disable Notifications", "Enable Notifications": "Enable Notifications", "Securely cache encrypted messages locally for them to appear in search results, using ": "Securely cache encrypted messages locally for them to appear in search results, using ", diff --git a/src/settings/Settings.js b/src/settings/Settings.js index 461761dfa2..0d72017878 100644 --- a/src/settings/Settings.js +++ b/src/settings/Settings.js @@ -16,6 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +import {MatrixClient} from 'matrix-js-sdk'; + import {_td} from '../languageHandler'; import { AudioNotificationsEnabledController, @@ -24,6 +26,7 @@ import { } from "./controllers/NotificationControllers"; import CustomStatusController from "./controllers/CustomStatusController"; import ThemeController from './controllers/ThemeController'; +import PushToMatrixClientController from './controllers/PushToMatrixClientController'; import ReloadOnChangeController from "./controllers/ReloadOnChangeController"; import {RIGHT_PANEL_PHASES} from "../stores/RightPanelStorePhases"; @@ -525,4 +528,12 @@ export const SETTINGS = { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: true, }, + "e2ee.manuallyVerifyAllSessions": { + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, + displayName: _td("Manually verify all remote sessions"), + default: false, + controller: new PushToMatrixClientController( + MatrixClient.prototype.setCryptoTrustCrossSignedDevices, true, + ), + }, }; From 327b3c860b4f0c622654f83e08454a75a4d5e195 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 25 Mar 2020 18:47:57 +0000 Subject: [PATCH 2/2] Adding the files would help --- res/css/views/settings/_E2eAdvancedPanel.scss | 20 ++++++++++ .../views/settings/E2eAdvancedPanel.js | 39 +++++++++++++++++++ .../PushToMatrixClientController.js | 37 ++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 res/css/views/settings/_E2eAdvancedPanel.scss create mode 100644 src/components/views/settings/E2eAdvancedPanel.js create mode 100644 src/settings/controllers/PushToMatrixClientController.js diff --git a/res/css/views/settings/_E2eAdvancedPanel.scss b/res/css/views/settings/_E2eAdvancedPanel.scss new file mode 100644 index 0000000000..9e32685d12 --- /dev/null +++ b/res/css/views/settings/_E2eAdvancedPanel.scss @@ -0,0 +1,20 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_E2eAdvancedPanel_settingLongDescription { + margin-right: 150px; +} + diff --git a/src/components/views/settings/E2eAdvancedPanel.js b/src/components/views/settings/E2eAdvancedPanel.js new file mode 100644 index 0000000000..709465bcb0 --- /dev/null +++ b/src/components/views/settings/E2eAdvancedPanel.js @@ -0,0 +1,39 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from 'react'; + +import * as sdk from '../../../index'; +import {_t} from "../../../languageHandler"; +import {SettingLevel} from "../../../settings/SettingsStore"; + +const SETTING_MANUALLY_VERIFY_ALL_SESSIONS = "e2ee.manuallyVerifyAllSessions"; + +const E2eAdvancedPanel = props => { + const SettingsFlag = sdk.getComponent('views.elements.SettingsFlag'); + return
+ {_t("Advanced")} + + +
{_t( + "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.", + )}
+
; +}; + +export default E2eAdvancedPanel; diff --git a/src/settings/controllers/PushToMatrixClientController.js b/src/settings/controllers/PushToMatrixClientController.js new file mode 100644 index 0000000000..b7c285227f --- /dev/null +++ b/src/settings/controllers/PushToMatrixClientController.js @@ -0,0 +1,37 @@ +/* +Copyright 2020 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { MatrixClientPeg } from '../../MatrixClientPeg'; + +/** + * When the value changes, call a setter function on the matrix client with the new value + */ +export default class PushToMatrixClientController { + constructor(setter, inverse) { + this._setter = setter; + this._inverse = inverse; + } + + getValueOverride(level, roomId, calculatedValue, calculatedAtLevel) { + return null; // no override + } + + onChange(level, roomId, newValue) { + // XXX does this work? This surely isn't necessarily the effective value, + // but it's what NotificationsEnabledController does... + this._setter.call(MatrixClientPeg.get(), this._inverse ? !newValue : newValue); + } +}