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