qubes-notify-updates 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/python
  2. #
  3. # The Qubes OS Project, http://www.qubes-os.org
  4. #
  5. # Copyright (C) 2012 Marek Marczykowski <marmarek@invisiblethingslab.com>
  6. #
  7. # This program is free software; you can redistribute it and/or
  8. # modify it under the terms of the GNU General Public License
  9. # as published by the Free Software Foundation; either version 2
  10. # of the License, or (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. #
  21. #
  22. import os
  23. import os.path
  24. import sys
  25. import subprocess
  26. import shutil
  27. import grp
  28. from datetime import datetime
  29. from qubes.qubes import QubesVmCollection
  30. from qubes.qubes import vm_files
  31. def main():
  32. qvm_collection = QubesVmCollection()
  33. qvm_collection.lock_db_for_reading()
  34. qvm_collection.load()
  35. qvm_collection.unlock_db()
  36. source = os.getenv("QREXEC_REMOTE_DOMAIN")
  37. if source is None:
  38. print >> sys.stderr, 'This script must be called as qrexec service!'
  39. exit(1)
  40. source_vm = qvm_collection.get_vm_by_name(source)
  41. if source_vm is None:
  42. print >> sys.stderr, 'Domain ' + source + ' does not exist (?!)'
  43. exit(1)
  44. os.umask(0002)
  45. qubes_gid = grp.getgrnam('qubes').gr_gid
  46. untrusted_update_count = sys.stdin.readline(128).strip()
  47. if not untrusted_update_count.isdigit():
  48. print >> sys.stderr, 'Domain ' + source + ' sent invalid number of updates: %s' % untrusted_update_count
  49. exit(1)
  50. # now sanitized
  51. update_count = untrusted_update_count
  52. if source_vm.updateable:
  53. # Just trust information from VM itself
  54. update_f = open(source_vm.dir_path + '/' + vm_files["updates_stat_file"], "w")
  55. update_f.write(update_count)
  56. update_f.close()
  57. try:
  58. os.chown(source_vm.dir_path + '/' + vm_files["updates_stat_file"], -1, qubes_gid)
  59. except OSError:
  60. pass
  61. elif source_vm.template is not None:
  62. # Hint about updates availability in template
  63. # If template is running - it will notify about updates itself
  64. if source_vm.template.is_running():
  65. return
  66. # Ignore no-updates info
  67. if int(update_count) > 0:
  68. stat_file = source_vm.template.dir_path + '/' + vm_files["updates_stat_file"]
  69. # If VM is started before last updates.stat - it means that updates
  70. # already was installed (but VM still hasn't been restarted), or other
  71. # VM has already notified about updates availability
  72. if os.path.exists(stat_file) and \
  73. source_vm.get_start_time() < datetime.fromtimestamp(os.path.getmtime(stat_file)):
  74. return
  75. update_f = open(stat_file, "w")
  76. update_f.write(update_count)
  77. update_f.close()
  78. try:
  79. os.chown(stat_file, -1, qubes_gid)
  80. except OSError:
  81. pass
  82. else:
  83. print >> sys.stderr, 'Ignoring notification of no updates'
  84. main()