rethink proxy with no credentials
This commit is contained in:
@@ -33,58 +33,6 @@ from rdpy.ui import view
|
|||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
class IProxyClient(object):
|
|
||||||
"""
|
|
||||||
Interface use by Proxy server to interact with client
|
|
||||||
"""
|
|
||||||
def close(self):
|
|
||||||
"""
|
|
||||||
Close proxy client
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getColorDepth", "IProxyClient"))
|
|
||||||
|
|
||||||
def getColorDepth(self):
|
|
||||||
"""
|
|
||||||
Color depth client, Use to re-negociate color depth with server
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getColorDepth", "IProxyClient"))
|
|
||||||
|
|
||||||
def sendKeyEventScancode(self, code, isPressed):
|
|
||||||
"""
|
|
||||||
Key event as scan code
|
|
||||||
@param code: scan code of key
|
|
||||||
@param isPressed: True if key is down
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendKeyEventScancode", "IProxyClient"))
|
|
||||||
|
|
||||||
def sendKeyEventUnicode(self, code, isPressed):
|
|
||||||
"""
|
|
||||||
Key event as unicode
|
|
||||||
@param code: unicode of key
|
|
||||||
@param isPressed: True if key is down
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendKeyEventUnicode", "IProxyClient"))
|
|
||||||
|
|
||||||
def sendPointerEvent(self, x, y, button, isPressed):
|
|
||||||
"""
|
|
||||||
Mouse event
|
|
||||||
@param x: x position
|
|
||||||
@param y: y position
|
|
||||||
@param isPressed: True if button is down
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendPointerEvent", "IProxyClient"))
|
|
||||||
|
|
||||||
def sendRefreshOrder(self, left, top, right, bottom):
|
|
||||||
"""
|
|
||||||
Refresh zone
|
|
||||||
@param left: left postion
|
|
||||||
@param top: top position
|
|
||||||
@param right: right position
|
|
||||||
@param bottom: bottom position
|
|
||||||
"""
|
|
||||||
raise error.CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendRefreshOrder", "IProxyClient"))
|
|
||||||
|
|
||||||
|
|
||||||
class ProxyServer(rdp.RDPServerObserver):
|
class ProxyServer(rdp.RDPServerObserver):
|
||||||
"""
|
"""
|
||||||
Server side of proxy
|
Server side of proxy
|
||||||
@@ -104,21 +52,17 @@ class ProxyServer(rdp.RDPServerObserver):
|
|||||||
@param client: ProxyClient
|
@param client: ProxyClient
|
||||||
"""
|
"""
|
||||||
self._client = client
|
self._client = client
|
||||||
self._controller.setColorDepth(self._client.getColorDepth())
|
self._controller.setColorDepth(self._client._controller.getColorDepth())
|
||||||
|
|
||||||
def onReady(self):
|
def onReady(self):
|
||||||
"""
|
"""
|
||||||
Event use to inform state of server stack
|
Event use to inform state of server stack
|
||||||
Use to connect client
|
Use to connect client
|
||||||
|
On ready is not launch only on connection but after a reactivation process
|
||||||
"""
|
"""
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
#try a connection
|
#try a connection
|
||||||
domain, username, password = self._controller.getCredentials()
|
domain, username, password = self._controller.getCredentials()
|
||||||
|
|
||||||
if self._credentialProvider.isAdmin(domain, username, password):
|
|
||||||
self.clientConnected(ProxyAdmin(self))
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ip, port = self._credentialProvider.getProxyPass(domain, username)
|
ip, port = self._credentialProvider.getProxyPass(domain, username)
|
||||||
except error.InvalidExpectedDataException as e:
|
except error.InvalidExpectedDataException as e:
|
||||||
@@ -130,14 +74,15 @@ class ProxyServer(rdp.RDPServerObserver):
|
|||||||
else:
|
else:
|
||||||
#refresh client
|
#refresh client
|
||||||
width, height = self._controller.getScreen()
|
width, height = self._controller.getScreen()
|
||||||
self._client.sendRefreshOrder(0, 0, width, height)
|
self._client._controller.sendRefreshOrder(0, 0, width, height)
|
||||||
|
|
||||||
def onClose(self):
|
def onClose(self):
|
||||||
"""
|
"""
|
||||||
Call when client close connection
|
Call when client close connection
|
||||||
"""
|
"""
|
||||||
if not self._client is None:
|
if self._client is None:
|
||||||
self._client.close()
|
return
|
||||||
|
self._client._controller.close()
|
||||||
|
|
||||||
def onKeyEventScancode(self, code, isPressed):
|
def onKeyEventScancode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
@@ -148,8 +93,7 @@ class ProxyServer(rdp.RDPServerObserver):
|
|||||||
#no client connected
|
#no client connected
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
return
|
return
|
||||||
|
self._client._controller.sendKeyEventScancode(code, isPressed)
|
||||||
self._client.sendKeyEventScancode(code, isPressed)
|
|
||||||
|
|
||||||
def onKeyEventUnicode(self, code, isPressed):
|
def onKeyEventUnicode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
@@ -160,8 +104,7 @@ class ProxyServer(rdp.RDPServerObserver):
|
|||||||
#no client connected domain
|
#no client connected domain
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
return
|
return
|
||||||
|
self._client._controller.sendKeyEventUnicode(code, isPressed)
|
||||||
self._client.sendKeyEventUnicode(code, isPressed)
|
|
||||||
|
|
||||||
def onPointerEvent(self, x, y, button, isPressed):
|
def onPointerEvent(self, x, y, button, isPressed):
|
||||||
"""
|
"""
|
||||||
@@ -174,10 +117,28 @@ class ProxyServer(rdp.RDPServerObserver):
|
|||||||
#no client connected
|
#no client connected
|
||||||
if self._client is None:
|
if self._client is None:
|
||||||
return
|
return
|
||||||
|
self._client._controller.sendPointerEvent(x, y, button, isPressed)
|
||||||
|
|
||||||
self._client.sendPointerEvent(x, y, button, isPressed)
|
class ProxyServerFactory(rdp.ServerFactory):
|
||||||
|
"""
|
||||||
|
Factory on listening events
|
||||||
|
"""
|
||||||
|
def __init__(self, credentialProvider, privateKeyFilePath, certificateFilePath):
|
||||||
|
"""
|
||||||
|
@param config: rdp-proxy configuration
|
||||||
|
@param credentialProvider: CredentialProvider
|
||||||
|
"""
|
||||||
|
rdp.ServerFactory.__init__(self, privateKeyFilePath, certificateFilePath, 16)
|
||||||
|
self._credentialProvider = credentialProvider
|
||||||
|
|
||||||
|
def buildObserver(self, controller):
|
||||||
|
"""
|
||||||
|
Implement rdp.ServerFactory
|
||||||
|
@param controller: rdp.RDPServerController
|
||||||
|
"""
|
||||||
|
return ProxyServer(controller, self._credentialProvider)
|
||||||
|
|
||||||
class ProxyClient(rdp.RDPClientObserver, IProxyClient):
|
class ProxyClient(rdp.RDPClientObserver):
|
||||||
"""
|
"""
|
||||||
Client side of proxy
|
Client side of proxy
|
||||||
"""
|
"""
|
||||||
@@ -209,12 +170,6 @@ class ProxyClient(rdp.RDPClientObserver, IProxyClient):
|
|||||||
del ProxyClient._CONNECTED_[self._name]
|
del ProxyClient._CONNECTED_[self._name]
|
||||||
self._server._controller.close()
|
self._server._controller.close()
|
||||||
|
|
||||||
def close(self):
|
|
||||||
"""
|
|
||||||
Close proxy client
|
|
||||||
"""
|
|
||||||
self._controller.close()
|
|
||||||
|
|
||||||
def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
||||||
"""
|
"""
|
||||||
Event use to inform bitmap update
|
Event use to inform bitmap update
|
||||||
@@ -230,66 +185,6 @@ class ProxyClient(rdp.RDPClientObserver, IProxyClient):
|
|||||||
@param data: bitmap data
|
@param data: bitmap data
|
||||||
"""
|
"""
|
||||||
self._server._controller.sendUpdate(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data)
|
self._server._controller.sendUpdate(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data)
|
||||||
|
|
||||||
def getColorDepth(self):
|
|
||||||
"""
|
|
||||||
Color depth client, Use to re-negociate color depth with server
|
|
||||||
"""
|
|
||||||
return self._controller.getColorDepth()
|
|
||||||
|
|
||||||
def sendKeyEventScancode(self, code, isPressed):
|
|
||||||
"""
|
|
||||||
Key event as scan code
|
|
||||||
@param code: scan code of key
|
|
||||||
@param isPressed: True if key is down
|
|
||||||
"""
|
|
||||||
self._controller.sendKeyEventScancode(code, isPressed)
|
|
||||||
|
|
||||||
def sendKeyEventUnicode(self, code, isPressed):
|
|
||||||
"""
|
|
||||||
Key event as uni code
|
|
||||||
@param code: uni code of key
|
|
||||||
@param isPressed: True if key is down
|
|
||||||
"""
|
|
||||||
self._controller.sendKeyEventUnicode(code, isPressed)
|
|
||||||
|
|
||||||
def sendPointerEvent(self, x, y, button, isPressed):
|
|
||||||
"""
|
|
||||||
Mouse event
|
|
||||||
@param x: x position
|
|
||||||
@param y: y position
|
|
||||||
@param isPressed: True if button is down
|
|
||||||
"""
|
|
||||||
self._controller.sendPointerEvent(x, y, button, isPressed)
|
|
||||||
|
|
||||||
def sendRefreshOrder(self, left, top, right, bottom):
|
|
||||||
"""
|
|
||||||
Refresh zone
|
|
||||||
@param left: left postion
|
|
||||||
@param top: top position
|
|
||||||
@param right: right position
|
|
||||||
@param bottom: bottom position
|
|
||||||
"""
|
|
||||||
self._controller.sendRefreshOrder(left, top, right, bottom)
|
|
||||||
|
|
||||||
class ProxyServerFactory(rdp.ServerFactory):
|
|
||||||
"""
|
|
||||||
Factory on listening events
|
|
||||||
"""
|
|
||||||
def __init__(self, credentialProvider, privateKeyFilePath, certificateFilePath):
|
|
||||||
"""
|
|
||||||
@param config: rdp-proxy configuration
|
|
||||||
@param credentialProvider: CredentialProvider
|
|
||||||
"""
|
|
||||||
rdp.ServerFactory.__init__(self, privateKeyFilePath, certificateFilePath, 16)
|
|
||||||
self._credentialProvider = credentialProvider
|
|
||||||
|
|
||||||
def buildObserver(self, controller):
|
|
||||||
"""
|
|
||||||
Implement rdp.ServerFactory
|
|
||||||
@param controller: rdp.RDPServerController
|
|
||||||
"""
|
|
||||||
return ProxyServer(controller, self._credentialProvider)
|
|
||||||
|
|
||||||
class ProxyClientFactory(rdp.ClientFactory):
|
class ProxyClientFactory(rdp.ClientFactory):
|
||||||
"""
|
"""
|
||||||
@@ -305,7 +200,7 @@ class ProxyClientFactory(rdp.ClientFactory):
|
|||||||
@param password: password session
|
@param password: password session
|
||||||
@param name: name of session
|
@param name: name of session
|
||||||
"""
|
"""
|
||||||
self._server = server
|
self._controller = server
|
||||||
self._width = width
|
self._width = width
|
||||||
self._height = height
|
self._height = height
|
||||||
self._domain = domain
|
self._domain = domain
|
||||||
@@ -325,7 +220,7 @@ class ProxyClientFactory(rdp.ClientFactory):
|
|||||||
controller.setDomain(self._domain)
|
controller.setDomain(self._domain)
|
||||||
controller.setUsername(self._username)
|
controller.setUsername(self._username)
|
||||||
controller.setPassword(self._password)
|
controller.setPassword(self._password)
|
||||||
proxy = ProxyClient(controller, self._server, self._name)
|
proxy = ProxyClient(controller, self._controller, self._name)
|
||||||
return proxy
|
return proxy
|
||||||
|
|
||||||
def startedConnecting(self, connector):
|
def startedConnecting(self, connector):
|
||||||
@@ -338,12 +233,12 @@ class ProxyClientFactory(rdp.ClientFactory):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProxyAdmin(IProxyClient):
|
class ProxyAdmin(rdp.RDPServerObserver):
|
||||||
"""
|
"""
|
||||||
Use to manage client side of admin session
|
Use to manage client side of admin session
|
||||||
Add GUI to select which session to see
|
Add GUI to select which session to see
|
||||||
And manage see session
|
And manage see session
|
||||||
Just escape key is authorized during see session
|
Just escape key is authorized during spy session
|
||||||
"""
|
"""
|
||||||
class State(object):
|
class State(object):
|
||||||
"""
|
"""
|
||||||
@@ -353,45 +248,47 @@ class ProxyAdmin(IProxyClient):
|
|||||||
GUI = 0
|
GUI = 0
|
||||||
SPY = 1
|
SPY = 1
|
||||||
|
|
||||||
def __init__(self, server):
|
def __init__(self, controller):
|
||||||
"""
|
"""
|
||||||
@param server: rdp.RDPServerController
|
@param server: rdp.RDPServerController
|
||||||
"""
|
"""
|
||||||
self._server = server
|
rdp.RDPServerObserver.__init__(self, controller)
|
||||||
self._spyProxy = None
|
self._controller = controller
|
||||||
self.initView()
|
self._spy = None
|
||||||
self._state = ProxyAdmin.State.GUI
|
self._state = ProxyAdmin.State.GUI
|
||||||
|
|
||||||
def initView(self):
|
def initView(self):
|
||||||
"""
|
"""
|
||||||
Init GUI view
|
Init GUI view
|
||||||
"""
|
"""
|
||||||
width, height = self._server._controller.getScreen()
|
width, height = self._controller.getScreen()
|
||||||
self._window = view.WindowView(width, height, QtGui.QColor(24, 93, 123))
|
self._window = view.WindowView(width, height, QtGui.QColor(24, 93, 123))
|
||||||
self._list = view.ListView(ProxyClient._CONNECTED_.keys(), 500, 500, self.onSelect, QtGui.QColor(24, 93, 123))
|
self._list = view.ListView(ProxyClient._CONNECTED_.keys(), 500, 500, self.onSelect, QtGui.QColor(24, 93, 123))
|
||||||
self._window.addView(view.AnchorView(width / 2 - 250, height / 2 - 250, self._list))
|
self._window.addView(view.AnchorView(width / 2 - 250, height / 2 - 250, self._list))
|
||||||
self._render = view.RDPRenderer(self._server._controller)
|
self._render = view.RDPRenderer(self._controller, self._controller.getColorDepth())
|
||||||
|
|
||||||
def close(self):
|
def onReady(self):
|
||||||
"""
|
"""
|
||||||
Close proxy client
|
Stack is ready and connected
|
||||||
|
May be called after an setColorDepth too
|
||||||
|
"""
|
||||||
|
if self._state == ProxyAdmin.State.GUI:
|
||||||
|
self.initView()
|
||||||
|
self._window.update(self._render, True)
|
||||||
|
elif self._state == ProxyAdmin.State.SPY:
|
||||||
|
#refresh client
|
||||||
|
width, height = self._controller.getScreen()
|
||||||
|
self._spy._controller.sendRefreshOrder(0, 0, width, height)
|
||||||
|
|
||||||
|
def onClose(self):
|
||||||
|
"""
|
||||||
|
Stack is closes
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def getColorDepth(self):
|
def onKeyEventScancode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
Use same Color depth as server init
|
Event call when a keyboard event is catch in scan code format
|
||||||
@return color depth of GUI
|
|
||||||
"""
|
|
||||||
if self._state == ProxyAdmin.State.GUI:
|
|
||||||
return self._server._controller.getColorDepth()
|
|
||||||
elif self._state == ProxyAdmin.State.SPY:
|
|
||||||
return self._spyProxy.getColorDepth()
|
|
||||||
|
|
||||||
def sendKeyEventScancode(self, code, isPressed):
|
|
||||||
"""
|
|
||||||
IProxyClient implement is unauthorized during admin session
|
|
||||||
Only for GUI
|
|
||||||
@param code: scan code of key
|
@param code: scan code of key
|
||||||
@param isPressed: True if key is down
|
@param isPressed: True if key is down
|
||||||
"""
|
"""
|
||||||
@@ -402,40 +299,29 @@ class ProxyAdmin(IProxyClient):
|
|||||||
self._window.update(self._render)
|
self._window.update(self._render)
|
||||||
elif code == 1:
|
elif code == 1:
|
||||||
#escape button refresh GUI
|
#escape button refresh GUI
|
||||||
self._spyProxy._controller.removeClientObserver(self._spyProxy)
|
|
||||||
self._state = ProxyAdmin.State.GUI
|
self._state = ProxyAdmin.State.GUI
|
||||||
self._list._labels = ProxyClient._CONNECTED_.keys()
|
self._spy._controller.removeClientObserver(self._spy)
|
||||||
self._server.clientConnected(self)
|
self.onReady()
|
||||||
|
|
||||||
def sendKeyEventUnicode(self, code, isPressed):
|
def onKeyEventUnicode(self, code, isPressed):
|
||||||
"""
|
"""
|
||||||
Key event as uni code is unauthorized during admin session
|
Event call when a keyboard event is catch in unicode format
|
||||||
@param code: uni code of key
|
In admin mode is forbidden
|
||||||
|
@param code: unicode of key
|
||||||
@param isPressed: True if key is down
|
@param isPressed: True if key is down
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def sendPointerEvent(self, x, y, button, isPressed):
|
def onPointerEvent(self, x, y, button, isPressed):
|
||||||
"""
|
"""
|
||||||
Mouse event is unauthorized during admin session
|
Event call on mouse event
|
||||||
|
In admin mode is forbidden
|
||||||
@param x: x position
|
@param x: x position
|
||||||
@param y: y position
|
@param y: y position
|
||||||
@param isPressed: True if button is down
|
@param button: 1, 2 or 3 button
|
||||||
|
@param isPressed: True if mouse button is pressed
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def sendRefreshOrder(self, left, top, right, bottom):
|
|
||||||
"""
|
|
||||||
Refresh zone
|
|
||||||
@param left: left postion
|
|
||||||
@param top: top position
|
|
||||||
@param right: right position
|
|
||||||
@param bottom: bottom position
|
|
||||||
"""
|
|
||||||
if self._state == ProxyAdmin.State.GUI:
|
|
||||||
self._window.update(self._render, True)
|
|
||||||
elif self._state == ProxyAdmin.State.SPY:
|
|
||||||
self._spyProxy.sendRefreshOrder(left, top, right, bottom)
|
|
||||||
|
|
||||||
def onSelect(self, name):
|
def onSelect(self, name):
|
||||||
"""
|
"""
|
||||||
@@ -444,10 +330,27 @@ class ProxyAdmin(IProxyClient):
|
|||||||
"""
|
"""
|
||||||
if not ProxyClient._CONNECTED_.has_key(name):
|
if not ProxyClient._CONNECTED_.has_key(name):
|
||||||
return
|
return
|
||||||
self._spyProxy = ProxyClient(ProxyClient._CONNECTED_[name]._controller, self._server, "Admin")
|
|
||||||
self._state = ProxyAdmin.State.SPY
|
self._state = ProxyAdmin.State.SPY
|
||||||
#reconnect me
|
self._spy = ProxyClient(ProxyClient._CONNECTED_[name]._controller, self, "Admin")
|
||||||
self._server.clientConnected(self)
|
self._controller.setColorDepth(self._spy._controller.getColorDepth())
|
||||||
|
|
||||||
|
class ProxyAdminFactory(rdp.ServerFactory):
|
||||||
|
"""
|
||||||
|
Factory for admin
|
||||||
|
"""
|
||||||
|
def __init__(self, privateKeyFilePath, certificateFilePath):
|
||||||
|
"""
|
||||||
|
@param privateKeyFilePath: private key for admin session
|
||||||
|
@param certificateFilePath: certificate for admin session
|
||||||
|
"""
|
||||||
|
rdp.ServerFactory.__init__(self, privateKeyFilePath, certificateFilePath, 16)
|
||||||
|
|
||||||
|
def buildObserver(self, controller):
|
||||||
|
"""
|
||||||
|
Implement rdp.ServerFactory
|
||||||
|
@param controller: rdp.RDPServerController
|
||||||
|
"""
|
||||||
|
return ProxyAdmin(controller)
|
||||||
|
|
||||||
class CredentialProvider(object):
|
class CredentialProvider(object):
|
||||||
"""
|
"""
|
||||||
@@ -475,13 +378,6 @@ class CredentialProvider(object):
|
|||||||
if not account.has_key("ip") or not account.has_key("port"):
|
if not account.has_key("ip") or not account.has_key("port"):
|
||||||
raise error.InvalidExpectedDataException("Invalid credentials declaration %s\\%s"%(domain, username))
|
raise error.InvalidExpectedDataException("Invalid credentials declaration %s\\%s"%(domain, username))
|
||||||
return str(account['ip']), account['port']
|
return str(account['ip']), account['port']
|
||||||
|
|
||||||
def isAdmin(self, domain, username, password):
|
|
||||||
"""
|
|
||||||
@return: True if credential match admin credential
|
|
||||||
"""
|
|
||||||
account = self.getAccount(domain, username)
|
|
||||||
return account.has_key("admin") and account["admin"] and account.has_key("password")# and str(account["password"]) == password
|
|
||||||
|
|
||||||
def help():
|
def help():
|
||||||
"""
|
"""
|
||||||
@@ -508,9 +404,10 @@ if __name__ == '__main__':
|
|||||||
configFilePath = None
|
configFilePath = None
|
||||||
privateKeyFilePath = None
|
privateKeyFilePath = None
|
||||||
certificateFilePath = None
|
certificateFilePath = None
|
||||||
|
adminInterface = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], "hf:k:c:")
|
opts, args = getopt.getopt(sys.argv[1:], "hf:k:c:i:")
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError:
|
||||||
help()
|
help()
|
||||||
for opt, arg in opts:
|
for opt, arg in opts:
|
||||||
@@ -523,6 +420,8 @@ if __name__ == '__main__':
|
|||||||
privateKeyFilePath = arg
|
privateKeyFilePath = arg
|
||||||
elif opt == "-c":
|
elif opt == "-c":
|
||||||
certificateFilePath = arg
|
certificateFilePath = arg
|
||||||
|
elif opt == "-i":
|
||||||
|
adminInterface = arg
|
||||||
|
|
||||||
if configFilePath is None:
|
if configFilePath is None:
|
||||||
print "Config file is mandatory"
|
print "Config file is mandatory"
|
||||||
@@ -549,4 +448,12 @@ if __name__ == '__main__':
|
|||||||
app = QtGui.QApplication(sys.argv)
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
|
||||||
reactor.listenTCP(int(args[0]), ProxyServerFactory(CredentialProvider(config), privateKeyFilePath, certificateFilePath))
|
reactor.listenTCP(int(args[0]), ProxyServerFactory(CredentialProvider(config), privateKeyFilePath, certificateFilePath))
|
||||||
|
|
||||||
|
if not adminInterface is None:
|
||||||
|
if ':' in adminInterface:
|
||||||
|
adminInterface, adminPort = adminInterface.split(':')
|
||||||
|
else:
|
||||||
|
adminInterface, adminPort = adminInterface, "3390"
|
||||||
|
log.info("Admin listen on %s:%s"%(adminInterface, adminPort))
|
||||||
|
reactor.listenTCP(int(adminPort), ProxyAdminFactory(privateKeyFilePath, certificateFilePath), interface = adminInterface)
|
||||||
reactor.run()
|
reactor.run()
|
||||||
@@ -226,9 +226,9 @@ class Capability(CompositeType):
|
|||||||
A capability
|
A capability
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240486.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240486.aspx
|
||||||
"""
|
"""
|
||||||
def __init__(self, capabilitySetType = 0, capability = None):
|
def __init__(self, capability = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.capabilitySetType = UInt16Le(capabilitySetType, constant = (not capability is None))
|
self.capabilitySetType = UInt16Le(lambda:capability.__class__._TYPE_)
|
||||||
self.lengthCapability = UInt16Le(lambda:sizeof(self))
|
self.lengthCapability = UInt16Le(lambda:sizeof(self))
|
||||||
|
|
||||||
def CapabilityFactory():
|
def CapabilityFactory():
|
||||||
|
|||||||
@@ -83,29 +83,29 @@ class PDULayer(LayerAutomata):
|
|||||||
self._info = data.RDPInfo(extendedInfoConditional = lambda:(self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_CORE).rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS))
|
self._info = data.RDPInfo(extendedInfoConditional = lambda:(self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_CORE).rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS))
|
||||||
#server capabilities
|
#server capabilities
|
||||||
self._serverCapabilities = {
|
self._serverCapabilities = {
|
||||||
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.CapsType.CAPSTYPE_GENERAL, caps.GeneralCapability()),
|
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.GeneralCapability()),
|
||||||
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.CapsType.CAPSTYPE_BITMAP, caps.BitmapCapability()),
|
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.BitmapCapability()),
|
||||||
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.CapsType.CAPSTYPE_ORDER, caps.OrderCapability()),
|
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.OrderCapability()),
|
||||||
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.CapsType.CAPSTYPE_POINTER, caps.PointerCapability()),
|
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.PointerCapability()),
|
||||||
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.CapsType.CAPSTYPE_INPUT, caps.InputCapability()),
|
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.InputCapability()),
|
||||||
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.CapsType.CAPSTYPE_VIRTUALCHANNEL, caps.VirtualChannelCapability()),
|
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.VirtualChannelCapability()),
|
||||||
caps.CapsType.CAPSTYPE_FONT : caps.Capability(caps.CapsType.CAPSTYPE_FONT, caps.FontCapability()),
|
caps.CapsType.CAPSTYPE_FONT : caps.Capability(caps.FontCapability()),
|
||||||
caps.CapsType.CAPSTYPE_COLORCACHE : caps.Capability(caps.CapsType.CAPSTYPE_COLORCACHE, caps.ColorCacheCapability()),
|
caps.CapsType.CAPSTYPE_COLORCACHE : caps.Capability(caps.ColorCacheCapability()),
|
||||||
caps.CapsType.CAPSTYPE_SHARE : caps.Capability(caps.CapsType.CAPSTYPE_SHARE, caps.ShareCapability())
|
caps.CapsType.CAPSTYPE_SHARE : caps.Capability(caps.ShareCapability())
|
||||||
}
|
}
|
||||||
#client capabilities
|
#client capabilities
|
||||||
self._clientCapabilities = {
|
self._clientCapabilities = {
|
||||||
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.CapsType.CAPSTYPE_GENERAL, caps.GeneralCapability()),
|
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.GeneralCapability()),
|
||||||
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.CapsType.CAPSTYPE_BITMAP, caps.BitmapCapability()),
|
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.BitmapCapability()),
|
||||||
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.CapsType.CAPSTYPE_ORDER, caps.OrderCapability()),
|
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.OrderCapability()),
|
||||||
caps.CapsType.CAPSTYPE_BITMAPCACHE : caps.Capability(caps.CapsType.CAPSTYPE_BITMAPCACHE, caps.BitmapCacheCapability()),
|
caps.CapsType.CAPSTYPE_BITMAPCACHE : caps.Capability(caps.BitmapCacheCapability()),
|
||||||
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.CapsType.CAPSTYPE_POINTER, caps.PointerCapability()),
|
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.PointerCapability()),
|
||||||
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.CapsType.CAPSTYPE_INPUT, caps.InputCapability()),
|
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.InputCapability()),
|
||||||
caps.CapsType.CAPSTYPE_BRUSH : caps.Capability(caps.CapsType.CAPSTYPE_BRUSH, caps.BrushCapability()),
|
caps.CapsType.CAPSTYPE_BRUSH : caps.Capability(caps.BrushCapability()),
|
||||||
caps.CapsType.CAPSTYPE_GLYPHCACHE : caps.Capability(caps.CapsType.CAPSTYPE_GLYPHCACHE, caps.GlyphCapability()),
|
caps.CapsType.CAPSTYPE_GLYPHCACHE : caps.Capability(caps.GlyphCapability()),
|
||||||
caps.CapsType.CAPSTYPE_OFFSCREENCACHE : caps.Capability(caps.CapsType.CAPSTYPE_OFFSCREENCACHE, caps.OffscreenBitmapCacheCapability()),
|
caps.CapsType.CAPSTYPE_OFFSCREENCACHE : caps.Capability(caps.OffscreenBitmapCacheCapability()),
|
||||||
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.CapsType.CAPSTYPE_VIRTUALCHANNEL, caps.VirtualChannelCapability()),
|
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.VirtualChannelCapability()),
|
||||||
caps.CapsType.CAPSTYPE_SOUND : caps.Capability(caps.CapsType.CAPSTYPE_SOUND, caps.SoundCapability())
|
caps.CapsType.CAPSTYPE_SOUND : caps.Capability(caps.SoundCapability())
|
||||||
}
|
}
|
||||||
#share id between client and server
|
#share id between client and server
|
||||||
self._shareId = 0x103EA
|
self._shareId = 0x103EA
|
||||||
|
|||||||
@@ -183,12 +183,13 @@ class WindowView(IView):
|
|||||||
view.update(render, force)
|
view.update(render, force)
|
||||||
|
|
||||||
class RDPRenderer(object):
|
class RDPRenderer(object):
|
||||||
def __init__(self, server):
|
def __init__(self, controller, colorDepth):
|
||||||
"""
|
"""
|
||||||
@param server: RDPServerController
|
@param server: RDPServerController
|
||||||
|
@param colorDepth: color depth
|
||||||
"""
|
"""
|
||||||
self._server = server
|
self._controller = controller
|
||||||
self._colorDepth = self._server.getColorDepth()
|
self._colorDepth = colorDepth
|
||||||
self._dx = 0
|
self._dx = 0
|
||||||
self._dy = 0
|
self._dy = 0
|
||||||
self._renderSize = 64
|
self._renderSize = 64
|
||||||
@@ -220,5 +221,5 @@ class RDPRenderer(object):
|
|||||||
tmp = tmp.transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
|
tmp = tmp.transformed(QtGui.QMatrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0))
|
||||||
ptr = tmp.bits()
|
ptr = tmp.bits()
|
||||||
ptr.setsize(tmp.byteCount())
|
ptr.setsize(tmp.byteCount())
|
||||||
self._server.sendUpdate(i * self._renderSize + self._dx, j * self._renderSize + self._dy, min((i + 1) * self._renderSize, image.width()) + self._dx - 1, min((j + 1) * self._renderSize, image.height()) + self._dy - 1, tmp.width(), tmp.height(), self._colorDepth, False, ptr.asstring())
|
self._controller.sendUpdate(i * self._renderSize + self._dx, j * self._renderSize + self._dy, min((i + 1) * self._renderSize, image.width()) + self._dx - 1, min((j + 1) * self._renderSize, image.height()) + self._dy - 1, tmp.width(), tmp.height(), self._colorDepth, False, ptr.asstring())
|
||||||
|
|
||||||
Reference in New Issue
Block a user