diff --git a/qubes/tests/api_admin.py b/qubes/tests/api_admin.py index 6b752b392..819cecb5c 100644 --- a/qubes/tests/api_admin.py +++ b/qubes/tests/api_admin.py @@ -1495,6 +1495,18 @@ def test_334_vm_create_invalid_name(self, storage_mock): self.assertNotIn('test-###', self.app.domains) self.assertFalse(self.app.save.called) + with self.assertRaises(qubes.exc.QubesValueError): + self.call_mgmt_func(b'admin.vm.Create.AppVM', + b'dom0', b'test-template', b'name=--helpVM') + self.assertNotIn('--helpVM', self.app.domains) + self.assertFalse(self.app.save.called) + + with self.assertRaises(qubes.exc.QubesValueError): + self.call_mgmt_func(b'admin.vm.Create.AppVM', + b'dom0', b'test-template', b'name=1stVM') + self.assertNotIn('1stVM', self.app.domains) + self.assertFalse(self.app.save.called) + @unittest.mock.patch('qubes.storage.Storage.create') def test_335_vm_create_missing_name(self, storage_mock): storage_mock.side_effect = self.dummy_coro diff --git a/qubes/vm/__init__.py b/qubes/vm/__init__.py index 1b0772b23..a82251a51 100644 --- a/qubes/vm/__init__.py +++ b/qubes/vm/__init__.py @@ -52,6 +52,14 @@ def validate_name(holder, prop, value): raise qubes.exc.QubesValueError( 'VM name must be shorter than 32 characters') + if re.match(r"\A[0-9_-].*\Z", value) is not None: + if holder is not None and prop is not None: + raise qubes.exc.QubesPropertyValueError(holder, prop, value, + '{} cannot start with hyphen, underscore or numbers'.format( + prop.__name__)) + raise qubes.exc.QubesValueError( + 'VM name cannot start with hyphen, underscore or numbers') + # this regexp does not contain '+'; if it had it, we should specifically # disallow 'lost+found' #1440 if re.match(r"\A[a-zA-Z][a-zA-Z0-9_-]*\Z", value) is None: