add comment and per functions
This commit is contained in:
@@ -9,6 +9,7 @@ class InvalidValue(Exception):
|
||||
def __init__(self, message = ""):
|
||||
'''
|
||||
constructor with message
|
||||
@param message: message show when exception is raised
|
||||
'''
|
||||
Exception.__init__(self, message)
|
||||
|
||||
@@ -19,6 +20,7 @@ class InvalidExpectedDataException(Exception):
|
||||
def __init__(self, message = ""):
|
||||
'''
|
||||
constructor with message
|
||||
@param message: message show when exception is raised
|
||||
'''
|
||||
Exception.__init__(self, message)
|
||||
|
||||
@@ -29,6 +31,7 @@ class NegotiationFailure(Exception):
|
||||
def __init__(self, message = ""):
|
||||
'''
|
||||
constructor with message
|
||||
@param message: message show when exception is raised
|
||||
'''
|
||||
Exception.__init__(self, message)
|
||||
|
||||
@@ -39,6 +42,7 @@ class InvalidType(Exception):
|
||||
def __init__(self, message = ""):
|
||||
'''
|
||||
constructor with message
|
||||
@param message: message show when exception is raised
|
||||
'''
|
||||
Exception.__init__(self, message)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class Layer(object):
|
||||
def __init__(self, presentation = None):
|
||||
'''
|
||||
Constructor
|
||||
@param presentation: Layer which handled connect and recv messages
|
||||
'''
|
||||
#presentation layer higher layer in model
|
||||
self._presentation = presentation
|
||||
@@ -28,20 +29,22 @@ class Layer(object):
|
||||
if not self._presentation is None:
|
||||
self._presentation.connect()
|
||||
|
||||
def recv(self, data):
|
||||
def recv(self, s):
|
||||
'''
|
||||
signal that data is available for this layer
|
||||
call by transport layer
|
||||
default is to pass data to presentation layer
|
||||
@param s: raw Stream receive from transport layer
|
||||
'''
|
||||
if not self._presentation is None:
|
||||
self._presentation.recv(data)
|
||||
self._presentation.recv(s)
|
||||
|
||||
def send(self, data):
|
||||
'''
|
||||
classical use by presentation layer
|
||||
write data for this layer
|
||||
default pass data to transport layer
|
||||
@param data: Type or tuple element handle by transport layer
|
||||
'''
|
||||
if not self._transport is None:
|
||||
self._transport.send(data)
|
||||
@@ -54,6 +57,7 @@ class LayerAutomata(Layer):
|
||||
def __init__(self, presentation = None):
|
||||
'''
|
||||
Constructor
|
||||
@param presentation: presentation Layer
|
||||
'''
|
||||
#call parent constructor
|
||||
Layer.__init__(self, presentation)
|
||||
@@ -61,6 +65,9 @@ class LayerAutomata(Layer):
|
||||
def setNextState(self, callback = None):
|
||||
'''
|
||||
set recv function to next callback or
|
||||
current self.recv function if it's None
|
||||
@param callback: a callable object that can
|
||||
receive Layer, Stream parameters
|
||||
'''
|
||||
if callback is None:
|
||||
callback = self.__class__.recv
|
||||
@@ -93,6 +100,7 @@ class RawLayer(protocol.Protocol, LayerAutomata):
|
||||
'''
|
||||
inherit from protocol class
|
||||
main event of received data
|
||||
@param data: string data receive from twisted
|
||||
'''
|
||||
#add in buffer
|
||||
self._buffer += data
|
||||
@@ -114,7 +122,10 @@ class RawLayer(protocol.Protocol, LayerAutomata):
|
||||
|
||||
def expect(self, expectedLen, callback = None):
|
||||
'''
|
||||
new expected len
|
||||
configura layer to change nextsatte with callback only
|
||||
when expectLen byte is received from transport layer
|
||||
@param expectedLen: in bytes len use to call nextstate
|
||||
@param callback: callback call when expectedlen bytes is received
|
||||
'''
|
||||
self._expectedLen = expectedLen
|
||||
#default callback is recv from LayerAutomata
|
||||
@@ -123,6 +134,8 @@ class RawLayer(protocol.Protocol, LayerAutomata):
|
||||
def send(self, message):
|
||||
'''
|
||||
send stream on tcp layer
|
||||
format message into raw stream understood by transport layer
|
||||
@param message: (tuple | Type)
|
||||
'''
|
||||
s = Stream()
|
||||
s.writeType(message)
|
||||
|
||||
@@ -9,6 +9,9 @@ from error import InvalidValue, InvalidType
|
||||
def sizeof(element):
|
||||
'''
|
||||
byte size of type
|
||||
@param element: Type or Tuple(Type | Tuple,)
|
||||
@return: size of element in byte
|
||||
@raise InvalidType: if type is different than tuple of Type inheritance
|
||||
'''
|
||||
if isinstance(element, tuple):
|
||||
size = 0
|
||||
@@ -28,18 +31,22 @@ class Type(object):
|
||||
def write(self, s):
|
||||
'''
|
||||
interface definition of write function
|
||||
@param s: Stream which will be written
|
||||
'''
|
||||
pass
|
||||
|
||||
def read(self, s):
|
||||
'''
|
||||
interface definition of read value
|
||||
@param s: Stream
|
||||
@return: Type read from Stream s
|
||||
'''
|
||||
pass
|
||||
|
||||
def __sizeof__(self):
|
||||
'''
|
||||
return size of type
|
||||
return size of type use for sizeof function
|
||||
@return: size in byte of type
|
||||
'''
|
||||
pass
|
||||
|
||||
@@ -48,6 +55,13 @@ class SimpleType(Type):
|
||||
simple type
|
||||
'''
|
||||
def __init__(self, structFormat, typeSize, signed, value):
|
||||
'''
|
||||
constructor of simple type
|
||||
@param structFormat: letter that represent type in struct package
|
||||
@param typeSize: size in byte of type
|
||||
@param signed: true if type represent a signed type
|
||||
@param value: value record in this object
|
||||
'''
|
||||
self._typeSize = typeSize
|
||||
self._structFormat = structFormat
|
||||
self._signed = signed
|
||||
@@ -57,6 +71,7 @@ class SimpleType(Type):
|
||||
def value(self):
|
||||
'''
|
||||
shortcut to access inner value
|
||||
@return: inner value(python type value)
|
||||
'''
|
||||
return self._value
|
||||
|
||||
@@ -64,6 +79,8 @@ class SimpleType(Type):
|
||||
def value(self, value):
|
||||
'''
|
||||
setter of value after check it
|
||||
@param value: new value encompass in simpletype object
|
||||
@raise InvalidValue: if value doesn't respect type range
|
||||
'''
|
||||
if not self.isInRange(value):
|
||||
raise InvalidValue("value is out of range for %s"%self.__class__)
|
||||
@@ -72,18 +89,25 @@ class SimpleType(Type):
|
||||
def __cmp__(self, other):
|
||||
'''
|
||||
compare inner value
|
||||
magic function of python use for any compare operators
|
||||
@param other: Type value which will be compared with self value
|
||||
@return: python value compare
|
||||
'''
|
||||
return self._value.__cmp__(other.value)
|
||||
|
||||
def write(self, s):
|
||||
'''
|
||||
write value in stream s
|
||||
use struct package to pack value
|
||||
@param s: Stream which will be written
|
||||
'''
|
||||
s.write(struct.pack(self._structFormat, self._value))
|
||||
|
||||
def read(self, s):
|
||||
'''
|
||||
read value from stream
|
||||
read inner value from stream
|
||||
use struct package
|
||||
@param s: Stream
|
||||
'''
|
||||
self._value = struct.unpack(self._structFormat,s.read(self._typeSize))[0]
|
||||
|
||||
@@ -91,19 +115,20 @@ class SimpleType(Type):
|
||||
def mask(self):
|
||||
'''
|
||||
compute bit mask for type
|
||||
beacause in python all numbers are int long or float
|
||||
because in python all numbers are int long or float
|
||||
'''
|
||||
if not self.__dict__.has_key("_mask"):
|
||||
mask = 0xff
|
||||
for i in range(1, self._typeSize):
|
||||
mask = mask << 8
|
||||
mask |= 0xff
|
||||
mask = mask << 8 | 0xff
|
||||
self._mask = mask
|
||||
return self._mask
|
||||
|
||||
def isInRange(self, value):
|
||||
'''
|
||||
check if value is in mask range
|
||||
@param value: python value
|
||||
@return: true if value is in type range
|
||||
'''
|
||||
if self._signed:
|
||||
return not (value < -(self.mask() >> 1) or value > (self.mask() >> 1))
|
||||
@@ -113,12 +138,14 @@ class SimpleType(Type):
|
||||
def __sizeof__(self):
|
||||
'''
|
||||
return size of type
|
||||
@return: typeSize pass in constructor
|
||||
'''
|
||||
return self._typeSize
|
||||
|
||||
def __invert__(self):
|
||||
'''
|
||||
implement not operator
|
||||
@return: __class__ value
|
||||
'''
|
||||
invert = ~self._value
|
||||
if not self._signed:
|
||||
@@ -128,24 +155,36 @@ class SimpleType(Type):
|
||||
def __add__(self, other):
|
||||
'''
|
||||
implement addition operator
|
||||
@attention: type overflow are not handle
|
||||
@param other: SimpleType value
|
||||
@return: self.__class__ object with add result
|
||||
@raise InvalidValue: if new value is out of bound
|
||||
'''
|
||||
return self.__class__(self._value.__add__(other._value))
|
||||
|
||||
def __sub__(self, other):
|
||||
'''
|
||||
implement sub operator
|
||||
@attention: type overflow are not handle
|
||||
@param other: SimpleType value
|
||||
@return: self.__class__ object with sub result
|
||||
@raise InvalidValue: if new value is out of bound
|
||||
'''
|
||||
return self.__class__(self._value.__sub__(other._value))
|
||||
|
||||
def __and__(self, other):
|
||||
'''
|
||||
implement bitwise and operator
|
||||
@param other: SimpleType value
|
||||
@return: self.__class__ object with and result
|
||||
'''
|
||||
return self.__class__(self._value.__and__(other._value))
|
||||
|
||||
def __or__(self, other):
|
||||
'''
|
||||
implement bitwise and operator
|
||||
@param other: SimpleType value
|
||||
@return: self.__class__ object with or result
|
||||
'''
|
||||
return self.__class__(self._value.__or__(other._value))
|
||||
|
||||
@@ -159,11 +198,14 @@ class CompositeType(Type):
|
||||
'''
|
||||
init list of simple value
|
||||
'''
|
||||
#list of ordoned type
|
||||
self._type = []
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
'''
|
||||
magic function to update type list
|
||||
@param name: name of new attribute
|
||||
@param value: value of new attribute
|
||||
'''
|
||||
if name[0] != '_' and (isinstance(value, Type) or isinstance(value, tuple)) and not self.__dict__.has_key(name):
|
||||
self._type.append(value)
|
||||
@@ -172,6 +214,7 @@ class CompositeType(Type):
|
||||
def read(self, s):
|
||||
'''
|
||||
call read on each ordered subtype
|
||||
@param s: Stream
|
||||
'''
|
||||
for i in self._type:
|
||||
s.readType(i)
|
||||
@@ -179,13 +222,15 @@ class CompositeType(Type):
|
||||
def write(self, s):
|
||||
'''
|
||||
call write on each ordered subtype
|
||||
@param s: Stream
|
||||
'''
|
||||
for i in self._type:
|
||||
s.writeType(i)
|
||||
|
||||
def __sizeof__(self):
|
||||
'''
|
||||
call sizeof on each subtype
|
||||
call sizeof on each subtype$
|
||||
@return: sum of sizeof of each public type attributes
|
||||
'''
|
||||
size = 0
|
||||
for i in self._type:
|
||||
@@ -197,90 +242,77 @@ class UInt8(SimpleType):
|
||||
unsigned byte
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "B", 1, False, value)
|
||||
|
||||
class SInt8(SimpleType):
|
||||
'''
|
||||
unsigned byte
|
||||
signed byte
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "b", 1, True, value)
|
||||
|
||||
|
||||
class UInt16Be(SimpleType):
|
||||
'''
|
||||
unsigned short with big endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, ">H", 2, False, value)
|
||||
|
||||
class UInt16Le(SimpleType):
|
||||
'''
|
||||
unsigned short with little endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "<H", 2, False, value)
|
||||
|
||||
class UInt32Be(SimpleType):
|
||||
'''
|
||||
unsigned int with big endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, ">I", 4, False, value)
|
||||
|
||||
class UInt32Le(SimpleType):
|
||||
'''
|
||||
unsigned int with little endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "<I", 4, False, value)
|
||||
|
||||
class SInt32Le(SimpleType):
|
||||
'''
|
||||
unsigned int with little endian representation
|
||||
signed int with little endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "<I", 4, True, value)
|
||||
|
||||
class SInt32Be(SimpleType):
|
||||
'''
|
||||
unsigned int with big endian representation
|
||||
signed int with big endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, ">I", 4, True, value)
|
||||
|
||||
class UInt24Be(SimpleType):
|
||||
'''
|
||||
unsigned int with big endian representation
|
||||
unsigned 24 bit int with big endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, ">I", 3, False, value)
|
||||
|
||||
def write(self, s):
|
||||
@@ -289,34 +321,23 @@ class UInt24Be(SimpleType):
|
||||
'''
|
||||
s.write(struct.pack(">I", self._value)[1:])
|
||||
|
||||
def read(self, s):
|
||||
'''
|
||||
special read for a special type
|
||||
'''
|
||||
self._value = struct.unpack(">I",s.read(3))[0]
|
||||
|
||||
class UInt24Le(SimpleType):
|
||||
'''
|
||||
unsigned int with little endian representation
|
||||
@attention: inner value is in machine representation
|
||||
Big endian is just for read or write in stream
|
||||
'''
|
||||
def __init__(self, value = 0):
|
||||
'''
|
||||
constructor check value range
|
||||
'''
|
||||
SimpleType.__init__(self, "<I", 3, False, value)
|
||||
|
||||
def write(self, s):
|
||||
'''
|
||||
special write for a special type
|
||||
@param s: Stream
|
||||
'''
|
||||
#don't write first byte
|
||||
s.write(struct.pack("<I", self._value)[1:])
|
||||
|
||||
def read(self, s):
|
||||
'''
|
||||
special read for a special type
|
||||
'''
|
||||
self._value = struct.unpack("<I",s.read(3))[0]
|
||||
|
||||
class String(Type):
|
||||
'''
|
||||
String network type
|
||||
@@ -324,36 +345,47 @@ class String(Type):
|
||||
def __init__(self, value = ""):
|
||||
'''
|
||||
constructor with new string
|
||||
@param value: python string use for inner value
|
||||
'''
|
||||
self._value = value
|
||||
|
||||
def __eq__(self, other):
|
||||
'''
|
||||
call raw compare value
|
||||
@param other: other String parameter
|
||||
@return: if two inner value are equals
|
||||
'''
|
||||
return self._value == other._value
|
||||
|
||||
def __str__(self):
|
||||
'''
|
||||
call when str function is call
|
||||
@return: inner python string
|
||||
'''
|
||||
return self._value
|
||||
|
||||
def write(self, s):
|
||||
'''
|
||||
write the entire raw value
|
||||
@param s: Stream
|
||||
'''
|
||||
s.write(self._value)
|
||||
|
||||
def read(self, s):
|
||||
'''
|
||||
read all stream
|
||||
read all stream if len of inner value is zero
|
||||
else read the len of inner string
|
||||
@param s: Stream
|
||||
'''
|
||||
self._value = s.getvalue()
|
||||
if len(self._value) == 0:
|
||||
self._value = s.getvalue()
|
||||
else:
|
||||
self._value = s.read(len(self._value))
|
||||
|
||||
def __sizeof__(self):
|
||||
'''
|
||||
return len of string
|
||||
@return: len of inner string
|
||||
'''
|
||||
return len(self._value)
|
||||
|
||||
@@ -361,16 +393,20 @@ class String(Type):
|
||||
class Stream(StringIO):
|
||||
'''
|
||||
use string io inheritance
|
||||
but in future (for python 3)
|
||||
make your own stream class
|
||||
'''
|
||||
def dataLen(self):
|
||||
'''
|
||||
not yet read length
|
||||
@return: not yet read length
|
||||
'''
|
||||
return self.len - self.pos
|
||||
|
||||
def readType(self, value):
|
||||
'''
|
||||
call specific read on type object
|
||||
or iterate over tuple elements
|
||||
@param value: (tuple | Type) object
|
||||
'''
|
||||
#read each tuple
|
||||
if isinstance(value, tuple):
|
||||
@@ -382,6 +418,7 @@ class Stream(StringIO):
|
||||
def readNextType(self, t):
|
||||
'''
|
||||
read next type but didn't consume it
|
||||
@param t: Type element
|
||||
'''
|
||||
self.readType(t)
|
||||
self.pos -= sizeof(t)
|
||||
@@ -389,6 +426,8 @@ class Stream(StringIO):
|
||||
def writeType(self, value):
|
||||
'''
|
||||
call specific write on type object
|
||||
or iterate over tuple element
|
||||
@param value: (tuple | Type)
|
||||
'''
|
||||
#write each element of tuple
|
||||
if isinstance(value, tuple):
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
'''
|
||||
@author: sylvain
|
||||
'''
|
||||
|
||||
from rdpy.protocol.network.type import UInt8, UInt16Be, UInt32Be
|
||||
|
||||
def readLength(s):
|
||||
'''
|
||||
read length use in per specification
|
||||
@param s: Stream
|
||||
@return: UInt16Be
|
||||
'''
|
||||
byte = UInt8()
|
||||
s.readType(byte)
|
||||
size = None
|
||||
if (byte & UInt8(0x80)) == UInt8(0x80):
|
||||
byte &= ~UInt8(0x80)
|
||||
size = UInt16Be(byte.value << 8)
|
||||
s.readType(byte)
|
||||
size += s.value + byte
|
||||
else:
|
||||
size = UInt16Be(byte.value)
|
||||
return size
|
||||
@@ -9,7 +9,7 @@ from message import ProtocolVersion, SecurityType, Encoding, ClientToServerMessa
|
||||
|
||||
class Rfb(RawLayer):
|
||||
'''
|
||||
implements rfb protocol message
|
||||
implements rfb protocol
|
||||
'''
|
||||
CLIENT = 0
|
||||
SERVER = 1
|
||||
@@ -18,7 +18,8 @@ class Rfb(RawLayer):
|
||||
'''
|
||||
constructor
|
||||
mode can be only client or server mode
|
||||
in this version of RDPY only support client mode
|
||||
in this RDPY version only client mode is supported
|
||||
@param mode: Rfb.CLIENT | Rfb.SERVER
|
||||
'''
|
||||
RawLayer.__init__(self)
|
||||
#usefull for rfb protocol
|
||||
@@ -48,6 +49,7 @@ class Rfb(RawLayer):
|
||||
def addObserver(self, observer):
|
||||
'''
|
||||
add observer for input/ouput events
|
||||
@param observer: RfbObserver interface implementation
|
||||
'''
|
||||
self._observer.append(observer)
|
||||
|
||||
@@ -55,13 +57,16 @@ class Rfb(RawLayer):
|
||||
'''
|
||||
2nd level of waiting event
|
||||
read expectedHeaderLen that contain body size
|
||||
@param expectedHeaderLen: bytes read and use to compute bodylen
|
||||
@param callbackBody: next state use when value read from header
|
||||
are received
|
||||
'''
|
||||
self._callbackBody = callbackBody
|
||||
self.expect(expectedHeaderLen, self.expectedBody)
|
||||
|
||||
def expectedBody(self, data):
|
||||
'''
|
||||
read header and expect body
|
||||
read header and wait header value to call next state
|
||||
'''
|
||||
bodyLen = None
|
||||
if data.len == 1:
|
||||
|
||||
Reference in New Issue
Block a user