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
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')
oliver@64
    62
    theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
mb@60
    63
    theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
mb@60
    64
    
mb@60
    65
    """get the path to the VirtualBox installation on this system"""
mb@60
    66
    try:
mb@60
    67
        k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\Oracle\VirtualBox')
mb@60
    68
        theClass.vbox_root = _winreg.QueryValueEx(k, 'InstallDir')[0]
mb@60
    69
        theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
mb@60
    70
        _winreg.CloseKey(k)
mb@60
    71
    except:
mb@60
    72
        pass
mb@60
    73
    return theClass
om@13
    74
mb@60
    75
@once
om@13
    76
class Cygwin(object):
mb@60
    77
    cygwin_root = ''
mb@60
    78
    cygwin_bin = ''
mb@60
    79
    cygwin_bash = ''
mb@60
    80
    cygwin_ssh = ''
oliver@64
    81
    cygwin_x11 = ''
mb@60
    82
    vbox_root = ''
mb@60
    83
    vbox_man = ''
mb@60
    84
    win_cmd = ''
om@13
    85
    """Some nifty methods working with Cygwin"""
om@13
    86
    
mb@60
    87
    def __call__(self, command, arguments, wait_return=True, window = False):
om@13
    88
        """make an instance of this object act as a function"""
mb@60
    89
        return self.execute(command, arguments, wait_return, window)
om@13
    90
om@13
    91
        
om@13
    92
    @staticmethod
om@13
    93
    def root():
mb@60
    94
        return Cygwin.cygwin_root
om@13
    95
mb@60
    96
    @staticmethod
mb@60
    97
    def bin():
mb@60
    98
        return Cygwin.cygwin_bin
mb@60
    99
    
mb@60
   100
    @staticmethod
mb@60
   101
    def bash():
mb@60
   102
        return Cygwin.cygwin_bash
mb@60
   103
    
mb@60
   104
    @staticmethod    
mb@60
   105
    def ssh():
mb@60
   106
        return Cygwin.cygwin_ssh
oliver@64
   107
oliver@64
   108
    @staticmethod    
oliver@64
   109
    def x11():
oliver@64
   110
        return Cygwin.cygwin_x11
mb@60
   111
    
mb@60
   112
    @staticmethod
mb@60
   113
    def vboxman():
mb@60
   114
        return Cygwin.vbox_man
mb@60
   115
    
mb@60
   116
    @staticmethod
mb@60
   117
    def cmd():
mb@60
   118
        return Cygwin.win_cmd
mb@60
   119
    
mb@60
   120
    #executes command on host system
mb@60
   121
    @staticmethod
mb@60
   122
    def execute(program, arguments, wait_return=True, window = False):
mb@60
   123
        _startupinfo = STARTUPINFO()
mb@60
   124
        if not window:
mb@60
   125
            _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
mb@60
   126
            _startupinfo.wShowWindow = _subprocess.SW_HIDE
mb@60
   127
            
mb@60
   128
        logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
mb@60
   129
        try:
mb@60
   130
            process = Popen(executable=program, args=' ' + arguments, startupinfo = _startupinfo, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell = False)
mb@60
   131
            logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
mb@60
   132
            if not wait_return:
mb@60
   133
                return [0, 'working in background', '']
mb@60
   134
            result = process.wait()
mb@60
   135
            res_stdout = process.stdout.read();
mb@60
   136
            res_stderr = process.stderr.read();
mb@60
   137
            if res_stdout != "":
mb@60
   138
                logger.debug(res_stdout)
mb@60
   139
            if res_stderr != "":
mb@60
   140
                logger.debug(res_stderr)
mb@60
   141
        except:
mb@60
   142
            logger.error('Failed to execute cygwin command.\n\tcommand=' + program + ' ' + ''.join(arguments) + '\n')
mb@60
   143
            #TODO: throw exception
mb@60
   144
        return result, res_stdout, res_stderr
mb@60
   145
    
mb@60
   146
    @staticmethod
mb@60
   147
    def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
mb@60
   148
        return Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
mb@60
   149
    
mb@60
   150
    @staticmethod
mb@60
   151
    def bashExecute(command, wait_return=True, window = False, bash_opts=''):
oliver@64
   152
        command = bash_opts + ' -l -c '  + command
mb@60
   153
        return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window)
mb@60
   154
    
mb@60
   155
    @staticmethod
mb@60
   156
    def cmdExecute(command, wait_return=True, window = False, bash_opts=''):
mb@60
   157
        command = ' /c ' + command 
mb@60
   158
        return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
om@13
   159
mb@60
   160
    # executes command over ssh on guest vm
mb@60
   161
    @staticmethod
mb@60
   162
    def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
mb@60
   163
        command = ' -v -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
mb@60
   164
        return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)     
mb@60
   165
    
mb@60
   166
    #machineFolder + '/' + vm_name + '/dvm_key
mb@60
   167
    #address = self.getHostOnlyIP(vm_name)
mb@60
   168
    #machineFolder = self.getDefaultMachineFolder()
mb@60
   169
    #machineFolder = Cygwin.cygwinPath(machineFolder)
mb@60
   170
    
mb@60
   171
    # executes command over ssh on guest vm with X forwarding
mb@60
   172
    @staticmethod
mb@60
   173
    def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
mb@60
   174
        return Cygwin.bashExecute('"DISPLAY=:0.0 /usr/bin/ssh -v -Y -i \\"' + certificate +'\\" ' + user_name + '@' + address + ' ' + command + '\"')
dyle@52
   175
om@13
   176
    @staticmethod
om@13
   177
    def is_X11_running():
om@13
   178
        """check if we can connect to a X11 running instance"""
mb@60
   179
        p = Cygwin.bashExecute('"DISPLAY=:0 /usr/bin/xset -q"')
mb@60
   180
        return p[0] == 0
om@13
   181
        
om@13
   182
        
om@13
   183
    @staticmethod
om@13
   184
    def start_X11():
om@13
   185
        """start X11 in the background (if not already running) on DISPLAY=:0"""
om@13
   186
        # do not start if already running
om@13
   187
        if Cygwin.is_X11_running():
mb@60
   188
            return           
om@13
   189
        # launch X11 (forget output and return immediately)
oliver@64
   190
        return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = False, window = False)
mb@60
   191
    
mb@60
   192
    @staticmethod    
mb@60
   193
    def cygPath(path):
mb@60
   194
        cmd = '"/usr/bin/cygpath -u \\"' + path + '\\""'
mb@60
   195
        return Cygwin.bashExecute(cmd)[1].rstrip('\n')
om@13
   196
    
om@13
   197
# start
om@13
   198
if __name__ == "__main__":
mb@60
   199
    logger = setupLogger('Cygwin')
mb@60
   200
    c = Cygwin()
mb@60
   201
    logger.info(c.root())
mb@60
   202
    logger.info(c.bin())
mb@60
   203
    logger.info(c.bash())
mb@60
   204
    logger.info(c.ssh())
mb@60
   205
    
mb@60
   206
    c.cygPath('C:')
mb@60
   207
    c.start_X11()
om@13
   208
mb@60
   209
        
om@13
   210
    
om@13
   211