OpenSecurity/bin/cygwin.py
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Tue, 18 Feb 2014 12:57:28 +0100
changeset 64 f770ea31e5fa
parent 60 eeb778585a4d
child 71 0ca25608ed0f
permissions -rwxr-xr-x
fix to start X11 server directly and not via bash
     1 #!/bin/env python
     2 # -*- coding: utf-8 -*-
     3 
     4 # ------------------------------------------------------------
     5 # cygwin command
     6 # 
     7 # executes a cygwin command inside the opensecurity project
     8 #
     9 # Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
    10 #        Oliver Maurhart, <oliver.maurhart@ait.ac.at>
    11 #
    12 # Copyright (C) 2013 AIT Austrian Institute of Technology
    13 # AIT Austrian Institute of Technology GmbH
    14 # Donau-City-Strasse 1 | 1220 Vienna | Austria
    15 # http://www.ait.ac.at
    16 #
    17 # This program is free software; you can redistribute it and/or
    18 # modify it under the terms of the GNU General Public License
    19 # as published by the Free Software Foundation version 2.
    20 # 
    21 # This program is distributed in the hope that it will be useful,
    22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
    23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    24 # GNU General Public License for more details.
    25 # 
    26 # You should have received a copy of the GNU General Public License
    27 # along with this program; if not, write to the Free Software
    28 # Foundation, Inc., 51 Franklin Street, Fifth Floor, 
    29 # Boston, MA  02110-1301, USA.
    30 # ------------------------------------------------------------
    31 
    32 
    33 # ------------------------------------------------------------
    34 # imports
    35 
    36 import os
    37 import subprocess
    38 import sys
    39 import _winreg
    40 from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
    41 # local
    42 from environment import Environment
    43 from opensecurity_util import logger, setupLogger, OpenSecurityException
    44 # ------------------------------------------------------------
    45 # code
    46 
    47 def once(theClass):
    48     """get the path to our local cygwin installment"""
    49     home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
    50     path_hint = [ 
    51         os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin')), 
    52         os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, '..', 'cygwin64')), 
    53         os.path.abspath(os.path.join(home_drive, 'cygwin')),
    54         os.path.abspath(os.path.join(home_drive, 'cygwin64'))
    55     ]
    56     path_valid = [ p for p in path_hint if os.path.exists(p) ]
    57         
    58     theClass.cygwin_root = path_valid[0]
    59     theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
    60     theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
    61     theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
    62     theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
    63     theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
    64     
    65     """get the path to the VirtualBox installation on this system"""
    66     try:
    67         k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\Oracle\VirtualBox')
    68         theClass.vbox_root = _winreg.QueryValueEx(k, 'InstallDir')[0]
    69         theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
    70         _winreg.CloseKey(k)
    71     except:
    72         pass
    73     return theClass
    74 
    75 @once
    76 class Cygwin(object):
    77     cygwin_root = ''
    78     cygwin_bin = ''
    79     cygwin_bash = ''
    80     cygwin_ssh = ''
    81     cygwin_x11 = ''
    82     vbox_root = ''
    83     vbox_man = ''
    84     win_cmd = ''
    85     """Some nifty methods working with Cygwin"""
    86     
    87     def __call__(self, command, arguments, wait_return=True, window = False):
    88         """make an instance of this object act as a function"""
    89         return self.execute(command, arguments, wait_return, window)
    90 
    91         
    92     @staticmethod
    93     def root():
    94         return Cygwin.cygwin_root
    95 
    96     @staticmethod
    97     def bin():
    98         return Cygwin.cygwin_bin
    99     
   100     @staticmethod
   101     def bash():
   102         return Cygwin.cygwin_bash
   103     
   104     @staticmethod    
   105     def ssh():
   106         return Cygwin.cygwin_ssh
   107 
   108     @staticmethod    
   109     def x11():
   110         return Cygwin.cygwin_x11
   111     
   112     @staticmethod
   113     def vboxman():
   114         return Cygwin.vbox_man
   115     
   116     @staticmethod
   117     def cmd():
   118         return Cygwin.win_cmd
   119     
   120     #executes command on host system
   121     @staticmethod
   122     def execute(program, arguments, wait_return=True, window = False):
   123         _startupinfo = STARTUPINFO()
   124         if not window:
   125             _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
   126             _startupinfo.wShowWindow = _subprocess.SW_HIDE
   127             
   128         logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
   129         try:
   130             process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
   131             logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
   132             if not wait_return:
   133                 return [0, 'working in background', '']
   134             result = process.wait()
   135             res_stdout = process.stdout.read();
   136             res_stderr = process.stderr.read();
   137             if res_stdout != "":
   138                 logger.debug(res_stdout)
   139             if res_stderr != "":
   140                 logger.debug(res_stderr)
   141         except:
   142             logger.error('Failed to execute cygwin command.\n\tcommand=' + program + ' ' + ''.join(arguments) + '\n')
   143             #TODO: throw exception
   144         return result, res_stdout, res_stderr
   145     
   146     @staticmethod
   147     def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
   148         return Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
   149     
   150     @staticmethod
   151     def bashExecute(command, wait_return=True, window = False, bash_opts=''):
   152         command = bash_opts + ' -l -c '  + command
   153         return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window)
   154     
   155     @staticmethod
   156     def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
   157         command = ' /c ' + command 
   158         return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
   159 
   160     # executes command over ssh on guest vm
   161     @staticmethod
   162     def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
   163         command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
   164         return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)     
   165     
   166     #machineFolder + '/' + vm_name + '/dvm_key
   167     #address = self.getHostOnlyIP(vm_name)
   168     #machineFolder = self.getDefaultMachineFolder()
   169     #machineFolder = Cygwin.cygwinPath(machineFolder)
   170     
   171     # executes command over ssh on guest vm with X forwarding
   172     @staticmethod
   173     def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
   174         return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
   175 
   176     @staticmethod
   177     def is_X11_running():
   178         """check if we can connect to a X11 running instance"""
   179         p = Cygwin.bashExecute('"DISPLAY=:0 /usr/bin/xset -q"')
   180         return p[0] == 0
   181         
   182         
   183     @staticmethod
   184     def start_X11():
   185         """start X11 in the background (if not already running) on DISPLAY=:0"""
   186         # do not start if already running
   187         if Cygwin.is_X11_running():
   188             return           
   189         # launch X11 (forget output and return immediately)
   190         return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
   191     
   192     @staticmethod    
   193     def cygPath(path):
   194         cmd = '"/usr/bin/cygpath -u \\"' + path + '\\""'
   195         return Cygwin.bashExecute(cmd)[1].rstrip('\n')
   196     
   197 # start
   198 if __name__ == "__main__":
   199     logger = setupLogger('Cygwin')
   200     c = Cygwin()
   201     logger.info(c.root())
   202     logger.info(c.bin())
   203     logger.info(c.bash())
   204     logger.info(c.ssh())
   205     
   206     c.cygPath('C:')
   207     c.start_X11()
   208 
   209         
   210     
   211