change write function to send and add protocol negotiation in tpdu layer
This commit is contained in:
@@ -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())
|
||||
self._rfb.sendKeyEvent(True, e.nativeVirtualKey())
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user