Started client part

This commit is contained in:
Adolfo Gómez García 2015-03-30 08:11:29 +02:00
parent dc006e7cbc
commit c70d94e866
10 changed files with 263 additions and 36 deletions

View File

@ -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]

View 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
View 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
View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

123
client/src/uds/forward.py Normal file
View 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
View 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

View File

@ -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)
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:
transportInfo = transportInstance.getUDSTransportData(userService, transport, ip, self.request.os, self._request.user, password, self._request)
return Client.result(transportInfo)
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)