OpenSecurity/bin/cygwin.py
author Oliver Maurhart <oliver.maurhart@ait.ac.at>
Tue, 13 May 2014 10:24:57 +0200
changeset 145 758031cf192a
parent 143 36948a118f71
child 152 028c3055147f
permissions -rwxr-xr-x
tray icon mailing done
oliver@91
     1
#!/bin/env python
oliver@91
     2
# -*- coding: utf-8 -*-
oliver@91
     3
oliver@91
     4
# ------------------------------------------------------------
oliver@91
     5
# cygwin command
oliver@91
     6
# 
oliver@91
     7
# executes a cygwin command inside the opensecurity project
oliver@91
     8
#
oliver@91
     9
# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
oliver@91
    10
#        Oliver Maurhart, <oliver.maurhart@ait.ac.at>
oliver@91
    11
#
oliver@91
    12
# Copyright (C) 2013 AIT Austrian Institute of Technology
oliver@91
    13
# AIT Austrian Institute of Technology GmbH
oliver@91
    14
# Donau-City-Strasse 1 | 1220 Vienna | Austria
oliver@91
    15
# http://www.ait.ac.at
oliver@91
    16
#
oliver@91
    17
# This program is free software; you can redistribute it and/or
oliver@91
    18
# modify it under the terms of the GNU General Public License
oliver@91
    19
# as published by the Free Software Foundation version 2.
oliver@91
    20
# 
oliver@91
    21
# This program is distributed in the hope that it will be useful,
oliver@91
    22
# but WITHOUT ANY WARRANTY; without even the implied warranty of
oliver@91
    23
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
oliver@91
    24
# GNU General Public License for more details.
oliver@91
    25
# 
oliver@91
    26
# You should have received a copy of the GNU General Public License
oliver@91
    27
# along with this program; if not, write to the Free Software
oliver@91
    28
# Foundation, Inc., 51 Franklin Street, Fifth Floor, 
oliver@91
    29
# Boston, MA  02110-1301, USA.
oliver@91
    30
# ------------------------------------------------------------
oliver@91
    31
oliver@91
    32
oliver@91
    33
# ------------------------------------------------------------
oliver@91
    34
# imports
oliver@91
    35
oliver@91
    36
import os
oliver@91
    37
import subprocess
oliver@91
    38
import sys
oliver@91
    39
import _winreg
oliver@91
    40
from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
oliver@91
    41
import threading
oliver@145
    42
oliver@91
    43
# local
oliver@91
    44
from environment import Environment
oliver@91
    45
from opensecurity_util import logger, setupLogger, OpenSecurityException
mb@110
    46
import time
oliver@145
    47
oliver@145
    48
oliver@91
    49
# ------------------------------------------------------------
oliver@91
    50
# code
oliver@91
    51
oliver@91
    52
def once(theClass):
oliver@91
    53
    """get the path to our local cygwin installment"""
oliver@91
    54
    home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
oliver@91
    55
    path_hint = [ 
oliver@91
    56
        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin')), 
oliver@91
    57
        os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin64')), 
oliver@91
    58
        os.path.abspath(os.path.join(home_drive, 'cygwin')),
oliver@91
    59
        os.path.abspath(os.path.join(home_drive, 'cygwin64'))
oliver@91
    60
    ]
oliver@91
    61
    path_valid = [ p for p in path_hint if os.path.exists(p) ]
oliver@91
    62
        
oliver@91
    63
    theClass.cygwin_root = path_valid[0]
oliver@91
    64
    theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
oliver@91
    65
    theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
oliver@91
    66
    theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
BarthaM@143
    67
    theClass.cygwin_scp = os.path.join(theClass.cygwin_bin, 'scp.exe')
oliver@91
    68
    theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
oliver@91
    69
    theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe") 
oliver@91
    70
    """get the path to the VirtualBox installation on this system"""
oliver@91
    71
    theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]  
oliver@91
    72
    theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
BarthaM@143
    73
    #theClass.user_home = os.path.expanduser("~")
BarthaM@143
    74
    theClass.user_home = os.environ['APPDATA']#os.path.expandvars("%APPDATA%")
oliver@91
    75
    return theClass
oliver@91
    76
mb@110
    77
class XRunner(threading.Thread): 
mb@110
    78
    #running = True
mb@110
    79
    def __init__(self): 
mb@110
    80
        threading.Thread.__init__(self)
mb@110
    81
 
mb@110
    82
    def stop(self):
mb@110
    83
        self.running = False
mb@110
    84
        
mb@110
    85
    def run(self):
mb@110
    86
        #while self.running:
mb@110
    87
        logger.info('X starting')
mb@110
    88
        if not Cygwin.is_X11_running():
mb@110
    89
            #os.system('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize')
mb@110
    90
            sts = call('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize', shell=True)
mb@110
    91
        else:
mb@110
    92
            logger.info('X already started')
mb@110
    93
                
mb@110
    94
            
mb@110
    95
            
oliver@91
    96
@once
oliver@91
    97
class Cygwin(object):
oliver@91
    98
    cygwin_root = ''
oliver@91
    99
    cygwin_bin = ''
oliver@91
   100
    cygwin_bash = ''
oliver@91
   101
    cygwin_ssh = ''
oliver@91
   102
    cygwin_x11 = ''
BarthaM@143
   103
    cygwin_scp = ''
oliver@91
   104
    vbox_root = ''
oliver@91
   105
    vbox_man = ''
oliver@91
   106
    win_cmd = ''
BarthaM@143
   107
    user_home = ''
oliver@91
   108
    """Some nifty methods working with Cygwin"""
oliver@91
   109
    
oliver@91
   110
    def __call__(self, command, arguments, wait_return=True, window = False):
oliver@91
   111
        """make an instance of this object act as a function"""
oliver@91
   112
        return self.execute(command, arguments, wait_return, window)
oliver@91
   113
oliver@91
   114
    @staticmethod
oliver@91
   115
    def getRegEntry(key, value):
oliver@91
   116
        try:
oliver@91
   117
            k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
oliver@91
   118
            value = _winreg.QueryValueEx(k, value)
oliver@91
   119
            _winreg.CloseKey(k)
oliver@91
   120
            return value
oliver@91
   121
        except:
oliver@91
   122
            pass
oliver@91
   123
    
oliver@91
   124
            
oliver@91
   125
    @staticmethod
oliver@91
   126
    def root():
oliver@91
   127
        return Cygwin.cygwin_root
oliver@91
   128
oliver@91
   129
    @staticmethod
oliver@91
   130
    def bin():
oliver@91
   131
        return Cygwin.cygwin_bin
oliver@91
   132
    
oliver@91
   133
    @staticmethod
oliver@91
   134
    def bash():
oliver@91
   135
        return Cygwin.cygwin_bash
oliver@91
   136
    
oliver@91
   137
    @staticmethod    
oliver@91
   138
    def ssh():
oliver@91
   139
        return Cygwin.cygwin_ssh
BarthaM@143
   140
    
BarthaM@143
   141
    @staticmethod    
BarthaM@143
   142
    def scp():
BarthaM@143
   143
        return Cygwin.cygwin_scp
oliver@91
   144
oliver@91
   145
    @staticmethod    
oliver@91
   146
    def x11():
oliver@91
   147
        return Cygwin.cygwin_x11
oliver@91
   148
    
oliver@91
   149
    @staticmethod
oliver@91
   150
    def vboxman():
oliver@91
   151
        return Cygwin.vbox_man
oliver@91
   152
    
oliver@91
   153
    @staticmethod
oliver@91
   154
    def cmd():
oliver@91
   155
        return Cygwin.win_cmd
oliver@91
   156
    
BarthaM@143
   157
    @staticmethod
BarthaM@143
   158
    def home():
BarthaM@143
   159
        return Cygwin.user_home
BarthaM@143
   160
    
oliver@91
   161
    executeLock = threading.Lock()
oliver@91
   162
    #executes command on host system
oliver@91
   163
    @staticmethod
oliver@91
   164
    def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
oliver@91
   165
        _startupinfo = STARTUPINFO()
oliver@91
   166
        if not window:
oliver@91
   167
            _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
oliver@91
   168
            _startupinfo.wShowWindow = _subprocess.SW_HIDE
oliver@91
   169
oliver@91
   170
            #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
oliver@91
   171
        res_stderr = None
oliver@91
   172
        try:
oliver@91
   173
            # quote the executable otherwise we run into troubles
oliver@91
   174
            # when the path contains spaces and additonal arguments
oliver@91
   175
            # are presented as well.
oliver@91
   176
            # special: invoking bash as login shell here with
oliver@91
   177
            # an unquoted command does not execute /etc/profile
oliver@91
   178
            args = '"' + program + '" ' + arguments
oliver@91
   179
            process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
oliver@91
   180
            logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
oliver@91
   181
            if not wait_return:
oliver@91
   182
                return [0, 'working in background', '']
oliver@91
   183
            result = process.wait()
oliver@91
   184
            res_stdout = process.stdout.read();
oliver@91
   185
            res_stderr = process.stderr.read();
oliver@91
   186
oliver@91
   187
        except Exception as ex:
oliver@91
   188
            res_stderr = ''.join(str(ex.args))
oliver@91
   189
            result = 1 
oliver@91
   190
            
oliver@91
   191
        return result, res_stdout, res_stderr
oliver@91
   192
    
oliver@91
   193
    @staticmethod
oliver@91
   194
    def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
oliver@91
   195
        retry = 0
oliver@91
   196
        result = None
oliver@91
   197
        while retry < 3:
oliver@91
   198
            if Cygwin.executeLock.acquire(True):
oliver@91
   199
                result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
oliver@91
   200
                Cygwin.executeLock.release()
oliver@91
   201
                if result[0] == 0:
oliver@91
   202
                    return result
oliver@91
   203
                retry+=1
oliver@91
   204
        return result
oliver@91
   205
oliver@91
   206
oliver@91
   207
    @staticmethod
oliver@91
   208
    def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
oliver@91
   209
        # for some reason, the '-l' is ignored when started via python
oliver@91
   210
        # so the same behavior is triggered by calling /etc/profile 
oliver@91
   211
        # directly
oliver@91
   212
        command = bash_opts + ' -l -c "'  + command + '"'
oliver@91
   213
        return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
oliver@91
   214
    
oliver@91
   215
    @staticmethod
BarthaM@135
   216
    def cmdExecute(command, wait_return=True, window = False):
oliver@91
   217
        command = ' /c ' + command 
oliver@91
   218
        return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
oliver@91
   219
oliver@91
   220
    # executes command over ssh on guest vm
oliver@91
   221
    @staticmethod
oliver@91
   222
    def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
BarthaM@135
   223
        command = ' -v -o StrictHostKeyChecking=no -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command        
BarthaM@143
   224
        return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
oliver@91
   225
    
oliver@91
   226
    #machineFolder + '/' + vm_name + '/dvm_key
oliver@91
   227
    #address = self.getHostOnlyIP(vm_name)
oliver@91
   228
    #machineFolder = self.getDefaultMachineFolder()
oliver@91
   229
    #machineFolder = Cygwin.cygwinPath(machineFolder)
oliver@91
   230
    
oliver@91
   231
    # executes command over ssh on guest vm with X forwarding
oliver@91
   232
    @staticmethod
oliver@91
   233
    def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
mb@110
   234
        #return call('"'+ Cygwin.cygwin_bash +'" -l -c "' + 'DISPLAY=:0.0 ssh -Y -i \\\"' + certificate +'\\\" ' + user_name + '@' + address + ' ' + command + '"', shell=True)
BarthaM@135
   235
        return Cygwin.bashExecute('DISPLAY=:0.0 ssh -Y -o StrictHostKeyChecking=no -i \\\"' + certificate +'\\\" ' + user_name + '@' + address + ' ' + command + '')
oliver@91
   236
oliver@91
   237
    @staticmethod
oliver@91
   238
    def is_X11_running():
oliver@91
   239
        """check if we can connect to a X11 running instance"""
mb@110
   240
        p = Cygwin.bashExecute('xset -display :0.0 q', wait_return = True, window = False) 
oliver@91
   241
        return p[0] == 0
oliver@91
   242
        
oliver@91
   243
    @staticmethod
oliver@91
   244
    def start_X11():
oliver@91
   245
        """start X11 in the background (if not already running) on DISPLAY=:0"""
mb@110
   246
        runner = XRunner()
mb@110
   247
        runner.start()
mb@110
   248
        return (0, None, None)
mb@110
   249
mb@110
   250
        # launch X11
mb@110
   251
        #return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = True, window = False)
mb@110
   252
        #return Cygwin.bashExecute('XWin :0 -multiwindow', wait_return = True, window = False)
mb@110
   253
        #return Cygwin.bashExecute('DISPLAY=:0.0 xhost +', wait_return = True, window = False)
mb@110
   254
        #return os.system('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize')
oliver@91
   255
    
oliver@91
   256
    @staticmethod    
oliver@91
   257
    def cygPath(path):
oliver@91
   258
        cmd = 'cygpath -u \'' + path + '\''
oliver@91
   259
        return Cygwin.bashExecute(cmd)[1].rstrip('\n')
mb@110
   260
                
oliver@91
   261
# start
BarthaM@143
   262
import os
BarthaM@143
   263
import win32api
BarthaM@143
   264
import win32con
BarthaM@143
   265
import win32security
BarthaM@143
   266
oliver@91
   267
if __name__ == "__main__":
oliver@91
   268
    logger = setupLogger('Cygwin')
oliver@91
   269
    c = Cygwin()
BarthaM@143
   270
    #logger.info(c.root())
BarthaM@143
   271
    #logger.info(c.bin())
BarthaM@143
   272
    #logger.info(c.bash())
BarthaM@143
   273
    #logger.info(c.ssh())
BarthaM@143
   274
    #logger.info(c.x11())
BarthaM@143
   275
    #logger.info(c.home())   
oliver@91
   276
    
BarthaM@143
   277
    #PSEXEC -i -s -d CMD
BarthaM@143
   278
    #tasklist /v /fo list /fi "IMAGENAME eq explorer.exe"
mb@110
   279
    
BarthaM@143
   280
    #runner = XRunner()
BarthaM@143
   281
    #runner.start()
BarthaM@143
   282
    
BarthaM@143
   283
    #Cygwin.start_X11()
mb@110
   284
    
mb@110
   285
    
mb@110
   286
            
mb@110
   287
    #time.sleep(500)
mb@110
   288
    
mb@110
   289
    #Cygwin.start_X11()
mb@110
   290
    #print (Cygwin.is_X11_running())
mb@110
   291
    #print (Cygwin.is_X11_running())
mb@110
   292
    #new_sdvm = 'SecurityDVM0'
mb@110
   293
    #new_ip = Cygwin.vboxExecute('guestproperty get ' + new_sdvm + ' /VirtualBox/GuestInfo/Net/0/V4/IP')[1]
mb@110
   294
    #new_ip = new_ip[new_ip.index(':')+1:].strip()
mb@110
   295
    #new_ip = '+'
mb@110
   296
    #result = Cygwin.bashExecute('DISPLAY=:0.0 xhost '+new_ip)
mb@110
   297
    #browser = '/usr/bin/midori '
mb@110
   298
    #print(Cygwin.sshExecuteX11(browser, new_ip, 'osecuser', '/cygdrive/c/Users/BarthaM/VirtualBox VMs' + '/' + new_sdvm + '/dvm_key'))
mb@110
   299
            
mb@110
   300
    #print(Cygwin.bashExecute('echo $PATH')[1])
mb@110
   301
    #print(Cygwin.cygPath('C:'))
mb@110
   302
    #print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))
mb@110
   303
    
mb@110
   304
    sys.exit(0)
BarthaM@135
   305