Support qubes.VMExec call
The feature is advertised by core-agent so that it can be used instead of VMShell. See QubesOS/qubes-issues#4850.
This commit is contained in:
parent
0a66a0c7dd
commit
08d83fb241
2
Makefile
2
Makefile
@ -178,6 +178,7 @@ endif
|
|||||||
cp qubes-rpc-policy/qubes.OpenURL.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenURL
|
cp qubes-rpc-policy/qubes.OpenURL.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenURL
|
||||||
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
|
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
|
||||||
cp qubes-rpc-policy/qubes.VMRootShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMRootShell
|
cp qubes-rpc-policy/qubes.VMRootShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMRootShell
|
||||||
|
cp qubes-rpc-policy/qubes.VMExec.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMExec
|
||||||
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
||||||
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
|
cp qubes-rpc-policy/qubes.NotifyTools.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyTools
|
||||||
cp qubes-rpc-policy/qubes.GetImageRGBA.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetImageRGBA
|
cp qubes-rpc-policy/qubes.GetImageRGBA.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetImageRGBA
|
||||||
@ -186,7 +187,6 @@ endif
|
|||||||
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
cp qubes-rpc-policy/qubes.NotifyUpdates.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.NotifyUpdates
|
||||||
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
|
cp qubes-rpc-policy/qubes.OpenInVM.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.OpenInVM
|
||||||
cp qubes-rpc-policy/qubes.StartApp.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.StartApp
|
cp qubes-rpc-policy/qubes.StartApp.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.StartApp
|
||||||
cp qubes-rpc-policy/qubes.VMShell.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.VMShell
|
|
||||||
cp qubes-rpc-policy/qubes.UpdatesProxy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.UpdatesProxy
|
cp qubes-rpc-policy/qubes.UpdatesProxy.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.UpdatesProxy
|
||||||
cp qubes-rpc-policy/qubes.GetDate.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetDate
|
cp qubes-rpc-policy/qubes.GetDate.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.GetDate
|
||||||
cp qubes-rpc-policy/qubes.ConnectTCP.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.ConnectTCP
|
cp qubes-rpc-policy/qubes.ConnectTCP.policy $(DESTDIR)/etc/qubes-rpc/policy/qubes.ConnectTCP
|
||||||
|
31
qubes-rpc-policy/qubes.VMExec.policy
Normal file
31
qubes-rpc-policy/qubes.VMExec.policy
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
## Note that policy parsing stops at the first match,
|
||||||
|
## so adding anything below "$anyvm $anyvm action" line will have no effect
|
||||||
|
|
||||||
|
## Please use a single # to start your custom comments
|
||||||
|
|
||||||
|
$anyvm $dispvm allow
|
||||||
|
$anyvm $anyvm deny
|
||||||
|
|
||||||
|
# WARNING: The qubes.VMExec service is dangerous and there are really few
|
||||||
|
# cases when it could be safely used. Especially when policy set to "ask" you
|
||||||
|
# have no way to know for sure what command(s) will be called. Compromissed
|
||||||
|
# source VM can substitute the command. Allowing one VM to execute
|
||||||
|
# qubes.VMExec over the other VM allows the former to TAKE FULL CONTROL over
|
||||||
|
# the later. In most cases this is not what we want!
|
||||||
|
#
|
||||||
|
# Instead we should be using task-specific qrexec services which provide
|
||||||
|
# assurance as to what program will be responding to the (untrusted) VM
|
||||||
|
# requests.
|
||||||
|
#
|
||||||
|
# It is, however, safe, in most cases, to allow ultimate control of the
|
||||||
|
# creating AppVM over the DisposableVM it creates as part of the qrexec service
|
||||||
|
# invocation. That's why by default we have "$anyvm $dispvm allow" rule. Note
|
||||||
|
# that it does _not_ allow any AppVM to execute qubes.VMExec service over any
|
||||||
|
# DispVM created in the system -- that would obviously be wrong. It only allows
|
||||||
|
# qubes.VMExec service access to the AppVM which creates the DispVM as part of
|
||||||
|
# this very service invocation.
|
||||||
|
#
|
||||||
|
# See e.g. this thread for some discussion:
|
||||||
|
# https://groups.google.com/d/msg/qubes-users/xnAByaL_bjI/3PjYdiTDW-0J
|
||||||
|
#
|
||||||
|
#
|
@ -1,4 +1,4 @@
|
|||||||
# -*- encoding: utf8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# The Qubes OS Project, http://www.qubes-os.org
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
#
|
#
|
||||||
@ -34,7 +34,8 @@ class CoreFeatures(qubes.ext.Extension):
|
|||||||
return
|
return
|
||||||
|
|
||||||
requested_features = {}
|
requested_features = {}
|
||||||
for feature in ('qrexec', 'gui', 'gui-emulated', 'qubes-firewall'):
|
for feature in (
|
||||||
|
'qrexec', 'gui', 'gui-emulated', 'qubes-firewall', 'vmexec'):
|
||||||
untrusted_value = untrusted_features.get(feature, None)
|
untrusted_value = untrusted_features.get(feature, None)
|
||||||
if untrusted_value in ('1', '0'):
|
if untrusted_value in ('1', '0'):
|
||||||
requested_features[feature] = bool(int(untrusted_value))
|
requested_features[feature] = bool(int(untrusted_value))
|
||||||
@ -53,7 +54,7 @@ class CoreFeatures(qubes.ext.Extension):
|
|||||||
vm.features[feature] = requested_features[feature]
|
vm.features[feature] = requested_features[feature]
|
||||||
|
|
||||||
# those features can be freely enabled or disabled by template
|
# those features can be freely enabled or disabled by template
|
||||||
for feature in ('qubes-firewall',):
|
for feature in ('qubes-firewall', 'vmexec'):
|
||||||
if feature in requested_features:
|
if feature in requested_features:
|
||||||
vm.features[feature] = requested_features[feature]
|
vm.features[feature] = requested_features[feature]
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# -*- encoding: utf8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# The Qubes OS Project, http://www.qubes-os.org
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
#
|
#
|
||||||
@ -46,13 +46,15 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'gui': '1',
|
'gui': '1',
|
||||||
'version': '1',
|
'version': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
'qrexec': '1'}))
|
'qrexec': '1',
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
'vmexec': '1'}))
|
||||||
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('qrexec',), {}),
|
('features.__contains__', ('qrexec',), {}),
|
||||||
('features.__setitem__', ('qrexec', True), {}),
|
('features.__setitem__', ('qrexec', True), {}),
|
||||||
('features.__contains__', ('gui',), {}),
|
('features.__contains__', ('gui',), {}),
|
||||||
('features.__setitem__', ('gui', True), {}),
|
('features.__setitem__', ('gui', True), {}),
|
||||||
|
('features.__setitem__', ('vmexec', True), {}),
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('fire_event_async', ('template-postinstall',), {}),
|
('fire_event_async', ('template-postinstall',), {}),
|
||||||
('fire_event_async().__iter__', (), {}),
|
('fire_event_async().__iter__', (), {}),
|
||||||
@ -66,13 +68,15 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'gui': '0',
|
'gui': '0',
|
||||||
'version': '1',
|
'version': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
'qrexec': '0'}))
|
'qrexec': '0',
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
'vmexec': '0'}))
|
||||||
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('qrexec',), {}),
|
('features.__contains__', ('qrexec',), {}),
|
||||||
('features.__setitem__', ('qrexec', False), {}),
|
('features.__setitem__', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('gui',), {}),
|
('features.__contains__', ('gui',), {}),
|
||||||
('features.__setitem__', ('gui', False), {}),
|
('features.__setitem__', ('gui', False), {}),
|
||||||
|
('features.__setitem__', ('vmexec', False), {}),
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -84,7 +88,7 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'version': '1',
|
'version': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
}))
|
}))
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
])
|
])
|
||||||
@ -98,7 +102,7 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'gui': '1',
|
'gui': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
}))
|
}))
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('qrexec',), {}),
|
('features.__contains__', ('qrexec',), {}),
|
||||||
('features.__setitem__', ('qrexec', True), {}),
|
('features.__setitem__', ('qrexec', True), {}),
|
||||||
@ -136,7 +140,7 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'gui': 'invalid',
|
'gui': 'invalid',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
}))
|
}))
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('qrexec',), {}),
|
('features.__contains__', ('qrexec',), {}),
|
||||||
('features.__setitem__', ('qrexec', True), {}),
|
('features.__setitem__', ('qrexec', True), {}),
|
||||||
@ -171,7 +175,7 @@ class TC_00_CoreFeatures(qubes.tests.QubesTestCase):
|
|||||||
'version': '1',
|
'version': '1',
|
||||||
'default-user': 'user',
|
'default-user': 'user',
|
||||||
'qrexec': '1'}))
|
'qrexec': '1'}))
|
||||||
self.assertEqual(self.vm.mock_calls, [
|
self.assertListEqual(self.vm.mock_calls, [
|
||||||
('features.get', ('qrexec', False), {}),
|
('features.get', ('qrexec', False), {}),
|
||||||
('features.__contains__', ('qrexec',), {}),
|
('features.__contains__', ('qrexec',), {}),
|
||||||
('features.__contains__', ('gui',), {}),
|
('features.__contains__', ('gui',), {}),
|
||||||
|
@ -402,6 +402,7 @@ fi
|
|||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.StartApp
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.StartApp
|
||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMShell
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMShell
|
||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMRootShell
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMRootShell
|
||||||
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.VMExec
|
||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.UpdatesProxy
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.UpdatesProxy
|
||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetDate
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/qubes.GetDate
|
||||||
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/policy.RegisterArgument
|
%attr(0664,root,qubes) %config(noreplace) /etc/qubes-rpc/policy/policy.RegisterArgument
|
||||||
|
Loading…
Reference in New Issue
Block a user