From 0f6952f6b0dac0ddee1837e162b265b82d6681b3 Mon Sep 17 00:00:00 2001 From: speyrefitte Date: Mon, 14 Oct 2013 18:21:39 +0200 Subject: [PATCH] change write function to send and add protocol negotiation in tpdu layer --- rdpy/display/qt/adaptor.py | 4 +- rdpy/protocol/common/error.py | 8 +-- rdpy/protocol/common/layer.py | 11 ++- rdpy/protocol/rdp/tpdu.py | 126 +++++++++++++++++++++++++--------- rdpy/protocol/rdp/tpkt.py | 2 +- rdpy/protocol/rfb/rfb.py | 32 ++++----- 6 files changed, 123 insertions(+), 60 deletions(-) diff --git a/rdpy/display/qt/adaptor.py b/rdpy/display/qt/adaptor.py index 0a2d6b2..7cfca41 100644 --- a/rdpy/display/qt/adaptor.py +++ b/rdpy/display/qt/adaptor.py @@ -54,10 +54,10 @@ class RfbAdaptor(RfbObserver, QAdaptor): ''' convert qt mouse event to rfb mouse event ''' - self._rfb.writePointerEvent(0, e.pos().x(), e.pos().y()) + self._rfb.sendPointerEvent(0, e.pos().x(), e.pos().y()) def sendKeyEvent(self, e): ''' convert qt key press event to rfb press event ''' - self._rfb.writeKeyEvent(True, e.nativeVirtualKey()) \ No newline at end of file + self._rfb.sendKeyEvent(True, e.nativeVirtualKey()) \ No newline at end of file diff --git a/rdpy/protocol/common/error.py b/rdpy/protocol/common/error.py index 04f7072..453edf7 100644 --- a/rdpy/protocol/common/error.py +++ b/rdpy/protocol/common/error.py @@ -10,11 +10,5 @@ class InvalidExpectedDataException(Exception): ''' constructor with message ''' - self._message = message - - def __str__(self): - ''' - return string representation of exception - ''' - return "%s"%self._message + Exception.__init__(self, message) diff --git a/rdpy/protocol/common/layer.py b/rdpy/protocol/common/layer.py index 989b9d7..48b69f8 100644 --- a/rdpy/protocol/common/layer.py +++ b/rdpy/protocol/common/layer.py @@ -37,14 +37,14 @@ class Layer(object): if not self._presentation is None: self._presentation.recv(data) - def write(self, data): + def send(self, data): ''' classical use by presentation layer write data for this layer default pass data to transport layer ''' if not self._transport is None: - self._transport.write(data) + self._transport.send(data) class LayerAutomata(Layer): ''' @@ -105,6 +105,13 @@ class RawLayer(protocol.Protocol, LayerAutomata): #call recv function self.recv(expectedData) + def connectionMade(self): + ''' + inherit from twisted protocol + ''' + #join two scheme + self.connect() + def expect(self, expectedLen, callback = None): ''' new expected len diff --git a/rdpy/protocol/rdp/tpdu.py b/rdpy/protocol/rdp/tpdu.py index cee2fad..8d77a1f 100644 --- a/rdpy/protocol/rdp/tpdu.py +++ b/rdpy/protocol/rdp/tpdu.py @@ -1,12 +1,11 @@ ''' -Created on 5 sept. 2013 - @author: sylvain ''' -from rdpy.protocol.common.layer import Layer +from rdpy.protocol.common.layer import LayerAutomata from rdpy.protocol.common.stream import Stream from rdpy.protocol.common.error import InvalidExpectedDataException -class TPDU(Layer): + +class TPDU(LayerAutomata): ''' classdocs ''' @@ -15,40 +14,63 @@ class TPDU(Layer): X224_TPDU_DISCONNECT_REQUEST = 0x80 X224_TPDU_DATA = 0xF0 X224_TPDU_ERROR = 0x70 + + #negotiation header + TYPE_RDP_NEG_REQ = 0x01 + TYPE_RDP_NEG_RSP = 0x02 + TYPE_RDP_NEG_FAILURE = 0x03 + #rdp negotiation protocol + PROTOCOL_RDP = 0x00000000 + PROTOCOL_SSL = 0x00000001 + PROTOCOL_HYBRID = 0x00000002 + PROTOCOL_HYBRID_EX = 0x00000008 def __init__(self, presentation = None): ''' Constructor ''' - Layer.__init__(self, presentation) + LayerAutomata.__init__(self, presentation) + + #default protocol is SSl because is the only supported + #in this version of RDPY + self._protocol = TPDU.PROTOCOL_SSL def connect(self): - self.writeMessage(TPDU.X224_TPDU_CONNECTION_REQUEST) - - def recv(self, data): ''' - main receive function - layer complexity doesn't need automata + connection request + for client send a connection request packet ''' - #unused length - len = data.read_uint8() - code = data.read_uint8() - - if code == TPDU.X224_TPDU_DATA: - data.read_uint8() - self._presentation.recv(data) - else: - #padding - data.read_leuint32() - if code == TPDU.X224_TPDU_CONNECTION_CONFIRM: - self._presentation.connect() - elif code == TPDU.X224_TPDU_CONNECTION_REQUEST: - self.writeMessage(TPDU.X224_TPDU_CONNECTION_CONFIRM) - self._presentation.connect() - else: - raise InvalidExpectedDataException("invalid TPDU header code %d"%code) + self.sendConnectionRequest() + + def readHeader(self, data): + ''' + read a typical TPDU header (len and code) + ''' + return data.read_uint8(), data.read_uint8() - def write(self, data): + def recvConnectionConfirm(self, data): + ''' + recv connection confirm message + ''' + (len, code) = self.readHeader(data) + if code != TPDU.X224_TPDU_CONNECTION_CONFIRM: + raise InvalidExpectedDataException("invalid TPDU header code X224_TPDU_CONNECTION_CONFIRM != %d"%code) + data.read_leuint32() + data.read_uint8() + #check presence of negotiation response + if data.dataLen() == 8: + self.readNeg(data) + + def sendConnectionRequest(self): + ''' + write connection request message + ''' + s = Stream() + self.writeNegReq(s) + self.sendMessage(TPDU.X224_TPDU_CONNECTION_REQUEST, s) + self.setNextState(self.recvConnectionConfirm) + + def send(self, data): ''' write message packet for TPDU layer add TPDU header @@ -58,17 +80,57 @@ class TPDU(Layer): s.write_uint8(TPDU.X224_TPDU_DATA) s.write_uint8(0x80) s.write(data.getvalue()) - self._transport.write(data) + self._transport.send(data) - def writeMessage(self, code): + def sendMessage(self, code, data = Stream()): ''' special write function that packet TPDU message ''' s = Stream() - s.write_uint8(6) + s.write_uint8(6 + data.len) s.write_uint8(code) s.write_beuint16(0) s.write_beuint16(0) s.write_uint8(0) - self.write(s) \ No newline at end of file + if data.len > 0: + s.write(data.getvalue()) + self._transport.send(s) + + def writeNegReq(self, s): + ''' + write negociation request structure + ''' + s.write_uint8(TPDU.TYPE_RDP_NEG_REQ) + #flags + s.write_uint8(0) + #write fixed packet size + s.write_leuint16(0x0008) + #write protocol + s.write_leuint32(self._protocol) + + def readNeg(self, data): + ''' + read neagotiation response + ''' + code = data.read_uint8() + + if code == TPDU.TYPE_RDP_NEG_FAILURE: + self.readNegFailure(data) + elif code == TPDU.TYPE_RDP_NEG_RSP: + self.readNegResp(data) + else: + raise InvalidExpectedDataException("bad protocol negotiation response code") + + def readNegFailure(self, data): + ''' + read negotiation failure packet + ''' + pass + + def readNegResp(self, data): + ''' + read negotiatiion response packet + ''' + pass + \ No newline at end of file diff --git a/rdpy/protocol/rdp/tpkt.py b/rdpy/protocol/rdp/tpkt.py index 16d4f57..41fa1e1 100644 --- a/rdpy/protocol/rdp/tpkt.py +++ b/rdpy/protocol/rdp/tpkt.py @@ -81,7 +81,7 @@ class TPKT(RawLayer): self._presentation.recv(data) self.expect(2, self.readHeader) - def write(self, data): + def send(self, data): s = Stream() s.write_uint8(3) s.write_uint8(0) diff --git a/rdpy/protocol/rfb/rfb.py b/rdpy/protocol/rfb/rfb.py index bfe5f7a..df57dc9 100644 --- a/rdpy/protocol/rfb/rfb.py +++ b/rdpy/protocol/rfb/rfb.py @@ -85,7 +85,7 @@ class Rfb(RawLayer): return self._version = ProtocolVersion.UNKNOWN - def writeProtocolVersionFormat(self): + def sendProtocolVersionFormat(self): s = Stream() if self._version == ProtocolVersion.RFB003003: s.write("RFB 003.003\n") @@ -95,7 +95,7 @@ class Rfb(RawLayer): s.write("RFB 003.008\n") self.transport.write(s.getvalue()) - def connectionMade(self): + def connect(self): ''' call when transport layer connection is made @@ -103,7 +103,7 @@ class Rfb(RawLayer): if self._mode == Rfb.CLIENT: self.expect(12, self.readProtocolVersion) else: - self.writeProtocolVersionFormat() + self.sendProtocolVersionFormat() def readProtocolVersion(self, data): ''' @@ -116,7 +116,7 @@ class Rfb(RawLayer): #protocol version is unknow try best version we can handle self._version = ProtocolVersion.RFB003008 #send same version of - self.writeProtocolVersionFormat() + self.sendProtocolVersionFormat() #next state read security if self._version == ProtocolVersion.RFB003003: @@ -161,7 +161,7 @@ class Rfb(RawLayer): self.expectWithHeader(4, self.readSecurityFailed) else: print "Authentification OK" - self.writeClientInit() + self.sendClientInit() def readSecurityFailed(self, data): print "Security failed cause to %s"%data.getvalue() @@ -184,11 +184,11 @@ class Rfb(RawLayer): print "Server name %s"%self._serverName #end of handshake #send pixel format - self.writeSetPixelFormat(self._pixelFormat) + self.sendSetPixelFormat(self._pixelFormat) #write encoding - self.writeSetEncoding() + self.sendSetEncoding() #request entire zone - self.writeFramebufferUpdateRequest(False, 0, 0, self._width, self._height) + self.sendFramebufferUpdateRequest(False, 0, 0, self._width, self._height) self.expect(1, self.readServerOrder) def readServerOrder(self, data): @@ -231,12 +231,12 @@ class Rfb(RawLayer): #if there is another rect to read if self._nbRect == 0: #job is finish send a request - self.writeFramebufferUpdateRequest(True, 0, 0, self._width, self._height) + self.sendFramebufferUpdateRequest(True, 0, 0, self._width, self._height) self.expect(1, self.readServerOrder) else: self.expect(12, self.readRectHeader) - def writeClientInit(self): + def sendClientInit(self): ''' write client init packet ''' @@ -245,7 +245,7 @@ class Rfb(RawLayer): self.transport.write(s.getvalue()) self.expect(20, self.readServerInit) - def writeSetPixelFormat(self, pixelFormat): + def sendSetPixelFormat(self, pixelFormat): ''' write set pixel format packet ''' @@ -259,7 +259,7 @@ class Rfb(RawLayer): pixelFormat.write(s) self.transport.write(s.getvalue()) - def writeSetEncoding(self): + def sendSetEncoding(self): ''' write set encoding packet ''' @@ -274,7 +274,7 @@ class Rfb(RawLayer): s.write_besint32(0) self.transport.write(s.getvalue()) - def writeFramebufferUpdateRequest(self, incremental, x, y, width, height): + def sendFramebufferUpdateRequest(self, incremental, x, y, width, height): ''' request server the specified zone incremental means request only change before last update @@ -288,7 +288,7 @@ class Rfb(RawLayer): s.write_beuint16(height) self.transport.write(s.getvalue()) - def writeKeyEvent(self, downFlag, key): + def sendKeyEvent(self, downFlag, key): ''' write key event packet ''' @@ -299,7 +299,7 @@ class Rfb(RawLayer): s.write_beuint32(key) self.transport.write(s.getvalue()) - def writePointerEvent(self, mask, x, y): + def sendPointerEvent(self, mask, x, y): ''' write pointer event packet ''' @@ -310,7 +310,7 @@ class Rfb(RawLayer): s.write_beuint16(y) self.transport.write(s.getvalue()) - def writeClientCutText(self, text): + def sendClientCutText(self, text): ''' write client cut text event packet '''