063b436b03
If running as normal user, chown will fail. This isn't a problem, because the file is probably already owned by the correct user. The whole point about this chown is to give access to the file for normal user, so if the write succeeded, it isn't needed.
92 lines
3.3 KiB
Python
Executable File
92 lines
3.3 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 vm_files
|
|
|
|
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
|
|
|
|
untrusted_update_count = sys.stdin.readline(128).strip()
|
|
if not untrusted_update_count.isdigit():
|
|
print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: %s' % untrusted_update_count
|
|
exit(1)
|
|
# now sanitized
|
|
update_count = untrusted_update_count
|
|
if source_vm.updateable:
|
|
# Just trust information from VM itself
|
|
update_f = open(source_vm.dir_path + '/' + vm_files["updates_stat_file"], "w")
|
|
update_f.write(update_count)
|
|
update_f.close()
|
|
try:
|
|
os.chown(source_vm.dir_path + '/' + vm_files["updates_stat_file"], -1, qubes_gid)
|
|
except OSError:
|
|
pass
|
|
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 + '/' + vm_files["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()
|
|
try:
|
|
os.chown(stat_file, -1, qubes_gid)
|
|
except OSError:
|
|
pass
|
|
else:
|
|
print >> sys.stderr, 'Ignoring notification of no updates'
|
|
|
|
main() |