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