This commit is contained in:
citronneur
2014-07-29 22:55:00 +02:00
parent be1eb94920
commit aa5473c35c
3 changed files with 105 additions and 29 deletions

View File

@@ -17,7 +17,6 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from twisted.mail.pop3client import ERR
"""
RDP proxy recorder and spy function
@@ -124,7 +123,6 @@ class ProxyServer(rdp.RDPServerObserver):
ip, port = self._credentialProvider.getProxyPass(domain, username)
except error.InvalidExpectedDataException as e:
log.info(e.message)
#self._controller.close()
return
width, height = self._controller.getScreen()
@@ -278,12 +276,12 @@ class ProxyServerFactory(rdp.ServerFactory):
"""
Factory on listening events
"""
def __init__(self, credentialProvider):
def __init__(self, credentialProvider, privateKeyFilePath, certificateFilePath):
"""
@param config: rdp-proxy configuration
@param credentialProvider: CredentialProvider
"""
rdp.ServerFactory.__init__(self, "/home/speyrefitte/dev/certificate/rdpy.key", "/home/speyrefitte/dev/certificate/rdpy.crt", 16)
rdp.ServerFactory.__init__(self, privateKeyFilePath, certificateFilePath, 16)
self._credentialProvider = credentialProvider
def buildObserver(self, controller):
@@ -370,7 +368,8 @@ class ProxyAdmin(IProxyClient):
"""
width, height = self._server._controller.getScreen()
self._window = view.WindowView(width, height, QtGui.QColor(24, 93, 123))
self._window.addView(view.AnchorView(width / 2 - 250, height / 2 - 250, 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._render = view.RDPRenderer(self._server._controller)
def close(self):
@@ -405,6 +404,7 @@ class ProxyAdmin(IProxyClient):
#escape button refresh GUI
self._spyProxy._controller.removeClientObserver(self._spyProxy)
self._state = ProxyAdmin.State.GUI
self._list._labels = ProxyClient._CONNECTED_.keys()
self._server.clientConnected(self)
def sendKeyEventUnicode(self, code, isPressed):
@@ -433,7 +433,7 @@ class ProxyAdmin(IProxyClient):
@param bottom: bottom position
"""
if self._state == ProxyAdmin.State.GUI:
self._window.update(self._render)
self._window.update(self._render, True)
elif self._state == ProxyAdmin.State.SPY:
self._spyProxy.sendRefreshOrder(left, top, right, bottom)
@@ -487,7 +487,7 @@ def help():
"""
Print help in console
"""
print "Usage: rdpy-rdpproxy -f config_file_path listen_port"
print "Usage: rdpy-rdpproxy -f credential_file_path -k private_key_file_path -c certificate_file_path listen_port"
def loadConfig(configFilePath):
"""
@@ -506,8 +506,11 @@ def loadConfig(configFilePath):
if __name__ == '__main__':
configFilePath = None
privateKeyFilePath = None
certificateFilePath = None
try:
opts, args = getopt.getopt(sys.argv[1:], "hf:")
opts, args = getopt.getopt(sys.argv[1:], "hf:k:c:")
except getopt.GetoptError:
help()
for opt, arg in opts:
@@ -516,11 +519,25 @@ if __name__ == '__main__':
sys.exit()
elif opt == "-f":
configFilePath = arg
elif opt == "-k":
privateKeyFilePath = arg
elif opt == "-c":
certificateFilePath = arg
if configFilePath is None:
print "Config file is mandatory"
help()
sys.exit()
if certificateFilePath is None:
print "Certificate file is mandatory"
help()
sys.exit()
if privateKeyFilePath is None:
print "Private key file is mandatory"
help()
sys.exit()
#load config file
config = loadConfig(configFilePath)
@@ -531,5 +548,5 @@ if __name__ == '__main__':
#use to init font
app = QtGui.QApplication(sys.argv)
reactor.listenTCP(int(args[0]), ProxyServerFactory(CredentialProvider(config)))
reactor.listenTCP(int(args[0]), ProxyServerFactory(CredentialProvider(config), privateKeyFilePath, certificateFilePath))
reactor.run()

View File

@@ -245,6 +245,13 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
"""
#do something maybe a loader
pass
def onClose(self):
"""
Call when stack is ready
"""
#do something maybe a loader
pass
class QRemoteDesktop(QtGui.QWidget):

View File

@@ -20,44 +20,88 @@
"""
Fake widget
"""
from rdpy.base.error import CallPureVirtualFuntion, InvalidExpectedDataException
from rdpy.base.error import CallPureVirtualFuntion
from PyQt4 import QtGui, QtCore
class KeyCode(object):
"""
Interesting Scan code
"""
ENTER = 28
UP = 328
DOWN = 336
UP = 72
DOWN = 80
class IRender(object):
"""
Render Interface
"""
def translate(self, dx, dy):
pass
"""
Translate next render
@param dx: delta x
@param dy: delta y
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "translate", "IRender"))
def drawImage(self, image):
pass
"""
Draw QImage
@param image: QImage
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "drawImage", "IRender"))
def getImageFormat(self):
pass
"""
@return: Image format use for render
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getImageFormat", "IRender"))
class IView(object):
"""
View interface
"""
def keyEvent(self, code):
pass
"""
Key event notification
@param code: scan code
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "keyEvent", "IView"))
def pointerEvent(self, x, y, button):
pass
def update(self, render):
pass
"""
Pointer event notification
@param x: x position
@param y: y position
@param button: button pressed
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "pointerEvent", "IView"))
def update(self, render, force = False):
"""
Update view
@param render: IRender
@param force: force update
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "update", "IView"))
class AnchorView(IView):
def __init__(self, x, y, view):
self._x = x
self._y = y
self._view = view
def keyEvent(self, code):
self._view.keyEvent(code)
def pointerEvent(self, x, y, button):
self._view.pointerEvent(x - self._x, y - self._y)
def update(self, render):
def update(self, render, force = False):
render.translate(self._x, self._y)
self._view.update(render)
render.translate(- self._x, - self._y)
self._view.update(render, force)
render.translate(-self._x, -self._y)
class ListView(IView):
"""
@@ -72,6 +116,7 @@ class ListView(IView):
self._fontSize = 14
self._current = 0
self._callback = callback
self._needUpdate = False
def keyEvent(self, code):
#enter key
@@ -81,26 +126,32 @@ class ListView(IView):
self._callback(self._labels[self._current])
elif code == KeyCode.DOWN:
self._current = min(len(self._labels) - 1, self._current + 1)
self._needUpdate = True
elif code == KeyCode.UP:
self._current = max(0, self._current - 1)
self._needUpdate = True
def pointerEvent(self, x, y, button):
pass
def update(self, render):
def update(self, render, force = False):
"""
Draw GUI that list active session
"""
if not force and not self._needUpdate:
return
self._needUpdate = False
i = 0
drawArea = QtGui.QImage(self._width, self._height, render.getImageFormat())
#fill with background Color
drawArea.fill(self._backgroudColor)
with QtGui.QPainter(drawArea) as qp:
for label in self._labels:
rect = QtCore.QRect(0, i * self._cellHeight, self._width, self._cellHeight)
rect = QtCore.QRect(0, i * self._cellHeight, self._width - 2, self._cellHeight)
if i == self._current:
qp.setPen(QtCore.Qt.darkGreen)
qp.drawRoundedRect(rect, 0.2, 0.2)
qp.drawRoundedRect(rect, 5.0, 5.0)
qp.setPen(QtCore.Qt.white)
qp.setFont(QtGui.QFont('arial', self._fontSize, QtGui.QFont.Bold))
qp.drawText(rect, QtCore.Qt.AlignCenter, label)
@@ -122,13 +173,14 @@ class WindowView(IView):
def pointerEvent(self, x, y, button):
if self._focusIndex < len(self._views):
self._views[self._focusIndex].pointerEvent(x, y, button)
def update(self, render):
def update(self, render, force = False):
drawArea = QtGui.QImage(self._width, self._height, render.getImageFormat())
#fill with background Color
drawArea.fill(self._backgroundColor)
render.drawImage(drawArea)
if force:
drawArea.fill(self._backgroundColor)
render.drawImage(drawArea)
for view in self._views:
view.update(render)
view.update(render, force)
class RDPRenderer(object):
def __init__(self, server):