9b3a77bc1d
This makes more clear which code have contact with untrusted data from VM.
85 lines
3.1 KiB
Python
Executable File
85 lines
3.1 KiB
Python
Executable File
#!/usr/bin/python
|
|
#
|
|
# The Qubes OS Project, http://www.qubes-os.org
|
|
#
|
|
# Copyright (C) 2012 Marek Marczykowski <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, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
#
|
|
import os
|
|
import os.path
|
|
import sys
|
|
import subprocess
|
|
import shutil
|
|
import grp
|
|
from datetime import datetime
|
|
from qubes.qubes import QubesVmCollection
|
|
from qubes.qubes import updates_stat_file
|
|
|
|
def main():
|
|
|
|
qvm_collection = QubesVmCollection()
|
|
qvm_collection.lock_db_for_reading()
|
|
qvm_collection.load()
|
|
qvm_collection.unlock_db()
|
|
|
|
source = os.getenv("QREXEC_REMOTE_DOMAIN")
|
|
|
|
if source is None:
|
|
print >> sys.stderr, 'This script must be called as qrexec service!'
|
|
exit(1)
|
|
|
|
source_vm = qvm_collection.get_vm_by_name(source)
|
|
if source_vm is None:
|
|
print >> sys.stderr, 'Domain ' + source + ' does not exists (?!)'
|
|
exit(1)
|
|
|
|
os.umask(0002)
|
|
qubes_gid = grp.getgrnam('qubes').gr_gid
|
|
|
|
update_count = sys.stdin.readline(128).strip()
|
|
if not update_count.isdigit():
|
|
print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: ' + update_count
|
|
exit(1)
|
|
if source_vm.updateable:
|
|
# Just trust information from VM itself
|
|
update_f = open(source_vm.dir_path + '/' + updates_stat_file, "w")
|
|
update_f.write(update_count)
|
|
update_f.close()
|
|
os.chown(source_vm.dir_path + '/' + updates_stat_file, -1, qubes_gid)
|
|
elif source_vm.template is not None:
|
|
# Hint about updates availability in template
|
|
# If template is running - it will notify about updates itself
|
|
if source_vm.template.is_running():
|
|
return
|
|
# Ignore no-updates info
|
|
if int(update_count) > 0:
|
|
stat_file = source_vm.template.dir_path + '/' + updates_stat_file
|
|
# If VM is started before last updates.stat - it means that updates
|
|
# already was installed (but VM still hasn't been restarted), or other
|
|
# VM has already notified about updates availability
|
|
if os.path.exists(stat_file) and \
|
|
source_vm.get_start_time() < datetime.fromtimestamp(os.path.getmtime(stat_file)):
|
|
return
|
|
update_f = open(stat_file, "w")
|
|
update_f.write(update_count)
|
|
update_f.close()
|
|
os.chown(stat_file, -1, qubes_gid)
|
|
else:
|
|
print >> sys.stderr, 'Ignoring notification of no updates'
|
|
|
|
main()
|