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
|
||||
install -d $(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 -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)
|
||||
if action.action == qubespolicy.Action.ask:
|
||||
# late import to save on time for allow/deny actions
|
||||
import qubespolicy.rpcconfirmation as rpcconfirmation
|
||||
entries_info = system_info['domains'].copy()
|
||||
import pydbus
|
||||
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']:
|
||||
if not system_info['domains'][dispvm_base]['dispvm_allowed']:
|
||||
continue
|
||||
dispvm_api_name = '$dispvm:' + dispvm_base
|
||||
entries_info[dispvm_api_name] = \
|
||||
system_info['domains'][dispvm_base].copy()
|
||||
entries_info[dispvm_api_name]['icon'] = \
|
||||
entries_info[dispvm_api_name]['icon'].replace('app', 'disp')
|
||||
icons[dispvm_api_name] = \
|
||||
system_info['domains'][dispvm_base]['icon']
|
||||
icons[dispvm_api_name] = \
|
||||
icons[dispvm_api_name].replace('app', 'disp')
|
||||
|
||||
response = rpcconfirmation.confirm_rpc(
|
||||
entries_info, args.domain, args.service_name,
|
||||
action.targets_for_ask, action.target)
|
||||
response = proxy.Ask(args.domain, args.service_name,
|
||||
action.targets_for_ask, action.target or '', icons)
|
||||
if response:
|
||||
action.handle_user_response(True, response)
|
||||
else:
|
||||
|
@ -73,6 +73,7 @@ Requires: python3
|
||||
Requires: python3-docutils
|
||||
Requires: python3-jinja2
|
||||
Requires: python3-lxml
|
||||
Requires: python3-pydbus
|
||||
Requires: python3-qubesdb
|
||||
Requires: python3-setuptools
|
||||
Requires: python3-xen
|
||||
@ -210,11 +211,13 @@ fi
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%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/qubes-*
|
||||
/usr/bin/qmemmand
|
||||
/usr/bin/qubesd*
|
||||
/usr/bin/qrexec-policy
|
||||
/usr/bin/qrexec-policy-agent
|
||||
|
||||
%dir %{python3_sitelib}/qubes-*.egg-info
|
||||
%{python3_sitelib}/qubes-*.egg-info/*
|
||||
@ -385,6 +388,7 @@ fi
|
||||
%{python3_sitelib}/qubespolicy/__pycache__/*
|
||||
%{python3_sitelib}/qubespolicy/__init__.py
|
||||
%{python3_sitelib}/qubespolicy/cli.py
|
||||
%{python3_sitelib}/qubespolicy/agent.py
|
||||
%{python3_sitelib}/qubespolicy/gtkhelpers.py
|
||||
%{python3_sitelib}/qubespolicy/rpcconfirmation.py
|
||||
%{python3_sitelib}/qubespolicy/utils.py
|
||||
@ -454,5 +458,6 @@ fi
|
||||
%attr(2770,root,qubes) %dir /var/log/qubes
|
||||
%attr(0770,root,qubes) %dir /var/run/qubes
|
||||
/etc/xdg/autostart/qubes-guid.desktop
|
||||
/etc/xdg/autostart/qrexec-policy-agent.desktop
|
||||
|
||||
/usr/share/doc/qubes/relaxng/*.rng
|
||||
|
Loading…
Reference in New Issue
Block a user