qubespolicy: run GUI code inside user session and expose it as dbus object
This way it will work independently from where qrexec-policy tool will be called (in most cases - from a system service, as root). This is also very similar architecture to what we'll need when moving to GUI domain - there GUI part will also be separated from policy evaluation logic. QubesOS/qubes-issues#910
This commit is contained in:
parent
e76ede3ad0
commit
a3da85bfda
@ -8,4 +8,8 @@ install:
|
|||||||
ln -s block-snapshot $(DESTDIR)/etc/xen/scripts/block-origin
|
ln -s block-snapshot $(DESTDIR)/etc/xen/scripts/block-origin
|
||||||
install -d $(DESTDIR)/etc/xdg/autostart
|
install -d $(DESTDIR)/etc/xdg/autostart
|
||||||
install -m 0644 qubes-guid.desktop $(DESTDIR)/etc/xdg/autostart/
|
install -m 0644 qubes-guid.desktop $(DESTDIR)/etc/xdg/autostart/
|
||||||
|
install -m 0644 qrexec-policy-agent.desktop $(DESTDIR)/etc/xdg/autostart/
|
||||||
install -m 0644 -D tmpfiles-qubes.conf $(DESTDIR)/usr/lib/tmpfiles.d/qubes.conf
|
install -m 0644 -D tmpfiles-qubes.conf $(DESTDIR)/usr/lib/tmpfiles.d/qubes.conf
|
||||||
|
install -d $(DESTDIR)/etc/dbus-1/system.d
|
||||||
|
install -m 0644 dbus-org.qubesos.PolicyAgent.conf \
|
||||||
|
$(DESTDIR)/etc/dbus-1/system.d/org.qubesos.PolicyAgent.conf
|
||||||
|
19
linux/system-config/dbus-org.qubesos.PolicyAgent.conf
Normal file
19
linux/system-config/dbus-org.qubesos.PolicyAgent.conf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
|
||||||
|
|
||||||
|
<!DOCTYPE busconfig PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
<!-- User need to be in qubes group to own the service -->
|
||||||
|
<policy group="qubes">
|
||||||
|
<allow own="org.qubesos.PolicyAgent"/>
|
||||||
|
</policy>
|
||||||
|
<policy context="default">
|
||||||
|
|
||||||
|
<allow send_destination="org.qubesos.PolicyAgent"
|
||||||
|
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||||
|
|
||||||
|
<allow send_destination="org.qubesos.PolicyAgent"
|
||||||
|
send_interface="org.qubesos.PolicyAgent"/>
|
||||||
|
</policy>
|
||||||
|
</busconfig>
|
7
linux/system-config/qrexec-policy-agent.desktop
Normal file
7
linux/system-config/qrexec-policy-agent.desktop
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Name=Qubes Qrexec Policy agent
|
||||||
|
Comment=Agent for handling policy confirmation prompts
|
||||||
|
Icon=qubes
|
||||||
|
Exec=qrexec-policy-agent
|
||||||
|
Terminal=false
|
||||||
|
Type=Application
|
70
qubespolicy/agent.py
Normal file
70
qubespolicy/agent.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# -*- encoding: utf8 -*-
|
||||||
|
#
|
||||||
|
# The Qubes OS Project, http://www.qubes-os.org
|
||||||
|
#
|
||||||
|
# Copyright (C) 2017 Marek Marczykowski-Górecki
|
||||||
|
# <marmarek@invisiblethingslab.com>
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along
|
||||||
|
# with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
''' Agent running in user session, responsible for asking the user about policy
|
||||||
|
decisions.'''
|
||||||
|
|
||||||
|
import pydbus
|
||||||
|
import gi
|
||||||
|
gi.require_version('Gtk', '3.0')
|
||||||
|
from gi.repository import GLib
|
||||||
|
|
||||||
|
import qubespolicy.rpcconfirmation
|
||||||
|
|
||||||
|
class PolicyAgent(object):
|
||||||
|
dbus = """
|
||||||
|
<node>
|
||||||
|
<interface name='org.qubesos.PolicyAgent'>
|
||||||
|
<method name='Ask'>
|
||||||
|
<arg type='s' name='source' direction='in'/>
|
||||||
|
<arg type='s' name='service_name' direction='in'/>
|
||||||
|
<arg type='as' name='targets' direction='in'/>
|
||||||
|
<arg type='s' name='default_target' direction='in'/>
|
||||||
|
<arg type='a{ss}' name='icons' direction='in'/>
|
||||||
|
<arg type='s' name='response' direction='out'/>
|
||||||
|
</method>
|
||||||
|
</interface>
|
||||||
|
</node>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def Ask(self, source, service_name, targets, default_target,
|
||||||
|
icons):
|
||||||
|
entries_info = {}
|
||||||
|
for target in targets:
|
||||||
|
entries_info[target] = {}
|
||||||
|
entries_info[target]['icon'] = icons.get(target, None)
|
||||||
|
|
||||||
|
response = qubespolicy.rpcconfirmation.confirm_rpc(
|
||||||
|
entries_info, source, service_name,
|
||||||
|
targets, default_target or None)
|
||||||
|
return response or ''
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
loop = GLib.MainLoop()
|
||||||
|
bus = pydbus.SystemBus()
|
||||||
|
obj = PolicyAgent()
|
||||||
|
bus.publish('org.qubesos.PolicyAgent', obj)
|
||||||
|
loop.run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
@ -68,20 +68,24 @@ def main(args=None):
|
|||||||
action = policy.evaluate(system_info, args.domain, args.target)
|
action = policy.evaluate(system_info, args.domain, args.target)
|
||||||
if action.action == qubespolicy.Action.ask:
|
if action.action == qubespolicy.Action.ask:
|
||||||
# late import to save on time for allow/deny actions
|
# late import to save on time for allow/deny actions
|
||||||
import qubespolicy.rpcconfirmation as rpcconfirmation
|
import pydbus
|
||||||
entries_info = system_info['domains'].copy()
|
bus = pydbus.SystemBus()
|
||||||
|
proxy = bus.get('org.qubesos.PolicyAgent',
|
||||||
|
'/org/qubesos/PolicyAgent')
|
||||||
|
|
||||||
|
icons = {name: system_info['domains'][name]['icon']
|
||||||
|
for name in system_info['domains'].keys()}
|
||||||
for dispvm_base in system_info['domains']:
|
for dispvm_base in system_info['domains']:
|
||||||
if not system_info['domains'][dispvm_base]['dispvm_allowed']:
|
if not system_info['domains'][dispvm_base]['dispvm_allowed']:
|
||||||
continue
|
continue
|
||||||
dispvm_api_name = '$dispvm:' + dispvm_base
|
dispvm_api_name = '$dispvm:' + dispvm_base
|
||||||
entries_info[dispvm_api_name] = \
|
icons[dispvm_api_name] = \
|
||||||
system_info['domains'][dispvm_base].copy()
|
system_info['domains'][dispvm_base]['icon']
|
||||||
entries_info[dispvm_api_name]['icon'] = \
|
icons[dispvm_api_name] = \
|
||||||
entries_info[dispvm_api_name]['icon'].replace('app', 'disp')
|
icons[dispvm_api_name].replace('app', 'disp')
|
||||||
|
|
||||||
response = rpcconfirmation.confirm_rpc(
|
response = proxy.Ask(args.domain, args.service_name,
|
||||||
entries_info, args.domain, args.service_name,
|
action.targets_for_ask, action.target or '', icons)
|
||||||
action.targets_for_ask, action.target)
|
|
||||||
if response:
|
if response:
|
||||||
action.handle_user_response(True, response)
|
action.handle_user_response(True, response)
|
||||||
else:
|
else:
|
||||||
|
@ -73,6 +73,7 @@ Requires: python3
|
|||||||
Requires: python3-docutils
|
Requires: python3-docutils
|
||||||
Requires: python3-jinja2
|
Requires: python3-jinja2
|
||||||
Requires: python3-lxml
|
Requires: python3-lxml
|
||||||
|
Requires: python3-pydbus
|
||||||
Requires: python3-qubesdb
|
Requires: python3-qubesdb
|
||||||
Requires: python3-setuptools
|
Requires: python3-setuptools
|
||||||
Requires: python3-xen
|
Requires: python3-xen
|
||||||
@ -210,11 +211,13 @@ fi
|
|||||||
%files
|
%files
|
||||||
%defattr(-,root,root,-)
|
%defattr(-,root,root,-)
|
||||||
%config(noreplace) %attr(0664,root,qubes) %{_sysconfdir}/qubes/qmemman.conf
|
%config(noreplace) %attr(0664,root,qubes) %{_sysconfdir}/qubes/qmemman.conf
|
||||||
|
%config(noreplace) /etc/dbus-1/system.d/org.qubesos.PolicyAgent.conf
|
||||||
/usr/bin/qvm-*
|
/usr/bin/qvm-*
|
||||||
/usr/bin/qubes-*
|
/usr/bin/qubes-*
|
||||||
/usr/bin/qmemmand
|
/usr/bin/qmemmand
|
||||||
/usr/bin/qubesd*
|
/usr/bin/qubesd*
|
||||||
/usr/bin/qrexec-policy
|
/usr/bin/qrexec-policy
|
||||||
|
/usr/bin/qrexec-policy-agent
|
||||||
|
|
||||||
%dir %{python3_sitelib}/qubes-*.egg-info
|
%dir %{python3_sitelib}/qubes-*.egg-info
|
||||||
%{python3_sitelib}/qubes-*.egg-info/*
|
%{python3_sitelib}/qubes-*.egg-info/*
|
||||||
@ -385,6 +388,7 @@ fi
|
|||||||
%{python3_sitelib}/qubespolicy/__pycache__/*
|
%{python3_sitelib}/qubespolicy/__pycache__/*
|
||||||
%{python3_sitelib}/qubespolicy/__init__.py
|
%{python3_sitelib}/qubespolicy/__init__.py
|
||||||
%{python3_sitelib}/qubespolicy/cli.py
|
%{python3_sitelib}/qubespolicy/cli.py
|
||||||
|
%{python3_sitelib}/qubespolicy/agent.py
|
||||||
%{python3_sitelib}/qubespolicy/gtkhelpers.py
|
%{python3_sitelib}/qubespolicy/gtkhelpers.py
|
||||||
%{python3_sitelib}/qubespolicy/rpcconfirmation.py
|
%{python3_sitelib}/qubespolicy/rpcconfirmation.py
|
||||||
%{python3_sitelib}/qubespolicy/utils.py
|
%{python3_sitelib}/qubespolicy/utils.py
|
||||||
@ -454,5 +458,6 @@ fi
|
|||||||
%attr(2770,root,qubes) %dir /var/log/qubes
|
%attr(2770,root,qubes) %dir /var/log/qubes
|
||||||
%attr(0770,root,qubes) %dir /var/run/qubes
|
%attr(0770,root,qubes) %dir /var/run/qubes
|
||||||
/etc/xdg/autostart/qubes-guid.desktop
|
/etc/xdg/autostart/qubes-guid.desktop
|
||||||
|
/etc/xdg/autostart/qrexec-policy-agent.desktop
|
||||||
|
|
||||||
/usr/share/doc/qubes/relaxng/*.rng
|
/usr/share/doc/qubes/relaxng/*.rng
|
||||||
|
1
setup.py
1
setup.py
@ -33,6 +33,7 @@ if __name__ == '__main__':
|
|||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': list(get_console_scripts()) + [
|
'console_scripts': list(get_console_scripts()) + [
|
||||||
'qrexec-policy = qubespolicy.cli:main',
|
'qrexec-policy = qubespolicy.cli:main',
|
||||||
|
'qrexec-policy-agent = qubespolicy.agent:main',
|
||||||
],
|
],
|
||||||
'qubes.vm': [
|
'qubes.vm': [
|
||||||
'AppVM = qubes.vm.appvm:AppVM',
|
'AppVM = qubes.vm.appvm:AppVM',
|
||||||
|
Loading…
Reference in New Issue
Block a user