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