oliver@167
|
1 |
#!/bin/env python
|
oliver@167
|
2 |
# -*- coding: utf-8 -*-
|
oliver@167
|
3 |
|
oliver@167
|
4 |
# ------------------------------------------------------------
|
oliver@167
|
5 |
# cygwin command
|
oliver@167
|
6 |
#
|
oliver@167
|
7 |
# executes a cygwin command inside the opensecurity project
|
oliver@167
|
8 |
#
|
oliver@167
|
9 |
# Autor: Mihai Bartha, <mihai.bartha@ait.ac.at>
|
oliver@167
|
10 |
# Oliver Maurhart, <oliver.maurhart@ait.ac.at>
|
oliver@167
|
11 |
#
|
oliver@240
|
12 |
# Copyright 2013-2014 X-Net and AIT Austrian Institute of Technology
|
oliver@167
|
13 |
#
|
oliver@167
|
14 |
#
|
oliver@240
|
15 |
# X-Net Services GmbH
|
oliver@240
|
16 |
# Elisabethstrasse 1
|
oliver@240
|
17 |
# 4020 Linz
|
oliver@240
|
18 |
# AUSTRIA
|
oliver@240
|
19 |
# https://www.x-net.at
|
oliver@240
|
20 |
#
|
oliver@240
|
21 |
# AIT Austrian Institute of Technology
|
oliver@240
|
22 |
# Donau City Strasse 1
|
oliver@240
|
23 |
# 1220 Wien
|
oliver@240
|
24 |
# AUSTRIA
|
oliver@240
|
25 |
# http://www.ait.ac.at
|
oliver@240
|
26 |
#
|
oliver@240
|
27 |
#
|
oliver@240
|
28 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
oliver@240
|
29 |
# you may not use this file except in compliance with the License.
|
oliver@240
|
30 |
# You may obtain a copy of the License at
|
oliver@240
|
31 |
#
|
oliver@240
|
32 |
# http://www.apache.org/licenses/LICENSE-2.0
|
oliver@240
|
33 |
#
|
oliver@240
|
34 |
# Unless required by applicable law or agreed to in writing, software
|
oliver@240
|
35 |
# distributed under the License is distributed on an "AS IS" BASIS,
|
oliver@240
|
36 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
oliver@240
|
37 |
# See the License for the specific language governing permissions and
|
oliver@240
|
38 |
# limitations under the License.
|
oliver@167
|
39 |
# ------------------------------------------------------------
|
oliver@167
|
40 |
|
oliver@167
|
41 |
|
oliver@167
|
42 |
# ------------------------------------------------------------
|
oliver@167
|
43 |
# imports
|
oliver@167
|
44 |
|
oliver@167
|
45 |
import os
|
oliver@167
|
46 |
import subprocess
|
oliver@167
|
47 |
import sys
|
oliver@167
|
48 |
import _winreg
|
oliver@167
|
49 |
from subprocess import Popen, PIPE, STARTUPINFO, _subprocess
|
oliver@167
|
50 |
import threading
|
oliver@167
|
51 |
|
oliver@167
|
52 |
# local
|
oliver@167
|
53 |
from environment import Environment
|
oliver@167
|
54 |
from opensecurity_util import logger, setupLogger, OpenSecurityException
|
oliver@167
|
55 |
import time
|
oliver@167
|
56 |
|
oliver@167
|
57 |
|
oliver@167
|
58 |
# ------------------------------------------------------------
|
oliver@167
|
59 |
# code
|
oliver@167
|
60 |
|
oliver@167
|
61 |
def once(theClass):
|
oliver@167
|
62 |
"""get the path to our local cygwin installment"""
|
oliver@167
|
63 |
home_drive = os.path.expandvars("%HOMEDRIVE%") + os.sep
|
BarthaM@212
|
64 |
e = Environment('OpenSecurity')
|
oliver@167
|
65 |
path_hint = [
|
BarthaM@212
|
66 |
os.path.abspath(os.path.join(e.prefix_path, 'cygwin')),
|
BarthaM@212
|
67 |
os.path.abspath(os.path.join(e.prefix_path, 'cygwin64')),
|
oliver@167
|
68 |
os.path.abspath(os.path.join(home_drive, 'cygwin')),
|
oliver@167
|
69 |
os.path.abspath(os.path.join(home_drive, 'cygwin64'))
|
oliver@167
|
70 |
]
|
oliver@167
|
71 |
path_valid = [ p for p in path_hint if os.path.exists(p) ]
|
oliver@167
|
72 |
theClass.cygwin_root = path_valid[0]
|
oliver@167
|
73 |
theClass.cygwin_bin = os.path.join(theClass.cygwin_root, 'bin') + os.path.sep
|
oliver@167
|
74 |
theClass.cygwin_bash = os.path.join(theClass.cygwin_bin, 'bash.exe')
|
oliver@167
|
75 |
theClass.cygwin_ssh = os.path.join(theClass.cygwin_bin, 'ssh.exe')
|
oliver@167
|
76 |
theClass.cygwin_scp = os.path.join(theClass.cygwin_bin, 'scp.exe')
|
mihai@252
|
77 |
theClass.cygwin_rsync = os.path.join(theClass.cygwin_bin, 'rsync.exe')
|
oliver@167
|
78 |
theClass.cygwin_x11 = os.path.join(theClass.cygwin_bin, 'XWin.exe')
|
oliver@167
|
79 |
theClass.win_cmd = os.environ.get("COMSPEC", "cmd.exe")
|
oliver@167
|
80 |
"""get the path to the VirtualBox installation on this system"""
|
oliver@167
|
81 |
theClass.vbox_root = theClass.getRegEntry('SOFTWARE\Oracle\VirtualBox', 'InstallDir')[0]
|
oliver@167
|
82 |
theClass.vbox_man = os.path.join(theClass.vbox_root, 'VBoxManage.exe')
|
oliver@167
|
83 |
#theClass.user_home = os.path.expanduser("~")
|
oliver@167
|
84 |
theClass.user_home = os.environ['APPDATA']#os.path.expandvars("%APPDATA%")
|
BarthaM@219
|
85 |
theClass.allow_exec = True
|
oliver@167
|
86 |
return theClass
|
oliver@167
|
87 |
|
oliver@167
|
88 |
|
oliver@167
|
89 |
@once
|
oliver@167
|
90 |
class Cygwin(object):
|
oliver@167
|
91 |
cygwin_root = ''
|
oliver@167
|
92 |
cygwin_bin = ''
|
oliver@167
|
93 |
cygwin_bash = ''
|
oliver@167
|
94 |
cygwin_ssh = ''
|
oliver@167
|
95 |
cygwin_x11 = ''
|
oliver@167
|
96 |
cygwin_scp = ''
|
mihai@252
|
97 |
cygwin_rsync = ''
|
oliver@167
|
98 |
vbox_root = ''
|
oliver@167
|
99 |
vbox_man = ''
|
oliver@167
|
100 |
win_cmd = ''
|
oliver@167
|
101 |
user_home = ''
|
BarthaM@219
|
102 |
allow_exec = True
|
oliver@167
|
103 |
"""Some nifty methods working with Cygwin"""
|
oliver@167
|
104 |
|
oliver@167
|
105 |
def __call__(self, command, arguments, wait_return=True, window = False):
|
oliver@167
|
106 |
"""make an instance of this object act as a function"""
|
oliver@167
|
107 |
return self.execute(command, arguments, wait_return, window)
|
oliver@167
|
108 |
|
oliver@167
|
109 |
@staticmethod
|
oliver@167
|
110 |
def getRegEntry(key, value):
|
oliver@167
|
111 |
try:
|
oliver@167
|
112 |
k = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
|
oliver@167
|
113 |
value = _winreg.QueryValueEx(k, value)
|
oliver@167
|
114 |
_winreg.CloseKey(k)
|
oliver@167
|
115 |
return value
|
oliver@167
|
116 |
except:
|
oliver@167
|
117 |
pass
|
oliver@167
|
118 |
|
oliver@167
|
119 |
|
oliver@167
|
120 |
@staticmethod
|
oliver@167
|
121 |
def root():
|
oliver@167
|
122 |
return Cygwin.cygwin_root
|
oliver@167
|
123 |
|
oliver@167
|
124 |
@staticmethod
|
oliver@167
|
125 |
def bin():
|
oliver@167
|
126 |
return Cygwin.cygwin_bin
|
oliver@167
|
127 |
|
oliver@167
|
128 |
@staticmethod
|
oliver@167
|
129 |
def bash():
|
oliver@167
|
130 |
return Cygwin.cygwin_bash
|
oliver@167
|
131 |
|
oliver@167
|
132 |
@staticmethod
|
oliver@167
|
133 |
def ssh():
|
oliver@167
|
134 |
return Cygwin.cygwin_ssh
|
oliver@167
|
135 |
|
oliver@167
|
136 |
@staticmethod
|
oliver@167
|
137 |
def scp():
|
oliver@167
|
138 |
return Cygwin.cygwin_scp
|
mihai@252
|
139 |
|
mihai@252
|
140 |
@staticmethod
|
mihai@252
|
141 |
def rsync():
|
mihai@252
|
142 |
return Cygwin.cygwin_rsync
|
oliver@167
|
143 |
|
oliver@167
|
144 |
@staticmethod
|
oliver@167
|
145 |
def x11():
|
oliver@167
|
146 |
return Cygwin.cygwin_x11
|
oliver@167
|
147 |
|
oliver@167
|
148 |
@staticmethod
|
oliver@167
|
149 |
def vboxman():
|
oliver@167
|
150 |
return Cygwin.vbox_man
|
oliver@167
|
151 |
|
oliver@167
|
152 |
@staticmethod
|
oliver@167
|
153 |
def cmd():
|
oliver@167
|
154 |
return Cygwin.win_cmd
|
oliver@167
|
155 |
|
oliver@167
|
156 |
@staticmethod
|
oliver@167
|
157 |
def home():
|
oliver@167
|
158 |
return Cygwin.user_home
|
oliver@167
|
159 |
|
BarthaM@219
|
160 |
@staticmethod
|
BarthaM@219
|
161 |
def allowExec():
|
BarthaM@219
|
162 |
Cygwin.allow_exec = True
|
BarthaM@219
|
163 |
|
BarthaM@219
|
164 |
@staticmethod
|
BarthaM@219
|
165 |
def denyExec():
|
BarthaM@219
|
166 |
Cygwin.allow_exec = False
|
BarthaM@219
|
167 |
|
oliver@167
|
168 |
executeLock = threading.Lock()
|
oliver@167
|
169 |
#executes command on host system
|
oliver@167
|
170 |
@staticmethod
|
oliver@167
|
171 |
def execute(program, arguments, wait_return=True, window = False, stdin = PIPE, stdout = PIPE, stderr = PIPE):
|
BarthaM@219
|
172 |
if not Cygwin.allow_exec:
|
BarthaM@219
|
173 |
logger.error('Execution cancelled by system (shutting down).')
|
BarthaM@219
|
174 |
raise OpenSecurityException('Execution cancelled by system (shutting down).')
|
BarthaM@219
|
175 |
|
oliver@167
|
176 |
_startupinfo = STARTUPINFO()
|
oliver@167
|
177 |
if not window:
|
oliver@167
|
178 |
_startupinfo.dwFlags |= _subprocess.STARTF_USESHOWWINDOW
|
oliver@167
|
179 |
_startupinfo.wShowWindow = _subprocess.SW_HIDE
|
oliver@167
|
180 |
#logger.debug('trying to launch: ' + program + ' ' + ''.join(arguments))
|
oliver@167
|
181 |
|
BarthaM@212
|
182 |
result, res_stdout, res_stderr = None, None, None
|
oliver@167
|
183 |
try:
|
oliver@167
|
184 |
# quote the executable otherwise we run into troubles
|
BarthaM@218
|
185 |
# when the path contains spaces and additional arguments
|
oliver@167
|
186 |
# are presented as well.
|
oliver@167
|
187 |
# special: invoking bash as login shell here with
|
oliver@167
|
188 |
# an unquoted command does not execute /etc/profile
|
oliver@167
|
189 |
args = '"' + program + '" ' + arguments
|
oliver@169
|
190 |
logger.debug('Launching: ' + program + ' ' + ''.join(arguments))
|
oliver@167
|
191 |
process = Popen(args, startupinfo = _startupinfo, stdin = stdin, stdout = stdout, stderr = stderr, shell = False)
|
oliver@167
|
192 |
if not wait_return:
|
oliver@167
|
193 |
return [0, 'working in background', '']
|
BarthaM@212
|
194 |
|
oliver@167
|
195 |
res_stdout, res_stderr = process.communicate()
|
oliver@167
|
196 |
result = process.returncode
|
oliver@169
|
197 |
logger.debug('Finished: ' + program + ' ' + ''.join(arguments))
|
oliver@167
|
198 |
|
oliver@167
|
199 |
except Exception as ex:
|
oliver@167
|
200 |
res_stderr = ''.join(str(ex.args))
|
oliver@167
|
201 |
result = 1
|
BarthaM@218
|
202 |
|
BarthaM@218
|
203 |
if result != 0:
|
BarthaM@218
|
204 |
logger.error('Command failed:' + ''.join(res_stderr))
|
BarthaM@218
|
205 |
raise OpenSecurityException('Command failed:' + ''.join(res_stderr))
|
BarthaM@218
|
206 |
|
oliver@167
|
207 |
return result, res_stdout, res_stderr
|
oliver@167
|
208 |
|
oliver@167
|
209 |
@staticmethod
|
BarthaM@212
|
210 |
def vboxExecute(command, wait_return=True, window = False, bash_opts='', try_count = 3):
|
oliver@167
|
211 |
retry = 0
|
oliver@167
|
212 |
result = None
|
BarthaM@212
|
213 |
while retry < try_count:
|
oliver@167
|
214 |
if Cygwin.executeLock.acquire(True):
|
BarthaM@218
|
215 |
try:
|
BarthaM@218
|
216 |
result = Cygwin.execute(Cygwin.vbox_man, command, wait_return, window)
|
BarthaM@218
|
217 |
except Exception as ex:
|
BarthaM@218
|
218 |
Cygwin.executeLock.release()
|
BarthaM@218
|
219 |
if (retry+1) == try_count:
|
BarthaM@218
|
220 |
raise ex
|
BarthaM@218
|
221 |
else:
|
BarthaM@218
|
222 |
Cygwin.executeLock.release()
|
oliver@167
|
223 |
return result
|
BarthaM@218
|
224 |
retry+=1
|
BarthaM@218
|
225 |
raise OpenSecurityException('Command max retry reached: ' + ''.join(command))
|
oliver@167
|
226 |
|
oliver@167
|
227 |
|
oliver@167
|
228 |
@staticmethod
|
oliver@167
|
229 |
def bashExecute(command, wait_return=True, window = False, bash_opts='', stdin = PIPE, stdout = PIPE, stderr = PIPE):
|
oliver@167
|
230 |
# for some reason, the '-l' is ignored when started via python
|
oliver@167
|
231 |
# so the same behavior is triggered by calling /etc/profile
|
oliver@167
|
232 |
# directly
|
oliver@167
|
233 |
command = bash_opts + ' -l -c "' + command + '"'
|
oliver@167
|
234 |
return Cygwin.execute(Cygwin.cygwin_bash, command, wait_return, window, stdin = stdin, stdout = stdout, stderr = stderr)
|
oliver@167
|
235 |
|
oliver@167
|
236 |
@staticmethod
|
oliver@167
|
237 |
def cmdExecute(command, wait_return=True, window = False):
|
oliver@167
|
238 |
command = ' /c ' + command
|
oliver@167
|
239 |
return Cygwin.execute(Cygwin.win_cmd, command, wait_return, window)
|
oliver@167
|
240 |
|
oliver@167
|
241 |
# executes command over ssh on guest vm
|
oliver@167
|
242 |
@staticmethod
|
oliver@167
|
243 |
def sshExecute(command, address, user_name, certificate, wait_return=True, window = False):
|
BarthaM@218
|
244 |
if command == None or address == None or user_name == None or certificate == None:
|
BarthaM@218
|
245 |
raise OpenSecurityException('Invalid parameter value')
|
oliver@167
|
246 |
command = ' -v -o StrictHostKeyChecking=no -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command
|
oliver@167
|
247 |
return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
|
BarthaM@212
|
248 |
|
BarthaM@212
|
249 |
# executes command over ssh on guest vm
|
oliver@167
|
250 |
@staticmethod
|
oliver@167
|
251 |
def sshBackgroundExecute(command, address, user_name, certificate, wait_return=True, window = False):
|
oliver@167
|
252 |
command = ' -f -v -o StrictHostKeyChecking=no -i "' + certificate + '" ' + user_name + '@' + address + ' ' + command
|
oliver@167
|
253 |
return Cygwin.execute(Cygwin.cygwin_ssh, command, wait_return, window)
|
oliver@167
|
254 |
|
oliver@167
|
255 |
#machineFolder + '/' + vm_name + '/dvm_key
|
oliver@167
|
256 |
#address = self.getHostOnlyIP(vm_name)
|
oliver@167
|
257 |
#machineFolder = self.getDefaultMachineFolder()
|
oliver@167
|
258 |
#machineFolder = Cygwin.cygwinPath(machineFolder)
|
oliver@167
|
259 |
|
oliver@167
|
260 |
# executes command over ssh on guest vm with X forwarding
|
oliver@167
|
261 |
@staticmethod
|
oliver@167
|
262 |
def sshExecuteX11(command, address, user_name, certificate, wait_return=True):
|
oliver@167
|
263 |
return Cygwin.bashExecute('DISPLAY=:0.0 ssh -Y -o StrictHostKeyChecking=no -i \\\"' + certificate +'\\\" ' + user_name + '@' + address + ' ' + command + '')
|
oliver@167
|
264 |
|
oliver@167
|
265 |
@staticmethod
|
oliver@167
|
266 |
def is_X11_running():
|
oliver@167
|
267 |
"""check if we can connect to a X11 running instance"""
|
oliver@167
|
268 |
p = Cygwin.bashExecute('xset -display :0 q', wait_return = True, window = False)
|
oliver@167
|
269 |
return p[0] == 0
|
oliver@167
|
270 |
|
oliver@167
|
271 |
@staticmethod
|
oliver@167
|
272 |
def start_X11():
|
oliver@167
|
273 |
"""start X11 in the background (if not already running) on DISPLAY=:0
|
oliver@167
|
274 |
|
oliver@167
|
275 |
If there is already a X11 running then exit silently, calling this
|
oliver@167
|
276 |
method as often as needed.
|
oliver@167
|
277 |
"""
|
oliver@167
|
278 |
Popen('"' + Cygwin.cygwin_x11 + '" :0 -multiwindow -resize -silent-dup-error')
|
oliver@167
|
279 |
return (0, None, None)
|
oliver@167
|
280 |
|
oliver@167
|
281 |
@staticmethod
|
oliver@167
|
282 |
def cygPath(path):
|
oliver@167
|
283 |
cmd = 'cygpath -u \'' + path + '\''
|
oliver@167
|
284 |
return Cygwin.bashExecute(cmd)[1].rstrip('\n')
|
oliver@167
|
285 |
|
oliver@167
|
286 |
# start
|
oliver@167
|
287 |
import os
|
oliver@167
|
288 |
import win32api
|
oliver@167
|
289 |
import win32con
|
oliver@167
|
290 |
import win32security
|
oliver@167
|
291 |
|
oliver@167
|
292 |
if __name__ == "__main__":
|
oliver@167
|
293 |
logger = setupLogger('Cygwin')
|
oliver@167
|
294 |
c = Cygwin()
|
BarthaM@212
|
295 |
logger.info(c.root())
|
BarthaM@212
|
296 |
logger.info(c.bin())
|
BarthaM@212
|
297 |
logger.info(c.bash())
|
BarthaM@212
|
298 |
logger.info(c.ssh())
|
BarthaM@212
|
299 |
logger.info(c.x11())
|
BarthaM@212
|
300 |
logger.info(c.home())
|
oliver@167
|
301 |
|
oliver@167
|
302 |
#PSEXEC -i -s -d CMD
|
oliver@167
|
303 |
#tasklist /v /fo list /fi "IMAGENAME eq explorer.exe"
|
oliver@167
|
304 |
|
oliver@167
|
305 |
#runner = XRunner()
|
oliver@167
|
306 |
#runner.start()
|
oliver@167
|
307 |
|
oliver@167
|
308 |
#Cygwin.start_X11()
|
oliver@167
|
309 |
|
oliver@167
|
310 |
#time.sleep(500)
|
oliver@167
|
311 |
|
oliver@167
|
312 |
#Cygwin.start_X11()
|
oliver@167
|
313 |
#print (Cygwin.is_X11_running())
|
oliver@167
|
314 |
#print (Cygwin.is_X11_running())
|
oliver@167
|
315 |
#new_sdvm = 'SecurityDVM0'
|
oliver@167
|
316 |
#new_ip = Cygwin.vboxExecute('guestproperty get ' + new_sdvm + ' /VirtualBox/GuestInfo/Net/0/V4/IP')[1]
|
oliver@167
|
317 |
#new_ip = new_ip[new_ip.index(':')+1:].strip()
|
oliver@167
|
318 |
#new_ip = '+'
|
oliver@167
|
319 |
#result = Cygwin.bashExecute('DISPLAY=:0.0 xhost '+new_ip)
|
oliver@167
|
320 |
#browser = '/usr/bin/midori '
|
oliver@167
|
321 |
#print(Cygwin.sshExecuteX11(browser, new_ip, 'osecuser', '/cygdrive/c/Users/BarthaM/VirtualBox VMs' + '/' + new_sdvm + '/dvm_key'))
|
oliver@167
|
322 |
|
oliver@167
|
323 |
#print(Cygwin.bashExecute('echo $PATH')[1])
|
oliver@167
|
324 |
#print(Cygwin.cygPath('C:'))
|
oliver@167
|
325 |
#print('C:\\Program Files\\OpenSecurity: ' + c.cygPath('C:\\Program Files\\OpenSecurity'))
|
oliver@167
|
326 |
|
oliver@167
|
327 |
sys.exit(0)
|
oliver@167
|
328 |
|