OpenSecurity/bin/cygwin.py
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Mon, 10 Mar 2014 13:01:08 +0100
changeset 91 a26757850ea9
parent 90 bfd41c38d156
child 96 630b62946c9e
permissions -rwxr-xr-x
download and initial import from within service working
     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 import threading
    42 # local
    43 from environment import Environment
    44 from opensecurity_util import logger, setupLogger, OpenSecurityException
    45 
    46 # ------------------------------------------------------------
    47 # code
    48 
    49 def once(theClass):
    50     """get the path to our local cygwin installment"""
    51     home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
    52     path_hint = [ 
    53         os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin')), 
    54         os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin64')), 
    55         os.path.abspath(os.path.join(home_drive, 'cygwin')),
    56         os.path.abspath(os.path.join(home_drive, 'cygwin64'))
    57     ]
    58     path_valid = [ p for p in path_hint if os.path.exists(p) ]
    59         
    60     theClass.cygwin_root = path_valid[0]
    61     theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
    62     theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
    63     theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
    64     theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
    65     theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
    66     """get the path to the VirtualBox installation on this system"""
    67     theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]  
    68     theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
    69     
    70     return theClass
    71 
    72 @once
    73 class Cygwin(object):
    74     cygwin_root = ''
    75     cygwin_bin = ''
    76     cygwin_bash = ''
    77     cygwin_ssh = ''
    78     cygwin_x11 = ''
    79     vbox_root = ''
    80     vbox_man = ''
    81     win_cmd = ''
    82     """Some nifty methods working with Cygwin"""
    83     
    84     def __call__(self, command, arguments, wait_return=True, window = False):
    85         """make an instance of this object act as a function"""
    86         return self.execute(command, arguments, wait_return, window)
    87 
    88     @staticmethod
    89     def getRegEntry(key, value):
    90         try:
    91             k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
    92             value = _winreg.QueryValueEx(k, value)
    93             _winreg.CloseKey(k)
    94             return value
    95         except:
    96             pass
    97     
    98             
    99     @staticmethod
   100     def root():
   101         return Cygwin.cygwin_root
   102 
   103     @staticmethod
   104     def bin():
   105         return Cygwin.cygwin_bin
   106     
   107     @staticmethod
   108     def bash():
   109         return Cygwin.cygwin_bash
   110     
   111     @staticmethod    
   112     def ssh():
   113         return Cygwin.cygwin_ssh
   114 
   115     @staticmethod    
   116     def x11():
   117         return Cygwin.cygwin_x11
   118     
   119     @staticmethod
   120     def vboxman():
   121         return Cygwin.vbox_man
   122     
   123     @staticmethod
   124     def cmd():
   125         return Cygwin.win_cmd
   126     
   127     executeLock = threading.Lock()
   128     #executes command on host system
   129     @staticmethod
   130     def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
   131         _startupinfo = STARTUPINFO()
   132         if not window:
   133             _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
   134             _startupinfo.wShowWindow = _subprocess.SW_HIDE
   135 
   136             #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
   137         res_stderr = None
   138         try:
   139             # quote the executable otherwise we run into troubles
   140             # when the path contains spaces and additonal arguments
   141             # are presented as well.
   142             # special: invoking bash as login shell here with
   143             # an unquoted command does not execute /etc/profile
   144             args = '"' + program + '" ' + arguments
   145             process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
   146             logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
   147             if not wait_return:
   148                 return [0, 'working in background', '']
   149             result = process.wait()
   150             res_stdout = process.stdout.read();
   151             res_stderr = process.stderr.read();
   152 
   153         except Exception as ex:
   154             res_stderr = ''.join(str(ex.args))
   155             result = 1 
   156             
   157         return result, res_stdout, res_stderr
   158     
   159     @staticmethod
   160     def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
   161         retry = 0
   162         result = None
   163         while retry < 3:
   164             if Cygwin.executeLock.acquire(True):
   165                 result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
   166                 Cygwin.executeLock.release()
   167                 if result[0] == 0:
   168                     return result
   169                 retry+=1
   170         return result
   171 
   172 
   173     @staticmethod
   174     def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
   175         # for some reason, the '-l' is ignored when started via python
   176         # so the same behavior is triggered by calling /etc/profile 
   177         # directly
   178         command = bash_opts + ' -l -c "'  + command + '"'
   179         return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
   180     
   181     @staticmethod
   182     def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
   183         command = ' /c ' + command 
   184         return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
   185 
   186     # executes command over ssh on guest vm
   187     @staticmethod
   188     def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
   189         command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
   190         return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)     
   191     
   192     #machineFolder + '/' + vm_name + '/dvm_key
   193     #address = self.getHostOnlyIP(vm_name)
   194     #machineFolder = self.getDefaultMachineFolder()
   195     #machineFolder = Cygwin.cygwinPath(machineFolder)
   196     
   197     # executes command over ssh on guest vm with X forwarding
   198     @staticmethod
   199     def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
   200         return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
   201 
   202     @staticmethod
   203     def is_X11_running():
   204         """check if we can connect to a X11 running instance"""
   205         p = Cygwin.bashExecute('DISPLAY=:0 /usr/bin/xset -q')
   206         return p[0] == 0
   207         
   208         
   209     @staticmethod
   210     def start_X11():
   211         """start X11 in the background (if not already running) on DISPLAY=:0"""
   212         # do not start if already running
   213         if Cygwin.is_X11_running():
   214             return           
   215         # launch X11 (forget output and return immediately)
   216         return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
   217     
   218     @staticmethod    
   219     def cygPath(path):
   220         cmd = 'cygpath -u \'' + path + '\''
   221         return Cygwin.bashExecute(cmd)[1].rstrip('\n')
   222     
   223 # start
   224 if __name__ == "__main__":
   225     logger = setupLogger('Cygwin')
   226     c = Cygwin()
   227     logger.info(c.root())
   228     logger.info(c.bin())
   229     logger.info(c.bash())
   230     logger.info(c.ssh())
   231     
   232     print(c.bashExecute('echo $PATH')[1])
   233     print(c.cygPath('C:'))
   234     print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))
   235     c.start_X11()
   236