From ecf200dca366e1c92b877fe54ffc7355b4f86eb6 Mon Sep 17 00:00:00 2001 From: Rafal Wojtczuk Date: Tue, 5 Jul 2011 18:35:03 +0200 Subject: [PATCH] qrexec: last two missing pieces of the new rpc infrastructure --- qrexec/qrexec_policy | 75 ++++++++++++++++++++++++++++++++++++ qrexec/qubes_rpc_multiplexer | 14 +++++++ rpm_spec/core-appvm.spec | 5 +++ rpm_spec/core-dom0.spec | 5 +++ 4 files changed, 99 insertions(+) create mode 100755 qrexec/qrexec_policy create mode 100755 qrexec/qubes_rpc_multiplexer diff --git a/qrexec/qrexec_policy b/qrexec/qrexec_policy new file mode 100755 index 00000000..146c4767 --- /dev/null +++ b/qrexec/qrexec_policy @@ -0,0 +1,75 @@ +#!/usr/bin/python +import sys +import os +import subprocess + +POLICY_FILE_DIR="/etc/qubes_rpc/policy" +QREXEC_CLIENT="/usr/lib/qubes/qrexec_client" + +def read_policy_file(exec_index): + policy=list() + f = open(POLICY_FILE_DIR+"/"+exec_index) + for iter in f.readlines(): + policy.append(iter.split()) + f.close() + return policy + +def is_match(item, config_term): + return (item is not "dom0" and config_term == "anyvm") or item == config_term + +def apply_policy(policy, domain, target): + for iter in policy: + if len(iter) < 3: + continue + if not is_match(domain, iter[0]): + continue + if not is_match(target, iter[1]): + continue + ret=iter[2].split("=") + if len(ret)==1: + return (ret[0], None) + else: + return (ret[0], ret[1]) + return (None, None) + +def do_execute(domain, target, exec_index, process_ident): + cmd= "qvm-run -q -a --pass_io "+target + cmd+=" '/usr/lib/qubes/qubes_rpc_multiplexer "+exec_index + " " + domain + "'" + os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", cmd, "-c", process_ident) + +def confirm_execution(domain, target, exec_index): + text = "Do you allow domain \"" +domain + "\" to execute " + exec_index + text+= " operation on the domain \"" + target +"\"?" + retcode = subprocess.call(["/usr/bin/zenity", "--question", "--text", text]) + return retcode==0 + +def policy_editor(domain, target, exec_index): + text = "Policy editor not yet implemented. Please add a line in the form \"" + text+= domain + " " + target + "action_to_take\"" + text+= " to /etc/qubes_rpc/policy/" + exec_index +" file in dom0, then close this info." + subprocess.call(["/usr/bin/zenity", "--info", "--text", text]) + +def main(): + domain=sys.argv[1] + target=sys.argv[2] + exec_index=sys.argv[3] + process_ident=sys.argv[4] + + action = None + while action is None: + policy = read_policy_file(exec_index) + (action, params) = apply_policy(policy, domain, target) + if action is None: + policy_editor(domain, target, exec_index) + if action == "allow": + do_execute(domain, target, exec_index, process_ident) + elif action == "divert": + do_execute(domain, params, exec_index, process_ident) + elif action == "ask": + if confirm_execution(domain, target, exec_index): + do_execute(domain, target, exec_index, process_ident) + print >> sys.stderr, "Rpc denied:", domain, target, exec_index + os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", "/bin/false", "-c", process_ident) + +main() + \ No newline at end of file diff --git a/qrexec/qubes_rpc_multiplexer b/qrexec/qubes_rpc_multiplexer new file mode 100755 index 00000000..8f03137a --- /dev/null +++ b/qrexec/qubes_rpc_multiplexer @@ -0,0 +1,14 @@ +#!/bin/sh +QUBES_RPC=/etc/qubes_rpc +if ! [ $# = 2 ] ; then + echo $0: bad argument count >&2 + exit 1 +fi +CFG_FILE=$QUBES_RPC/"$1" +if [ -s "$CFG_FILE" ] ; then + exec $(cat "$CFG_FILE") "$2" + echo "$0: failed to execute handler for" "$1" >&2 + exit 1 +fi +echo "$0: nonexistent or empty" "$CFG_FILE" file >&2 +exit 1 diff --git a/rpm_spec/core-appvm.spec b/rpm_spec/core-appvm.spec index c13daa18..dfc7e061 100644 --- a/rpm_spec/core-appvm.spec +++ b/rpm_spec/core-appvm.spec @@ -82,11 +82,14 @@ cp qvm-copy-to-vm2.gnome $RPM_BUILD_ROOT/usr/lib/qubes cp qvm-trigger-copy-to-vm $RPM_BUILD_ROOT/usr/lib/qubes cp ../qrexec/qrexec_agent $RPM_BUILD_ROOT/usr/lib/qubes cp ../qrexec/qrexec_client_vm $RPM_BUILD_ROOT/usr/lib/qubes +cp ../qrexec/qubes_rpc_multiplexer $RPM_BUILD_ROOT/usr/lib/qubes cp dvm_file_editor qfile-agent qfile-agent-dvm qfile-unpacker $RPM_BUILD_ROOT/usr/lib/qubes cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes mkdir -p $RPM_BUILD_ROOT/%{kde_service_dir} cp qvm-copy.desktop qvm-dvm.desktop $RPM_BUILD_ROOT/%{kde_service_dir} mkdir -p $RPM_BUILD_ROOT/mnt/removable +mkdir -p $RPM_BUILD_ROOT/etc/qubes_rpc + mkdir -p $RPM_BUILD_ROOT/etc/X11 cp xorg-preload-apps.conf $RPM_BUILD_ROOT/etc/X11 @@ -144,10 +147,12 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/qubes/qvm-trigger-copy-to-vm /usr/lib/qubes/qrexec_agent /usr/lib/qubes/qrexec_client_vm +/usr/lib/qubes/qubes_rpc_multiplexer /usr/lib/qubes/qfile-agent /usr/lib/qubes/qfile-agent-dvm /usr/lib/qubes/qfile-unpacker %dir /mnt/removable +%dir /etc/qubes_rpc /usr/bin/qubes_timestamp %dir /home_volatile %attr(700,user,user) /home_volatile/user diff --git a/rpm_spec/core-dom0.spec b/rpm_spec/core-dom0.spec index e5a74469..7a5d90b3 100644 --- a/rpm_spec/core-dom0.spec +++ b/rpm_spec/core-dom0.spec @@ -96,8 +96,11 @@ cp qmemman/server.py $RPM_BUILD_ROOT/usr/lib/qubes/qmemman_daemon.py cp ../common/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../qrexec/qrexec_daemon $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../qrexec/qrexec_client $RPM_BUILD_ROOT/usr/lib/qubes/ +cp ../qrexec/qrexec_policy $RPM_BUILD_ROOT/usr/lib/qubes/ cp aux-tools/qfile-dom0-unpacker $RPM_BUILD_ROOT/usr/lib/qubes/ +mkdir -p $RPM_BUILD_ROOT/etc/qubes_rpc/policy + cp restore/qvm-create-default-dvm $RPM_BUILD_ROOT/usr/bin cp restore/xenstore-watch $RPM_BUILD_ROOT/usr/bin/xenstore-watch-qubes cp restore/qubes_restore restore/xenfreepages $RPM_BUILD_ROOT/usr/lib/qubes @@ -321,6 +324,8 @@ fi /etc/xen/scripts/block-origin /etc/xen/scripts/vif-route-qubes /usr/lib/qubes/qrexec_client +/usr/lib/qubes/qrexec_policy +%dir /etc/qubes_rpc/policy %attr(4750,root,qubes) /usr/lib/qubes/qrexec_daemon %attr(4750,root,qubes) /usr/lib/qubes/xenfreepages %attr(2770,root,qubes) %dir /var/log/qubes