Merge branch 'hvm' of 10.141.1.101:/var/lib/qubes/git/marmarek/core into hvm

This commit is contained in:
Joanna Rutkowska 2012-08-24 15:12:07 +02:00
commit 4092814534
24 changed files with 323 additions and 279 deletions

View File

@ -214,12 +214,14 @@ class SystemState:
print 'dom %s didnt react to memory request (holds %d, requested balloon down to %d)' % (dom2, self.domdict[dom2].memory_actual, mem2) print 'dom %s didnt react to memory request (holds %d, requested balloon down to %d)' % (dom2, self.domdict[dom2].memory_actual, mem2)
self.domdict[dom2].no_progress = True self.domdict[dom2].no_progress = True
dom_name = self.xs.read('', '/local/domain/%s/name' % str(dom2)) dom_name = self.xs.read('', '/local/domain/%s/name' % str(dom2))
notify_error_qubes_manager(dom_name, no_progress_msg) if dom_name is not None:
notify_error_qubes_manager(str(dom_name), no_progress_msg)
else: else:
print 'dom %s still hold more memory than have assigned (%d > %d)' % (dom2, self.domdict[dom2].memory_actual, mem2) print 'dom %s still hold more memory than have assigned (%d > %d)' % (dom2, self.domdict[dom2].memory_actual, mem2)
self.domdict[dom2].slow_memset_react = True self.domdict[dom2].slow_memset_react = True
dom_name = self.xs.read('', '/local/domain/%s/name' % str(dom2)) dom_name = self.xs.read('', '/local/domain/%s/name' % str(dom2))
notify_error_qubes_manager(dom_name, slow_memset_react_msg) if dom_name is not None:
notify_error_qubes_manager(str(dom_name), slow_memset_react_msg)
self.mem_set(dom, self.get_free_xen_memory() + self.domdict[dom].memory_actual - self.XEN_FREE_MEM_LEFT) self.mem_set(dom, self.get_free_xen_memory() + self.domdict[dom].memory_actual - self.XEN_FREE_MEM_LEFT)
return return

View File

@ -1 +0,0 @@
/usr/bin/qvm-sync-appmenus

View File

@ -50,10 +50,12 @@ def main():
os.umask(0002) os.umask(0002)
qubes_gid = grp.getgrnam('qubes').gr_gid qubes_gid = grp.getgrnam('qubes').gr_gid
update_count = sys.stdin.readline(128).strip() untrusted_update_count = sys.stdin.readline(128).strip()
if not update_count.isdigit(): if not untrusted_update_count.isdigit():
print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: ' + update_count print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: %s' % untrusted_update_count
exit(1) exit(1)
# now sanitized
update_count = untrusted_update_count
if source_vm.updateable: if source_vm.updateable:
# Just trust information from VM itself # Just trust information from VM itself
update_f = open(source_vm.dir_path + '/' + updates_stat_file, "w") update_f = open(source_vm.dir_path + '/' + updates_stat_file, "w")

View File

