use new python object style to send packet

This commit is contained in:
speyrefitte
2013-10-16 15:00:35 +02:00
parent b67635e47d
commit 0f09d2909c
7 changed files with 181 additions and 91 deletions

View File

@@ -70,7 +70,7 @@ class LayerAutomata(Layer):
#twitsed layer concept
from twisted.internet import protocol
#first that handle stream
from stream import Stream
from network import Stream
class RawLayer(protocol.Protocol, LayerAutomata):
'''
@@ -118,4 +118,10 @@ class RawLayer(protocol.Protocol, LayerAutomata):
'''
self._expectedLen = expectedLen
#default callback is recv from LayerAutomata
self.setNextState(callback)
self.setNextState(callback)
def send(self, s):
'''
send stream on tcp layer
'''
self.transport.write(s.getvalue())

View File

@@ -26,14 +26,23 @@ class SimpleType(Type):
'''
simple type
'''
def __init__(self, typeSize, structFormat, value):
def __init__(self, structFormat, typeSize, value):
self._typeSize = typeSize
self._structFormat = structFormat
self._value = value
@property
def value(self):
return self._value;
'''
shortcut to access inner value
'''
return self._value
def __cmp__(self, other):
'''
compare inner value
'''
return self._value.__cmp__(other.value)
def write(self, s):
'''
@@ -211,7 +220,34 @@ class UInt24Le(SimpleType):
special read for a special type
'''
self._value = struct.unpack("<I",s.read(3))[0]
class String(Type):
'''
String network type
'''
def __init__(self, value = ""):
'''
constructor with new string
'''
self._value = value
def __eq__(self, other):
'''
call raw compare value
'''
return self._value == other._value
def write(self, s):
'''
write the entire raw value
'''
s.write(self._value)
def read(self, s):
'''
read all stream
'''
self._value = s.getvalue()
class Stream(StringIO):

View File

