bug fix + finish proxy
This commit is contained in:
@@ -138,5 +138,4 @@ if __name__ == '__main__':
|
||||
from twisted.internet import reactor
|
||||
reactor.connectTCP(ip, int(port), RDPClientQtFactory(width, height, username, password, domain))
|
||||
reactor.runReturn()
|
||||
app.exec_()
|
||||
reactor.stop()
|
||||
app.exec_()
|
||||
@@ -21,8 +21,6 @@
|
||||
"""
|
||||
RDP proxy recorder and spyer
|
||||
Proxy RDP protocol
|
||||
With admin account you can watch all currently session
|
||||
For special session you can record
|
||||
"""
|
||||
|
||||
import sys, os
|
||||
@@ -43,14 +41,6 @@ class ProxyServer(rdp.RDPServerObserver):
|
||||
rdp.RDPServerObserver.__init__(self, controller)
|
||||
self._client = None
|
||||
|
||||
def onReady(self):
|
||||
"""
|
||||
Event use to inform state of server stack
|
||||
Use to connect client
|
||||
"""
|
||||
width, height = self._controller.getScreen()
|
||||
reactor.connectTCP("wav-glw-013", 3389, ProxyClientFactory(self, width, height))
|
||||
|
||||
def clientConnected(self, client):
|
||||
"""
|
||||
Event throw by client when it's ready
|
||||
@@ -58,6 +48,52 @@ class ProxyServer(rdp.RDPServerObserver):
|
||||
"""
|
||||
self._client = client
|
||||
self._controller.setColorDepth(self._client._controller.getColorDepth())
|
||||
|
||||
def onReady(self):
|
||||
"""
|
||||
Event use to inform state of server stack
|
||||
Use to connect client
|
||||
"""
|
||||
width, height = self._controller.getScreen()
|
||||
reactor.connectTCP("si-hyperv-002", 3389, ProxyClientFactory(self, width, height))
|
||||
|
||||
def onKeyEventScancode(self, code, isPressed):
|
||||
"""
|
||||
Event call when a keyboard event is catch in scan code format
|
||||
@param code: scan code of key
|
||||
@param isPressed: True if key is down
|
||||
"""
|
||||
#no client connected
|
||||
if self._client is None:
|
||||
return
|
||||
|
||||
self._client._controller.sendKeyEventScancode(code, isPressed)
|
||||
|
||||
def onKeyEventUnicode(self, code, isPressed):
|
||||
"""
|
||||
Event call when a keyboard event is catch in unicode format
|
||||
@param code: unicode of key
|
||||
@param isPressed: True if key is down
|
||||
"""
|
||||
#no client connected
|
||||
if self._client is None:
|
||||
return
|
||||
|
||||
self._client._controller.sendKeyEventUnicode(code, isPressed)
|
||||
|
||||
def onPointerEvent(self, x, y, button, isPressed):
|
||||
"""
|
||||
Event call on mouse event
|
||||
@param x: x position
|
||||
@param y: y position
|
||||
@param button: 1, 2 or 3 button
|
||||
@param isPressed: True if mouse button is pressed
|
||||
"""
|
||||
#no client connected
|
||||
if self._client is None:
|
||||
return
|
||||
|
||||
self._client._controller.sendPointerEvent(x, y, button, isPressed)
|
||||
|
||||
class ProxyClient(rdp.RDPClientObserver):
|
||||
"""
|
||||
|
||||
@@ -151,6 +151,12 @@ class RawLayer(protocol.Protocol, LayerAutomata, StreamSender):
|
||||
"""
|
||||
#join two scheme
|
||||
self.connect()
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Close raw layer
|
||||
"""
|
||||
self.transport.loseConnection()
|
||||
|
||||
def expect(self, expectedLen, callback = None):
|
||||
"""
|
||||
|
||||
@@ -240,8 +240,8 @@ class ClientCoreData(CompositeType):
|
||||
self.postBeta2ColorDepth = UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP)
|
||||
self.clientProductId = UInt16Le(1)
|
||||
self.serialNumber = UInt32Le(0)
|
||||
self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_15BPP)
|
||||
self.supportedColorDepths = UInt16Le(Support.RNS_UD_15BPP_SUPPORT)
|
||||
self.highColorDepth = UInt16Le(HighColor.HIGH_COLOR_24BPP)
|
||||
self.supportedColorDepths = UInt16Le(Support.RNS_UD_15BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_32BPP_SUPPORT)
|
||||
self.earlyCapabilityFlags = UInt16Le(CapabilityFlags.RNS_UD_CS_SUPPORT_ERRINFO_PDU)
|
||||
self.clientDigProductId = String("\x00"*64, readLen = UInt8(64))
|
||||
self.connectionType = UInt8()
|
||||
|
||||
@@ -25,7 +25,7 @@ The main channel is the graphical channel.
|
||||
It exist channel for file system order, audio channel, clipboard etc...
|
||||
"""
|
||||
from rdpy.network.layer import LayerAutomata, StreamSender, Layer
|
||||
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Le
|
||||
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Le, String
|
||||
from rdpy.base.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
||||
from rdpy.protocol.rdp.ber import writeLength
|
||||
import rdpy.base.log as log
|
||||
@@ -137,6 +137,14 @@ class MCSLayer(LayerAutomata):
|
||||
#receive opcode
|
||||
self._receiveOpcode = receiveOpcode
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Send disconnect provider ultimatum
|
||||
"""
|
||||
self._transport.send((UInt8(self.writeMCSPDUHeader(DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM, 1)),
|
||||
per.writeEnumerates(0x80), String("\x00" * 6)))
|
||||
self._transport.close()
|
||||
|
||||
def allChannelConnected(self):
|
||||
"""
|
||||
All channels are connected to MCS layer
|
||||
|
||||
@@ -783,8 +783,8 @@ class ClientInputEventPDU(CompositeType):
|
||||
|
||||
class ShutdownRequestPDU(CompositeType):
|
||||
"""
|
||||
PDU use to signal that the session will be closzed are connected
|
||||
server -> client
|
||||
PDU use to signal that the session will be closed
|
||||
client -> server
|
||||
"""
|
||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_REQUEST
|
||||
def __init__(self):
|
||||
@@ -792,7 +792,7 @@ class ShutdownRequestPDU(CompositeType):
|
||||
|
||||
class ShutdownDeniedPDU(CompositeType):
|
||||
"""
|
||||
PDU use to signal that the session will be closzed are connected
|
||||
PDU use to signal which the session will be closed is connected
|
||||
server -> client
|
||||
"""
|
||||
_PDUTYPE2_ = PDUType2.PDUTYPE2_SHUTDOWN_DENIED
|
||||
@@ -842,17 +842,17 @@ class FastPathUpdatePDU(CompositeType):
|
||||
CompositeType.__init__(self)
|
||||
self.updateHeader = UInt8(lambda:updateData.__class__._FASTPATH_UPDATE_TYPE_)
|
||||
self.compressionFlags = UInt8(conditional = lambda:((self.updateHeader.value >> 4) & FastPathOutputCompression.FASTPATH_OUTPUT_COMPRESSION_USED))
|
||||
self.size = UInt16Le()
|
||||
self.size = UInt16Le(lambda:sizeof(self.updateData))
|
||||
|
||||
def UpdateDataFactory():
|
||||
"""
|
||||
Create correct object in accordance to self.updateHeader field
|
||||
"""
|
||||
if (self.updateHeader.value & 0xf) == FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP:
|
||||
return (UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, constant = True), BitmapUpdateDataPDU(readLen = self.size - 2))
|
||||
else:
|
||||
log.debug("unknown Fast Path PDU update data type : %s"%hex(self.updateHeader.value & 0xf))
|
||||
return String()
|
||||
for c in [FastPathBitmapUpdateDataPDU]:
|
||||
if (self.updateHeader.value & 0xf) == c._FASTPATH_UPDATE_TYPE_:
|
||||
return c()
|
||||
log.debug("unknown Fast Path PDU update data type : %s"%hex(self.updateHeader.value & 0xf))
|
||||
return String()
|
||||
|
||||
if updateData is None:
|
||||
updateData = FactoryType(UpdateDataFactory)
|
||||
@@ -867,7 +867,6 @@ class BitmapUpdateDataPDU(CompositeType):
|
||||
@see: http://msdn.microsoft.com/en-us/library/dd306368.aspx
|
||||
"""
|
||||
_UPDATE_TYPE_ = UpdateType.UPDATETYPE_BITMAP
|
||||
_FASTPATH_UPDATE_TYPE_ = FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP
|
||||
|
||||
def __init__(self, readLen = None):
|
||||
"""
|
||||
@@ -946,7 +945,20 @@ class BitmapData(CompositeType):
|
||||
self.bitmapLength = UInt16Le(lambda:(sizeof(self.bitmapComprHdr) + sizeof(self.bitmapDataStream)))
|
||||
self.bitmapComprHdr = BitmapCompressedDataHeader(bodySize = lambda:sizeof(self.bitmapDataStream), scanWidth = lambda:self.width.value, uncompressedSize = lambda:(self.width.value * self.height.value * self.bitsPerPixel.value), conditional = lambda:((self.flags.value | BitmapFlag.BITMAP_COMPRESSION) and not (self.flags.value | BitmapFlag.NO_BITMAP_COMPRESSION_HDR)))
|
||||
self.bitmapDataStream = String(bitmapDataStream, readLen = UInt16Le(lambda:(self.bitmapLength.value if (self.flags.value | BitmapFlag.NO_BITMAP_COMPRESSION_HDR) else self.bitmapComprHdr.cbCompMainBodySize.value)))
|
||||
|
||||
|
||||
class FastPathBitmapUpdateDataPDU(CompositeType):
|
||||
"""
|
||||
Fast path version of bitmap update PDU
|
||||
@see: http://msdn.microsoft.com/en-us/library/dd306368.aspx
|
||||
"""
|
||||
_FASTPATH_UPDATE_TYPE_ = FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP
|
||||
|
||||
def __init__(self):
|
||||
CompositeType.__init__(self)
|
||||
self.header = UInt16Le(FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP, constant = True)
|
||||
self.numberRectangles = UInt16Le(lambda:len(self.rectangles._array))
|
||||
self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles)
|
||||
|
||||
class SlowPathInputEvent(CompositeType):
|
||||
"""
|
||||
PDU use in slow-path sending client inputs
|
||||
|
||||
@@ -64,6 +64,12 @@ class PDUServerListener(object):
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "PDUServerListener"))
|
||||
|
||||
def onSlowPathInput(self, slowPathInputEvents):
|
||||
"""
|
||||
Event call when slow path input are available
|
||||
@param slowPathInputEvents: [data.SlowPathInputEvent]
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onSlowPathInput", "PDUServerListener"))
|
||||
|
||||
class PDULayer(LayerAutomata):
|
||||
"""
|
||||
@@ -128,6 +134,8 @@ class Client(PDULayer, tpkt.FastPathListener):
|
||||
"""
|
||||
PDULayer.__init__(self)
|
||||
self._listener = listener
|
||||
#enable or not fast path
|
||||
self._fastPathSender = None
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@@ -138,12 +146,22 @@ class Client(PDULayer, tpkt.FastPathListener):
|
||||
self.sendInfoPkt()
|
||||
#next state is license info PDU
|
||||
self.setNextState(self.recvLicenceInfo)
|
||||
#check if client support fast path message
|
||||
self._clientFastPathSupported = False
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Send PDU close packet and call close method on transport method
|
||||
"""
|
||||
self.sendDataPDU(data.ShutdownRequestPDU())
|
||||
self._transport.close()
|
||||
#self.sendDataPDU(data.ShutdownRequestPDU())
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: tpkt.FastPathSender
|
||||
@note: implement tpkt.FastPathListener
|
||||
"""
|
||||
self._fastPathSender = fastPathSender
|
||||
|
||||
def recvLicenceInfo(self, s):
|
||||
"""
|
||||
@@ -290,7 +308,7 @@ class Client(PDULayer, tpkt.FastPathListener):
|
||||
fastPathPDU = data.FastPathUpdatePDU()
|
||||
fastPathS.readType(fastPathPDU)
|
||||
if fastPathPDU.updateHeader.value == data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP:
|
||||
self._listener.onUpdate(fastPathPDU.updateData[1].rectangles._array)
|
||||
self._listener.onUpdate(fastPathPDU.updateData.rectangles._array)
|
||||
|
||||
def readDataPDU(self, dataPDU):
|
||||
"""
|
||||
@@ -333,7 +351,9 @@ class Client(PDULayer, tpkt.FastPathListener):
|
||||
generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability
|
||||
generalCapability.osMajorType.value = caps.MajorType.OSMAJORTYPE_WINDOWS
|
||||
generalCapability.osMinorType.value = caps.MinorType.OSMINORTYPE_WINDOWS_NT
|
||||
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR | caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
|
||||
generalCapability.extraFlags.value = caps.GeneralExtraFlag.LONG_CREDENTIALS_SUPPORTED | caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR
|
||||
if not self._fastPathSender is None:
|
||||
generalCapability.extraFlags.value |= caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
|
||||
|
||||
#init bitmap capability
|
||||
bitmapCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_BITMAP].capability
|
||||
@@ -390,7 +410,7 @@ class Client(PDULayer, tpkt.FastPathListener):
|
||||
pdu.slowPathInputEvents._array = [data.SlowPathInputEvent(x) for x in pointerEvents]
|
||||
self.sendDataPDU(pdu)
|
||||
|
||||
class Server(PDULayer):
|
||||
class Server(PDULayer, tpkt.FastPathListener):
|
||||
"""
|
||||
Server Automata of PDU layer
|
||||
"""
|
||||
@@ -400,6 +420,8 @@ class Server(PDULayer):
|
||||
"""
|
||||
PDULayer.__init__(self)
|
||||
self._listener = listener
|
||||
#fast path layer
|
||||
self._fastPathSender = None
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@@ -408,6 +430,13 @@ class Server(PDULayer):
|
||||
"""
|
||||
self.setNextState(self.recvInfoPkt)
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: tpkt.FastPathSender
|
||||
@note: implement tpkt.FastPathListener
|
||||
"""
|
||||
self._fastPathSender = fastPathSender
|
||||
|
||||
def recvInfoPkt(self, s):
|
||||
"""
|
||||
Receive info packet from client
|
||||
@@ -449,6 +478,9 @@ class Server(PDULayer):
|
||||
for cap in pdu.pduMessage.capabilitySets._array:
|
||||
self._clientCapabilities[cap.capabilitySetType] = cap
|
||||
|
||||
#find use full flag
|
||||
self._clientFastPathSupported = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags.value & caps.GeneralExtraFlag.FASTPATH_OUTPUT_SUPPORTED
|
||||
|
||||
self.setNextState(self.recvClientSynchronizePDU)
|
||||
|
||||
def recvClientSynchronizePDU(self, s):
|
||||
@@ -538,6 +570,18 @@ class Server(PDULayer):
|
||||
errorMessage = data.ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
||||
|
||||
log.error("INFO PDU : %s"%errorMessage)
|
||||
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_INPUT:
|
||||
self._listener.onSlowPathInput(dataPDU.pduData.slowPathInputEvents._array)
|
||||
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SHUTDOWN_REQUEST:
|
||||
self._transport.close()
|
||||
|
||||
def recvFastPath(self, fastPathS):
|
||||
"""
|
||||
Implement FastPathListener interface
|
||||
Fast path is needed by RDP 8.0
|
||||
@param fastPathS: Stream that contain fast path data
|
||||
"""
|
||||
pass
|
||||
|
||||
def sendLicensingErrorMessage(self):
|
||||
"""
|
||||
@@ -604,7 +648,16 @@ class Server(PDULayer):
|
||||
#check bitmap header for client that want it (very old client)
|
||||
if self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability.extraFlags.value & caps.GeneralExtraFlag.NO_BITMAP_COMPRESSION_HDR:
|
||||
for bitmapData in bitmapDatas:
|
||||
bitmapData.flags.value |= data.BitmapFlag.NO_BITMAP_COMPRESSION_HDR
|
||||
updateDataPDU = data.BitmapUpdateDataPDU()
|
||||
updateDataPDU.rectangles._array = bitmapDatas
|
||||
self.sendDataPDU(data.UpdateDataPDU(updateDataPDU))
|
||||
if bitmapData.flags.value & data.BitmapFlag.BITMAP_COMPRESSION:
|
||||
bitmapData.flags.value |= data.BitmapFlag.NO_BITMAP_COMPRESSION_HDR
|
||||
|
||||
if self._clientFastPathSupported and not self._fastPathSender is None:
|
||||
#fast path case
|
||||
fastPathUpdateDataPDU = data.FastPathBitmapUpdateDataPDU()
|
||||
fastPathUpdateDataPDU.rectangles._array = bitmapDatas
|
||||
self._fastPathSender.sendFastPath(data.FastPathUpdatePDU(fastPathUpdateDataPDU))
|
||||
else:
|
||||
#slow path case
|
||||
updateDataPDU = data.BitmapUpdateDataPDU()
|
||||
updateDataPDU.rectangles._array = bitmapDatas
|
||||
self.sendDataPDU(data.UpdateDataPDU(updateDataPDU))
|
||||
@@ -60,6 +60,12 @@ class RDPClientController(pdu.layer.PDUClientListener):
|
||||
@return: color depth set by the server (15, 16, 24)
|
||||
"""
|
||||
return self._pduLayer._serverCapabilities[pdu.caps.CapsType.CAPSTYPE_BITMAP].capability.preferredBitsPerPixel.value
|
||||
|
||||
def getKeyEventUniCodeSupport(self):
|
||||
"""
|
||||
@return: True if server support unicode input
|
||||
"""
|
||||
return self._pduLayer._serverCapabilities[pdu.caps.CapsType.CAPSTYPE_INPUT].capability.inputFlags.value & pdu.caps.InputFlags.INPUT_FLAG_UNICODE
|
||||
|
||||
def setPerformanceSession(self):
|
||||
"""
|
||||
@@ -298,6 +304,12 @@ class RDPServerController(pdu.layer.PDUServerListener):
|
||||
#restart connection sequence
|
||||
self._isReady = False
|
||||
self._pduLayer.sendPDU(pdu.data.DeactiveAllPDU())
|
||||
|
||||
def setKeyEventUnicodeSupport(self):
|
||||
"""
|
||||
Enable key event in unicode format
|
||||
"""
|
||||
self._pduLayer._serverCapabilities[pdu.caps.CapsType.CAPSTYPE_INPUT].capability.inputFlags.value |= pdu.caps.InputFlags.INPUT_FLAG_UNICODE
|
||||
|
||||
def onReady(self):
|
||||
"""
|
||||
@@ -309,6 +321,31 @@ class RDPServerController(pdu.layer.PDUServerListener):
|
||||
self._sendReady = True
|
||||
for observer in self._serverObserver:
|
||||
observer.onReady()
|
||||
|
||||
def onSlowPathInput(self, slowPathInputEvents):
|
||||
"""
|
||||
Event call when slow path input are available
|
||||
@param slowPathInputEvents: [data.SlowPathInputEvent]
|
||||
"""
|
||||
for observer in self._serverObserver:
|
||||
for event in slowPathInputEvents:
|
||||
#scan code
|
||||
if event.messageType.value == pdu.data.InputMessageType.INPUT_EVENT_SCANCODE:
|
||||
observer.onKeyEventScancode(event.slowPathInputData.keyCode.value, not (event.slowPathInputData.keyboardFlags.value & pdu.data.KeyboardFlag.KBDFLAGS_RELEASE))
|
||||
#unicode
|
||||
elif event.messageType.value == pdu.data.InputMessageType.INPUT_EVENT_UNICODE:
|
||||
observer.onKeyEventUnicode(event.slowPathInputData.unicode.value, not (event.slowPathInputData.keyboardFlags.value & pdu.data.KeyboardFlag.KBDFLAGS_RELEASE))
|
||||
#mouse event
|
||||
elif event.messageType.value == pdu.data.InputMessageType.INPUT_EVENT_MOUSE:
|
||||
isPressed = event.slowPathInputData.pointerFlags.value & pdu.data.PointerFlag.PTRFLAGS_DOWN
|
||||
button = 0
|
||||
if event.slowPathInputData.pointerFlags.value & pdu.data.PointerFlag.PTRFLAGS_BUTTON1:
|
||||
button = 1
|
||||
elif event.slowPathInputData.pointerFlags.value & pdu.data.PointerFlag.PTRFLAGS_BUTTON2:
|
||||
button = 2
|
||||
elif event.slowPathInputData.pointerFlags.value & pdu.data.PointerFlag.PTRFLAGS_BUTTON3:
|
||||
button = 3
|
||||
observer.onPointerEvent(event.slowPathInputData.xPos.value, event.slowPathInputData.yPos.value, button, isPressed)
|
||||
|
||||
def sendUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
|
||||
"""
|
||||
@@ -428,4 +465,30 @@ class RDPServerObserver(object):
|
||||
"""
|
||||
Stack is ready and connected
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "RDPServerObserver"))
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onReady", "RDPServerObserver"))
|
||||
|
||||
def onKeyEventScancode(self, code, isPressed):
|
||||
"""
|
||||
Event call when a keyboard event is catch in scan code format
|
||||
@param code: scan code of key
|
||||
@param isPressed: True if key is down
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onKeyEventScanCode", "RDPServerObserver"))
|
||||
|
||||
def onKeyEventUnicode(self, code, isPressed):
|
||||
"""
|
||||
Event call when a keyboard event is catch in unicode format
|
||||
@param code: unicode of key
|
||||
@param isPressed: True if key is down
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onKeyEventUnicode", "RDPServerObserver"))
|
||||
|
||||
def onPointerEvent(self, x, y, button, isPressed):
|
||||
"""
|
||||
Event call on mouse event
|
||||
@param x: x position
|
||||
@param y: y position
|
||||
@param button: 1, 2 or 3 button
|
||||
@param isPressed: True if mouse button is pressed
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onPointerEvent", "RDPServerObserver"))
|
||||
@@ -26,6 +26,14 @@ from rdpy.network.layer import RawLayer
|
||||
from rdpy.network.type import UInt8, UInt16Be, sizeof
|
||||
from rdpy.base.error import CallPureVirtualFuntion
|
||||
|
||||
class Action(object):
|
||||
"""
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240621.aspx
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240589.aspx
|
||||
"""
|
||||
FASTPATH_ACTION_FASTPATH = 0x0
|
||||
FASTPATH_ACTION_X224 = 0x3
|
||||
|
||||
class FastPathListener(object):
|
||||
"""
|
||||
Fast path packet listener
|
||||
@@ -36,19 +44,33 @@ class FastPathListener(object):
|
||||
Call when fast path packet is received
|
||||
@param fastPathS: Stream
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recv", "StreamListener"))
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recvFastPath", "recvFastPath"))
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: FastPathSender
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "setFastPathSender", "recvFastPath"))
|
||||
|
||||
class TPKT(RawLayer):
|
||||
class FastPathSender(object):
|
||||
"""
|
||||
Fast path send capability
|
||||
"""
|
||||
def sendFastPath(self, fastPathS):
|
||||
"""
|
||||
@param fastPathS: type transform to stream and send as fastpath
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendFastPath", "FastPathSender"))
|
||||
|
||||
class TPKT(RawLayer, FastPathSender):
|
||||
"""
|
||||
TPKT layer in RDP protocol stack
|
||||
This layer only handle size of packet and determine if is a fast path packet
|
||||
"""
|
||||
#first byte of classic tpkt header
|
||||
TPKT_PACKET = 3
|
||||
|
||||
def __init__(self, presentation, fastPathListener):
|
||||
"""
|
||||
@param presentation: presentation layer, in RDP case is TPDU layer
|
||||
@param fastPathListener: FastPathListener
|
||||
"""
|
||||
RawLayer.__init__(self, presentation)
|
||||
#last packet version read from header
|
||||
@@ -57,6 +79,8 @@ class TPKT(RawLayer):
|
||||
self._lastShortLength = UInt8()
|
||||
#fast path listener
|
||||
self._fastPathListener = fastPathListener
|
||||
#set me as fast path sender
|
||||
fastPathListener.setFastPathSender(self)
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@@ -77,7 +101,7 @@ class TPKT(RawLayer):
|
||||
#first read packet version
|
||||
data.readType(self._lastPacketVersion)
|
||||
#classic packet
|
||||
if self._lastPacketVersion.value == TPKT.TPKT_PACKET:
|
||||
if self._lastPacketVersion.value == Action.FASTPATH_ACTION_X224:
|
||||
#padding
|
||||
data.readType(UInt8())
|
||||
#read end header
|
||||
@@ -136,4 +160,10 @@ class TPKT(RawLayer):
|
||||
Send encompassed data
|
||||
@param message: network.Type message to send
|
||||
"""
|
||||
RawLayer.send(self, (UInt8(TPKT.TPKT_PACKET), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
||||
|
||||
def sendFastPath(self, fastPathS):
|
||||
"""
|
||||
@param fastPathS: type transform to stream and send as fastpath
|
||||
"""
|
||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
|
||||
Reference in New Issue
Block a user