1.1 --- a/OpenSecurity/bin/cygwin.py Fri Mar 07 14:32:12 2014 +0100
1.2 +++ b/OpenSecurity/bin/cygwin.py Mon Mar 10 13:01:08 2014 +0100
1.3 @@ -1,222 +1,236 @@
1.4 -#!/bin/env python
1.5 -# -*- coding: utf-8 -*-
1.6 -
1.7 -# ------------------------------------------------------------
1.8 -# cygwin command
1.9 -#
1.10 -# executes a cygwin command inside the opensecurity project
1.11 -#
1.12 -# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
1.13 -# Oliver Maurhart, <oliver.maurhart@ait.ac.at>
1.14 -#
1.15 -# Copyright (C) 2013 AIT Austrian Institute of Technology
1.16 -# AIT Austrian Institute of Technology GmbH
1.17 -# Donau-City-Strasse 1 | 1220 Vienna | Austria
1.18 -# http://www.ait.ac.at
1.19 -#
1.20 -# This program is free software; you can redistribute it and/or
1.21 -# modify it under the terms of the GNU General Public License
1.22 -# as published by the Free Software Foundation version 2.
1.23 -#
1.24 -# This program is distributed in the hope that it will be useful,
1.25 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
1.26 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.27 -# GNU General Public License for more details.
1.28 -#
1.29 -# You should have received a copy of the GNU General Public License
1.30 -# along with this program; if not, write to the Free Software
1.31 -# Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.32 -# Boston, MA 02110-1301, USA.
1.33 -# ------------------------------------------------------------
1.34 -
1.35 -
1.36 -# ------------------------------------------------------------
1.37 -# imports
1.38 -
1.39 -import os
1.40 -import subprocess
1.41 -import sys
1.42 -import _winreg
1.43 -from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
1.44 -import threading
1.45 -# local
1.46 -from environment import Environment
1.47 -from opensecurity_util import logger, setupLogger, OpenSecurityException
1.48 -
1.49 -# ------------------------------------------------------------
1.50 -# code
1.51 -
1.52 -def once(theClass):
1.53 - """get the path to our local cygwin installment"""
1.54 - home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
1.55 - path_hint = [
1.56 - os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin')),
1.57 - os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin64')),
1.58 - os.path.abspath(os.path.join(home_drive, 'cygwin')),
1.59 - os.path.abspath(os.path.join(home_drive, 'cygwin64'))
1.60 - ]
1.61 - path_valid = [ p for p in path_hint if os.path.exists(p) ]
1.62 -
1.63 - theClass.cygwin_root = path_valid[0]
1.64 - theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
1.65 - theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
1.66 - theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
1.67 - theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
1.68 - theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe")
1.69 - """get the path to the VirtualBox installation on this system"""
1.70 - theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]
1.71 - theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
1.72 -
1.73 - return theClass
1.74 -
1.75 -@once
1.76 -class Cygwin(object):
1.77 - cygwin_root = ''
1.78 - cygwin_bin = ''
1.79 - cygwin_bash = ''
1.80 - cygwin_ssh = ''
1.81 - cygwin_x11 = ''
1.82 - vbox_root = ''
1.83 - vbox_man = ''
1.84 - win_cmd = ''
1.85 - """Some nifty methods working with Cygwin"""
1.86 -
1.87 - def __call__(self, command, arguments, wait_return=True, window = False):
1.88 - """make an instance of this object act as a function"""
1.89 - return self.execute(command, arguments, wait_return, window)
1.90 -
1.91 - @staticmethod
1.92 - def getRegEntry(key, value):
1.93 - try:
1.94 - k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
1.95 - value = _winreg.QueryValueEx(k, value)
1.96 - _winreg.CloseKey(k)
1.97 - return value
1.98 - except:
1.99 - pass
1.100 -
1.101 - @staticmethod
1.102 - def root():
1.103 - return Cygwin.cygwin_root
1.104 -
1.105 - @staticmethod
1.106 - def bin():
1.107 - return Cygwin.cygwin_bin
1.108 -
1.109 - @staticmethod
1.110 - def bash():
1.111 - return Cygwin.cygwin_bash
1.112 -
1.113 - @staticmethod
1.114 - def ssh():
1.115 - return Cygwin.cygwin_ssh
1.116 -
1.117 - @staticmethod
1.118 - def x11():
1.119 - return Cygwin.cygwin_x11
1.120 -
1.121 - @staticmethod
1.122 - def vboxman():
1.123 - return Cygwin.vbox_man
1.124 -
1.125 - @staticmethod
1.126 - def cmd():
1.127 - return Cygwin.win_cmd
1.128 -
1.129 - executeLock = threading.Lock()
1.130 - #executes command on host system
1.131 - @staticmethod
1.132 - def execute(program, arguments, wait_return=True, window = False):
1.133 - _startupinfo = STARTUPINFO()
1.134 - if not window:
1.135 - _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
1.136 - _startupinfo.wShowWindow = _subprocess.SW_HIDE
1.137 -
1.138 - #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
1.139 - res_stderr = None
1.140 - try:
1.141 - process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
1.142 - logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
1.143 - if not wait_return:
1.144 - return [0, 'working in background', '']
1.145 - result = process.wait()
1.146 - res_stdout = process.stdout.read();
1.147 - res_stderr = process.stderr.read();
1.148 -
1.149 - except Exception as ex:
1.150 - res_stderr.join(ex.args)
1.151 - result = 1
1.152 -
1.153 - return result, res_stdout, res_stderr
1.154 -
1.155 - @staticmethod
1.156 - def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
1.157 - retry = 0
1.158 - result = None
1.159 - while retry < 3:
1.160 - if Cygwin.executeLock.acquire(True):
1.161 - result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
1.162 - Cygwin.executeLock.release()
1.163 - if result[0] == 0:
1.164 - return result
1.165 - retry+=1
1.166 - return result
1.167 -
1.168 -
1.169 - @staticmethod
1.170 - def bashExecute(command, wait_return=True, window = False, bash_opts=''):
1.171 - command = bash_opts + ' -l -c ' + command
1.172 - return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window)
1.173 -
1.174 - @staticmethod
1.175 - def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
1.176 - command = ' /c ' + command
1.177 - return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
1.178 -
1.179 - # executes command over ssh on guest vm
1.180 - @staticmethod
1.181 - def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
1.182 - command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command
1.183 - return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
1.184 -
1.185 - #machineFolder + '/' + vm_name + '/dvm_key
1.186 - #address = self.getHostOnlyIP(vm_name)
1.187 - #machineFolder = self.getDefaultMachineFolder()
1.188 - #machineFolder = Cygwin.cygwinPath(machineFolder)
1.189 -
1.190 - # executes command over ssh on guest vm with X forwarding
1.191 - @staticmethod
1.192 - def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
1.193 - return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
1.194 -
1.195 - @staticmethod
1.196 - def is_X11_running():
1.197 - """check if we can connect to a X11 running instance"""
1.198 - p = Cygwin.bashExecute('"DISPLAY=:0 /usr/bin/xset -q"')
1.199 - return p[0] == 0
1.200 -
1.201 -
1.202 - @staticmethod
1.203 - def start_X11():
1.204 - """start X11 in the background (if not already running) on DISPLAY=:0"""
1.205 - # do not start if already running
1.206 - if Cygwin.is_X11_running():
1.207 - return
1.208 - # launch X11 (forget output and return immediately)
1.209 - return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
1.210 -
1.211 - @staticmethod
1.212 - def cygPath(path):
1.213 - return Cygwin.bashExecute('"/usr/bin/cygpath -u \\"' + path + '\\""')[1].rstrip('\n')
1.214 -
1.215 -# start
1.216 -if __name__ == "__main__":
1.217 - logger = setupLogger('Cygwin')
1.218 - c = Cygwin()
1.219 - logger.info(c.root())
1.220 - logger.info(c.bin())
1.221 - logger.info(c.bash())
1.222 - logger.info(c.ssh())
1.223 -
1.224 - c.cygPath('C:')
1.225 - c.start_X11()
1.226 +#!/bin/env python
1.227 +# -*- coding: utf-8 -*-
1.228 +
1.229 +# ------------------------------------------------------------
1.230 +# cygwin command
1.231 +#
1.232 +# executes a cygwin command inside the opensecurity project
1.233 +#
1.234 +# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
1.235 +# Oliver Maurhart, <oliver.maurhart@ait.ac.at>
1.236 +#
1.237 +# Copyright (C) 2013 AIT Austrian Institute of Technology
1.238 +# AIT Austrian Institute of Technology GmbH
1.239 +# Donau-City-Strasse 1 | 1220 Vienna | Austria
1.240 +# http://www.ait.ac.at
1.241 +#
1.242 +# This program is free software; you can redistribute it and/or
1.243 +# modify it under the terms of the GNU General Public License
1.244 +# as published by the Free Software Foundation version 2.
1.245 +#
1.246 +# This program is distributed in the hope that it will be useful,
1.247 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
1.248 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.249 +# GNU General Public License for more details.
1.250 +#
1.251 +# You should have received a copy of the GNU General Public License
1.252 +# along with this program; if not, write to the Free Software
1.253 +# Foundation, Inc., 51 Franklin Street, Fifth Floor,
1.254 +# Boston, MA 02110-1301, USA.
1.255 +# ------------------------------------------------------------
1.256 +
1.257 +
1.258 +# ------------------------------------------------------------
1.259 +# imports
1.260 +
1.261 +import os
1.262 +import subprocess
1.263 +import sys
1.264 +import _winreg
1.265 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
1.266 +import threading
1.267 +# local
1.268 +from environment import Environment
1.269 +from opensecurity_util import logger, setupLogger, OpenSecurityException
1.270 +
1.271 +# ------------------------------------------------------------
1.272 +# code
1.273 +
1.274 +def once(theClass):
1.275 + """get the path to our local cygwin installment"""
1.276 + home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
1.277 + path_hint = [
1.278 + os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin')),
1.279 + os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin64')),
1.280 + os.path.abspath(os.path.join(home_drive, 'cygwin')),
1.281 + os.path.abspath(os.path.join(home_drive, 'cygwin64'))
1.282 + ]
1.283 + path_valid = [ p for p in path_hint if os.path.exists(p) ]
1.284 +
1.285 + theClass.cygwin_root = path_valid[0]
1.286 + theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
1.287 + theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
1.288 + theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
1.289 + theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
1.290 + theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe")
1.291 + """get the path to the VirtualBox installation on this system"""
1.292 + theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]
1.293 + theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
1.294 +
1.295 + return theClass
1.296 +
1.297 +@once
1.298 +class Cygwin(object):
1.299 + cygwin_root = ''
1.300 + cygwin_bin = ''
1.301 + cygwin_bash = ''
1.302 + cygwin_ssh = ''
1.303 + cygwin_x11 = ''
1.304 + vbox_root = ''
1.305 + vbox_man = ''
1.306 + win_cmd = ''
1.307 + """Some nifty methods working with Cygwin"""
1.308 +
1.309 + def __call__(self, command, arguments, wait_return=True, window = False):
1.310 + """make an instance of this object act as a function"""
1.311 + return self.execute(command, arguments, wait_return, window)
1.312 +
1.313 + @staticmethod
1.314 + def getRegEntry(key, value):
1.315 + try:
1.316 + k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
1.317 + value = _winreg.QueryValueEx(k, value)
1.318 + _winreg.CloseKey(k)
1.319 + return value
1.320 + except:
1.321 + pass
1.322 +
1.323 +
1.324 + @staticmethod
1.325 + def root():
1.326 + return Cygwin.cygwin_root
1.327 +
1.328 + @staticmethod
1.329 + def bin():
1.330 + return Cygwin.cygwin_bin
1.331 +
1.332 + @staticmethod
1.333 + def bash():
1.334 + return Cygwin.cygwin_bash
1.335 +
1.336 + @staticmethod
1.337 + def ssh():
1.338 + return Cygwin.cygwin_ssh
1.339 +
1.340 + @staticmethod
1.341 + def x11():
1.342 + return Cygwin.cygwin_x11
1.343 +
1.344 + @staticmethod
1.345 + def vboxman():
1.346 + return Cygwin.vbox_man
1.347 +
1.348 + @staticmethod
1.349 + def cmd():
1.350 + return Cygwin.win_cmd
1.351 +
1.352 + executeLock = threading.Lock()
1.353 + #executes command on host system
1.354 + @staticmethod
1.355 + def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
1.356 + _startupinfo = STARTUPINFO()
1.357 + if not window:
1.358 + _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
1.359 + _startupinfo.wShowWindow = _subprocess.SW_HIDE
1.360 +
1.361 + #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
1.362 + res_stderr = None
1.363 + try:
1.364 + # quote the executable otherwise we run into troubles
1.365 + # when the path contains spaces and additonal arguments
1.366 + # are presented as well.
1.367 + # special: invoking bash as login shell here with
1.368 + # an unquoted command does not execute /etc/profile
1.369 + args = '"' + program + '" ' + arguments
1.370 + process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
1.371 + logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
1.372 + if not wait_return:
1.373 + return [0, 'working in background', '']
1.374 + result = process.wait()
1.375 + res_stdout = process.stdout.read();
1.376 + res_stderr = process.stderr.read();
1.377 +
1.378 + except Exception as ex:
1.379 + res_stderr = ''.join(str(ex.args))
1.380 + result = 1
1.381 +
1.382 + return result, res_stdout, res_stderr
1.383 +
1.384 + @staticmethod
1.385 + def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
1.386 + retry = 0
1.387 + result = None
1.388 + while retry < 3:
1.389 + if Cygwin.executeLock.acquire(True):
1.390 + result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
1.391 + Cygwin.executeLock.release()
1.392 + if result[0] == 0:
1.393 + return result
1.394 + retry+=1
1.395 + return result
1.396 +
1.397 +
1.398 + @staticmethod
1.399 + def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
1.400 + # for some reason, the '-l' is ignored when started via python
1.401 + # so the same behavior is triggered by calling /etc/profile
1.402 + # directly
1.403 + command = bash_opts + ' -l -c "' + command + '"'
1.404 + return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
1.405 +
1.406 + @staticmethod
1.407 + def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
1.408 + command = ' /c ' + command
1.409 + return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
1.410 +
1.411 + # executes command over ssh on guest vm
1.412 + @staticmethod
1.413 + def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
1.414 + command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command
1.415 + return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
1.416 +
1.417 + #machineFolder + '/' + vm_name + '/dvm_key
1.418 + #address = self.getHostOnlyIP(vm_name)
1.419 + #machineFolder = self.getDefaultMachineFolder()
1.420 + #machineFolder = Cygwin.cygwinPath(machineFolder)
1.421 +
1.422 + # executes command over ssh on guest vm with X forwarding
1.423 + @staticmethod
1.424 + def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
1.425 + return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
1.426 +
1.427 + @staticmethod
1.428 + def is_X11_running():
1.429 + """check if we can connect to a X11 running instance"""
1.430 + p = Cygwin.bashExecute('DISPLAY=:0 /usr/bin/xset -q')
1.431 + return p[0] == 0
1.432 +
1.433 +
1.434 + @staticmethod
1.435 + def start_X11():
1.436 + """start X11 in the background (if not already running) on DISPLAY=:0"""
1.437 + # do not start if already running
1.438 + if Cygwin.is_X11_running():
1.439 + return
1.440 + # launch X11 (forget output and return immediately)
1.441 + return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
1.442 +
1.443 + @staticmethod
1.444 + def cygPath(path):
1.445 + cmd = 'cygpath -u \'' + path + '\''
1.446 + return Cygwin.bashExecute(cmd)[1].rstrip('\n')
1.447 +
1.448 +# start
1.449 +if __name__ == "__main__":
1.450 + logger = setupLogger('Cygwin')
1.451 + c = Cygwin()
1.452 + logger.info(c.root())
1.453 + logger.info(c.bin())
1.454 + logger.info(c.bash())
1.455 + logger.info(c.ssh())
1.456 +
1.457 + print(c.bashExecute('echo $PATH')[1])
1.458 + print(c.cygPath('C:'))
1.459 + print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))
1.460 + c.start_X11()
1.461 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/OpenSecurity/bin/download_initial_image.sh Mon Mar 10 13:01:08 2014 +0100
2.3 @@ -0,0 +1,47 @@
2.4 +#!/bin/bash
2.5 +
2.6 +# ------------------------------------------------------------
2.7 +# download initial VM for
2.8 +#
2.9 +# OpenSecurity V0.2
2.10 +#
2.11 +# (C)opyright 2014, AIT Austrian Instiitute of Technology
2.12 +# ------------------------------------------------------------
2.13 +
2.14 +# ------------------------------------------------------------
2.15 +# code
2.16 +
2.17 +
2.18 +# download the ionitial OsecVM.ova from the X-Net servers
2.19 +# and place the file in the folder specified by ${1}
2.20 +
2.21 +
2.22 +# ------------------------------
2.23 +# main ...
2.24 +#
2.25 +
2.26 +# check if we do have elevated rights
2.27 +# that is "Run as Administrator" invocation
2.28 +id -G | grep 544 &> /dev/null
2.29 +if [ "${?}" != 0 ]; then
2.30 + echo "Insufficient privileges."
2.31 + echo "Is this script executed with 'Run As Administrator'?"
2.32 + exit 1
2.33 +fi
2.34 +
2.35 +TARGET_FOLDER="${1}"
2.36 +echo "fetching OpenSecurity initial VM at " $(date)
2.37 +echo "target folder: ${TARGET_FOLDER}"
2.38 +
2.39 +# sanity check
2.40 +mkdir -p "${TARGET_FOLDER}"
2.41 +if [ ! -d "${TARGET_FOLDER}" ]; then
2.42 + echo "failed to access target folder."
2.43 + exit 1
2.44 +fi
2.45 +
2.46 +# start download
2.47 +URL="http://service.x-net.at/opensecurity/OsecVM_latest.ova"
2.48 +wget --progress=dot:mega ${URL} -O "${TARGET_FOLDER}"/OsecVM.ova
2.49 +
2.50 +
3.1 --- a/OpenSecurity/bin/environment.py Fri Mar 07 14:32:12 2014 +0100
3.2 +++ b/OpenSecurity/bin/environment.py Mon Mar 10 13:01:08 2014 +0100
3.3 @@ -64,7 +64,7 @@
3.4 if sys.platform == 'linux2':
3.5 self._prefix_path = os.path.split(sys.path[0])[0]
3.6 elif sys.platform == 'win32' or sys.platform == 'cygwin':
3.7 - self._prefix_path = sys.path[0]
3.8 + self._prefix_path = os.path.normpath(os.path.join(sys.path[0], '..'))
3.9
3.10 # the data path where all data files are stored
3.11 if sys.platform == 'linux2':
3.12 @@ -118,7 +118,7 @@
3.13 # somewhere like C:\Program Files\OpenSecurity\log
3.14 # having this script residing in
3.15 # C:\Progam Files\OpenSecurity\bin
3.16 - ideal_log_path = os.path.normpath(os.path.join(self.prefix_path, '..', 'log'))
3.17 + ideal_log_path = os.path.normpath(os.path.join(self.prefix_path, 'log'))
3.18
3.19 # check ideal path first
3.20 if not os.path.exists(ideal_log_path):
3.21 @@ -147,3 +147,4 @@
3.22 # test the module
3.23 if __name__ == '__main__':
3.24 test()
3.25 +
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/OpenSecurity/bin/initial_vm.sh Mon Mar 10 13:01:08 2014 +0100
4.3 @@ -0,0 +1,159 @@
4.4 +#!/bin/bash
4.5 +
4.6 +# ------------------------------------------------------------
4.7 +# install the initial VM for
4.8 +#
4.9 +# OpenSecurity V0.2
4.10 +#
4.11 +# This has been originally a Windows only BAT file.
4.12 +#
4.13 +# ... but coding this makes your head hurt and
4.14 +# supporting this "technology" any further by adding
4.15 +# software to the world relying on CMD.exe is an act
4.16 +# against humanity and should be punished by jail.
4.17 +#
4.18 +# (C)opyright 2014, AIT Austrian Instiitute of Technology
4.19 +# ------------------------------------------------------------
4.20 +
4.21 +
4.22 +# ------------------------------------------------------------
4.23 +# code
4.24 +
4.25 +# install the initial VM given by ${1}
4.26 +
4.27 +
4.28 +# ------------------------------
4.29 +# turns a windows path into a cygwin path
4.30 +#
4.31 +# $1 ... windows path
4.32 +# stdout the value found
4.33 +#
4.34 +function sanitize_path() {
4.35 + test -z "${1}" && return
4.36 + echo $(cygpath -u "${1}")
4.37 +}
4.38 +
4.39 +
4.40 +# ------------------------------
4.41 +# main ...
4.42 +#
4.43 +
4.44 +# check if we do have elevated rights
4.45 +# that is "Run as Administrator" invocation
4.46 +echo 'checking privileges...'
4.47 +id -G | grep 544 &> /dev/null
4.48 +if [ "${?}" != 0 ]; then
4.49 + echo "Insufficient privileges."
4.50 + echo "Is this script executed with 'Run As Administrator'?"
4.51 + exit 1
4.52 +echo 'privileges sufficient.'
4.53 +fi
4.54 +
4.55 +# check OpenSecurity Initial VM Image
4.56 +#
4.57 +echo "looking for VM image: ${1}..."
4.58 +OSECVM_IMAGE=$(cygpath -u "${1}")
4.59 +echo "looking for VM image: ${1}"
4.60 +if [ ! -f "${OSECVM_IMAGE}" ]; then
4.61 + echo "Warning: no OpenSecurity Initial Image found."
4.62 + echo "Please download using the OpenSecurity download tool."
4.63 + exit 1
4.64 +fi
4.65 +echo "initial VM image: ${1} found"
4.66 +
4.67 +# look up VirtulBox installation
4.68 +#
4.69 +echo "looking up VirtualBox installation..."
4.70 +VBOX_MANAGER="$(cat /proc/registry/HKEY_LOCAL_MACHINE/SOFTWARE/Oracle/VirtualBox/InstallDir)/VBoxManage.exe"
4.71 +VBOX_MANAGER=$(sanitize_path "${VBOX_MANAGER}")
4.72 +if [ ! -x "${VBOX_MANAGER}" ]; then
4.73 + echo "can't execute VBoxManage.exe - is VirtualBox installed?"
4.74 + echo "looked at: "$(cygpath -w ${VBOX_MANAGER})""
4.75 + exit 1
4.76 +fi
4.77 +echo "VirtualBox found at: ${VBOX_MANAGER}"
4.78 +
4.79 +# enforce VirtualBox to "feel good" by calling a function
4.80 +# (that is to "warm up" VirtualBox DCOM server ...)
4.81 +#
4.82 +echo "grabing VBox machine folder..."
4.83 +MACHINE_FOLDER=$("${VBOX_MANAGER}" list systemproperties | grep '^Default machine folder:' | sed 's/^Default machine folder: *//')
4.84 +MACHINE_FOLDER=$(cygpath -u "${MACHINE_FOLDER}")
4.85 +echo "machine folder: ${MACHINE_FOLDER}"
4.86 +
4.87 +# we have to stop the OpenSecurity service now
4.88 +# the VMManger does lock the SecurityDVMs so we can't
4.89 +# change them when he's on
4.90 +echo "stopping OpenSecurity service..."
4.91 +net stop "OpenSecurity Service"
4.92 +echo "OpenSecurity service stopped."
4.93 +
4.94 +echo -n "After stopping we'll wait 5 secs to let VirtualBox calm itself"
4.95 +for i in {1..5}; do
4.96 + echo -n .
4.97 + sleep 1
4.98 +done
4.99 +echo
4.100 +
4.101 +# do all stuff relativ to the given machinefolder
4.102 +pushd "${MACHINE_FOLDER}" &> /dev/null
4.103 +if [ "$?" != "0" ]; then
4.104 + echo "Failed to switch into machine folder."
4.105 + exit 1
4.106 +fi
4.107 +
4.108 +# the Security VM disk image
4.109 +VDISK_IMAGE="SecurityDVM/SecurityDVM.vmdk"
4.110 +
4.111 +# import VM
4.112 +#
4.113 +"${VBOX_MANAGER}" list vms | grep SecurityDVM &> /dev/null
4.114 +if [ ! "${?}" = "0" ]; then
4.115 + echo "importing VM: ${OSECVM_IMAGE}"
4.116 + "${VBOX_MANAGER}" import "$(cygpath -w "${OSECVM_IMAGE}")" --vsys 0 --vmname SecurityDVM --unit 12 --disk "${VDISK_IMAGE}"
4.117 +else
4.118 + echo "found SecurityDVM already present in VBox reusing it."
4.119 + echo "if you want a complete new import please remove the VM first."
4.120 + exit 1
4.121 +fi
4.122 +
4.123 +# grab VM storage controller and port
4.124 +#
4.125 +VDISK_SETUP=$("${VBOX_MANAGER}" showvminfo SecurityDVM | grep SecurityDVM.vmdk | cut -d ':' -f 1 | tr '(),' ' ')
4.126 +VDISK_CONTROLLER=$(echo ${VDISK_SETUP} | gawk '{print $1;}')
4.127 +VDISK_PORT=$(echo ${VDISK_SETUP} | gawk '{print $2;}')
4.128 +VDISK_DEVICE=$(echo ${VDISK_SETUP} | gawk '{print $3;}')
4.129 +if [ -z "${VDISK_CONTROLLER}" ]; then
4.130 + echo "unable to grab virtual disk controller in VM."
4.131 + echo "this shouldn't happen. It's a bug."
4.132 + exit 1
4.133 +fi
4.134 +
4.135 +# detach disk image
4.136 +#
4.137 +echo "detaching disk image ..."
4.138 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --medium none
4.139 +
4.140 +# turn disk image into writethrough
4.141 +#
4.142 +echo "turning disk image into writetrough ..."
4.143 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --device ${VDISK_DEVICE} --type hdd --mtype writethrough --medium "${VDISK_IMAGE}"
4.144 +
4.145 +# detach disk image
4.146 +#
4.147 +echo "detaching disk image ..."
4.148 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --medium none
4.149 +
4.150 +# immutablize disk
4.151 +#
4.152 +echo "reattach immutable disk image ..."
4.153 +"${VBOX_MANAGER}" storageattach SecurityDVM --storagectl ${VDISK_CONTROLLER} --port ${VDISK_PORT} --device ${VDISK_DEVICE} --type hdd --mtype immutable --medium "${VDISK_IMAGE}"
4.154 +
4.155 +echo "imported initial OsecVM.ova image"
4.156 +
4.157 +"${VBOX_MANAGER}" list vms
4.158 +
4.159 +echo "starting OpenSecurity service..."
4.160 +net start "OpenSecurity Service"
4.161 +echo "OpenSecurity service started"
4.162 +
5.1 --- a/OpenSecurity/bin/opensecurity_service.pyw Fri Mar 07 14:32:12 2014 +0100
5.2 +++ b/OpenSecurity/bin/opensecurity_service.pyw Mon Mar 10 13:01:08 2014 +0100
5.3 @@ -82,7 +82,10 @@
5.4 # the REST server from a distance ...
5.5 #
5.6 # TODO: find a better secure way to do that
5.7 - r = urllib2.urlopen('http://localhost:8080/terminate', timeout=1)
5.8 + try:
5.9 + r = urllib2.urlopen('http://localhost:8080/terminate', timeout=1)
5.10 + except:
5.11 + pass
5.12
5.13 win32event.SetEvent(self.hWaitStop)
5.14 self.log('OpenSecurity Service stopped...\n')
6.1 --- a/OpenSecurity/bin/opensecurityd.pyw Fri Mar 07 14:32:12 2014 +0100
6.2 +++ b/OpenSecurity/bin/opensecurityd.pyw Mon Mar 10 13:01:08 2014 +0100
6.3 @@ -36,12 +36,13 @@
6.4 import os.path
6.5 import subprocess
6.6 import sys
6.7 +import tempfile
6.8 import web
6.9 -from cygwin import Cygwin
6.10
6.11 import vmmanager
6.12
6.13 # local
6.14 +from cygwin import Cygwin
6.15 from environment import Environment
6.16 from opensecurity_util import logger
6.17
6.18 @@ -55,6 +56,8 @@
6.19 """All the URLs we know mapping to class handler"""
6.20 opensecurity_urls = (
6.21 '/browsing', 'os_browsing', # http://localhost:8080/browsing GET
6.22 + '/fetch_initial_image', 'os_fetch_image', # http://localhost:8080/fetch_initial_image GET
6.23 + '/init', 'os_init', # http://localhost:8080/init GET
6.24 '/sdvms', 'os_sdvms', # http://localhost:8080/sdvms GET, PUT
6.25 '/sdvms/(.*)/application/(.*)', 'os_sdvm_application', # http://localhost:8080/sdvms/[VMNAME]/application/[COMMAND] GET
6.26 '/sdvms/(.*)/ip', 'os_sdvm_ip', # http://localhost:8080/sdvms/[VMNAME]/ip GET
6.27 @@ -96,6 +99,52 @@
6.28 raise web.internalerror()
6.29
6.30
6.31 +class os_fetch_image:
6.32 + """OpenSecurity '/fetch_initial_image' handler
6.33 +
6.34 + - GET: fetch the initial image from the X-Net Servers
6.35 + The initial image is stored in the
6.36 + Virtual Box default machine path.
6.37 + The result to this call is a temprary file
6.38 + which shows the progress (or error state)
6.39 + of this call.
6.40 + """
6.41 +
6.42 + def GET(self):
6.43 +
6.44 + log_call(web.ctx.environ)
6.45 + global gvm_mgr
6.46 +
6.47 + trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_fetch_image.log')
6.48 + trace_file = open(trace_file_name, 'w+')
6.49 +
6.50 + machine_folder = Cygwin.cygPath(gvm_mgr.getMachineFolder())
6.51 + download_initial_image_script = '/OpenSecurity/bin/download_initial_image.sh \'' + machine_folder + '\''
6.52 + Cygwin.bashExecute(download_initial_image_script, wait_return = False, stdout = trace_file, stderr = trace_file)
6.53 +
6.54 + return trace_file_name
6.55 +
6.56 +
6.57 +class os_init:
6.58 + """OpenSecurity '/init' handler
6.59 +
6.60 + - GET: Do initial import of OsecVM.ova
6.61 + """
6.62 +
6.63 + def GET(self):
6.64 + log_call(web.ctx.environ)
6.65 + global gvm_mgr
6.66 +
6.67 + trace_file_name = os.path.join(tempfile.gettempdir(), 'OpenSecurity_initial_import.log')
6.68 + trace_file = open(trace_file_name, 'w+')
6.69 +
6.70 + vm_image = Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/OsecVM.ova'
6.71 + initial_import_script = '/OpenSecurity/bin/initial_vm.sh \'' + vm_image + '\''
6.72 + Cygwin.bashExecute(initial_import_script, wait_return = False, stdout = trace_file, stderr = trace_file)
6.73 +
6.74 + return trace_file_name
6.75 +
6.76 +
6.77 class os_root:
6.78 """OpenSecurity '/' handler
6.79
6.80 @@ -107,7 +156,8 @@
6.81 global gvm_mgr
6.82 res = "'os_server': { "
6.83 res += "'version': '" + __version__ + "', "
6.84 - res += "'machine_folder': '" + gvm_mgr.machineFolder + "' "
6.85 + res += "'virtual box systemproperties': '" + str(gvm_mgr.systemProperties) + "', "
6.86 + res += "'current temporary folder': '" + tempfile.gettempdir() + "' "
6.87 res += "}"
6.88 return res
6.89
6.90 @@ -141,7 +191,8 @@
6.91 global gvm_mgr
6.92 command = '/' + command
6.93 result = Cygwin.sshExecuteX11(command, gvm_mgr.getHostOnlyIP(name), 'osecuser', Cygwin.cygPath(gvm_mgr.getMachineFolder()) + '/' + name + '/dvm_key' )
6.94 - return result
6.95 + self.poweroffVM(name)
6.96 + return gvm_mgr.removeVM(name)
6.97
6.98
6.99 class os_sdvm_ip:
6.100 @@ -229,6 +280,7 @@
6.101 def GET(self):
6.102 log_call(web.ctx.environ)
6.103 global gvm_mgr
6.104 + gvm_mgr.stop()
6.105 gvm_mgr.cleanup()
6.106 sys.exit(0)
6.107 return None
7.1 --- a/OpenSecurity/bin/vmmanager.pyw Fri Mar 07 14:32:12 2014 +0100
7.2 +++ b/OpenSecurity/bin/vmmanager.pyw Mon Mar 10 13:01:08 2014 +0100
7.3 @@ -1,672 +1,681 @@
7.4 -'''
7.5 -Created on Nov 19, 2013
7.6 -
7.7 -@author: BarthaM
7.8 -'''
7.9 -import os
7.10 -import os.path
7.11 -from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
7.12 -import sys
7.13 -import re
7.14 -
7.15 -from cygwin import Cygwin
7.16 -from environment import Environment
7.17 -import threading
7.18 -import time
7.19 -import string
7.20 -
7.21 -import shutil
7.22 -import stat
7.23 -import tempfile
7.24 -from opensecurity_util import logger, setupLogger, OpenSecurityException
7.25 -import ctypes
7.26 -import itertools
7.27 -import _winreg
7.28 -DEBUG = True
7.29 -
7.30 -class VMManagerException(Exception):
7.31 - def __init__(self, value):
7.32 - self.value = value
7.33 - def __str__(self):
7.34 - return repr(self.value)
7.35 -
7.36 -class USBFilter:
7.37 - vendorid = ""
7.38 - productid = ""
7.39 - revision = ""
7.40 -
7.41 - def __init__(self, vendorid, productid, revision):
7.42 - self.vendorid = vendorid.lower()
7.43 - self.productid = productid.lower()
7.44 - self.revision = revision.lower()
7.45 - return
7.46 -
7.47 - def __eq__(self, other):
7.48 - return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
7.49 -
7.50 - def __hash__(self):
7.51 - return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
7.52 -
7.53 - def __repr__(self):
7.54 - return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
7.55 -
7.56 - #def __getitem__(self, item):
7.57 - # return self.coords[item]
7.58 -
7.59 -class VMManager(object):
7.60 - vmRootName = "SecurityDVM"
7.61 - systemProperties = None
7.62 - _instance = None
7.63 - machineFolder = ''
7.64 - rsdHandler = None
7.65 -
7.66 - def __init__(self):
7.67 - self.systemProperties = self.getSystemProperties()
7.68 - self.machineFolder = self.systemProperties["Default machine folder"]
7.69 - self.cleanup()
7.70 - self.rsdHandler = DeviceHandler(self)
7.71 - self.rsdHandler.start()
7.72 - return
7.73 -
7.74 - @staticmethod
7.75 - def getInstance():
7.76 - if VMManager._instance == None:
7.77 - VMManager._instance = VMManager()
7.78 - return VMManager._instance
7.79 -
7.80 - def cleanup(self):
7.81 - if self.rsdHandler != None:
7.82 - self.rsdHandler.stop()
7.83 - self.rsdHandler.join()
7.84 - drives = self.getNetworkDrives()
7.85 - for drive in drives.keys():
7.86 - self.unmapNetworkDrive(drive)
7.87 - for vm in self.listSDVM():
7.88 - self.poweroffVM(vm)
7.89 - self.removeVM(vm)
7.90 -
7.91 - # return hosty system properties
7.92 - def getSystemProperties(self):
7.93 - result = checkResult(Cygwin.vboxExecute('list systemproperties'))
7.94 - if result[1]=='':
7.95 - return None
7.96 - props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
7.97 - return props
7.98 -
7.99 - # return the folder containing the guest VMs
7.100 - def getMachineFolder(self):
7.101 - return self.machineFolder
7.102 -
7.103 - # list all existing VMs registered with VBox
7.104 - def listVM(self):
7.105 - result = checkResult(Cygwin.vboxExecute('list vms'))[1]
7.106 - vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
7.107 - return vms
7.108 -
7.109 - # list running VMs
7.110 - def listRunningVMS(self):
7.111 - result = checkResult(Cygwin.vboxExecute('list runningvms'))[1]
7.112 - vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
7.113 - return vms
7.114 -
7.115 - # list existing SDVMs
7.116 - def listSDVM(self):
7.117 - vms = self.listVM()
7.118 - svdms = []
7.119 - for vm in vms:
7.120 - if vm.startswith(self.vmRootName) and vm != self.vmRootName:
7.121 - svdms.append(vm)
7.122 - return svdms
7.123 -
7.124 - # generate valid (not already existing SDVM name). necessary for creating a new VM
7.125 - def generateSDVMName(self):
7.126 - vms = self.listVM()
7.127 - for i in range(0,999):
7.128 - if(not self.vmRootName+str(i) in vms):
7.129 - return self.vmRootName+str(i)
7.130 - return ''
7.131 -
7.132 - # check if the device is mass storage type
7.133 - @staticmethod
7.134 - def isMassStorageDevice(device):
7.135 - keyname = 'SYSTEM\CurrentControlSet\Enum\USB' + '\VID_' + device.vendorid+'&'+'PID_'+ device.productid
7.136 - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
7.137 - #subkeys = _winreg.QueryInfoKey(key)[0]
7.138 - #for i in range(0, subkeys):
7.139 - # print _winreg.EnumKey(key, i)
7.140 - devinfokeyname = _winreg.EnumKey(key, 0)
7.141 - _winreg.CloseKey(key)
7.142 -
7.143 - devinfokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname+'\\'+devinfokeyname)
7.144 - value = _winreg.QueryValueEx(devinfokey, 'SERVICE')[0]
7.145 - _winreg.CloseKey(devinfokey)
7.146 -
7.147 - return 'USBSTOR' in value
7.148 -
7.149 - # return the RSDs connected to the host
7.150 - @staticmethod
7.151 - def getConnectedRSDS():
7.152 - results = checkResult(Cygwin.vboxExecute('list usbhost'))[1]
7.153 - results = results.split('Host USB Devices:')[1].strip()
7.154 -
7.155 - items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
7.156 - rsds = dict()
7.157 - for item in items:
7.158 - props = dict()
7.159 - for line in item.splitlines():
7.160 - if line != "":
7.161 - k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
7.162 - props[k] = v
7.163 -
7.164 - #if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
7.165 -
7.166 - usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'],
7.167 - re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
7.168 - re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
7.169 - if VMManager.isMassStorageDevice(usb_filter):
7.170 - rsds[props['UUID']] = usb_filter;
7.171 - logger.debug(usb_filter)
7.172 - return rsds
7.173 -
7.174 - # return the RSDs attached to all existing SDVMs
7.175 - def getAttachedRSDs(self):
7.176 - vms = self.listSDVM()
7.177 - attached_devices = dict()
7.178 - for vm in vms:
7.179 - rsd_filter = self.getUSBFilter(vm)
7.180 - if rsd_filter != None:
7.181 - attached_devices[vm] = rsd_filter
7.182 - return attached_devices
7.183 -
7.184 - # configures hostonly networking and DHCP server. requires admin rights
7.185 - def configureHostNetworking(self):
7.186 - #cmd = 'vboxmanage list hostonlyifs'
7.187 - #Cygwin.vboxExecute(cmd)
7.188 - #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
7.189 - #Cygwin.vboxExecute(cmd)
7.190 - #cmd = 'vboxmanage hostonlyif create'
7.191 - #Cygwin.vboxExecute(cmd)
7.192 - checkResult(Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0'))
7.193 - #cmd = 'vboxmanage dhcpserver add'
7.194 - #Cygwin.vboxExecute(cmd)
7.195 - checkResult(Cygwin.vboxExecute('dhcpserver modify --ifname \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.100 --netmask 255.255.255.0 --lowerip 192.168.56.101 --upperip 192.168.56.200'))
7.196 -
7.197 - #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
7.198 - def createVM(self, vm_name):
7.199 - hostonly_if = self.getHostOnlyIFs()
7.200 - checkResult(Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register'))
7.201 - checkResult(Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat'))
7.202 - checkResult(Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2'))
7.203 - return
7.204 -
7.205 - # attach storage image to controller
7.206 - def storageAttach(self, vm_name):
7.207 - if self.isStorageAttached(vm_name):
7.208 - self.storageDetach(vm_name)
7.209 - checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"'))
7.210 -
7.211 - # return true if storage is attached
7.212 - def isStorageAttached(self, vm_name):
7.213 - info = self.getVMInfo(vm_name)
7.214 - return (info['SATA-0-0']!='none')
7.215 -
7.216 - # detach storage from controller
7.217 - def storageDetach(self, vm_name):
7.218 - if self.isStorageAttached(vm_name):
7.219 - checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none'))
7.220 -
7.221 - def changeStorageType(self, filename, storage_type):
7.222 - checkResult(Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type))
7.223 -
7.224 - # list storage snaphots for VM
7.225 - def updateTemplate(self):
7.226 - self.cleanup()
7.227 - self.poweroffVM('SecurityDVM')
7.228 - self.waitShutdown('SecurityDVM')
7.229 -
7.230 - # check for updates
7.231 - self.genCertificateISO('SecurityDVM')
7.232 - self.attachCertificateISO('SecurityDVM')
7.233 -
7.234 - self.storageDetach('SecurityDVM')
7.235 - results = checkResult(Cygwin.vboxExecute('list hdds'))[1]
7.236 - results = results.replace('Parent UUID', 'Parent')
7.237 - items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
7.238 -
7.239 - snaps = dict()
7.240 - for item in items:
7.241 - props = dict()
7.242 - for line in item.splitlines():
7.243 - if line != "":
7.244 - k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
7.245 - props[k] = v;
7.246 - snaps[props['UUID']] = props
7.247 -
7.248 -
7.249 - template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
7.250 -
7.251 - # find template uuid
7.252 - template_uuid = ''
7.253 - for hdd in snaps.values():
7.254 - if hdd['Location'] == template_storage:
7.255 - template_uuid = hdd['UUID']
7.256 - logger.debug('found parent uuid ' + template_uuid)
7.257 -
7.258 - # remove snapshots
7.259 - for hdd in snaps.values():
7.260 - if hdd['Parent'] == template_uuid:
7.261 - #template_uuid = hdd['UUID']
7.262 - logger.debug('removing snapshot ' + hdd['UUID'])
7.263 - checkResult(Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete'))#[1]
7.264 - # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
7.265 -
7.266 - self.changeStorageType(template_storage,'normal')
7.267 - self.storageAttach('SecurityDVM')
7.268 - self.startVM('SecurityDVM')
7.269 - self.waitStartup('SecurityDVM')
7.270 - checkResult(Cygwin.sshExecute('"sudo apt-get -y update"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
7.271 - checkResult(Cygwin.sshExecute('"sudo apt-get -y upgrade"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
7.272 - #self.stopVM('SecurityDVM')
7.273 - self.hibernateVM('SecurityDVM')
7.274 - self.waitShutdown('SecurityDVM')
7.275 - self.storageDetach('SecurityDVM')
7.276 - self.changeStorageType(template_storage,'immutable')
7.277 - self.storageAttach('SecurityDVM')
7.278 - self.rsdHandler = DeviceHandler(self)
7.279 - self.rsdHandler.start()
7.280 -
7.281 - #remove VM from the system. should be used on VMs returned by listSDVMs
7.282 - def removeVM(self, vm_name):
7.283 - logger.info('Removing ' + vm_name)
7.284 - checkResult(Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete'))
7.285 - machineFolder = Cygwin.cygPath(self.machineFolder)
7.286 - checkResult(Cygwin.bashExecute('"/usr/bin/rm -rf ' + machineFolder + '/' + vm_name + '"'))
7.287 -
7.288 - # start VM
7.289 - def startVM(self, vm_name):
7.290 - logger.info('Starting ' + vm_name)
7.291 - result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless' ))
7.292 - while 'successfully started' not in result[1]:
7.293 - logger.error("Failed to start SDVM: " + vm_name + " retrying")
7.294 - time.sleep(1)
7.295 - result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless'))
7.296 - return result[0]
7.297 -
7.298 - # return wether VM is running or not
7.299 - def isVMRunning(self, vm_name):
7.300 - return vm_name in self.listRunningVMS()
7.301 -
7.302 - # stop VM
7.303 - def stopVM(self, vm_name):
7.304 - logger.info('Sending shutdown signal to ' + vm_name)
7.305 - checkResult(Cygwin.sshExecute( '"sudo shutdown -h now"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' ))
7.306 -
7.307 - # stop VM
7.308 - def hibernateVM(self, vm_name):
7.309 - logger.info('Sending shutdown signal to ' + vm_name)
7.310 - checkResult(Cygwin.sshExecute( '"sudo hibernate-disk&"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key', wait_return=False))
7.311 -
7.312 - # poweroff VM
7.313 - def poweroffVM(self, vm_name):
7.314 - if not self.isVMRunning(vm_name):
7.315 - return
7.316 - logger.info('Powering off ' + vm_name)
7.317 - return checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff'))
7.318 -
7.319 - #list the hostonly IFs exposed by the VBox host
7.320 - @staticmethod
7.321 - def getHostOnlyIFs():
7.322 - result = Cygwin.vboxExecute('list hostonlyifs')[1]
7.323 - if result=='':
7.324 - return None
7.325 - props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
7.326 - return props
7.327 -
7.328 - # return the hostOnly IP for a running guest or the host
7.329 - @staticmethod
7.330 - def getHostOnlyIP(vm_name):
7.331 - if vm_name == None:
7.332 - logger.info('Gettting hostOnly IP address for Host')
7.333 - return VMManager.getHostOnlyIFs()['IPAddress']
7.334 - else:
7.335 - logger.info('Gettting hostOnly IP address ' + vm_name)
7.336 - result = checkResult(Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP'))
7.337 - if result=='':
7.338 - return None
7.339 - result = result[1]
7.340 - if result.startswith('No value set!'):
7.341 - return None
7.342 - return result[result.index(':')+1:].strip()
7.343 -
7.344 - # attach removable storage device to VM by provision of filter
7.345 - def attachRSD(self, vm_name, rsd_filter):
7.346 - return checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision))
7.347 -
7.348 - # detach removable storage from VM by
7.349 - def detachRSD(self, vm_name):
7.350 - return checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
7.351 -
7.352 - # return the description set for an existing VM
7.353 - def getVMInfo(self, vm_name):
7.354 - results = checkResult(Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable'))[1]
7.355 - props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
7.356 - return props
7.357 -
7.358 - # return the configured USB filter for an existing VM
7.359 - def getUSBFilter(self, vm_name):
7.360 - props = self.getVMInfo(vm_name)
7.361 - keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
7.362 - keyset = set(props.keys())
7.363 - usb_filter = None
7.364 - if keyset.issuperset(keys):
7.365 - usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
7.366 - return usb_filter
7.367 -
7.368 - #generates ISO containing authorized_keys for use with guest VM
7.369 - def genCertificateISO(self, vm_name):
7.370 - machineFolder = Cygwin.cygPath(self.machineFolder)
7.371 - # remove .ssh folder if exists
7.372 - checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.373 - # remove .ssh folder if exists
7.374 - checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
7.375 - # create .ssh folder in vm_name
7.376 - checkResult(Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.377 - # generate dvm_key pair in vm_name / .ssh
7.378 - checkResult(Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"'))
7.379 - # move out private key
7.380 - checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"'))
7.381 - # set permissions for private key
7.382 - checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
7.383 - # rename public key to authorized_keys
7.384 - checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"'))
7.385 - # set permissions for authorized_keys
7.386 - checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"'))
7.387 - # generate iso image with .ssh/authorized keys
7.388 - checkResult(Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.389 -
7.390 - # attaches generated ssh public cert to guest vm
7.391 - def attachCertificateISO(self, vm_name):
7.392 - result = checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"'))
7.393 - return result
7.394 -
7.395 - # wait for machine to come up
7.396 - def waitStartup(self, vm_name, timeout_ms = 30000):
7.397 - checkResult(Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' SDVMStarted --timeout ' + str(timeout_ms) + ' --fail-on-timeout'))
7.398 - return VMManager.getHostOnlyIP(vm_name)
7.399 -
7.400 - # wait for machine to shutdown
7.401 - def waitShutdown(self, vm_name):
7.402 - while vm_name in self.listRunningVMS():
7.403 - time.sleep(1)
7.404 - return
7.405 -
7.406 - # handles browsing request
7.407 - def handleBrowsingRequest(self):
7.408 - handler = BrowsingHandler(self)
7.409 - handler.start()
7.410 - return 'ok'
7.411 -
7.412 - #Small function to check the availability of network resource.
7.413 - #def isAvailable(self, path):
7.414 - #return os.path.exists(path)
7.415 - #result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
7.416 - #return string.find(result[1], 'YES',)
7.417 -
7.418 - #Small function to check if the mention location is a directory
7.419 - def isDirectory(self, path):
7.420 - result = checkResult(Cygwin.cmdExecute('dir ' + path + ' | FIND ".."'))
7.421 - return string.find(result[1], 'DIR',)
7.422 -
7.423 - def mapNetworkDrive(self, drive, networkPath, user, password):
7.424 - self.unmapNetworkDrive(drive)
7.425 - #Check for drive availability
7.426 - if os.path.exists(drive):
7.427 - logger.error("Drive letter is already in use: " + drive)
7.428 - return -1
7.429 - #Check for network resource availability
7.430 - retry = 5
7.431 - while not os.path.exists(networkPath):
7.432 - time.sleep(1)
7.433 - if retry == 0:
7.434 - return -1
7.435 - logger.info("Path not accessible: " + networkPath + " retrying")
7.436 - retry-=1
7.437 - #return -1
7.438 -
7.439 - command = 'USE ' + drive + ' ' + networkPath + ' /PERSISTENT:NO'
7.440 - if user != None:
7.441 - command += ' ' + password + ' /User' + user
7.442 -
7.443 - #TODO: Execute 'NET USE' command with authentication
7.444 - result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', command))
7.445 - if string.find(result[1], 'successfully',) == -1:
7.446 - logger.error("Failed: NET " + command)
7.447 - return -1
7.448 - return 1
7.449 -
7.450 - def unmapNetworkDrive(self, drive):
7.451 - drives = self.getNetworkDrives()
7.452 - if drive not in drives.keys():
7.453 - return 1
7.454 - result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES'))
7.455 - if string.find(str(result[1]), 'successfully',) == -1:
7.456 - logger.error(result[2])
7.457 - return -1
7.458 - return 1
7.459 -
7.460 - def getNetworkDrives(self):
7.461 - ip = VMManager.getHostOnlyIP(None)
7.462 - ip = ip[:ip.rindex('.')]
7.463 - drives = dict()
7.464 - result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
7.465 - for line in result[1].splitlines():
7.466 - if ip in line:
7.467 - parts = line.split()
7.468 - drives[parts[1]] = parts[2]
7.469 - return drives
7.470 -
7.471 - def genNetworkDrive(self):
7.472 - network_drives = self.getNetworkDrives()
7.473 - logical_drives = VMManager.getLogicalDrives()
7.474 - drives = list(map(chr, range(68, 91)))
7.475 - for drive in drives:
7.476 - if drive+':' not in network_drives and drive not in logical_drives:
7.477 - return drive+':'
7.478 -
7.479 - def getNetworkDrive(self, vm_name):
7.480 - ip = self.getHostOnlyIP(vm_name)
7.481 - result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
7.482 - for line in result[1].splitlines():
7.483 - if line != None and ip in line:
7.484 - parts = line.split()
7.485 - return parts[0]
7.486 - @staticmethod
7.487 - def getLogicalDrives():
7.488 - drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
7.489 - return list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
7.490 -
7.491 - @staticmethod
7.492 - def getDriveType(drive):
7.493 - return ctypes.cdll.kernel32.GetDriveTypeW(u"%s:\\"%drive)
7.494 -
7.495 - @staticmethod
7.496 - def getVolumeInfo(drive):
7.497 - volumeNameBuffer = ctypes.create_unicode_buffer(1024)
7.498 - fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
7.499 - serial_number = None
7.500 - max_component_length = None
7.501 - file_system_flags = None
7.502 -
7.503 - rc = ctypes.cdll.kernel32.GetVolumeInformationW(
7.504 - #ctypes.c_wchar_p("F:\\"),
7.505 - u"%s:\\"%drive,
7.506 - volumeNameBuffer,
7.507 - ctypes.sizeof(volumeNameBuffer),
7.508 - serial_number,
7.509 - max_component_length,
7.510 - file_system_flags,
7.511 - fileSystemNameBuffer,
7.512 - ctypes.sizeof(fileSystemNameBuffer)
7.513 - )
7.514 -
7.515 - return volumeNameBuffer.value, fileSystemNameBuffer.value
7.516 -
7.517 -def checkResult(result):
7.518 - if result[0] != 0:
7.519 - logger.error('Command failed:' + ''.join(result[2]))
7.520 - raise OpenSecurityException('Command failed:' + ''.join(result[2]))
7.521 - return result
7.522 -
7.523 -# handles browsing request
7.524 -class BrowsingHandler(threading.Thread):
7.525 - vmm = None
7.526 - def __init__(self, vmmanager):
7.527 - threading.Thread.__init__(self)
7.528 - self.vmm = vmmanager
7.529 -
7.530 - def run(self):
7.531 - try:
7.532 - new_sdvm = self.vmm.generateSDVMName()
7.533 - self.vmm.createVM(new_sdvm)
7.534 - self.vmm.storageAttach(new_sdvm)
7.535 - self.vmm.genCertificateISO(new_sdvm)
7.536 - self.vmm.attachCertificateISO(new_sdvm)
7.537 - self.vmm.startVM(new_sdvm)
7.538 - new_ip = self.vmm.waitStartup(new_sdvm)
7.539 - drive = self.vmm.genNetworkDrive()
7.540 - if new_ip != None:
7.541 - self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\Download', None, None)
7.542 - result = checkResult(Cygwin.sshExecuteX11('/usr/bin/iceweasel', new_ip, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + new_sdvm + '/dvm_key'))
7.543 - except:
7.544 - logger.error("BrowsingHandler failed. Cleaning up")
7.545 -
7.546 - self.vmm.unmapNetworkDrive(drive)
7.547 - self.vmm.poweroffVM(new_sdvm)
7.548 - self.vmm.removeVM(new_sdvm)
7.549 -
7.550 -class DeviceHandler(threading.Thread):
7.551 - vmm = None
7.552 - #handleDeviceChangeLock = threading.Lock()
7.553 - attachedRSDs = None
7.554 - connectedRSDs = None
7.555 - running = True
7.556 - def __init__(self, vmmanger):
7.557 - threading.Thread.__init__(self)
7.558 - self.vmm = vmmanger
7.559 -
7.560 - def stop(self):
7.561 - self.running = False
7.562 -
7.563 - def run(self):
7.564 - self.connectedRSDs = dict()
7.565 - self.attachedRSDs = self.vmm.getAttachedRSDs()
7.566 - while self.running:
7.567 - tmp_rsds = self.vmm.getConnectedRSDS()
7.568 - if tmp_rsds.keys() == self.connectedRSDs.keys():
7.569 - logger.debug("Nothing's changed. sleep(3)")
7.570 - time.sleep(3)
7.571 - continue
7.572 -
7.573 - logger.info("Something's changed")
7.574 - self.connectedRSDs = tmp_rsds
7.575 - self.attachedRSDs = self.vmm.getAttachedRSDs()
7.576 -
7.577 - for vm_name in self.attachedRSDs.keys():
7.578 - if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
7.579 - drive = self.vmm.getNetworkDrive(vm_name)
7.580 - self.vmm.unmapNetworkDrive(drive)
7.581 - #self.stopVM(vm_name)
7.582 - self.vmm.detachRSD(vm_name)
7.583 - self.vmm.poweroffVM(vm_name)
7.584 - self.vmm.removeVM(vm_name)
7.585 - #create new vm for attached device if any
7.586 - self.attachedRSDs = self.vmm.getAttachedRSDs()
7.587 - self.connectedRSDs = self.vmm.getConnectedRSDS()
7.588 -
7.589 - new_ip = None
7.590 - for connected_device in self.connectedRSDs.values():
7.591 - if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
7.592 - new_sdvm = self.vmm.generateSDVMName()
7.593 - self.vmm.createVM(new_sdvm)
7.594 - self.vmm.storageAttach(new_sdvm)
7.595 - self.vmm.attachRSD(new_sdvm, connected_device)
7.596 - self.vmm.startVM(new_sdvm)
7.597 - new_ip = self.vmm.waitStartup(new_sdvm)
7.598 - drive = self.vmm.genNetworkDrive()
7.599 - if new_ip != None:
7.600 - self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\USB', None, None)
7.601 -
7.602 -if __name__ == '__main__':
7.603 - #man = VMManager.getInstance()
7.604 - #man.listVM()
7.605 - #print man.getConnectedRSDs()
7.606 - #print man.getNetworkDrives()
7.607 - #man.genNetworkDrive()
7.608 - #drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
7.609 - #print list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
7.610 - #print list(map(chr, range(68, 91)))
7.611 - #print Cygwin.getRegEntry('SYSTEM\CurrentControlSet\Enum\USB', 'VID_1058&PID_0704')[0]
7.612 - #devices = VMManager.getConnectedRSDS()
7.613 - #print devices
7.614 -
7.615 - drives = VMManager.getLogicalDrives()
7.616 - print drives
7.617 - print VMManager.getDriveType("E")
7.618 - print VMManager.getVolumeInfo("E")
7.619 - #for device in devices.values():
7.620 - # #print device
7.621 - # if VMManager.isMassStorageDevice(device):
7.622 - # print device
7.623 -
7.624 -
7.625 -
7.626 - #time.sleep(-1)
7.627 - #man.listVM()
7.628 - #man.listVM()
7.629 - #man.listVM()
7.630 - #man.listVM()
7.631 - #man.genCertificateISO('SecurityDVM0')
7.632 - #man.guestExecute('SecurityDVM0', '/bin/ls -la')
7.633 - #logger = setupLogger('VMManager')
7.634 - #c = Cygwin()
7.635 -
7.636 - #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
7.637 - #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
7.638 - #man.removeVM('SecurityDVM0')
7.639 - #man.netUse('192.168.56.134', 'USB\\')
7.640 - #ip = '192.168.56.139'
7.641 -
7.642 - #man.cygwin_path = 'c:\\cygwin64\\bin\\'
7.643 - #man.handleDeviceChange()
7.644 - #print man.listSDVM()
7.645 - #man.configureHostNetworking()
7.646 - #new_vm = man.generateSDVMName()
7.647 - #man.createVM(new_vm)
7.648 -
7.649 - #print Cygwin.cmd()
7.650 - #man.isAvailable('c:')
7.651 - #ip = man.getHostOnlyIP('SecurityDVM0')
7.652 - #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
7.653 -
7.654 - #man.genCertificateISO(new_vm)
7.655 - #man.attachCertificateISO(new_vm)
7.656 -
7.657 - #man.attachCertificateISO(vm_name)
7.658 - #man.guestExecute(vm_name, "ls")
7.659 - #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
7.660 - #time.sleep(60)
7.661 - #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
7.662 - #man.genCertificateISO('SecurityDVM')
7.663 - #man.attachCertificateISO('SecurityDVM')
7.664 - #man.isStorageAttached('SecurityDVM')
7.665 - #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
7.666 - #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
7.667 -
7.668 - #man.stopVM('SecurityDVM')
7.669 - #man.storageDetach('SecurityDVM')
7.670 - #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
7.671 - #man.storageAttach('SecurityDVM')
7.672 -
7.673 -
7.674 - #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
7.675 - #man.execute(cmd)
7.676 +'''
7.677 +Created on Nov 19, 2013
7.678 +
7.679 +@author: BarthaM
7.680 +'''
7.681 +import os
7.682 +import os.path
7.683 +from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
7.684 +import sys
7.685 +import re
7.686 +
7.687 +from cygwin import Cygwin
7.688 +from environment import Environment
7.689 +import threading
7.690 +import time
7.691 +import string
7.692 +
7.693 +import shutil
7.694 +import stat
7.695 +import tempfile
7.696 +from opensecurity_util import logger, setupLogger, OpenSecurityException
7.697 +import ctypes
7.698 +import itertools
7.699 +import _winreg
7.700 +DEBUG = True
7.701 +
7.702 +class VMManagerException(Exception):
7.703 + def __init__(self, value):
7.704 + self.value = value
7.705 + def __str__(self):
7.706 + return repr(self.value)
7.707 +
7.708 +class USBFilter:
7.709 + vendorid = ""
7.710 + productid = ""
7.711 + revision = ""
7.712 +
7.713 + def __init__(self, vendorid, productid, revision):
7.714 + self.vendorid = vendorid.lower()
7.715 + self.productid = productid.lower()
7.716 + self.revision = revision.lower()
7.717 + return
7.718 +
7.719 + def __eq__(self, other):
7.720 + return self.vendorid == other.vendorid and self.productid == other.productid and self.revision == other.revision
7.721 +
7.722 + def __hash__(self):
7.723 + return hash(self.vendorid) ^ hash(self.productid) ^ hash(self.revision)
7.724 +
7.725 + def __repr__(self):
7.726 + return "VendorId = \'" + str(self.vendorid) + "\' ProductId = \'" + str(self.productid) + "\' Revision = \'" + str(self.revision) + "\'"
7.727 +
7.728 + #def __getitem__(self, item):
7.729 + # return self.coords[item]
7.730 +
7.731 +class VMManager(object):
7.732 + vmRootName = "SecurityDVM"
7.733 + systemProperties = None
7.734 + _instance = None
7.735 + machineFolder = ''
7.736 + rsdHandler = None
7.737 + _running = True
7.738 +
7.739 + def __init__(self):
7.740 + self._running = True
7.741 + self.systemProperties = self.getSystemProperties()
7.742 + self.machineFolder = self.systemProperties["Default machine folder"]
7.743 + self.cleanup()
7.744 + self.rsdHandler = DeviceHandler(self)
7.745 + self.rsdHandler.start()
7.746 + return
7.747 +
7.748 + @staticmethod
7.749 + def getInstance():
7.750 + if VMManager._instance == None:
7.751 + VMManager._instance = VMManager()
7.752 + return VMManager._instance
7.753 +
7.754 + def cleanup(self):
7.755 + if self.rsdHandler != None:
7.756 + self.rsdHandler.stop()
7.757 + self.rsdHandler.join()
7.758 + drives = self.getNetworkDrives()
7.759 + for drive in drives.keys():
7.760 + self.unmapNetworkDrive(drive)
7.761 + for vm in self.listSDVM():
7.762 + self.poweroffVM(vm)
7.763 + self.removeVM(vm)
7.764 +
7.765 + # return hosty system properties
7.766 + def getSystemProperties(self):
7.767 + result = checkResult(Cygwin.vboxExecute('list systemproperties'))
7.768 + if result[1]=='':
7.769 + return None
7.770 + props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result[1].strip().splitlines()))
7.771 + return props
7.772 +
7.773 + # return the folder containing the guest VMs
7.774 + def getMachineFolder(self):
7.775 + return self.machineFolder
7.776 +
7.777 + # list all existing VMs registered with VBox
7.778 + def listVM(self):
7.779 + result = checkResult(Cygwin.vboxExecute('list vms'))[1]
7.780 + vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
7.781 + return vms
7.782 +
7.783 + # list running VMs
7.784 + def listRunningVMS(self):
7.785 + result = checkResult(Cygwin.vboxExecute('list runningvms'))[1]
7.786 + vms = list(k.strip().strip('"') for k,_ in (line.split(' ') for line in result.splitlines()))
7.787 + return vms
7.788 +
7.789 + # list existing SDVMs
7.790 + def listSDVM(self):
7.791 + vms = self.listVM()
7.792 + svdms = []
7.793 + for vm in vms:
7.794 + if vm.startswith(self.vmRootName) and vm != self.vmRootName:
7.795 + svdms.append(vm)
7.796 + return svdms
7.797 +
7.798 + # generate valid (not already existing SDVM name). necessary for creating a new VM
7.799 + def generateSDVMName(self):
7.800 + vms = self.listVM()
7.801 + for i in range(0,999):
7.802 + if(not self.vmRootName+str(i) in vms):
7.803 + return self.vmRootName+str(i)
7.804 + return ''
7.805 +
7.806 + # check if the device is mass storage type
7.807 + @staticmethod
7.808 + def isMassStorageDevice(device):
7.809 + keyname = 'SYSTEM\CurrentControlSet\Enum\USB' + '\VID_' + device.vendorid+'&'+'PID_'+ device.productid
7.810 + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname)
7.811 + #subkeys = _winreg.QueryInfoKey(key)[0]
7.812 + #for i in range(0, subkeys):
7.813 + # print _winreg.EnumKey(key, i)
7.814 + devinfokeyname = _winreg.EnumKey(key, 0)
7.815 + _winreg.CloseKey(key)
7.816 +
7.817 + devinfokey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, keyname+'\\'+devinfokeyname)
7.818 + value = _winreg.QueryValueEx(devinfokey, 'SERVICE')[0]
7.819 + _winreg.CloseKey(devinfokey)
7.820 +
7.821 + return 'USBSTOR' in value
7.822 +
7.823 + # return the RSDs connected to the host
7.824 + @staticmethod
7.825 + def getConnectedRSDS():
7.826 + results = checkResult(Cygwin.vboxExecute('list usbhost'))[1]
7.827 + results = results.split('Host USB Devices:')[1].strip()
7.828 +
7.829 + items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
7.830 + rsds = dict()
7.831 + for item in items:
7.832 + props = dict()
7.833 + for line in item.splitlines():
7.834 + if line != "":
7.835 + k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
7.836 + props[k] = v
7.837 +
7.838 + #if 'Product' in props.keys() and props['Product'] == 'Mass Storage':
7.839 +
7.840 + usb_filter = USBFilter( re.search(r"\((?P<vid>[0-9A-Fa-f]+)\)", props['VendorId']).groupdict()['vid'],
7.841 + re.search(r"\((?P<pid>[0-9A-Fa-f]+)\)", props['ProductId']).groupdict()['pid'],
7.842 + re.search(r"\((?P<rev>[0-9A-Fa-f]+)\)", props['Revision']).groupdict()['rev'] )
7.843 + if VMManager.isMassStorageDevice(usb_filter):
7.844 + rsds[props['UUID']] = usb_filter;
7.845 + logger.debug(usb_filter)
7.846 + return rsds
7.847 +
7.848 + # return the RSDs attached to all existing SDVMs
7.849 + def getAttachedRSDs(self):
7.850 + vms = self.listSDVM()
7.851 + attached_devices = dict()
7.852 + for vm in vms:
7.853 + rsd_filter = self.getUSBFilter(vm)
7.854 + if rsd_filter != None:
7.855 + attached_devices[vm] = rsd_filter
7.856 + return attached_devices
7.857 +
7.858 + # configures hostonly networking and DHCP server. requires admin rights
7.859 + def configureHostNetworking(self):
7.860 + #cmd = 'vboxmanage list hostonlyifs'
7.861 + #Cygwin.vboxExecute(cmd)
7.862 + #cmd = 'vboxmanage hostonlyif remove \"VirtualBox Host-Only Ethernet Adapter\"'
7.863 + #Cygwin.vboxExecute(cmd)
7.864 + #cmd = 'vboxmanage hostonlyif create'
7.865 + #Cygwin.vboxExecute(cmd)
7.866 + checkResult(Cygwin.vboxExecute('hostonlyif ipconfig \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.1 --netmask 255.255.255.0'))
7.867 + #cmd = 'vboxmanage dhcpserver add'
7.868 + #Cygwin.vboxExecute(cmd)
7.869 + checkResult(Cygwin.vboxExecute('dhcpserver modify --ifname \"VirtualBox Host-Only Ethernet Adapter\" --ip 192.168.56.100 --netmask 255.255.255.0 --lowerip 192.168.56.101 --upperip 192.168.56.200'))
7.870 +
7.871 + #create new virtual machine instance based on template vm named SecurityDVM (\SecurityDVM\SecurityDVM.vmdk)
7.872 + def createVM(self, vm_name):
7.873 + hostonly_if = self.getHostOnlyIFs()
7.874 + checkResult(Cygwin.vboxExecute('createvm --name ' + vm_name + ' --ostype Debian --register'))
7.875 + checkResult(Cygwin.vboxExecute('modifyvm ' + vm_name + ' --memory 512 --vram 10 --cpus 1 --usb on --usbehci on --nic1 hostonly --hostonlyadapter1 \"' + hostonly_if['Name'] + '\" --nic2 nat'))
7.876 + checkResult(Cygwin.vboxExecute('storagectl ' + vm_name + ' --name SATA --add sata --portcount 2'))
7.877 + return
7.878 +
7.879 + # attach storage image to controller
7.880 + def storageAttach(self, vm_name):
7.881 + if self.isStorageAttached(vm_name):
7.882 + self.storageDetach(vm_name)
7.883 + checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium \"'+ self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk\"'))
7.884 +
7.885 + # return true if storage is attached
7.886 + def isStorageAttached(self, vm_name):
7.887 + info = self.getVMInfo(vm_name)
7.888 + return (info['SATA-0-0']!='none')
7.889 +
7.890 + # detach storage from controller
7.891 + def storageDetach(self, vm_name):
7.892 + if self.isStorageAttached(vm_name):
7.893 + checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 0 --device 0 --type hdd --medium none'))
7.894 +
7.895 + def changeStorageType(self, filename, storage_type):
7.896 + checkResult(Cygwin.vboxExecute('modifyhd \"' + filename + '\" --type ' + storage_type))
7.897 +
7.898 + # list storage snaphots for VM
7.899 + def updateTemplate(self):
7.900 + self.cleanup()
7.901 + self.poweroffVM('SecurityDVM')
7.902 + self.waitShutdown('SecurityDVM')
7.903 +
7.904 + # check for updates
7.905 + self.genCertificateISO('SecurityDVM')
7.906 + self.attachCertificateISO('SecurityDVM')
7.907 +
7.908 + self.storageDetach('SecurityDVM')
7.909 + results = checkResult(Cygwin.vboxExecute('list hdds'))[1]
7.910 + results = results.replace('Parent UUID', 'Parent')
7.911 + items = list( "UUID:"+result for result in results.split('UUID:') if result != '')
7.912 +
7.913 + snaps = dict()
7.914 + for item in items:
7.915 + props = dict()
7.916 + for line in item.splitlines():
7.917 + if line != "":
7.918 + k,v = line[:line.index(':')].strip(), line[line.index(':')+1:].strip()
7.919 + props[k] = v;
7.920 + snaps[props['UUID']] = props
7.921 +
7.922 +
7.923 + template_storage = self.machineFolder + '\SecurityDVM\SecurityDVM.vmdk'
7.924 +
7.925 + # find template uuid
7.926 + template_uuid = ''
7.927 + for hdd in snaps.values():
7.928 + if hdd['Location'] == template_storage:
7.929 + template_uuid = hdd['UUID']
7.930 + logger.debug('found parent uuid ' + template_uuid)
7.931 +
7.932 + # remove snapshots
7.933 + for hdd in snaps.values():
7.934 + if hdd['Parent'] == template_uuid:
7.935 + #template_uuid = hdd['UUID']
7.936 + logger.debug('removing snapshot ' + hdd['UUID'])
7.937 + checkResult(Cygwin.vboxExecute('closemedium disk {' + hdd['UUID'] + '} --delete'))#[1]
7.938 + # parse result 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
7.939 +
7.940 + self.changeStorageType(template_storage,'normal')
7.941 + self.storageAttach('SecurityDVM')
7.942 + self.startVM('SecurityDVM')
7.943 + self.waitStartup('SecurityDVM')
7.944 + checkResult(Cygwin.sshExecute('"sudo apt-get -y update"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
7.945 + checkResult(Cygwin.sshExecute('"sudo apt-get -y upgrade"', VMManager.getHostOnlyIP('SecurityDVM'), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + 'SecurityDVM' + '/dvm_key'))
7.946 + #self.stopVM('SecurityDVM')
7.947 + self.hibernateVM('SecurityDVM')
7.948 + self.waitShutdown('SecurityDVM')
7.949 + self.storageDetach('SecurityDVM')
7.950 + self.changeStorageType(template_storage,'immutable')
7.951 + self.storageAttach('SecurityDVM')
7.952 + self.rsdHandler = DeviceHandler(self)
7.953 + self.rsdHandler.start()
7.954 +
7.955 + #remove VM from the system. should be used on VMs returned by listSDVMs
7.956 + def removeVM(self, vm_name):
7.957 + logger.info('Removing ' + vm_name)
7.958 + checkResult(Cygwin.vboxExecute('unregistervm ' + vm_name + ' --delete'))
7.959 + vm_file = Cygwin.cygPath(self.machineFolder + '\\' + vm_name)
7.960 + checkResult(Cygwin.bashExecute('rm -rf \'' + vm_file + '\''))
7.961 +
7.962 + # start VM
7.963 + def startVM(self, vm_name):
7.964 + logger.info('Starting ' + vm_name)
7.965 + result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless' ))
7.966 + while 'successfully started' not in result[1] and _running:
7.967 + logger.error("Failed to start SDVM: " + vm_name + " retrying")
7.968 + time.sleep(1)
7.969 + result = checkResult(Cygwin.vboxExecute('startvm ' + vm_name + ' --type headless'))
7.970 + return result[0]
7.971 +
7.972 + # return wether VM is running or not
7.973 + def isVMRunning(self, vm_name):
7.974 + return vm_name in self.listRunningVMS()
7.975 +
7.976 + # stop VM
7.977 + def stopVM(self, vm_name):
7.978 + logger.info('Sending shutdown signal to ' + vm_name)
7.979 + checkResult(Cygwin.sshExecute( '"sudo shutdown -h now"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key' ))
7.980 +
7.981 + # stop VM
7.982 + def hibernateVM(self, vm_name):
7.983 + logger.info('Sending shutdown signal to ' + vm_name)
7.984 + checkResult(Cygwin.sshExecute( '"sudo hibernate-disk&"', VMManager.getHostOnlyIP(vm_name), 'osecuser', Cygwin.cygPath(self.machineFolder) + '/' + vm_name + '/dvm_key', wait_return=False))
7.985 +
7.986 + # poweroff VM
7.987 + def poweroffVM(self, vm_name):
7.988 + if not self.isVMRunning(vm_name):
7.989 + return
7.990 + logger.info('Powering off ' + vm_name)
7.991 + return checkResult(Cygwin.vboxExecute('controlvm ' + vm_name + ' poweroff'))
7.992 +
7.993 + #list the hostonly IFs exposed by the VBox host
7.994 + @staticmethod
7.995 + def getHostOnlyIFs():
7.996 + result = Cygwin.vboxExecute('list hostonlyifs')[1]
7.997 + if result=='':
7.998 + return None
7.999 + props = dict((k.strip(),v.strip().strip('"')) for k,v in (line.split(':', 1) for line in result.strip().splitlines()))
7.1000 + return props
7.1001 +
7.1002 + # return the hostOnly IP for a running guest or the host
7.1003 + @staticmethod
7.1004 + def getHostOnlyIP(vm_name):
7.1005 + if vm_name == None:
7.1006 + logger.info('Gettting hostOnly IP address for Host')
7.1007 + return VMManager.getHostOnlyIFs()['IPAddress']
7.1008 + else:
7.1009 + logger.info('Gettting hostOnly IP address ' + vm_name)
7.1010 + result = checkResult(Cygwin.vboxExecute('guestproperty get ' + vm_name + ' /VirtualBox/GuestInfo/Net/0/V4/IP'))
7.1011 + if result=='':
7.1012 + return None
7.1013 + result = result[1]
7.1014 + if result.startswith('No value set!'):
7.1015 + return None
7.1016 + return result[result.index(':')+1:].strip()
7.1017 +
7.1018 + # attach removable storage device to VM by provision of filter
7.1019 + def attachRSD(self, vm_name, rsd_filter):
7.1020 + return checkResult(Cygwin.vboxExecute('usbfilter add 0 --target ' + vm_name + ' --name OpenSecurityRSD --vendorid ' + rsd_filter.vendorid + ' --productid ' + rsd_filter.productid + ' --revision ' + rsd_filter.revision))
7.1021 +
7.1022 + # detach removable storage from VM by
7.1023 + def detachRSD(self, vm_name):
7.1024 + return checkResult(Cygwin.vboxExecute('usbfilter remove 0 --target ' + vm_name))
7.1025 +
7.1026 + # return the description set for an existing VM
7.1027 + def getVMInfo(self, vm_name):
7.1028 + results = checkResult(Cygwin.vboxExecute('showvminfo ' + vm_name + ' --machinereadable'))[1]
7.1029 + props = dict((k.strip().strip('"'),v.strip().strip('"')) for k,v in (line.split('=', 1) for line in results.splitlines()))
7.1030 + return props
7.1031 +
7.1032 + # return the configured USB filter for an existing VM
7.1033 + def getUSBFilter(self, vm_name):
7.1034 + props = self.getVMInfo(vm_name)
7.1035 + keys = set(['USBFilterVendorId1', 'USBFilterProductId1', 'USBFilterRevision1'])
7.1036 + keyset = set(props.keys())
7.1037 + usb_filter = None
7.1038 + if keyset.issuperset(keys):
7.1039 + usb_filter = USBFilter(props['USBFilterVendorId1'], props['USBFilterProductId1'], props['USBFilterRevision1'])
7.1040 + return usb_filter
7.1041 +
7.1042 + #generates ISO containing authorized_keys for use with guest VM
7.1043 + def genCertificateISO(self, vm_name):
7.1044 + machineFolder = Cygwin.cygPath(self.machineFolder)
7.1045 + # remove .ssh folder if exists
7.1046 + checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.1047 + # remove .ssh folder if exists
7.1048 + checkResult(Cygwin.bashExecute('\"/usr/bin/rm -rf \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
7.1049 + # create .ssh folder in vm_name
7.1050 + checkResult(Cygwin.bashExecute('\"/usr/bin/mkdir -p \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.1051 + # generate dvm_key pair in vm_name / .ssh
7.1052 + checkResult(Cygwin.bashExecute('\"/usr/bin/ssh-keygen -q -t rsa -N \\"\\" -C \\\"' + vm_name + '\\\" -f \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\"\"'))
7.1053 + # move out private key
7.1054 + checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key\\\" \\\"' + machineFolder + '/' + vm_name + '\\\"'))
7.1055 + # set permissions for private key
7.1056 + checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/dvm_key\\\"\"'))
7.1057 + # rename public key to authorized_keys
7.1058 + checkResult(Cygwin.bashExecute('\"/usr/bin/mv \\\"' + machineFolder + '/' + vm_name + '/.ssh/dvm_key.pub\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"'))
7.1059 + # set permissions for authorized_keys
7.1060 + checkResult(Cygwin.bashExecute('\"/usr/bin/chmod 500 \\\"' + machineFolder + '/' + vm_name + '/.ssh/authorized_keys\\\"\"'))
7.1061 + # generate iso image with .ssh/authorized keys
7.1062 + checkResult(Cygwin.bashExecute('\"/usr/bin/genisoimage -J -R -o \\\"' + machineFolder + '/' + vm_name + '/'+ vm_name + '.iso\\\" \\\"' + machineFolder + '/' + vm_name + '/.ssh\\\"\"'))
7.1063 +
7.1064 + # attaches generated ssh public cert to guest vm
7.1065 + def attachCertificateISO(self, vm_name):
7.1066 + result = checkResult(Cygwin.vboxExecute('storageattach ' + vm_name + ' --storagectl SATA --port 1 --device 0 --type dvddrive --mtype readonly --medium \"' + self.machineFolder + '\\' + vm_name + '\\'+ vm_name + '.iso\"'))
7.1067 + return result
7.1068 +
7.1069 + # wait for machine to come up
7.1070 + def waitStartup(self, vm_name, timeout_ms = 30000):
7.1071 + checkResult(Cygwin.vboxExecute('guestproperty wait ' + vm_name + ' SDVMStarted --timeout ' + str(timeout_ms) + ' --fail-on-timeout'))
7.1072 + return VMManager.getHostOnlyIP(vm_name)
7.1073 +
7.1074 + # wait for machine to shutdown
7.1075 + def waitShutdown(self, vm_name):
7.1076 + while vm_name in self.listRunningVMS() and _running:
7.1077 + time.sleep(1)
7.1078 + return
7.1079 +
7.1080 + # handles browsing request
7.1081 + def handleBrowsingRequest(self):
7.1082 + handler = BrowsingHandler(self)
7.1083 + handler.start()
7.1084 + return 'ok'
7.1085 +
7.1086 + #Small function to check the availability of network resource.
7.1087 + #def isAvailable(self, path):
7.1088 + #return os.path.exists(path)
7.1089 + #result = Cygwin.cmdExecute('IF EXIST "' + path + '" echo YES')
7.1090 + #return string.find(result[1], 'YES',)
7.1091 +
7.1092 + #Small function to check if the mention location is a directory
7.1093 + def isDirectory(self, path):
7.1094 + result = checkResult(Cygwin.cmdExecute('dir ' + path + ' | FIND ".."'))
7.1095 + return string.find(result[1], 'DIR',)
7.1096 +
7.1097 + def mapNetworkDrive(self, drive, networkPath, user, password):
7.1098 + self.unmapNetworkDrive(drive)
7.1099 + #Check for drive availability
7.1100 + if os.path.exists(drive):
7.1101 + logger.error("Drive letter is already in use: " + drive)
7.1102 + return -1
7.1103 + #Check for network resource availability
7.1104 + retry = 5
7.1105 + while not os.path.exists(networkPath):
7.1106 + time.sleep(1)
7.1107 + if retry == 0:
7.1108 + return -1
7.1109 + logger.info("Path not accessible: " + networkPath + " retrying")
7.1110 + retry-=1
7.1111 + #return -1
7.1112 +
7.1113 + command = 'USE ' + drive + ' ' + networkPath + ' /PERSISTENT:NO'
7.1114 + if user != None:
7.1115 + command += ' ' + password + ' /User' + user
7.1116 +
7.1117 + #TODO: Execute 'NET USE' command with authentication
7.1118 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', command))
7.1119 + if string.find(result[1], 'successfully',) == -1:
7.1120 + logger.error("Failed: NET " + command)
7.1121 + return -1
7.1122 + return 1
7.1123 +
7.1124 + def unmapNetworkDrive(self, drive):
7.1125 + drives = self.getNetworkDrives()
7.1126 + if drive not in drives.keys():
7.1127 + return 1
7.1128 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE ' + drive + ' /DELETE /YES'))
7.1129 + if string.find(str(result[1]), 'successfully',) == -1:
7.1130 + logger.error(result[2])
7.1131 + return -1
7.1132 + return 1
7.1133 +
7.1134 + def getNetworkDrives(self):
7.1135 + ip = VMManager.getHostOnlyIP(None)
7.1136 + ip = ip[:ip.rindex('.')]
7.1137 + drives = dict()
7.1138 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
7.1139 + for line in result[1].splitlines():
7.1140 + if ip in line:
7.1141 + parts = line.split()
7.1142 + drives[parts[1]] = parts[2]
7.1143 + return drives
7.1144 +
7.1145 + def genNetworkDrive(self):
7.1146 + network_drives = self.getNetworkDrives()
7.1147 + logical_drives = VMManager.getLogicalDrives()
7.1148 + drives = list(map(chr, range(68, 91)))
7.1149 + for drive in drives:
7.1150 + if drive+':' not in network_drives and drive not in logical_drives:
7.1151 + return drive+':'
7.1152 +
7.1153 + def getNetworkDrive(self, vm_name):
7.1154 + ip = self.getHostOnlyIP(vm_name)
7.1155 + result = checkResult(Cygwin.execute('C:\\Windows\\system32\\net.exe', 'USE'))
7.1156 + for line in result[1].splitlines():
7.1157 + if line != None and ip in line:
7.1158 + parts = line.split()
7.1159 + return parts[0]
7.1160 + @staticmethod
7.1161 + def getLogicalDrives():
7.1162 + drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
7.1163 + return list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
7.1164 +
7.1165 + @staticmethod
7.1166 + def getDriveType(drive):
7.1167 + return ctypes.cdll.kernel32.GetDriveTypeW(u"%s:\\"%drive)
7.1168 +
7.1169 + @staticmethod
7.1170 + def getVolumeInfo(drive):
7.1171 + volumeNameBuffer = ctypes.create_unicode_buffer(1024)
7.1172 + fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
7.1173 + serial_number = None
7.1174 + max_component_length = None
7.1175 + file_system_flags = None
7.1176 +
7.1177 + rc = ctypes.cdll.kernel32.GetVolumeInformationW(
7.1178 + #ctypes.c_wchar_p("F:\\"),
7.1179 + u"%s:\\"%drive,
7.1180 + volumeNameBuffer,
7.1181 + ctypes.sizeof(volumeNameBuffer),
7.1182 + serial_number,
7.1183 + max_component_length,
7.1184 + file_system_flags,
7.1185 + fileSystemNameBuffer,
7.1186 + ctypes.sizeof(fileSystemNameBuffer)
7.1187 + )
7.1188 +
7.1189 + return volumeNameBuffer.value, fileSystemNameBuffer.value
7.1190 +
7.1191 + @staticmethod
7.1192 + def stop():
7.1193 + """stop all running infinite loops now --> needed for gracefull shutdown"""
7.1194 + _running = False
7.1195 +
7.1196 +
7.1197 +
7.1198 +def checkResult(result):
7.1199 + if result[0] != 0:
7.1200 + logger.error('Command failed:' + ''.join(result[2]))
7.1201 + raise OpenSecurityException('Command failed:' + ''.join(result[2]))
7.1202 + return result
7.1203 +
7.1204 +# handles browsing request
7.1205 +class BrowsingHandler(threading.Thread):
7.1206 + vmm = None
7.1207 + def __init__(self, vmmanager):
7.1208 + threading.Thread.__init__(self)
7.1209 + self.vmm = vmmanager
7.1210 +
7.1211 + def run(self):
7.1212 + try:
7.1213 + new_sdvm = self.vmm.generateSDVMName()
7.1214 + self.vmm.createVM(new_sdvm)
7.1215 + self.vmm.storageAttach(new_sdvm)
7.1216 + self.vmm.genCertificateISO(new_sdvm)
7.1217 + self.vmm.attachCertificateISO(new_sdvm)
7.1218 + self.vmm.startVM(new_sdvm)
7.1219 + new_ip = self.vmm.waitStartup(new_sdvm)
7.1220 + drive = self.vmm.genNetworkDrive()
7.1221 + if new_ip != None:
7.1222 + self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\Download', None, None)
7.1223 + result = checkResult(Cygwin.sshExecuteX11('/usr/bin/iceweasel', new_ip, 'osecuser', Cygwin.cygPath(self.vmm.getMachineFolder()) + '/' + new_sdvm + '/dvm_key'))
7.1224 + except:
7.1225 + logger.error("BrowsingHandler failed. Cleaning up")
7.1226 +
7.1227 + self.vmm.unmapNetworkDrive(drive)
7.1228 + self.vmm.poweroffVM(new_sdvm)
7.1229 + self.vmm.removeVM(new_sdvm)
7.1230 +
7.1231 +class DeviceHandler(threading.Thread):
7.1232 + vmm = None
7.1233 + #handleDeviceChangeLock = threading.Lock()
7.1234 + attachedRSDs = None
7.1235 + connectedRSDs = None
7.1236 + running = True
7.1237 + def __init__(self, vmmanger):
7.1238 + threading.Thread.__init__(self)
7.1239 + self.vmm = vmmanger
7.1240 +
7.1241 + def stop(self):
7.1242 + self.running = False
7.1243 +
7.1244 + def run(self):
7.1245 + self.connectedRSDs = dict()
7.1246 + self.attachedRSDs = self.vmm.getAttachedRSDs()
7.1247 + while self.running:
7.1248 + tmp_rsds = self.vmm.getConnectedRSDS()
7.1249 + if tmp_rsds.keys() == self.connectedRSDs.keys():
7.1250 + logger.debug("Nothing's changed. sleep(3)")
7.1251 + time.sleep(3)
7.1252 + continue
7.1253 +
7.1254 + logger.info("Something's changed")
7.1255 + self.connectedRSDs = tmp_rsds
7.1256 + self.attachedRSDs = self.vmm.getAttachedRSDs()
7.1257 +
7.1258 + for vm_name in self.attachedRSDs.keys():
7.1259 + if self.attachedRSDs[vm_name] not in self.connectedRSDs.values():
7.1260 + drive = self.vmm.getNetworkDrive(vm_name)
7.1261 + self.vmm.unmapNetworkDrive(drive)
7.1262 + #self.stopVM(vm_name)
7.1263 + self.vmm.detachRSD(vm_name)
7.1264 + self.vmm.poweroffVM(vm_name)
7.1265 + self.vmm.removeVM(vm_name)
7.1266 + #create new vm for attached device if any
7.1267 + self.attachedRSDs = self.vmm.getAttachedRSDs()
7.1268 + self.connectedRSDs = self.vmm.getConnectedRSDS()
7.1269 +
7.1270 + new_ip = None
7.1271 + for connected_device in self.connectedRSDs.values():
7.1272 + if (self.attachedRSDs and False) or (connected_device not in self.attachedRSDs.values()):
7.1273 + new_sdvm = self.vmm.generateSDVMName()
7.1274 + self.vmm.createVM(new_sdvm)
7.1275 + self.vmm.storageAttach(new_sdvm)
7.1276 + self.vmm.attachRSD(new_sdvm, connected_device)
7.1277 + self.vmm.startVM(new_sdvm)
7.1278 + new_ip = self.vmm.waitStartup(new_sdvm)
7.1279 + drive = self.vmm.genNetworkDrive()
7.1280 + if new_ip != None:
7.1281 + self.vmm.mapNetworkDrive(drive, '\\\\' + new_ip + '\\USB', None, None)
7.1282 +
7.1283 +if __name__ == '__main__':
7.1284 + #man = VMManager.getInstance()
7.1285 + #man.listVM()
7.1286 + #print man.getConnectedRSDs()
7.1287 + #print man.getNetworkDrives()
7.1288 + #man.genNetworkDrive()
7.1289 + #drive_bitmask = ctypes.cdll.kernel32.GetLogicalDrives()
7.1290 + #print list(itertools.compress(string.ascii_uppercase, map(lambda x:ord(x) - ord('0'), bin(drive_bitmask)[:1:-1])))
7.1291 + #print list(map(chr, range(68, 91)))
7.1292 + #print Cygwin.getRegEntry('SYSTEM\CurrentControlSet\Enum\USB', 'VID_1058&PID_0704')[0]
7.1293 + #devices = VMManager.getConnectedRSDS()
7.1294 + #print devices
7.1295 +
7.1296 + drives = VMManager.getLogicalDrives()
7.1297 + print drives
7.1298 + print VMManager.getDriveType("E")
7.1299 + print VMManager.getVolumeInfo("E")
7.1300 + #for device in devices.values():
7.1301 + # #print device
7.1302 + # if VMManager.isMassStorageDevice(device):
7.1303 + # print device
7.1304 +
7.1305 +
7.1306 +
7.1307 + #time.sleep(-1)
7.1308 + #man.listVM()
7.1309 + #man.listVM()
7.1310 + #man.listVM()
7.1311 + #man.listVM()
7.1312 + #man.genCertificateISO('SecurityDVM0')
7.1313 + #man.guestExecute('SecurityDVM0', '/bin/ls -la')
7.1314 + #logger = setupLogger('VMManager')
7.1315 + #c = Cygwin()
7.1316 +
7.1317 + #man.sshExecute('/bin/ls -la', 'SecurityDVM0')
7.1318 + #man.sshExecuteX11('/usr/bin/iceweasel', 'SecurityDVM0')
7.1319 + #man.removeVM('SecurityDVM0')
7.1320 + #man.netUse('192.168.56.134', 'USB\\')
7.1321 + #ip = '192.168.56.139'
7.1322 +
7.1323 + #man.cygwin_path = 'c:\\cygwin64\\bin\\'
7.1324 + #man.handleDeviceChange()
7.1325 + #print man.listSDVM()
7.1326 + #man.configureHostNetworking()
7.1327 + #new_vm = man.generateSDVMName()
7.1328 + #man.createVM(new_vm)
7.1329 +
7.1330 + #print Cygwin.cmd()
7.1331 + #man.isAvailable('c:')
7.1332 + #ip = man.getHostOnlyIP('SecurityDVM0')
7.1333 + #man.mapNetworkDrive('h:', '\\\\' + ip + '\Download', None, None)
7.1334 +
7.1335 + #man.genCertificateISO(new_vm)
7.1336 + #man.attachCertificateISO(new_vm)
7.1337 +
7.1338 + #man.attachCertificateISO(vm_name)
7.1339 + #man.guestExecute(vm_name, "ls")
7.1340 + #man.sshGuestX11Execute('SecurityDVM1', '/usr/bin/iceweasel')
7.1341 + #time.sleep(60)
7.1342 + #print man.cygwinPath("C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\.ssh\*")
7.1343 + #man.genCertificateISO('SecurityDVM')
7.1344 + #man.attachCertificateISO('SecurityDVM')
7.1345 + #man.isStorageAttached('SecurityDVM')
7.1346 + #man.guestExecute('SecurityDVM', 'sudo apt-get -y update')
7.1347 + #man.guestExecute('SecurityDVM', 'sudo apt-get -y upgrade' )
7.1348 +
7.1349 + #man.stopVM('SecurityDVM')
7.1350 + #man.storageDetach('SecurityDVM')
7.1351 + #man.changeStorageType('C:\Users\BarthaM\VirtualBox VMs\SecurityDVM\SecurityDVM.vmdk','immutable')
7.1352 + #man.storageAttach('SecurityDVM')
7.1353 +
7.1354 +
7.1355 + #cmd = "c:\\cygwin64\\bin\\bash.exe --login -c \"/bin/ls\""
7.1356 + #man.execute(cmd)