diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index e6f6fd8fb..6510ca797 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -243,27 +243,63 @@ def test_027_vm_property_get_all(self): self.assertEqual(value, expected) def test_028_vm_property_get_list(self): + self.vm.features['ipv6'] = '1' self.vm.provides_network = True value = self.call_mgmt_func( b'admin.vm.property.Get', b'test-vm1', b'dns') self.assertEqual(value, 'default=True type=str 10.139.1.1 10.139.1.2') + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'default=True type=str ') + self.vm.features['supported-feature.ipv6dns'] = '1' + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'default=True type=str fd09:24ef:4179::a8b:1 fd09:24ef:4179::a8b:2') def test_029_vm_property_get_list_none(self): + self.vm.features['ipv6'] = '1' value = self.call_mgmt_func( b'admin.vm.property.Get', b'test-vm1', b'dns') self.assertEqual(value, 'default=True type=str ') + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'default=True type=str ') + self.vm.features['supported-feature.ipv6dns'] = '1' + value = self.call_mgmt_func( + b'admin.vm.property.Get', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'default=True type=str ') def test_029_vm_property_get_list_default(self): + self.vm.features['ipv6'] = '1' self.vm.provides_network = True value = self.call_mgmt_func( b'admin.vm.property.GetDefault', b'test-vm1', b'dns') self.assertEqual(value, 'type=str 10.139.1.1 10.139.1.2') + value = self.call_mgmt_func( + b'admin.vm.property.GetDefault', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'type=str ') + self.vm.features['supported-feature.ipv6dns'] = '1' + value = self.call_mgmt_func( + b'admin.vm.property.GetDefault', + b'test-vm1', + b'dns6') + self.assertEqual(value, 'type=str fd09:24ef:4179::a8b:1 fd09:24ef:4179::a8b:2') def test_030_vm_property_set_vm(self): netvm = self.app.add_new_vm('AppVM', label='red', name='test-net', diff --git a/qubes/tests/vm/qubesvm.py b/qubes/tests/vm/qubesvm.py index 8bd2fb338..cf4df4133 100644 --- a/qubes/tests/vm/qubesvm.py +++ b/qubes/tests/vm/qubesvm.py @@ -1797,19 +1797,32 @@ def test_621_qdb_vm_with_network(self, mock_qubesdb, mock_urandom, vm.create_qdb_entries() self.assertEqual(test_qubesdb.data, expected) + test_qubesdb.data.clear() + with self.subTest('ipv6_dns'): + template.features['supported-feature.ipv6dns'] = '1' + netvm.features['ipv6'] = True + expected['/qubes-primary-dns6'] = 'fd09:24ef:4179::a8b:1' + expected['/qubes-secondary-dns6'] = 'fd09:24ef:4179::a8b:2' + vm.create_qdb_entries() + self.assertEqual(test_qubesdb.data, expected) + test_qubesdb.data.clear() with self.subTest('ipv6_just_appvm'): + template.features['supported-feature.ipv6dns'] = '1' del netvm.features['ipv6'] vm.features['ipv6'] = True expected['/qubes-ip6'] = \ qubes.config.qubes_ipv6_prefix.replace(':0000', '') + \ '::a89:3' del expected['/qubes-gateway6'] + del expected['/qubes-primary-dns6'] + del expected['/qubes-secondary-dns6'] vm.create_qdb_entries() self.assertEqual(test_qubesdb.data, expected) test_qubesdb.data.clear() with self.subTest('proxy_ipv4'): + del template.features['supported-feature.ipv6dns'] del vm.features['ipv6'] expected['/name'] = 'test-inst-netvm' expected['/qubes-vm-type'] = 'NetVM' @@ -1858,6 +1871,18 @@ def test_621_qdb_vm_with_network(self, mock_qubesdb, mock_urandom, netvm.create_qdb_entries() self.assertEqual(test_qubesdb.data, expected) + test_qubesdb.data.clear() + with self.subTest('proxy_ipv6_dns'): + template.features['supported-feature.ipv6dns'] = '1' + netvm.features['ipv6'] = True + expected['/qubes-netvm-primary-dns6'] = 'fd09:24ef:4179::a8b:1' + expected['/qubes-netvm-secondary-dns6'] = 'fd09:24ef:4179::a8b:2' + + with unittest.mock.patch('qubes.vm.qubesvm.QubesVM.is_running', + lambda _: True): + netvm.create_qdb_entries() + self.assertEqual(test_qubesdb.data, expected) + @unittest.mock.patch('qubes.utils.get_timezone') @unittest.mock.patch('qubes.utils.urandom') @unittest.mock.patch('qubes.vm.qubesvm.QubesVM.untrusted_qdb') diff --git a/qubes/vm/mix/net.py b/qubes/vm/mix/net.py index 4df2d9a57..19bdb922d 100644 --- a/qubes/vm/mix/net.py +++ b/qubes/vm/mix/net.py @@ -254,6 +254,19 @@ def dns(self): return None + @qubes.stateless_property + def dns6(self): + '''IPv6 DNS servers set up for this domain.''' + if self.features.check_with_netvm('ipv6', False) and \ + self.features.check_with_template("supported-feature.ipv6dns", \ + False) and (self.netvm is not None or self.provides_network): + return StrSerializableTuple(( + 'fd09:24ef:4179::a8b:1', + 'fd09:24ef:4179::a8b:2', + )) + + return None + def __init__(self, *args, **kwargs): self._firewall = None super().__init__(*args, **kwargs) @@ -506,7 +519,7 @@ def on_property_set_ip(self, _event, name, newvalue=None, oldvalue=None): vm.fire_event( 'property-reset:visible_gateway', name='visible_gateway') - @qubes.events.handler('property-set:ip6', 'property-reset:ipv6') + @qubes.events.handler('property-set:ip6', 'property-reset:ip6') def on_property_set_ip6(self, _event, name, newvalue=None, oldvalue=None): # pylint: disable=unused-argument if newvalue == oldvalue: diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py index bc0a9cd08..e072b3c9c 100644 --- a/qubes/vm/qubesvm.py +++ b/qubes/vm/qubesvm.py @@ -2252,7 +2252,12 @@ def create_qdb_entries(self): self.untrusted_qdb.write('/qubes-netvm-netmask', str(self.netmask)) for i, addr in zip(('primary', 'secondary'), self.dns): - self.untrusted_qdb.write('/qubes-netvm-{}-dns'.format(i), addr) + self.untrusted_qdb.write('/qubes-netvm-{}-dns'.format(i), \ + str(addr)) + if self.dns6: # pylint: disable=using-constant-test + for i, addr in zip(('primary', 'secondary'), self.dns6): + self.untrusted_qdb.write('/qubes-netvm-{}-dns6'.format(i), \ + str(addr)) if self.netvm is not None: self.untrusted_qdb.write('/qubes-mac', str(self.mac)) @@ -2270,6 +2275,11 @@ def create_qdb_entries(self): if self.visible_gateway6: # pylint: disable=using-constant-test self.untrusted_qdb.write('/qubes-gateway6', str(self.visible_gateway6)) + if self.dns6 and self.netvm.features.check_with_netvm('ipv6', \ + False): # pylint: disable=using-constant-test + for i, addr in zip(('primary', 'secondary'), self.dns6): + self.untrusted_qdb.write('/qubes-{}-dns6'.format(i), \ + str(addr)) tzname = qubes.utils.get_timezone() if tzname: