From a9f5064b2084262cb966466ce49762f113d3c20f Mon Sep 17 00:00:00 2001 From: Guillaume Chinal Date: Thu, 6 Mar 2025 22:43:26 +0100 Subject: [PATCH 1/2] add a warning box when connecting an anon vm to a non-anon gateway Anon AppVM like anon-whonix needs an anon-gateway like sys-whonix to provide a correct level of anonymity and privacy. This commit adds a warning when a user try to connect a VM with the tag anon-vm to a Net Qube that does not have the tag anon-gateway --- qubesmanager/settings.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/qubesmanager/settings.py b/qubesmanager/settings.py index 12a6ece9b..d5af9f6ee 100644 --- a/qubesmanager/settings.py +++ b/qubesmanager/settings.py @@ -485,6 +485,7 @@ def __init_basic_tab__(self): self.netVM.currentIndexChanged.connect(self.check_warn_dispvmnetvm) self.netVM.currentIndexChanged.connect(self.check_warn_templatenetvm) self.netVM.currentIndexChanged.connect(self.check_network_availability) + self.netVM.currentIndexChanged.connect(self.check_warn_anonnetvm) try: self.include_in_backups.setChecked(self.vm.include_in_backups) @@ -745,6 +746,30 @@ def check_warn_dispvmnetvm(self): else: self.warn_netvm_dispvm.setVisible(False) + def check_warn_anonnetvm(self): + if 'anon-vm' not in self.vm.tags: + return + + current_net_vm = self.netVM.currentData() + + if current_net_vm is None: + return + + if current_net_vm == qubesadmin.DEFAULT: + current_net_vm = self.vm.property_get_default('netvm') + + if 'anon-gateway' not in current_net_vm.tags: + QtWidgets.QMessageBox.warning( + self, + self.tr("Warning!"), + self.tr( + "Anonymous qubes must be connected to an anonymous gateway " + "to ensure privacy and anonymity. By changing the net qube " + "to a gateway that does not provide anonymity, your IP " + "address will be leaked on the Internet. Continue at your " + "own risk.") + ) + def rename_vm(self): dependencies = admin_utils.vm_dependencies(self.vm.app, self.vm) From 26e8131d71918cd014f757fe5d275ae82c80da6e Mon Sep 17 00:00:00 2001 From: Guillaume Chinal Date: Sun, 16 Mar 2025 10:10:44 +0100 Subject: [PATCH 2/2] add a test for warning message when changing anon-vm netvm --- qubesmanager/tests/test_vm_settings.py | 36 +++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/qubesmanager/tests/test_vm_settings.py b/qubesmanager/tests/test_vm_settings.py index 571d7e6c2..383972c5a 100644 --- a/qubesmanager/tests/test_vm_settings.py +++ b/qubesmanager/tests/test_vm_settings.py @@ -93,6 +93,13 @@ def settings_fixture(request, qapp, test_qubes_app) -> Tuple[ name="test-pci-dev", qapp=test_qubes_app, label="green", virt_mode='hvm' ) + + test_qubes_app._qubes['sys-whonix'] = MockQube( + name="sys-whonix", qapp=test_qubes_app, tags=['anon-gateway']) + + test_qubes_app._qubes['anon-whonix'] = MockQube( + name="anon-whonix", qapp=test_qubes_app, tags=['anon-vm']) + test_qubes_app._devices.append( MockDevice(test_qubes_app, 'pci', 'USB Controller', '00:03.2', 'dom0', attached='test-pci-dev')) @@ -316,7 +323,6 @@ def test_102_change_netvm(settings_fixture): assert expected_call not in settings_window.qubesapp.actual_calls, \ "Unnecessary NetVM change" - @mock.patch('PyQt6.QtWidgets.QMessageBox.warning') @pytest.mark.parametrize("settings_fixture", ["fedora-35"], indirect=True) def test_103_change_netvm_tpl(mock_warning, settings_fixture): @@ -583,6 +589,34 @@ def test_112_clonevm(mock_clone, settings_fixture): mock_clone.assert_called_with(mock.ANY, mock.ANY, src_vm=vm) +@mock.patch('PyQt6.QtWidgets.QMessageBox.warning') +@pytest.mark.parametrize("settings_fixture", ["anon-whonix"], indirect=True) +def test_113_change_netvm_anon(mock_warning, settings_fixture): + settings_window, page, vm_name = settings_fixture + vm = settings_window.qubesapp.domains[vm_name] + + change_netvm_call = (vm_name, 'admin.vm.property.Set', 'netvm', b'sys-net') + get_tag_call = (vm_name, 'admin.vm.tag.Get', 'anon-vm', None) + + assert settings_window.netVM.isEnabled() + + _select_item(settings_window.netVM, "sys-net") + + assert get_tag_call in settings_window.qubesapp.actual_calls + + assert change_netvm_call not in settings_window.qubesapp.expected_calls + settings_window.qubesapp.expected_calls[change_netvm_call] = b'0\x00' + + settings_window.accept() + + settings_window.qubesapp.expected_calls[change_netvm_call] = b'0\x00' + + assert mock_warning.call_count == 1, ("Didn't warn for changing netvm " + "on anon-vm") + + assert change_netvm_call in settings_window.qubesapp.actual_calls + + # ADVANCED TAB @check_errors