@ -0,0 +1,226 @@
#!/usr/bin/python
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2011 Marek Marczykowski <marmarek@mimuw.edu.pl>
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
import subprocess
import re
import os
import sys
import fnmatch
import shutil
from optparse import OptionParser
from qubes.qubes import QubesVmCollection,QubesException
from qubes.qubes import qrexec_client_path
# fields required to be present (and verified) in retrieved desktop file
required_fields = [ "Name", "Exec" ]
#limits
appmenus_line_size = 1024
appmenus_line_count = 100000
# regexps for sanitization of retrieved values
std_re = re.compile(r"^[/a-zA-Z0-9.,&() -]*$")
fields_regexp = {
"Name": std_re,
"GenericName": std_re,
"Comment": std_re,
"Categories": re.compile(r"^[a-zA-Z0-9/.; -]*$"),
"Exec": re.compile(r"^[a-zA-Z0-9%>/:.= -]*$"),
}
def get_appmenus(xid):
global appmenus_line_count
global appmenus_line_size
untrusted_appmenulist = []
if xid == -1:
while appmenus_line_count > 0:
untrusted_line = sys.stdin.readline(appmenus_line_size)
if untrusted_line == "":
break;
untrusted_appmenulist.append(untrusted_line.strip())
appmenus_line_count -= 1
if appmenus_line_count == 0:
raise QubesException("Line count limit exceeded")
else:
p = subprocess.Popen ([qrexec_client_path, '-d', str(xid),
'user:QUBESRPC qubes.GetAppmenus dom0'], stdout=subprocess.PIPE)
while appmenus_line_count > 0:
untrusted_line = p.stdout.readline(appmenus_line_size)
if untrusted_line == "":
break;
untrusted_appmenulist.append(untrusted_line.strip())
appmenus_line_count -= 1
p.wait()
if p.returncode != 0:
raise QubesException("Error getting application list")
if appmenus_line_count == 0:
raise QubesException("Line count limit exceeded")
row_no = 0
appmenus = {}
line_rx = re.compile(r"([a-zA-Z0-9-.]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)")
ignore_rx = re.compile(r".*([a-zA-Z0-9-.]+.desktop):(#.*|\s+)$")
for untrusted_line in untrusted_appmenulist:
# Ignore blank lines and comments
if len(untrusted_line) == 0 or ignore_rx.match(untrusted_line):
continue
# use search instead of match to skip file path
untrusted_m = line_rx.search(untrusted_line)
if untrusted_m:
untrusted_key = untrusted_m.group(2)
untrusted_value = untrusted_m.group(3)
# Look only at predefined keys
if fields_regexp.has_key(untrusted_key):
if fields_regexp[untrusted_key].match(untrusted_value):
# now values are sanitized
key = untrusted_key
value = untrusted_value
filename = untrusted_m.group(1)
if not appmenus.has_key(filename):
appmenus[filename] = {}
appmenus[filename][key]=value
else:
print >>sys.stderr, "Warning: ignoring key %s: %s" % (untrusted_key, untrusted_value)
# else: ignore this key
else:
print >>sys.stderr, "Warning: ignoring line: %s" % (untrusted_line);
return appmenus
def create_template(path, values):
# check if all required fields are present
for key in required_fields:
if not values.has_key(key):
print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key)
return
desktop_file = open(path, "w")
desktop_file.write("[Desktop Entry]\n")
desktop_file.write("Version=1.0\n")
desktop_file.write("Type=Application\n")
desktop_file.write("Terminal=false\n")
desktop_file.write("X-Qubes-VmName=%VMNAME%\n")
desktop_file.write("Icon=%VMDIR%/icon.png\n")
for key in ["Name", "GenericName" ]:
if values.has_key(key):
desktop_file.write("{0}=%VMNAME%: {1}\n".format(key, values[key]))
for key in [ "Comment", "Categories" ]:
if values.has_key(key):
desktop_file.write("{0}={1}\n".format(key, values[key]))
desktop_file.write("Exec=qvm-run -q --tray -a %VMNAME% '{0}'\n".format(values['Exec']))
desktop_file.close()
def main():
env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN")
usage = "usage: %prog [options] <vm-name>\n"\
"Updates desktop file templates for given StandaloneVM or TemplateVM"
parser = OptionParser (usage)
parser.add_option ("-v", "--verbose", action="store_true", dest="verbose", default=False)
parser.add_option ("--force-root", action="store_true", dest="force_root", default=False,
help="Force to run, even with root privileges")
(options, args) = parser.parse_args ()
if (len (args) != 1) and env_vmname is None:
parser.error ("You must specify at least the VM name!")
if env_vmname:
vmname=env_vmname
else:
vmname=args[0]
if os.geteuid() == 0:
if not options.force_root:
print >> sys.stderr, "*** Running this tool as root is strongly discouraged, this will lead you in permissions problems."
print >> sys.stderr, "Retry as unprivileged user."
print >> sys.stderr, "... or use --force-root to continue anyway."
exit(1)
qvm_collection = QubesVmCollection()
qvm_collection.lock_db_for_reading()
qvm_collection.load()
qvm_collection.unlock_db()
vm = qvm_collection.get_vm_by_name(vmname)
if vm is None:
print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname)
exit(1)
if vm.template is not None:
print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead"
exit(1)
if not vm.is_running():
print >>sys.stderr, "ERROR: Appmenus can be retrieved only from running VM - start it first"
exit(1)
new_appmenus = {}
if env_vmname is None:
# Get appmenus from VM
xid = vm.get_xid()
assert xid > 0
new_appmenus = get_appmenus(xid)
else:
options.verbose = False
new_appmenus = get_appmenus(-1)
if len(new_appmenus) == 0:
print >>sys.stderr, "ERROR: No appmenus received, terminating"
exit(1)
if not os.path.exists(vm.appmenus_templates_dir):
os.mkdir(vm.appmenus_templates_dir)
# Create new/update existing templates
if options.verbose:
print >> sys.stderr, "--> Got {0} appmenus, storing to disk".format(str(len(new_appmenus)))
for appmenu_file in new_appmenus.keys():
if options.verbose:
if os.path.exists(vm.appmenus_templates_dir + '/' + appmenu_file):
print >> sys.stderr, "---> Updating {0}".format(appmenu_file)
else:
print >> sys.stderr, "---> Creating {0}".format(appmenu_file)
create_template(vm.appmenus_templates_dir + '/' + appmenu_file, new_appmenus[appmenu_file])
# Delete appmenus of remove applications
if options.verbose:
print >> sys.stderr, "--> Cleaning old files"
for appmenu_file in os.listdir(vm.appmenus_templates_dir):
if not fnmatch.fnmatch(appmenu_file, '*.desktop'):
continue
if not new_appmenus.has_key(appmenu_file):
if options.verbose:
print >> sys.stderr, "---> Removing {0}".format(appmenu_file)
os.unlink(vm.appmenus_templates_dir + '/' + appmenu_file)
main()

