wni.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/usr/bin/python2
  2. #
  3. # The Qubes OS Project, http://www.qubes-os.org
  4. #
  5. # Copyright (C) 2013 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. from __future__ import absolute_import
  23. import sys
  24. import os
  25. import os.path
  26. import win32api
  27. import win32net
  28. import win32netcon
  29. import pywintypes
  30. import md5
  31. from qubes.storage import QubesVmStorage
  32. from qubes.qubes import QubesException,system_path
  33. class QubesWniVmStorage(QubesVmStorage):
  34. """
  35. Class for VM storage of WNI VMs.
  36. """
  37. def __init__(self, *args, **kwargs):
  38. super(QubesWniVmStorage, self).__init__(*args, **kwargs)
  39. # Use the user profile as "private.img"
  40. self.private_img = os.path.join("c:\\Users", self._get_username())
  41. self.home_root = 'c:\\Users'
  42. # Pass paths for WNI libvirt driver
  43. os.putenv("WNI_DRIVER_QUBESDB_PATH", system_path['qubesdb_daemon_path'])
  44. os.putenv("WNI_DRIVER_QREXEC_PATH", system_path['qrexec_agent_path'])
  45. def _get_secret(self):
  46. # TODO: some machine-specific secret (accessible only to Administrator)
  47. return ""
  48. def _get_username(self, vmname = None):
  49. if vmname is None:
  50. vmname = self.vm.name
  51. return "qubes-vm-%s" % vmname
  52. def _get_password(self, vmname = None):
  53. if vmname is None:
  54. vmname = self.vm.name
  55. return md5.md5("%s-%s" % (vmname, self._get_secret())).hexdigest()
  56. def get_config_params(self):
  57. return {}
  58. def create_on_disk_private_img(self, verbose, source_template = None):
  59. home_dir = os.path.join(self.home_root, self._get_username())
  60. # Create user data in information level 1 (PyUSER_INFO_1) format.
  61. user_data = {}
  62. user_data['name'] = self._get_username()
  63. user_data['full_name'] = self._get_username()
  64. user_data['password'] = self._get_password()
  65. user_data['flags'] = (
  66. win32netcon.UF_NORMAL_ACCOUNT |
  67. win32netcon.UF_SCRIPT |
  68. win32netcon.UF_DONT_EXPIRE_PASSWD
  69. )
  70. user_data['priv'] = win32netcon.USER_PRIV_USER
  71. user_data['home_dir'] = home_dir
  72. user_data['max_storage'] = win32netcon.USER_MAXSTORAGE_UNLIMITED
  73. # TODO: catch possible exception
  74. win32net.NetUserAdd(None, 1, user_data)
  75. def create_on_disk_root_img(self, verbose, source_template = None):
  76. pass
  77. def remove_from_disk(self):
  78. try:
  79. win32net.NetUserDel(None, self._get_username())
  80. except pywintypes.error, details:
  81. if details[0] == 2221:
  82. # "The user name cannot be found."
  83. raise IOError("User %s doesn't exist" % self._get_username())
  84. else:
  85. raise
  86. super(QubesWniVmStorage, self).remove_from_disk()
  87. def rename(self, old_name, new_name):
  88. super(QubesWniVmStorage, self).rename(old_name, new_name)
  89. user_data = {}
  90. user_data['name'] = self._get_username(new_name)
  91. win32net.NetUserSetInfo(None,
  92. self._get_username(old_name), 0, user_data)
  93. win32net.NetUserChangePassword(None,
  94. self._get_username(new_name),
  95. self._get_password(old_name),
  96. self._get_password(new_name))
  97. #TODO: rename user profile
  98. def verify_files(self):
  99. if not os.path.exists (self.vmdir):
  100. raise QubesException (
  101. "VM directory doesn't exist: {0}".\
  102. format(self.vmdir))
  103. try:
  104. # TemplateVm in WNI is quite virtual, so do not require the user
  105. if not self.vm.is_template():
  106. win32net.NetUserGetInfo(None, self._get_username(), 0)
  107. except pywintypes.error, details:
  108. if details[0] == 2221:
  109. # "The user name cannot be found."
  110. raise QubesException("User %s doesn't exist" % self._get_username())
  111. else:
  112. raise
  113. def reset_volatile_storage(self, verbose = False, source_template = None):
  114. pass
  115. def prepare_for_vm_startup(self, verbose = False):
  116. if self.vm.is_template():
  117. raise QubesException("Starting TemplateVM is not supported")