forked from shaba/openuds
Started client part
This commit is contained in:
parent
dc006e7cbc
commit
c70d94e866
@ -37,6 +37,7 @@ from PyQt4 import QtCore, QtGui
|
||||
import six
|
||||
|
||||
from uds.rest import RestRequest
|
||||
from uds.forward import forward
|
||||
|
||||
|
||||
def done(data):
|
||||
@ -46,6 +47,10 @@ def done(data):
|
||||
if __name__ == "__main__":
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
|
||||
if six.PY3 is False:
|
||||
import threading
|
||||
threading._DummyThread._Thread__stop = lambda x: 42
|
||||
|
||||
# First parameter must be url
|
||||
try:
|
||||
uri = sys.argv[1]
|
||||
|
6
client/src/UDSResources.qrc
Normal file
6
client/src/UDSResources.qrc
Normal file
@ -0,0 +1,6 @@
|
||||
<RCC>
|
||||
<qresource prefix="images">
|
||||
<file alias="logo-uds-small">images/logo-uds-small.png</file>
|
||||
<file alias="logo-uds-big">images/logo-uds.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
49
client/src/UDSWindow.py
Normal file
49
client/src/UDSWindow.py
Normal file
@ -0,0 +1,49 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'UDSWindow.ui'
|
||||
#
|
||||
# Created: Fri Mar 27 15:03:01 2015
|
||||
# by: PyQt4 UI code generator 4.11.2
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
try:
|
||||
_fromUtf8 = QtCore.QString.fromUtf8
|
||||
except AttributeError:
|
||||
def _fromUtf8(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
except AttributeError:
|
||||
def _translate(context, text, disambig):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
MainWindow.setObjectName(_fromUtf8("MainWindow"))
|
||||
MainWindow.resize(282, 185)
|
||||
self.centralwidget = QtGui.QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
QtCore.QMetaObject.connectSlotsByName(MainWindow)
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtGui.QApplication(sys.argv)
|
||||
MainWindow = QtGui.QMainWindow()
|
||||
ui = Ui_MainWindow()
|
||||
ui.setupUi(MainWindow)
|
||||
MainWindow.show()
|
||||
sys.exit(app.exec_())
|
||||
|
54
client/src/UDSWindow.ui
Normal file
54
client/src/UDSWindow.ui
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>282</width>
|
||||
<height>185</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="UDSResources.qrc">:/images/logo-uds-small</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="UDSResources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
BIN
client/src/images/logo-uds-small.png
Normal file
BIN
client/src/images/logo-uds-small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
client/src/images/logo-uds.png
Normal file
BIN
client/src/images/logo-uds.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
123
client/src/uds/forward.py
Normal file
123
client/src/uds/forward.py
Normal file
@ -0,0 +1,123 @@
|
||||
# Based on forward.py from paramiko
|
||||
# Copyright (C) 2003-2007 Robey Pointer <robeypointer@gmail.com>
|
||||
# https://github.com/paramiko/paramiko/blob/master/demos/forward.py
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import select
|
||||
import SocketServer
|
||||
|
||||
import sys
|
||||
|
||||
import paramiko
|
||||
import threading
|
||||
|
||||
g_verbose = True
|
||||
|
||||
|
||||
class ForwardServer (SocketServer.ThreadingTCPServer):
|
||||
daemon_threads = True
|
||||
allow_reuse_address = True
|
||||
|
||||
|
||||
class Handler (SocketServer.BaseRequestHandler):
|
||||
|
||||
def handle(self):
|
||||
try:
|
||||
chan = self.ssh_transport.open_channel('direct-tcpip',
|
||||
(self.chain_host, self.chain_port),
|
||||
self.request.getpeername())
|
||||
except Exception as e:
|
||||
verbose('Incoming request to %s:%d failed: %s' % (self.chain_host,
|
||||
self.chain_port,
|
||||
repr(e)))
|
||||
return
|
||||
if chan is None:
|
||||
verbose('Incoming request to %s:%d was rejected by the SSH server.' %
|
||||
(self.chain_host, self.chain_port))
|
||||
return
|
||||
|
||||
verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
|
||||
chan.getpeername(), (self.chain_host, self.chain_port)))
|
||||
while self.event.is_set() is False:
|
||||
r, w, x = select.select([self.request, chan], [], [], 1)
|
||||
|
||||
if self.request in r:
|
||||
data = self.request.recv(1024)
|
||||
if len(data) == 0:
|
||||
break
|
||||
chan.send(data)
|
||||
if chan in r:
|
||||
data = chan.recv(1024)
|
||||
if len(data) == 0:
|
||||
break
|
||||
self.request.send(data)
|
||||
|
||||
peername = self.request.getpeername()
|
||||
chan.close()
|
||||
self.request.close()
|
||||
verbose('Tunnel closed from %r' % (peername,))
|
||||
|
||||
|
||||
def verbose(s):
|
||||
if g_verbose:
|
||||
print(s)
|
||||
|
||||
|
||||
class ForwardThread(threading.Thread):
|
||||
def __init__(self, server, port, username, password, localPort, redirectHost, redirectPort):
|
||||
threading.Thread.__init__(self)
|
||||
self.client = None
|
||||
self.fs = None
|
||||
|
||||
self.server = server
|
||||
self.port = int(port)
|
||||
self.username = username
|
||||
self.password = password
|
||||
|
||||
self.localPort = int(localPort)
|
||||
self.redirectHost = redirectHost
|
||||
self.redirectPort = redirectPort
|
||||
|
||||
self.stopEvent = threading.Event()
|
||||
|
||||
def run(self):
|
||||
self.client = paramiko.SSHClient()
|
||||
self.client.load_system_host_keys()
|
||||
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
verbose('Connecting to ssh host %s:%d ...' % (self.server, self.port))
|
||||
|
||||
self.client.connect(self.server, self.port, username=self.username, password=self.password)
|
||||
|
||||
class SubHander (Handler):
|
||||
chain_host = self.redirectHost
|
||||
chain_port = self.redirectPort
|
||||
ssh_transport = self.client.get_transport()
|
||||
event = self.stopEvent
|
||||
|
||||
self.fs = ForwardServer(('', self.redirectPort), SubHander)
|
||||
self.fs.serve_forever()
|
||||
|
||||
def stop(self):
|
||||
try:
|
||||
self.stopEvent.set()
|
||||
self.fs.shutdown()
|
||||
|
||||
if self.client is not None:
|
||||
self.client.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def forward(server, port, username, password, localPort, redirectHost, redirectPort):
|
||||
port, redirectPort = int(port), int(redirectPort)
|
||||
|
||||
|
||||
verbose('Connected')
|
||||
|
||||
ft = ForwardThread(server, port, username, password, localPort, redirectHost, redirectPort)
|
||||
|
||||
ft.start()
|
||||
|
||||
return ft
|
15
client/src/update.sh
Executable file
15
client/src/update.sh
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
function process {
|
||||
for a in *.ui; do
|
||||
pyuic4 $a -o `basename $a .ui`.py -x
|
||||
done
|
||||
}
|
||||
|
||||
pyrcc4 -py3 UDSResources.qrc -o UDSResources_rc.py
|
||||
|
||||
|
||||
# process current directory ui's
|
||||
process
|
||||
|
@ -57,6 +57,7 @@ logger = logging.getLogger(__name__)
|
||||
CLIENT_VERSION = '1.7.0'
|
||||
REQUIRED_CLIENT_VERSION = '1.7.0'
|
||||
|
||||
|
||||
# Enclosed methods under /actor path
|
||||
class Client(Handler):
|
||||
'''
|
||||
@ -106,44 +107,18 @@ class Client(Handler):
|
||||
except Exception:
|
||||
return Client.result(error=errors.ACCESS_DENIED)
|
||||
|
||||
password = cryptoManager().xor(self._args[1], data['password']).decode('utf-8')
|
||||
user = User.objects.get(uuid=data['user'])
|
||||
userService = UserService.objects.get(uuid=data['service'])
|
||||
transport = Transport.objects.get(uuid=data['transport'])
|
||||
self._request.user = User.objects.get(uuid=data['user'])
|
||||
|
||||
try:
|
||||
logger.debug('idService: {}, idTransport: {}, user: {}'.format(data['service'], data['transport'], data['user']))
|
||||
res = getService(self._request, data['service'], data['transport'])
|
||||
if res is not None:
|
||||
ip, userService, userServiceInstance, transport, transportInstance = res
|
||||
password = cryptoManager().xor(self._args[1], data['password']).decode('utf-8')
|
||||
|
||||
if userService.isInMaintenance():
|
||||
return Client.result(error=errors.SERVICE_IN_MAINTENANCE)
|
||||
|
||||
logger.debug('Found service: {0}'.format(userService))
|
||||
|
||||
# Test if the service is ready
|
||||
if userService.isReady():
|
||||
log.doLog(userService, log.INFO, "User {0} from {1} has initiated access".format(user.name, self._request.ip), log.WEB)
|
||||
# If ready, show transport for this service, if also ready ofc
|
||||
userServiceIntance = userService.getInstance()
|
||||
ip = userServiceIntance.getIp()
|
||||
events.addEvent(userService.deployed_service, events.ET_ACCESS, username=user.name, srcip=self._request.ip, dstip=ip, uniqueid=userService.unique_id)
|
||||
if ip is not None:
|
||||
transportInstance = transport.getInstance()
|
||||
if transportInstance.isAvailableFor(ip):
|
||||
userService.setConnectionSource(self._request.ip, 'unknown')
|
||||
log.doLog(userService, log.INFO, "User service ready, rendering transport", log.WEB)
|
||||
UserServiceManager.manager().notifyPreconnect(userService, transportInstance.processedUser(userService, user), transportInstance.protocol)
|
||||
transportInfo = transportInstance.getUDSTransportData(userService, transport, ip, self.request.os, user, password, self._request)
|
||||
transportInfo = transportInstance.getUDSTransportData(userService, transport, ip, self.request.os, self._request.user, password, self._request)
|
||||
return Client.result(transportInfo)
|
||||
else:
|
||||
log.doLog(userService, log.WARN, "User service is not accessible (ip {0})".format(ip), log.TRANSPORT)
|
||||
logger.debug('Transport is not ready for user service {0}'.format(userService))
|
||||
else:
|
||||
logger.debug('Ip not available from user service {0}'.format(userService))
|
||||
else:
|
||||
log.doLog(userService, log.WARN, "User {0} from {1} tried to access, but machine was not ready".format(user.name, self._request.ip), log.WEB)
|
||||
# Not ready, show message and return to this page in a while
|
||||
return Client.result(error=errors.SERVICE_NOT_READY)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception("Exception")
|
||||
return Client.result(error=six.text_type(e))
|
||||
|
||||
raise RequestError('Request error')
|
||||
return Client.result(error=errors.SERVICE_NOT_READY)
|
||||
|
Loading…
Reference in New Issue
Block a user