View File

@ -66,9 +66,12 @@ def handle_dom0updates(updatevm):
os.chmod(updates_rpm_dir, 0775) os.chmod(updates_rpm_dir, 0775)
subprocess.check_call(["/usr/lib/qubes/qfile-dom0-unpacker", str(os.getuid()), updates_rpm_dir]) subprocess.check_call(["/usr/lib/qubes/qfile-dom0-unpacker", str(os.getuid()), updates_rpm_dir])
# Verify received files # Verify received files
for f in os.listdir(updates_rpm_dir): for untrusted_f in os.listdir(updates_rpm_dir):
full_path = updates_rpm_dir + "/" + f if not package_regex.match(untrusted_f):
if package_regex.match(f): dom0updates_fatal(untrusted_f, 'Domain ' + source + ' sent unexpected file: ' + untrusted_f)
else:
f = untrusted_f
full_path = updates_rpm_dir + "/" + f
if os.path.islink(full_path) or not os.path.isfile(full_path): if os.path.islink(full_path) or not os.path.isfile(full_path):
dom0updates_fatal(f, 'Domain ' + source + ' sent not regular file') dom0updates_fatal(f, 'Domain ' + source + ' sent not regular file')
p = subprocess.Popen (["/bin/rpm", "-K", full_path], p = subprocess.Popen (["/bin/rpm", "-K", full_path],
@ -78,8 +81,6 @@ def handle_dom0updates(updatevm):
dom0updates_fatal(f, 'Error while verifing %s signature: %s' % (f, output)) dom0updates_fatal(f, 'Error while verifing %s signature: %s' % (f, output))
if not gpg_ok_regex.search(output.strip()): if not gpg_ok_regex.search(output.strip()):
dom0updates_fatal(f, 'Domain ' + source + ' sent not signed rpm: ' + f) dom0updates_fatal(f, 'Domain ' + source + ' sent not signed rpm: ' + f)
else:
dom0updates_fatal(f, 'Domain ' + source + ' sent unexpected file: ' + f)
if updates_error_file_handle is not None: if updates_error_file_handle is not None:
updates_error_file_handle.close() updates_error_file_handle.close()
# After updates received - create repo metadata # After updates received - create repo metadata

View File

@ -0,0 +1 @@
/usr/lib/qubes/qubes-receive-appmenus

View File

@ -324,6 +324,9 @@ class QubesVm(object):
assert self.__qid < qubes_max_qid, "VM id out of bounds!" assert self.__qid < qubes_max_qid, "VM id out of bounds!"
assert self.name is not None assert self.name is not None
if not self.verify_name(self.name):
raise QubesException("Invalid characters in VM name")
if self.netvm is not None: if self.netvm is not None:
self.netvm.connected_vms[self.qid] = self self.netvm.connected_vms[self.qid] = self
@ -491,6 +494,9 @@ class QubesVm(object):
else: else:
return False return False
def verify_name(self, name):
return re.match(r"^[a-zA-Z0-9-]*$", name) is not None
def pre_rename(self, new_name): def pre_rename(self, new_name):
pass pass
@ -498,6 +504,9 @@ class QubesVm(object):
if self.is_running(): if self.is_running():
raise QubesException("Cannot change name of running VM!") raise QubesException("Cannot change name of running VM!")
if not self.verify_name(name):
raise QubesException("Invalid characters in VM name")
self.pre_rename(name) self.pre_rename(name)
new_conf = "%s/%s.conf" % (self.dir_path, name) new_conf = "%s/%s.conf" % (self.dir_path, name)

View File

@ -22,6 +22,7 @@
from qubes.qubes import QubesVmCollection from qubes.qubes import QubesVmCollection
from qubes.qubes import QubesVmLabels from qubes.qubes import QubesVmLabels
from qubes.qubes import QubesException
from optparse import OptionParser; from optparse import OptionParser;
import subprocess import subprocess
import re import re
@ -133,14 +134,18 @@ def main():
new_vm_template = template new_vm_template = template
vm = None vm = None
if options.netvm: try:
vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label) if options.netvm:
elif options.proxyvm: vm = qvm_collection.add_new_netvm(vmname, new_vm_template, label = label)
vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label) elif options.proxyvm:
elif options.hvm: vm = qvm_collection.add_new_proxyvm(vmname, new_vm_template, label = label)
vm = qvm_collection.add_new_hvm(vmname, label = label) elif options.hvm:
else: vm = qvm_collection.add_new_hvm(vmname, label = label)
vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label) else:
vm = qvm_collection.add_new_appvm(vmname, new_vm_template, label = label)
except QubesException as err:
print >> sys.stderr, "ERROR: {0}".format(err)
exit (1)
if options.internal: if options.internal:
vm.internal = True vm.internal = True

View File

@ -375,7 +375,11 @@ def do_set(vms, vm, property, args):
print >> sys.stderr, "ERROR: Property '{0}' not available for this VM".format(property) print >> sys.stderr, "ERROR: Property '{0}' not available for this VM".format(property)
return False return False
return properties[property](vms, vm, args) try:
return properties[property](vms, vm, args)
except Exception as err:
print >> sys.stderr, "ERROR: %s" % str(err)
return False
def main(): def main():

View File

@ -1,225 +1,2 @@
#!/usr/bin/python #!/bin/sh
# exec /usr/lib/qubes/qubes-receive-appmenus $@
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2011 Marek Marczykowski <marmarek@mimuw.edu.pl>
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
import subprocess
import re
import os
import sys
import fnmatch
import shutil
from optparse import OptionParser
from qubes.qubes import QubesVmCollection,QubesException
from qubes.qubes import qrexec_client_path
# fields required to be present (and verified) in retrieved desktop file
required_fields = [ "Name", "Exec" ]
#limits
appmenus_line_size = 1024
appmenus_line_count = 100000
# regexps for sanitization of retrieved values
std_re = re.compile(r"^[/a-zA-Z0-9.,&() -]*$")
fields_regexp = {
"Name": std_re,
"GenericName": std_re,
"Comment": std_re,
"Categories": re.compile(r"^[a-zA-Z0-9/.; -]*$"),
"Exec": re.compile(r"^[a-zA-Z0-9%>/:.= -]*$"),
}
def get_appmenus(xid):
global appmenus_line_count
global appmenus_line_size
untrusted_appmenulist = []
if xid == -1:
while appmenus_line_count > 0:
line = sys.stdin.readline(appmenus_line_size)
if line == "":
break;
untrusted_appmenulist.append(line.strip())
appmenus_line_count -= 1
if appmenus_line_count == 0:
raise QubesException("Line count limit exceeded")
else:
p = subprocess.Popen ([qrexec_client_path, '-d', str(xid),
'user:QUBESRPC qubes.GetAppmenus dom0'], stdout=subprocess.PIPE)
while appmenus_line_count > 0:
line = p.stdout.readline(appmenus_line_size)
if line == "":
break;
untrusted_appmenulist.append(line.strip())
appmenus_line_count -= 1
p.wait()
if p.returncode != 0:
raise QubesException("Error getting application list")
if appmenus_line_count == 0:
raise QubesException("Line count limit exceeded")
row_no = 0
appmenus = {}
line_rx = re.compile(r"([a-zA-Z0-9-.]+.desktop):([a-zA-Z0-9-]+(?:\[[a-zA-Z@_]+\])?)=(.*)")
ignore_rx = re.compile(r".*([a-zA-Z0-9-.]+.desktop):(#.*|\s+)$")
for untrusted_line in untrusted_appmenulist:
# Ignore blank lines and comments
if len(untrusted_line) == 0 or ignore_rx.match(untrusted_line):
continue
# use search instead of match to skip file path
untrusted_m = line_rx.search(untrusted_line)
if untrusted_m:
untrusted_key = untrusted_m.group(2)
untrusted_value = untrusted_m.group(3)
if fields_regexp.has_key(untrusted_key):
if fields_regexp[untrusted_key].match(untrusted_value):
# now values are sanitized
key = untrusted_key
value = untrusted_value
filename = untrusted_m.group(1)
if not appmenus.has_key(filename):
appmenus[filename] = {}
appmenus[filename][key]=value
else:
print >>sys.stderr, "Warning: ignoring key %s: %s" % (untrusted_key, untrusted_value)
# else: ignore this key
else:
print >>sys.stderr, "Warning: ignoring line: %s" % (untrusted_line);
return appmenus
def create_template(path, values):
# check if all required fields are present
for key in required_fields:
if not values.has_key(key):
print >>sys.stderr, "Warning: not creating/updating '%s' because of missing '%s' key" % (path, key)
return
desktop_file = open(path, "w")
desktop_file.write("[Desktop Entry]\n")
desktop_file.write("Version=1.0\n")
desktop_file.write("Type=Application\n")
desktop_file.write("Terminal=false\n")
desktop_file.write("X-Qubes-VmName=%VMNAME%\n")
desktop_file.write("Icon=%VMDIR%/icon.png\n")
for key in ["Name", "GenericName" ]:
if values.has_key(key):
desktop_file.write("{0}=%VMNAME%: {1}\n".format(key, values[key]))
for key in [ "Comment", "Categories" ]:
if values.has_key(key):
desktop_file.write("{0}={1}\n".format(key, values[key]))
desktop_file.write("Exec=qvm-run -q --tray -a %VMNAME% '{0}'\n".format(values['Exec']))
desktop_file.close()
def main():
env_vmname = os.environ.get("QREXEC_REMOTE_DOMAIN")
usage = "usage: %prog [options] <vm-name>\n"\
"Updates desktop file templates for given StandaloneVM or TemplateVM"
parser = OptionParser (usage)
parser.add_option ("-v", "--verbose", action="store_true", dest="verbose", default=False)
parser.add_option ("--force-root", action="store_true", dest="force_root", default=False,
help="Force to run, even with root privileges")
(options, args) = parser.parse_args ()
if (len (args) != 1) and env_vmname is None:
parser.error ("You must specify at least the VM name!")
if env_vmname:
vmname=env_vmname
else:
vmname=args[0]
if os.geteuid() == 0:
if not options.force_root:
print >> sys.stderr, "*** Running this tool as root is strongly discouraged, this will lead you in permissions problems."
print >> sys.stderr, "Retry as unprivileged user."
print >> sys.stderr, "... or use --force-root to continue anyway."
exit(1)
qvm_collection = QubesVmCollection()
qvm_collection.lock_db_for_reading()
qvm_collection.load()
qvm_collection.unlock_db()
vm = qvm_collection.get_vm_by_name(vmname)
if vm is None:
print >>sys.stderr, "ERROR: A VM with the name '{0}' does not exist in the system.".format(vmname)
exit(1)
if vm.template is not None:
print >>sys.stderr, "ERROR: To sync appmenus for template based VM, do it on template instead"
exit(1)
if not vm.is_running():
print >>sys.stderr, "ERROR: Appmenus can be retrieved only from running VM - start it first"
exit(1)
new_appmenus = {}
if env_vmname is None:
# Get appmenus from VM
xid = vm.get_xid()
assert xid > 0
new_appmenus = get_appmenus(xid)
else:
options.verbose = False
new_appmenus = get_appmenus(-1)
if len(new_appmenus) == 0:
print >>sys.stderr, "ERROR: No appmenus received, terminating"
exit(1)
if not os.path.exists(vm.appmenus_templates_dir):
os.mkdir(vm.appmenus_templates_dir)
# Create new/update existing templates
if options.verbose:
print >> sys.stderr, "--> Got {0} appmenus, storing to disk".format(str(len(new_appmenus)))
for appmenu_file in new_appmenus.keys():
if options.verbose:
if os.path.exists(vm.appmenus_templates_dir + '/' + appmenu_file):
print >> sys.stderr, "---> Updating {0}".format(appmenu_file)
else:
print >> sys.stderr, "---> Creating {0}".format(appmenu_file)
create_template(vm.appmenus_templates_dir + '/' + appmenu_file, new_appmenus[appmenu_file])
# Delete appmenus of remove applications
if options.verbose:
print >> sys.stderr, "--> Cleaning old files"
for appmenu_file in os.listdir(vm.appmenus_templates_dir):
if not fnmatch.fnmatch(appmenu_file, '*.desktop'):
continue
if not new_appmenus.has_key(appmenu_file):
if options.verbose:
print >> sys.stderr, "---> Removing {0}".format(appmenu_file)
os.unlink(vm.appmenus_templates_dir + '/' + appmenu_file)
main()

View File

@ -5,6 +5,8 @@ import os.path
import subprocess import subprocess
import xen.lowlevel.xl import xen.lowlevel.xl
import qubes.guihelpers import qubes.guihelpers
from optparse import OptionParser
from qubes.qubes import QubesVmCollection
import fcntl import fcntl
POLICY_FILE_DIR="/etc/qubes_rpc/policy" POLICY_FILE_DIR="/etc/qubes_rpc/policy"
@ -96,7 +98,7 @@ def do_execute(domain, target, user, exec_index, process_ident):
# also, dangling "xl" would keep stderr open and may prevent closing connection # also, dangling "xl" would keep stderr open and may prevent closing connection
spawn_target_if_necessary(target) spawn_target_if_necessary(target)
cmd= QREXEC_CLIENT + " -d " + target + " '" + user cmd= QREXEC_CLIENT + " -d " + target + " '" + user
cmd+=":/usr/lib/qubes/qubes_rpc_multiplexer "+ exec_index + " " + domain + "'" cmd+=":QUBESRPC "+ exec_index + " " + domain + "'"
os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", cmd, "-c", process_ident) os.execl(QREXEC_CLIENT, "qrexec_client", "-d", domain, "-l", cmd, "-c", process_ident)
def confirm_execution(domain, target, exec_index): def confirm_execution(domain, target, exec_index):
@ -126,10 +128,18 @@ def policy_editor(domain, target, exec_index):
subprocess.call(["/usr/bin/zenity", "--info", "--text", text]) subprocess.call(["/usr/bin/zenity", "--info", "--text", text])
def main(): def main():
domain=sys.argv[1] usage = "usage: %prog [options] <src-domain> <target-domain> <service> <process-ident>"
target=sys.argv[2] parser = OptionParser (usage)
exec_index=sys.argv[3] parser.add_option ("--assume-yes-for-ask", action="store_true", dest="assume_yes_for_ask", default=False,
process_ident=sys.argv[4] help="Allow run of service without confirmation if policy say 'ask'")
parser.add_option ("--just-evaluate", action="store_true", dest="just_evaluate", default=False,
help="Do not run the service, only evaluate policy; retcode=0 means 'allow'")
(options, args) = parser.parse_args ()
domain=args[0]
target=args[1]
exec_index=args[2]
process_ident=args[3]
policy_list=read_policy_file(exec_index) policy_list=read_policy_file(exec_index)
if policy_list==None: if policy_list==None:
@ -139,6 +149,9 @@ def main():
policy_list=list() policy_list=list()
policy_dict=find_policy(policy_list, domain, target) policy_dict=find_policy(policy_list, domain, target)
if policy_dict["action"] == "ask" and options.assume_yes_for_ask:
policy_dict["action"] = "allow"
if policy_dict["action"] == "ask": if policy_dict["action"] == "ask":
user_choice = confirm_execution(domain, target, exec_index) user_choice = confirm_execution(domain, target, exec_index)
@ -149,14 +162,29 @@ def main():
policy_dict["action"] = "allow" policy_dict["action"] = "allow"
else: else:
policy_dict["action"] = "deny" policy_dict["action"] = "deny"
if options.just_evaluate:
if policy_dict["action"] == "allow":
exit(0)
else:
exit(1)
if policy_dict["action"] == "allow": if policy_dict["action"] == "allow":
if policy_dict.has_key("action.target"): if policy_dict.has_key("action.target"):
target=policy_dict["action.target"] target=policy_dict["action.target"]
if policy_dict.has_key("action.user"): if policy_dict.has_key("action.user"):
user=policy_dict["action.user"] user=policy_dict["action.user"]
else: else:
user="user" qvm_collection = QubesVmCollection()
qvm_collection.lock_db_for_reading()
qvm_collection.load()
qvm_collection.unlock_db()
vm = qvm_collection.get_vm_by_name(target)
if vm is None:
print >> sys.stderr, "Cannot find settings of VM '%s', assuming default user 'user'" % target
user = "user"
else:
user = vm.default_user
do_execute(domain, target, user, exec_index, process_ident) do_execute(domain, target, user, exec_index, process_ident)
print >> sys.stderr, "Rpc denied:", domain, target, exec_index print >> sys.stderr, "Rpc denied:", domain, target, exec_index

View File

@ -3,4 +3,4 @@
## Please use a single # to start your custom comments ## Please use a single # to start your custom comments
$anyvm $anyvm ask,user=root $anyvm $anyvm ask

View File

@ -1,2 +1,2 @@
shopt -s nullglob shopt -s nullglob
/bin/grep -H = /usr/share/applications/*.desktop /usr/local/share/applications/*.desktop 2> /dev/null awk '/^\[/ { if (tolower($0) != "\[desktop entry\]") nextfile } /=/ {print FILENAME ":" $0 }' /usr/share/applications/*.desktop /usr/local/share/applications/*.desktop 2> /dev/null

View File

@ -53,7 +53,7 @@ The Qubes core files for installation on Dom0.
python -m compileall qvm-core qmemman python -m compileall qvm-core qmemman
python -O -m compileall qvm-core qmemman python -O -m compileall qvm-core qmemman
make -C restore make -C restore
make -C aux-tools make -C qubes_rpc
make -C ../qubes_rpc make -C ../qubes_rpc
make -C ../vchan -f Makefile.linux make -C ../vchan -f Makefile.linux
make -C ../u2mfn make -C ../u2mfn
@ -109,9 +109,10 @@ cp ../misc/meminfo-writer $RPM_BUILD_ROOT/usr/lib/qubes/
cp ../qrexec/qrexec_daemon $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_client $RPM_BUILD_ROOT/usr/lib/qubes/
cp ../qrexec/qrexec_policy $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/ cp qubes_rpc/qfile-dom0-unpacker $RPM_BUILD_ROOT/usr/lib/qubes/
cp aux-tools/qubes-notify-updates $RPM_BUILD_ROOT/usr/lib/qubes/ cp qubes_rpc/qubes-notify-updates $RPM_BUILD_ROOT/usr/lib/qubes/
cp aux-tools/qubes-receive-updates $RPM_BUILD_ROOT/usr/lib/qubes/ cp qubes_rpc/qubes-receive-appmenus $RPM_BUILD_ROOT/usr/lib/qubes/
cp qubes_rpc/qubes-receive-updates $RPM_BUILD_ROOT/usr/lib/qubes/
cp ../misc/block_add_change $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../misc/block_add_change $RPM_BUILD_ROOT/usr/lib/qubes/
cp ../misc/block_remove $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../misc/block_remove $RPM_BUILD_ROOT/usr/lib/qubes/
cp ../misc/block_cleanup $RPM_BUILD_ROOT/usr/lib/qubes/ cp ../misc/block_cleanup $RPM_BUILD_ROOT/usr/lib/qubes/
@ -122,13 +123,13 @@ mkdir -p $RPM_BUILD_ROOT/etc/qubes_rpc/policy
cp ../qubes_rpc/qubes.Filecopy.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.Filecopy cp ../qubes_rpc/qubes.Filecopy.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.Filecopy
cp ../qubes_rpc/qubes.OpenInVM.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.OpenInVM cp ../qubes_rpc/qubes.OpenInVM.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.OpenInVM
cp ../qubes_rpc/qubes.VMShell.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.VMShell cp ../qubes_rpc/qubes.VMShell.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.VMShell
cp qubes.SyncAppMenus.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.SyncAppMenus cp qubes_rpc/qubes.SyncAppMenus.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.SyncAppMenus
cp qubes.SyncAppMenus $RPM_BUILD_ROOT/etc/qubes_rpc/ cp qubes_rpc/qubes.SyncAppMenus $RPM_BUILD_ROOT/etc/qubes_rpc/
cp ../qrexec/qubes_rpc_multiplexer $RPM_BUILD_ROOT/usr/lib/qubes cp ../qrexec/qubes_rpc_multiplexer $RPM_BUILD_ROOT/usr/lib/qubes
cp aux-tools/qubes.NotifyUpdates.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.NotifyUpdates cp qubes_rpc/qubes.NotifyUpdates.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.NotifyUpdates
cp aux-tools/qubes.NotifyUpdates $RPM_BUILD_ROOT/etc/qubes_rpc/ cp qubes_rpc/qubes.NotifyUpdates $RPM_BUILD_ROOT/etc/qubes_rpc/
cp aux-tools/qubes.ReceiveUpdates.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.ReceiveUpdates cp qubes_rpc/qubes.ReceiveUpdates.policy $RPM_BUILD_ROOT/etc/qubes_rpc/policy/qubes.ReceiveUpdates
cp aux-tools/qubes.ReceiveUpdates $RPM_BUILD_ROOT/etc/qubes_rpc/ cp qubes_rpc/qubes.ReceiveUpdates $RPM_BUILD_ROOT/etc/qubes_rpc/
install -D aux-tools/qubes-dom0.modules $RPM_BUILD_ROOT/etc/sysconfig/modules/qubes-dom0.modules install -D aux-tools/qubes-dom0.modules $RPM_BUILD_ROOT/etc/sysconfig/modules/qubes-dom0.modules
install -D aux-tools/cpufreq-xen.modules $RPM_BUILD_ROOT/etc/sysconfig/modules/cpufreq-xen.modules install -D aux-tools/cpufreq-xen.modules $RPM_BUILD_ROOT/etc/sysconfig/modules/cpufreq-xen.modules
install -D aux-tools/qubes-dom0-updates.cron $RPM_BUILD_ROOT/etc/cron.daily/qubes-dom0-updates.cron install -D aux-tools/qubes-dom0-updates.cron $RPM_BUILD_ROOT/etc/cron.daily/qubes-dom0-updates.cron
@ -358,6 +359,7 @@ fi
/usr/lib/qubes/meminfo-writer /usr/lib/qubes/meminfo-writer
/usr/lib/qubes/qfile-daemon-dvm* /usr/lib/qubes/qfile-daemon-dvm*
/usr/lib/qubes/qubes-notify-updates /usr/lib/qubes/qubes-notify-updates
/usr/lib/qubes/qubes-receive-appmenus
/usr/lib/qubes/qubes-receive-updates /usr/lib/qubes/qubes-receive-updates
/usr/lib/qubes/block_add_change /usr/lib/qubes/block_add_change
/usr/lib/qubes/block_remove /usr/lib/qubes/block_remove

View File

@ -398,7 +398,7 @@ rm -rf $RPM_BUILD_ROOT
/usr/lib/qubes/meminfo-writer /usr/lib/qubes/meminfo-writer
/usr/lib/qubes/network-manager-prepare-conf-dir /usr/lib/qubes/network-manager-prepare-conf-dir
/usr/lib/qubes/qfile-agent /usr/lib/qubes/qfile-agent
/usr/lib/qubes/qfile-unpacker %attr(4755,root,root) /usr/lib/qubes/qfile-unpacker
/usr/lib/qubes/qopen-in-vm /usr/lib/qubes/qopen-in-vm
/usr/lib/qubes/qrexec_agent /usr/lib/qubes/qrexec_agent
/usr/lib/qubes/qrexec_client_vm /usr/lib/qubes/qrexec_client_vm

View File

@ -77,7 +77,7 @@ int libvchan_wait(struct libvchan *ctrl)
{ {
int ret; int ret;
ret = xc_evtchn_pending(ctrl->evfd); ret = xc_evtchn_pending_with_flush(ctrl->evfd);
if (ret!=-1 && xc_evtchn_unmask(ctrl->evfd, ctrl->evport)) if (ret!=-1 && xc_evtchn_unmask(ctrl->evfd, ctrl->evport))
return -1; return -1;
if (ret!=-1 && libvchan_is_eof(ctrl)) if (ret!=-1 && libvchan_is_eof(ctrl))
@ -125,12 +125,6 @@ int libvchan_write(struct libvchan *ctrl, char *data, int size)
{ {
int avail, avail_contig; int avail, avail_contig;
int real_idx; int real_idx;
#ifdef WINNT
// because of mask-on-fire and do_notify called previously, evtchn must be
// unmasked before libvchan_wait. Do it before checking if data is
// available to prevent race
libvchan_prepare_to_select(ctrl);
#endif
while ((avail = libvchan_buffer_space(ctrl)) == 0) while ((avail = libvchan_buffer_space(ctrl)) == 0)
if (libvchan_wait(ctrl) < 0) if (libvchan_wait(ctrl) < 0)
return -1; return -1;
@ -156,12 +150,6 @@ int libvchan_read(struct libvchan *ctrl, char *data, int size)
{ {
int avail, avail_contig; int avail, avail_contig;
int real_idx; int real_idx;
#ifdef WINNT
// because of mask-on-fire and do_notify called previously, evtchn must be
// unmasked before libvchan_wait. Do it before checking if data is
// available to prevent race
libvchan_prepare_to_select(ctrl);
#endif
while ((avail = libvchan_data_ready(ctrl)) == 0) while ((avail = libvchan_data_ready(ctrl)) == 0)
if (libvchan_wait(ctrl) < 0) if (libvchan_wait(ctrl) < 0)
return -1; return -1;

View File

@ -1 +1 @@
1.7.42 1.7.43