@@ -2,7 +2,7 @@
@author: sylvain
'''
from rdpy.protocol.common.layer import LayerAutomata
from rdpy.protocol.common.stream import Stream
from rdpy.protocol.common.network import Stream
from rdpy.protocol.common.error import InvalidExpectedDataException, NegotiationFailure
class TPDU(LayerAutomata):

View File

@@ -19,6 +19,7 @@ class Rfb(RawLayer):
'''
constructor
mode can be only client or server mode
in this version of RDPY only support client mode
'''
RawLayer.__init__(self)
#usefull for rfb protocol
@@ -30,7 +31,7 @@ class Rfb(RawLayer):
#nb security launch by server
self._securityLevel = SecurityType.INVALID
#shared framebuffer
self._sharedFlag = 0
self._sharedFlag = UInt8
#framebuffer width
self._width = 0
#framebuffer height
@@ -47,6 +48,9 @@ class Rfb(RawLayer):
self._observer = []
def addObserver(self, observer):
'''
add observer for input/ouput events
'''
self._observer.append(observer)
def expectWithHeader(self, expectedHeaderLen, callbackBody):
@@ -75,26 +79,17 @@ class Rfb(RawLayer):
self.expect(bodyLen.value, self._callbackBody)
def readProtocolVersionFormat(self, data):
if data.getvalue() == "RFB 003.003\n":
self._version = ProtocolVersion.RFB003003
return
if data.getvalue() == "RFB 003.007\n":
self._version = ProtocolVersion.RFB003007
return
if data.getvalue() == "RFB 003.008\n":
self._version = ProtocolVersion.RFB003008
return
self._version = ProtocolVersion.UNKNOWN
'''
read protocol version
'''
data.readType(self._version)
if not self._version in [ProtocolVersion.RFB003003, ProtocolVersion.RFB003007, ProtocolVersion.RFB003008]:
self._version = ProtocolVersion.UNKNOWN
def sendProtocolVersionFormat(self):
s = Stream()
if self._version == ProtocolVersion.RFB003003:
s.write("RFB 003.003\n")
if self._version == ProtocolVersion.RFB003007:
s.write("RFB 003.007\n")
if self._version == ProtocolVersion.RFB003008:
s.write("RFB 003.008\n")
self.transport.write(s.getvalue())
s.writeType(self._version)
self.send(s)
def connect(self):
'''
@@ -139,7 +134,9 @@ class Rfb(RawLayer):
'''
securityList = []
while data.dataLen() > 0:
securityList.append(data.read_uint8())
securityElement = UInt8()
data.readType(securityElement)
securityList.append(securityElement)
#select high security level
for s in securityList:
if s in [SecurityType.NONE, SecurityType.VNC] and s > self._securityLevel:
@@ -147,15 +144,16 @@ class Rfb(RawLayer):
break
#send back security level choosen
s = Stream()
s.write_uint8(self._securityLevel)
self.transport.write(s.getvalue())
s.writeType(self._securityLevel)
self.send(s)
self.expect(4, self.readSecurityResult)
def readSecurityResult(self, data):
'''
Read security result packet
'''
result = data.read_beuint32()
result = UInt32Be()
data.readType(result)
if result == 1:
print "Authentification failed"
if self._version == ProtocolVersion.RFB003008:
@@ -196,8 +194,9 @@ class Rfb(RawLayer):
'''
read order receive from server
'''
packet_type = data.read_uint8()
if packet_type == 0:
packet_type = UInt8()
data.readType(packet_type)
if packet_type == UInt8(0):
self.expect(3, self.readFrameBufferUpdateHeader)
def readFrameBufferUpdateHeader(self, data):
@@ -205,7 +204,7 @@ class Rfb(RawLayer):
read frame buffer update packet header
'''
#padding
data.read_uint8()
data.readType(UInt8())
self._nbRect = data.read_beuint16();
self.expect(12, self.readRectHeader)
@@ -242,8 +241,8 @@ class Rfb(RawLayer):
write client init packet
'''
s = Stream()
s.write_uint8(self._sharedFlag)
self.transport.write(s.getvalue())
s.writeType(self._sharedFlag)
self.send(s)
self.expect(20, self.readServerInit)
def sendSetPixelFormat(self, pixelFormat):

View File

@@ -1,72 +1,73 @@
'''
Created on 22 aout 2013
@author: sylvain
'''
from rdpy.protocol.common.network import UInt8, UInt16Be, UInt32Be, String
from rdpy.protocol.common.network import CompositeType
from rdpy.utils.const import ConstAttributes
@ConstAttributes
class ProtocolVersion(object):
'''
different ptotocol version
'''
UNKNOWN = 0
RFB003003 = 1
RFB003007 = 2
RFB003008 = 3
UNKNOWN = String()
RFB003003 = String("RFB 003.003\n")
RFB003007 = String("RFB 003.007\n")
RFB003008 = String("RFB 003.008\n")
@ConstAttributes
class SecurityType:
'''
security type supported by twisted remote desktop
security type supported
(or will be supported)
by rdpy
'''
INVALID = 0
NONE = 1
VNC = 2
class PixelFormat(object):
def __init__(self):
self.BitsPerPixel = 32
self.Depth = 24
self.BigEndianFlag = False
self.TrueColorFlag = True
self.RedMax = 255
self.GreenMax = 255
self.BlueMax = 255
self.RedShift = 16
self.GreenShift = 8
self.BlueShift = 0
def read(self, data):
self.BitsPerPixel = data.read_uint8()
self.Depth = data.read_uint8()
self.BigEndianFlag = data.read_uint8()
self.TrueColorFlag = data.read_uint8()
self.RedMax = data.read_beuint16()
self.GreenMax = data.read_beuint16()
self.BlueMax = data.read_beuint16()
self.RedShift = data.read_uint8()
self.GreenShift = data.read_uint8()
self.BlueShift = data.read_uint8()
#padding
data.read(3)
def write(self, data):
data.write_uint8(self.BitsPerPixel)
data.write_uint8(self.Depth)
data.write_uint8(self.BigEndianFlag)
data.write_uint8(self.TrueColorFlag)
data.write_beuint16(self.RedMax)
data.write_beuint16(self.GreenMax)
data.write_beuint16(self.BlueMax)
data.write_uint8(self.RedShift)
data.write_uint8(self.GreenShift)
data.write_uint8(self.BlueShift)
#padding
data.write_uint8(0)
data.write_uint8(0)
data.write_uint8(0)
INVALID = UInt8(0)
NONE = UInt8(1)
VNC = UInt8(2)
@ConstAttributes
class Pointer:
BUTTON1 = 0x1
BUTTON2 = 0x2
BUTTON3 = 0x4
'''
mouse event code (which button)
actually in RFB specification only$
three buttons are supported
'''
BUTTON1 = UInt32Be(0x1)
BUTTON2 = UInt32Be(0x2)
BUTTON3 = UInt32Be(0x4)
class PixelFormat(CompositeType):
'''
pixel format structure
'''
def __init__(self):
CompositeType.__init__(self)
self.BitsPerPixel = UInt8(32)
self.Depth = UInt8(24)
self.BigEndianFlag = UInt8(False)
self.TrueColorFlag = UInt8(True)
self.RedMax = UInt16Be(255)
self.GreenMax = UInt16Be(255)
self.BlueMax = UInt16Be(255)
self.RedShift = UInt8(16)
self.GreenShift = UInt8(8)
self.BlueShift = UInt8(0)
self.padding1 = UInt16Be()
self.padding2 = UInt8()
class ServerInit(CompositeType):
'''
message send by server to indicate
framebuffer configuration
'''
def __init__(self):
CompositeType.__init__(self)
self.width = UInt16Be()
self.height = UInt16Be()
self.pixelFormat = PixelFormat()
class Rectangle:
def __init__(self):

0
rdpy/utils/__init__.py Normal file
View File

48
rdpy/utils/const.py Normal file
View File

@@ -0,0 +1,48 @@
'''
@author: sylvain
'''
from copy import deepcopy
class Constant(object):
'''
Constant descriptor that deep copy value on get
'''
def __init__(self, value):
'''
Constructor keep value
'''
self._value = value
def __get__(self, obj, objType):
'''
on get constant return deep copy of wrapped value
'''
return deepcopy(self._value)
def __set__(self, obj, value):
'''
set is forbidden
in python 2.7 this function work only
on instanciate object
'''
raise Exception("can't assign constant")
def __delete__(self, obj):
'''
delete is forbidden on constant
'''
raise Exception("can't delete constant")
def ConstAttributes(cls):
'''
transform all attributes of class
in constant attribute
only attributes which are not begining with '_' char
and are not callable
'''
for c_name, c_value in cls.__dict__.iteritems():
if c_name[0] != '_' and not callable(c_value):
setattr(cls, c_name, Constant(c_value))
return cls