2013-10-28 05:09:54 +01:00
|
|
|
#!/usr/bin/python2
|
|
|
|
|
|
|
|
import os
|
2013-11-01 02:32:32 +01:00
|
|
|
import re
|
2013-10-28 05:09:54 +01:00
|
|
|
import sys
|
2013-12-04 03:02:39 +01:00
|
|
|
import subprocess
|
2013-10-28 05:09:54 +01:00
|
|
|
from qubes.qubes import QubesVmCollection,QubesException,QubesHVm
|
|
|
|
|
|
|
|
def main():
|
|
|
|
|
|
|
|
source = os.getenv("QREXEC_REMOTE_DOMAIN")
|
|
|
|
|
|
|
|
if source is None:
|
|
|
|
print >> sys.stderr, 'This script must be called as qrexec service!'
|
|
|
|
exit(1)
|
|
|
|
|
2015-07-01 07:03:52 +02:00
|
|
|
source_vm = None
|
2013-10-28 05:09:54 +01:00
|
|
|
qvm_collection = QubesVmCollection()
|
|
|
|
qvm_collection.lock_db_for_writing()
|
|
|
|
try:
|
|
|
|
qvm_collection.load()
|
|
|
|
|
|
|
|
source_vm = qvm_collection.get_vm_by_name(source)
|
|
|
|
if source_vm is None:
|
|
|
|
raise QubesException('Domain ' + source + ' does not exists (?!)')
|
|
|
|
|
|
|
|
if not isinstance(source_vm, QubesHVm):
|
|
|
|
raise QubesException('Service qubes.ToolsNotify is designed only for HVM domains')
|
|
|
|
|
|
|
|
# for now used only to check for the tools presence
|
2015-06-23 00:14:57 +02:00
|
|
|
untrusted_version = source_vm.qdb.read('/qubes-tools/version')
|
2013-10-28 05:09:54 +01:00
|
|
|
# reserved for future use
|
2015-06-23 00:14:57 +02:00
|
|
|
untrusted_os = source_vm.qdb.read('/qubes-tools/os')
|
2013-10-28 05:09:54 +01:00
|
|
|
# qrexec agent presence (0 or 1)
|
2015-06-23 00:14:57 +02:00
|
|
|
untrusted_qrexec = source_vm.qdb.read('/qubes-tools/qrexec')
|
2013-10-28 05:09:54 +01:00
|
|
|
# gui agent presence (0 or 1)
|
2015-06-23 00:14:57 +02:00
|
|
|
untrusted_gui = source_vm.qdb.read('/qubes-tools/gui')
|
2013-11-01 02:32:32 +01:00
|
|
|
# default user for qvm-run etc
|
2015-06-23 00:14:57 +02:00
|
|
|
untrusted_user = source_vm.qdb.read('/qubes-tools/default-user')
|
2013-10-28 05:09:54 +01:00
|
|
|
|
|
|
|
if untrusted_version is None:
|
|
|
|
# tools didn't advertised its features; it's strange that this
|
|
|
|
# service is called, but ignore it
|
|
|
|
return
|
|
|
|
|
|
|
|
# any suspicious string will raise exception here
|
|
|
|
version = int(untrusted_version)
|
|
|
|
|
|
|
|
# untrusted_os - ignore for now
|
|
|
|
|
|
|
|
if untrusted_qrexec is None:
|
|
|
|
qrexec = 0
|
|
|
|
else:
|
|
|
|
qrexec = int(untrusted_qrexec)
|
|
|
|
|
|
|
|
if untrusted_gui is None:
|
|
|
|
gui = 0
|
|
|
|
else:
|
|
|
|
gui = int(untrusted_gui)
|
2013-11-01 02:32:32 +01:00
|
|
|
|
2014-05-16 18:35:59 +02:00
|
|
|
if untrusted_user is not None and re.match(r'^[a-zA-Z0-9-]{1,255}$', untrusted_user):
|
|
|
|
assert '@' not in untrusted_user
|
|
|
|
assert '/' not in untrusted_user
|
|
|
|
|
|
|
|
user = untrusted_user
|
2013-11-01 02:32:32 +01:00
|
|
|
else:
|
|
|
|
user = None
|
|
|
|
|
2013-10-28 05:09:54 +01:00
|
|
|
# Let the tools to be able to enable *or disable* each particular component
|
|
|
|
source_vm.qrexec_installed = qrexec > 0
|
|
|
|
source_vm.guiagent_installed = gui > 0
|
|
|
|
|
2014-05-16 18:35:59 +02:00
|
|
|
if user is not None:
|
2013-11-01 02:32:32 +01:00
|
|
|
source_vm.default_user = user
|
|
|
|
|
2013-10-28 05:09:54 +01:00
|
|
|
qvm_collection.save()
|
2013-12-04 03:02:39 +01:00
|
|
|
|
2013-10-28 05:09:54 +01:00
|
|
|
except Exception as e:
|
|
|
|
print >> sys.stderr, e.message
|
|
|
|
exit(1)
|
|
|
|
finally:
|
|
|
|
qvm_collection.unlock_db()
|
|
|
|
|
2015-07-01 07:03:52 +02:00
|
|
|
retcode = subprocess.call(['qvm-sync-appmenus', '--force-rpc'])
|
|
|
|
if retcode == 0 and hasattr(source_vm, 'appmenus_recreate'):
|
|
|
|
# TODO: call the same for child VMs? This isn't done for Linux VMs,
|
|
|
|
# so probably should be ignored for Windows also
|
|
|
|
source_vm.appmenus_recreate()
|
|
|
|
|
|
|
|
|
2013-10-28 05:09:54 +01:00
|
|
|
main()
|