add comment and per functions

This commit is contained in:
speyrefitte
2013-10-21 12:00:32 +02:00
parent b4a5bb35ba
commit 19158040f4
5 changed files with 142 additions and 61 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):

View File

@@ -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

View File

@@ -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: