2 # -*- coding: utf-8 -*-
4 # ------------------------------------------------------------
7 # executes a cygwin command inside the opensecurity project
9 # Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
10 # Oliver Maurhart, <oliver.maurhart@ait.ac.at>
12 # Copyright (C) 2013 AIT Austrian Institute of Technology
13 # AIT Austrian Institute of Technology GmbH
14 # Donau-City-Strasse 1 | 1220 Vienna | Austria
15 # http://www.ait.ac.at
17 # This program is free software; you can redistribute it and/or
18 # modify it under the terms of the GNU General Public License
19 # as published by the Free Software Foundation version 2.
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 # Boston, MA 02110-1301, USA.
30 # ------------------------------------------------------------
33 # ------------------------------------------------------------
40 from subprocess import Popen, PIPE, call, STARTUPINFO, _subprocess
44 from environment import Environment
45 from opensecurity_util import logger, setupLogger, OpenSecurityException
49 # ------------------------------------------------------------
53 """get the path to our local cygwin installment"""
54 home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
56 os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin')),
57 os.path.abspath(os.path.join(Environment('OpenSecurity').prefix_path, 'cygwin64')),
58 os.path.abspath(os.path.join(home_drive, 'cygwin')),
59 os.path.abspath(os.path.join(home_drive, 'cygwin64'))
61 path_valid = [ p for p in path_hint if os.path.exists(p) ]
63 theClass.cygwin_root = path_valid[0]
64 theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
65 theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
66 theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
67 theClass.cygwin_scp = os.path.join(theClass.cygwin_bin, 'scp.exe')
68 theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
69 theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe")
70 """get the path to the VirtualBox installation on this system"""
71 theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]
72 theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
73 #theClass.user_home = os.path.expanduser("~")
74 theClass.user_home = os.environ['APPDATA']#os.path.expandvars("%APPDATA%")
77 class XRunner(threading.Thread):
80 threading.Thread.__init__(self)
87 logger.info('X starting')
88 if not Cygwin.is_X11_running():
89 #os.system('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize')
90 sts = call('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize', shell=True)
92 logger.info('X already started')
108 """Some nifty methods working with Cygwin"""
110 def __call__(self, command, arguments, wait_return=True, window = False):
111 """make an instance of this object act as a function"""
112 return self.execute(command, arguments, wait_return, window)
115 def getRegEntry(key, value):
117 k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
118 value = _winreg.QueryValueEx(k, value)
127 return Cygwin.cygwin_root
131 return Cygwin.cygwin_bin
135 return Cygwin.cygwin_bash
139 return Cygwin.cygwin_ssh
143 return Cygwin.cygwin_scp
147 return Cygwin.cygwin_x11
151 return Cygwin.vbox_man
155 return Cygwin.win_cmd
159 return Cygwin.user_home
161 executeLock = threading.Lock()
162 #executes command on host system
164 def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
165 _startupinfo = STARTUPINFO()
167 _startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
168 _startupinfo.wShowWindow = _subprocess.SW_HIDE
170 #logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
173 # quote the executable otherwise we run into troubles
174 # when the path contains spaces and additonal arguments
175 # are presented as well.
176 # special: invoking bash as login shell here with
177 # an unquoted command does not execute /etc/profile
178 args = '"' + program + '" ' + arguments
179 process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
180 logger.debug('Launched: ' + program + ' ' + ''.join(arguments))
182 return [0, 'working in background', '']
183 result = process.wait()
184 res_stdout = process.stdout.read();
185 res_stderr = process.stderr.read();
187 except Exception as ex:
188 res_stderr = ''.join(str(ex.args))
191 return result, res_stdout, res_stderr
194 def vboxExecute(command, wait_return=True, window = False, bash_opts=''):
198 if Cygwin.executeLock.acquire(True):
199 result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
200 Cygwin.executeLock.release()
208 def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
209 # for some reason, the '-l' is ignored when started via python
210 # so the same behavior is triggered by calling /etc/profile
212 command = bash_opts + ' -l -c "' + command + '"'
213 return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
216 def cmdExecute(command, wait_return=True, window = False):
217 command = ' /c ' + command
218 return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
220 # executes command over ssh on guest vm
222 def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
223 command = ' -v -o StrictHostKeyChecking=no -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command
224 return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
226 #machineFolder + '/' + vm_name + '/dvm_key
227 #address = self.getHostOnlyIP(vm_name)
228 #machineFolder = self.getDefaultMachineFolder()
229 #machineFolder = Cygwin.cygwinPath(machineFolder)
231 # executes command over ssh on guest vm with X forwarding
233 def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
234 #return call('"'+ Cygwin.cygwin_bash +'" -l -c "' + 'DISPLAY=:0.0 ssh -Y -i \\\"' + certificate +'\\\" ' + user_name + '@' + address + ' ' + command + '"', shell=True)
235 return Cygwin.bashExecute('DISPLAY=:0.0 ssh -Y -o StrictHostKeyChecking=no -i \\\"' + certificate +'\\\" ' + user_name + '@' + address + ' ' + command + '')
238 def is_X11_running():
239 """check if we can connect to a X11 running instance"""
240 p = Cygwin.bashExecute('xset -display :0.0 q', wait_return = True, window = False)
245 """start X11 in the background (if not already running) on DISPLAY=:0"""
248 return (0, None, None)
251 #return Cygwin.execute(Cygwin.cygwin_x11, ':0 -multiwindow', wait_return = True, window = False)
252 #return Cygwin.bashExecute('XWin :0 -multiwindow', wait_return = True, window = False)
253 #return Cygwin.bashExecute('DISPLAY=:0.0 xhost +', wait_return = True, window = False)
254 #return os.system('"'+Cygwin.cygwin_x11+'" :0 -multiwindow -resize')
258 cmd = 'cygpath -u \'' + path + '\''
259 return Cygwin.bashExecute(cmd)[1].rstrip('\n')
267 if __name__ == "__main__":
268 logger = setupLogger('Cygwin')
270 #logger.info(c.root())
271 #logger.info(c.bin())
272 #logger.info(c.bash())
273 #logger.info(c.ssh())
274 #logger.info(c.x11())
275 #logger.info(c.home())
278 #tasklist /v /fo list /fi "IMAGENAME eq explorer.exe"
290 #print (Cygwin.is_X11_running())
291 #print (Cygwin.is_X11_running())
292 #new_sdvm = 'SecurityDVM0'
293 #new_ip = Cygwin.vboxExecute('guestproperty get ' + new_sdvm + ' /VirtualBox/GuestInfo/Net/0/V4/IP')[1]
294 #new_ip = new_ip[new_ip.index(':')+1:].strip()
296 #result = Cygwin.bashExecute('DISPLAY=:0.0 xhost '+new_ip)
297 #browser = '/usr/bin/midori '
298 #print(Cygwin.sshExecuteX11(browser, new_ip, 'osecuser', '/cygdrive/c/Users/BarthaM/VirtualBox VMs' + '/' + new_sdvm + '/dvm_key'))
300 #print(Cygwin.bashExecute('echo $PATH')[1])
301 #print(Cygwin.cygPath('C:'))
302 #print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))