code refactoring + integrate rdesktop code for bitmap decompression
This commit is contained in:
@@ -53,7 +53,7 @@ class RDPClientQtFactory(rdp.ClientFactory):
|
|||||||
#create qt widget
|
#create qt widget
|
||||||
self._w = client.getWidget()
|
self._w = client.getWidget()
|
||||||
self._w.resize(self._width, self._height)
|
self._w.resize(self._width, self._height)
|
||||||
self._w.setWindowTitle('rdpyclient-rdp')
|
self._w.setWindowTitle('rdpy-rdpclient')
|
||||||
self._w.show()
|
self._w.show()
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class RFBClientQtFactory(rfb.ClientFactory):
|
|||||||
#create qt widget
|
#create qt widget
|
||||||
self._w = client.getWidget()
|
self._w = client.getWidget()
|
||||||
self._w.resize(1024, 800)
|
self._w.resize(1024, 800)
|
||||||
self._w.setWindowTitle('rdpyclient-vnc')
|
self._w.setWindowTitle('rdpy-vncclient')
|
||||||
self._w.show()
|
self._w.show()
|
||||||
return client
|
return client
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,5 @@
|
|||||||
#include "../../src/rle/rle.h"
|
#include "../../src/rle/rle.h"
|
||||||
%End
|
%End
|
||||||
|
|
||||||
int rle_decode_uint8(void* output, int width, int height, char* input, int size);
|
int bitmap_decompress(void * output, int width, int height, char * input, int size, int Bpp);
|
||||||
int rle_decode_uint16(void* output, int width, int height, char* input, int size);
|
|
||||||
int rle_decode_uint24(void* output, int width, int height, char* input, int size);
|
|
||||||
|
|||||||
1372
lib/src/rle/rle.c
1372
lib/src/rle/rle.c
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,6 @@
|
|||||||
#ifndef _RLE_H_
|
#ifndef _RLE_H_
|
||||||
#define _RLE_H_
|
#define _RLE_H_
|
||||||
|
|
||||||
|
int bitmap_decompress(char * output, int width, int height, char * input, int size, int Bpp);
|
||||||
int rle_decode_uint8(char* output, int width, int height, char* input, int size);
|
|
||||||
int rle_decode_uint16(char* output, int width, int height, char* input, int size);
|
|
||||||
int rle_decode_uint24(char* output, int width, int height, char* input, int size);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
#ifndef _RLE_M_H_
|
|
||||||
#define _RLE_M_H_
|
|
||||||
|
|
||||||
#include "rle.h"
|
|
||||||
|
|
||||||
#define CVAL(p) ((unsigned char)(*(p++)))
|
|
||||||
|
|
||||||
#if defined(B_ENDIAN)
|
|
||||||
#define EIK0 1
|
|
||||||
#define EIK1 0
|
|
||||||
#else
|
|
||||||
#define EIK0 0
|
|
||||||
#define EIK1 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define REPEAT(statement) \
|
|
||||||
{ \
|
|
||||||
while ((count > 0) && (x < width)) \
|
|
||||||
{ \
|
|
||||||
statement; \
|
|
||||||
count--; \
|
|
||||||
x++; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MASK_UPDATE \
|
|
||||||
{ \
|
|
||||||
mixmask <<= 1; \
|
|
||||||
if ((mixmask & 0xff) == 0) \
|
|
||||||
{ \
|
|
||||||
mask = fom_mask ? fom_mask : CVAL(input); \
|
|
||||||
mixmask = 1; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -28,17 +28,15 @@ import struct
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
from error import InvalidValue
|
from error import InvalidValue
|
||||||
from rdpy.network.error import InvalidExpectedDataException, InvalidSize
|
from rdpy.network.error import InvalidExpectedDataException, InvalidSize, CallPureVirtualFuntion
|
||||||
|
|
||||||
def sizeof(element):
|
def sizeof(element):
|
||||||
'''
|
"""
|
||||||
byte size of type
|
Byte size of type sum sizeof of tuple element
|
||||||
sum sizeof of tuple element
|
And count only element that condition is true at sizeof call
|
||||||
and count only element that condition
|
|
||||||
is true at sizeof call
|
|
||||||
@param element: Type or Tuple(Type | Tuple,)
|
@param element: Type or Tuple(Type | Tuple,)
|
||||||
@return: size of element in byte
|
@return: size of element in byte
|
||||||
'''
|
"""
|
||||||
if isinstance(element, tuple) or isinstance(element, list):
|
if isinstance(element, tuple) or isinstance(element, list):
|
||||||
size = 0
|
size = 0
|
||||||
for i in element:
|
for i in element:
|
||||||
@@ -50,18 +48,16 @@ def sizeof(element):
|
|||||||
|
|
||||||
|
|
||||||
class Type(object):
|
class Type(object):
|
||||||
'''
|
"""
|
||||||
root type object inheritance
|
Root type object inheritance
|
||||||
record conditional optional of constant
|
Record conditional optional of constant mechanism
|
||||||
mechanism
|
"""
|
||||||
'''
|
|
||||||
def __init__(self, conditional = lambda:True, optional = False, constant = False):
|
def __init__(self, conditional = lambda:True, optional = False, constant = False):
|
||||||
'''
|
"""
|
||||||
constructor of any type object
|
|
||||||
@param conditional : function call before read or write type
|
@param conditional : function call before read or write type
|
||||||
@param optional: boolean check before read if there is still data in stream
|
@param optional: boolean check before read if there is still data in stream
|
||||||
@param constant: if true check any changement of object during reading
|
@param constant: if true check any modification of object during reading
|
||||||
'''
|
"""
|
||||||
self._conditional = conditional
|
self._conditional = conditional
|
||||||
self._optional = optional
|
self._optional = optional
|
||||||
self._constant = constant
|
self._constant = constant
|
||||||
@@ -73,22 +69,22 @@ class Type(object):
|
|||||||
self._is_writed = False
|
self._is_writed = False
|
||||||
|
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
'''
|
"""
|
||||||
write type into stream if conditional is true
|
Write type into stream if conditional is true
|
||||||
and call private
|
Call virtual __write__ method
|
||||||
@param s: Stream which will be written
|
@param s: Stream which will be written
|
||||||
'''
|
"""
|
||||||
self._is_writed = self._conditional()
|
self._is_writed = self._conditional()
|
||||||
if not self._is_writed:
|
if not self._is_writed:
|
||||||
return
|
return
|
||||||
self.__write__(s)
|
self.__write__(s)
|
||||||
|
|
||||||
def read(self, s):
|
def read(self, s):
|
||||||
'''
|
"""
|
||||||
read type from stream s if conditional
|
Read type from stream s if conditional is true
|
||||||
is true and check constantness
|
Check constantness
|
||||||
@param s: Stream
|
@param s: Stream
|
||||||
'''
|
"""
|
||||||
self._is_readed = self._conditional()
|
self._is_readed = self._conditional()
|
||||||
if not self._is_readed:
|
if not self._is_readed:
|
||||||
return
|
return
|
||||||
@@ -108,56 +104,54 @@ class Type(object):
|
|||||||
raise InvalidExpectedDataException("%s const value expected %s != %s"%(self.__class__, old.value, self.value))
|
raise InvalidExpectedDataException("%s const value expected %s != %s"%(self.__class__, old.value, self.value))
|
||||||
|
|
||||||
def __read__(self, s):
|
def __read__(self, s):
|
||||||
'''
|
"""
|
||||||
interface definition of private read funtion
|
Interface definition of private read function
|
||||||
@param s: Stream
|
@param s: Stream
|
||||||
'''
|
"""
|
||||||
pass
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "__read__", "Type"))
|
||||||
|
|
||||||
def __write__(self, s):
|
def __write__(self, s):
|
||||||
'''
|
"""
|
||||||
interface definition of private write funtion
|
Interface definition of private write function
|
||||||
@param s: Stream
|
@param s: Stream
|
||||||
'''
|
"""
|
||||||
pass
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "__write__", "Type"))
|
||||||
|
|
||||||
def __sizeof__(self):
|
def __sizeof__(self):
|
||||||
'''
|
"""
|
||||||
return size of type use for sizeof function
|
Return size of type use for sizeof function
|
||||||
@return: size in byte of type
|
@return: size in byte of type
|
||||||
'''
|
"""
|
||||||
pass
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "__sizeof__", "Type"))
|
||||||
|
|
||||||
class CallableValue(object):
|
class CallableValue(object):
|
||||||
'''
|
"""
|
||||||
wrap access of callable value.
|
Wrap access of callable value.
|
||||||
When use getter value is call.
|
When use getter value is call.
|
||||||
Constant value can also be wrap
|
Constant value can also be wrap and will be transformed into callable value(lambda function)
|
||||||
and will be transformed into callable value(lambda function)
|
"""
|
||||||
'''
|
|
||||||
def __init__(self, value):
|
def __init__(self, value):
|
||||||
'''
|
"""
|
||||||
construtor
|
|
||||||
@param value: value will be wrapped (constant | lambda | function)
|
@param value: value will be wrapped (constant | lambda | function)
|
||||||
'''
|
"""
|
||||||
self._value = None
|
self._value = None
|
||||||
self.value = value
|
self.value = value
|
||||||
|
|
||||||
def __getValue__(self):
|
def __getValue__(self):
|
||||||
'''
|
"""
|
||||||
can be overwritten to add specific check before
|
Can be overwritten to add specific check before
|
||||||
self.value is call
|
self.value is call
|
||||||
@return: result of callbale value
|
@return: result of callable value
|
||||||
'''
|
"""
|
||||||
return self._value()
|
return self._value()
|
||||||
|
|
||||||
def __setValue__(self, value):
|
def __setValue__(self, value):
|
||||||
'''
|
"""
|
||||||
can be overwritten to add specific check before
|
Can be overwritten to add specific check before
|
||||||
self.value = value is call
|
self.value = value is call
|
||||||
check if value is callable and if not transform it
|
Check if value is callable and if not transform it
|
||||||
@param value: new value wrapped if constant -> lambda function
|
@param value: new value wrapped if constant -> lambda function
|
||||||
'''
|
"""
|
||||||
value_callable = lambda:value
|
value_callable = lambda:value
|
||||||
if callable(value):
|
if callable(value):
|
||||||
value_callable = value
|
value_callable = value
|
||||||
@@ -166,37 +160,34 @@ class CallableValue(object):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
'''
|
"""
|
||||||
shortcut to access inner value
|
Shortcut to access inner value main getter of value
|
||||||
main getter of value
|
|
||||||
@return: result of callable value
|
@return: result of callable value
|
||||||
'''
|
"""
|
||||||
return self.__getValue__()
|
return self.__getValue__()
|
||||||
|
|
||||||
@value.setter
|
@value.setter
|
||||||
def value(self, value):
|
def value(self, value):
|
||||||
'''
|
"""
|
||||||
setter of value after check it
|
Setter of value after check it main setter of value
|
||||||
main setter of value
|
@param value: new value encompass in value type object
|
||||||
@param value: new value encompass in valuetype object
|
"""
|
||||||
'''
|
|
||||||
self.__setValue__(value)
|
self.__setValue__(value)
|
||||||
|
|
||||||
class SimpleType(Type, CallableValue):
|
class SimpleType(Type, CallableValue):
|
||||||
'''
|
"""
|
||||||
simple type
|
Simple type
|
||||||
'''
|
"""
|
||||||
def __init__(self, structFormat, typeSize, signed, value, conditional = lambda:True, optional = False, constant = False):
|
def __init__(self, structFormat, typeSize, signed, value, conditional = lambda:True, optional = False, constant = False):
|
||||||
'''
|
"""
|
||||||
constructor of simple type
|
|
||||||
@param structFormat: letter that represent type in struct package
|
@param structFormat: letter that represent type in struct package
|
||||||
@param typeSize: size in byte of type
|
@param typeSize: size in byte of type
|
||||||
@param signed: true if type represent a signed type
|
@param signed: true if type represent a signed type
|
||||||
@param value: value recorded in this object (can be callable value which be call when is acces usefull with closure)
|
@param value: value recorded in this object (can be callable value which be call when is access useful with closure)
|
||||||
@param conditional : function call before read or write type
|
@param conditional : function call before read or write type
|
||||||
@param optional: boolean check before read if there is still data in stream
|
@param optional: boolean check before read if there is still data in stream
|
||||||
@param constant: if true check any changement of object during reading
|
@param constant: if true check any modification of object during reading
|
||||||
'''
|
"""
|
||||||
self._signed = signed
|
self._signed = signed
|
||||||
self._typeSize = typeSize
|
self._typeSize = typeSize
|
||||||
self._structFormat = structFormat
|
self._structFormat = structFormat
|
||||||
@@ -204,13 +195,12 @@ class SimpleType(Type, CallableValue):
|
|||||||
CallableValue.__init__(self, value)
|
CallableValue.__init__(self, value)
|
||||||
|
|
||||||
def __getValue__(self):
|
def __getValue__(self):
|
||||||
'''
|
"""
|
||||||
CallableValue overwrite
|
CallableValue overwrite check mask type of value
|
||||||
check mask type of value
|
|
||||||
use CallableValue access
|
use CallableValue access
|
||||||
@return: python value wrap into type
|
@return: Python value wrap into type
|
||||||
@raise InvalidValue: if value doesn't respect type range
|
@raise InvalidValue: if value doesn't respect type range
|
||||||
'''
|
"""
|
||||||
value = CallableValue.__getValue__(self)
|
value = CallableValue.__getValue__(self)
|
||||||
if not self.isInRange(value):
|
if not self.isInRange(value):
|
||||||
raise InvalidValue("value is out of range for %s"%self.__class__)
|
raise InvalidValue("value is out of range for %s"%self.__class__)
|
||||||
@@ -221,12 +211,12 @@ class SimpleType(Type, CallableValue):
|
|||||||
return value & self.mask()
|
return value & self.mask()
|
||||||
|
|
||||||
def __setValue__(self, value):
|
def __setValue__(self, value):
|
||||||
'''
|
"""
|
||||||
CallableValue overwrite
|
CallableValue overwrite
|
||||||
check mask type of value
|
Check mask type of value
|
||||||
@param value: new value encompass in object (respect python type | lambda | function)
|
@param value: new value encompass in object (respect Python type | lambda | function)
|
||||||
@raise InvalidValue: if value doesn't respect type range
|
@raise InvalidValue: if value doesn't respect type range
|
||||||
'''
|
"""
|
||||||
#check static value range
|
#check static value range
|
||||||
if not callable(value) and not self.isInRange(value):
|
if not callable(value) and not self.isInRange(value):
|
||||||
raise InvalidValue("value is out of range for %s"%self.__class__)
|
raise InvalidValue("value is out of range for %s"%self.__class__)
|
||||||
@@ -235,40 +225,40 @@ class SimpleType(Type, CallableValue):
|
|||||||
|
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
'''
|
"""
|
||||||
compare inner value
|
Compare inner value
|
||||||
magic function of python use for any compare operators
|
Magic function of Python use for any compare operators
|
||||||
@param other: SimpleType value which will be compared with self value
|
@param other: SimpleType value which will be compared with self value
|
||||||
or try to construct same type as self around other value
|
or try to construct same type as self around other value
|
||||||
@return: python value compare
|
@return: Python value compare
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.value.__cmp__(other.value)
|
return self.value.__cmp__(other.value)
|
||||||
|
|
||||||
def __write__(self, s):
|
def __write__(self, s):
|
||||||
'''
|
"""
|
||||||
write value in stream s
|
Write value in stream s
|
||||||
use struct package to pack value
|
Use Struct package to pack value
|
||||||
@param s: Stream which will be written
|
@param s: Stream which will be written
|
||||||
'''
|
"""
|
||||||
s.write(struct.pack(self._structFormat, self.value))
|
s.write(struct.pack(self._structFormat, self.value))
|
||||||
|
|
||||||
def __read__(self, s):
|
def __read__(self, s):
|
||||||
'''
|
"""
|
||||||
read inner value from stream
|
Read inner value from stream
|
||||||
use struct package
|
Use struct package
|
||||||
@param s: Stream
|
@param s: Stream
|
||||||
'''
|
"""
|
||||||
if s.dataLen() < self._typeSize:
|
if s.dataLen() < self._typeSize:
|
||||||
raise InvalidSize("Stream is too small to read expected data")
|
raise InvalidSize("Stream is too small to read expected data")
|
||||||
self.value = struct.unpack(self._structFormat, s.read(self._typeSize))[0]
|
self.value = struct.unpack(self._structFormat, s.read(self._typeSize))[0]
|
||||||
|
|
||||||
def mask(self):
|
def mask(self):
|
||||||
'''
|
"""
|
||||||
compute bit mask for type
|
Compute bit mask for type
|
||||||
because 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"):
|
if not self.__dict__.has_key("_mask"):
|
||||||
mask = 0xff
|
mask = 0xff
|
||||||
for i in range(1, self._typeSize):
|
for i in range(1, self._typeSize):
|
||||||
@@ -277,106 +267,106 @@ class SimpleType(Type, CallableValue):
|
|||||||
return self._mask
|
return self._mask
|
||||||
|
|
||||||
def isInRange(self, value):
|
def isInRange(self, value):
|
||||||
'''
|
"""
|
||||||
check if value is in mask range
|
Check if value is in mask range
|
||||||
@param value: python value
|
@param value: Python value
|
||||||
@return: true if value is in type range
|
@return: true if value is in type range
|
||||||
'''
|
"""
|
||||||
if self._signed:
|
if self._signed:
|
||||||
return not (value < -(self.mask() >> 1) or value > (self.mask() >> 1))
|
return not (value < -(self.mask() >> 1) or value > (self.mask() >> 1))
|
||||||
else:
|
else:
|
||||||
return not (value < 0 or value > self.mask())
|
return not (value < 0 or value > self.mask())
|
||||||
|
|
||||||
def __sizeof__(self):
|
def __sizeof__(self):
|
||||||
'''
|
"""
|
||||||
return size of type
|
Return size of type
|
||||||
@return: typeSize pass in constructor
|
@return: typeSize pass in constructor
|
||||||
'''
|
"""
|
||||||
return self._typeSize
|
return self._typeSize
|
||||||
|
|
||||||
def __invert__(self):
|
def __invert__(self):
|
||||||
'''
|
"""
|
||||||
implement not operator
|
Implement not operator
|
||||||
@return: __class__ value
|
@return: __class__ value
|
||||||
'''
|
"""
|
||||||
invert = ~self.value
|
invert = ~self.value
|
||||||
if not self._signed:
|
if not self._signed:
|
||||||
invert &= self.mask()
|
invert &= self.mask()
|
||||||
return self.__class__(invert)
|
return self.__class__(invert)
|
||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
'''
|
"""
|
||||||
implement addition operator
|
Implement addition operator
|
||||||
@param other: SimpleType value or try to construct same type as self
|
@param other: SimpleType value or try to construct same type as self
|
||||||
around other value
|
around other value
|
||||||
@return: self.__class__ object with add result
|
@return: self.__class__ object with add result
|
||||||
@raise InvalidValue: if new value is out of bound
|
@raise InvalidValue: if new value is out of bound
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__add__(other.value))
|
return self.__class__(self.value.__add__(other.value))
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
'''
|
"""
|
||||||
implement sub operator
|
Implement sub operator
|
||||||
@param other: SimpleType value or try to construct same type as self
|
@param other: SimpleType value or try to construct same type as self
|
||||||
around other value
|
around other value
|
||||||
@return: self.__class__ object with sub result
|
@return: self.__class__ object with sub result
|
||||||
@raise InvalidValue: if new value is out of bound
|
@raise InvalidValue: if new value is out of bound
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__sub__(other.value))
|
return self.__class__(self.value.__sub__(other.value))
|
||||||
|
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
'''
|
"""
|
||||||
implement bitwise and operator
|
Implement bitwise and operator
|
||||||
@param other: SimpleType value or try to construct same type as self
|
@param other: SimpleType value or try to construct same type as self
|
||||||
around other value
|
around other value
|
||||||
@return: self.__class__ object with and result
|
@return: self.__class__ object with and result
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__and__(other.value))
|
return self.__class__(self.value.__and__(other.value))
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
'''
|
"""
|
||||||
implement bitwise or operator
|
implement bitwise or operator
|
||||||
@param other: SimpleType value or try to construct same type as self
|
@param other: SimpleType value or try to construct same type as self
|
||||||
around other value
|
around other value
|
||||||
@return: self.__class__ object with or result
|
@return: self.__class__ object with or result
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__or__(other.value))
|
return self.__class__(self.value.__or__(other.value))
|
||||||
|
|
||||||
def __xor__(self, other):
|
def __xor__(self, other):
|
||||||
'''
|
"""
|
||||||
implement bitwise xor operator
|
Implement bitwise xor operator
|
||||||
@param other: SimpleType value or try to construct same type as self
|
@param other: SimpleType value or try to construct same type as self
|
||||||
around other value
|
around other value
|
||||||
@return: self.__class__ object with or result
|
@return: self.__class__ object with or result
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__xor__(other.value))
|
return self.__class__(self.value.__xor__(other.value))
|
||||||
|
|
||||||
def __lshift__(self, other):
|
def __lshift__(self, other):
|
||||||
'''
|
"""
|
||||||
left shift operator
|
Left shift operator
|
||||||
@param other: python int
|
@param other: Python Int
|
||||||
@return: self.__class__ object with or result
|
@return: self.__class__ object with or result
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__lshift__(other.value))
|
return self.__class__(self.value.__lshift__(other.value))
|
||||||
|
|
||||||
def __rshift__(self, other):
|
def __rshift__(self, other):
|
||||||
'''
|
"""
|
||||||
left shift operator
|
Left shift operator
|
||||||
@param other: python int
|
@param other: python int
|
||||||
@return: self.__class__ object with or result
|
@return: self.__class__ object with or result
|
||||||
'''
|
"""
|
||||||
if not isinstance(other, SimpleType):
|
if not isinstance(other, SimpleType):
|
||||||
other = self.__class__(other)
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__rshift__(other.value))
|
return self.__class__(self.value.__rshift__(other.value))
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'''
|
'''
|
||||||
@author sylvain
|
@author sylvain
|
||||||
@summary gcc language
|
@summary gcc language
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240508.aspx
|
||||||
'''
|
'''
|
||||||
from rdpy.network.const import ConstAttributes, TypeAttributes
|
from rdpy.network.const import ConstAttributes, TypeAttributes
|
||||||
from rdpy.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
|
from rdpy.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
|
||||||
|
|||||||
@@ -18,14 +18,12 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Implement Multi Channel Service
|
Implement Multi-Channel Service
|
||||||
|
|
||||||
Each channel have a particular role.
|
Each channel have a particular role.
|
||||||
The main channel is the graphical channel.
|
The main channel is the graphical channel.
|
||||||
It exist channel for file system order, audio channel, clipboard etc...
|
It exist channel for file system order, audio channel, clipboard etc...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.const import ConstAttributes, TypeAttributes
|
|
||||||
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
||||||
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Be
|
from rdpy.network.type import sizeof, Stream, UInt8, UInt16Be
|
||||||
from rdpy.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
from rdpy.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
||||||
@@ -33,8 +31,6 @@ from rdpy.protocol.rdp.ber import writeLength
|
|||||||
|
|
||||||
import ber, gcc, per
|
import ber, gcc, per
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt8)
|
|
||||||
class Message(object):
|
class Message(object):
|
||||||
"""
|
"""
|
||||||
Message type
|
Message type
|
||||||
@@ -42,8 +38,6 @@ class Message(object):
|
|||||||
MCS_TYPE_CONNECT_INITIAL = 0x65
|
MCS_TYPE_CONNECT_INITIAL = 0x65
|
||||||
MCS_TYPE_CONNECT_RESPONSE = 0x66
|
MCS_TYPE_CONNECT_RESPONSE = 0x66
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt8)
|
|
||||||
class DomainMCSPDU:
|
class DomainMCSPDU:
|
||||||
"""
|
"""
|
||||||
Domain MCS PDU header
|
Domain MCS PDU header
|
||||||
@@ -57,8 +51,6 @@ class DomainMCSPDU:
|
|||||||
SEND_DATA_REQUEST = 25
|
SEND_DATA_REQUEST = 25
|
||||||
SEND_DATA_INDICATION = 26
|
SEND_DATA_INDICATION = 26
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt16Be)
|
|
||||||
class Channel:
|
class Channel:
|
||||||
"""
|
"""
|
||||||
Channel id of main channels use in RDP
|
Channel id of main channels use in RDP
|
||||||
@@ -126,7 +118,7 @@ class MCS(LayerAutomata):
|
|||||||
self._clientSettings = gcc.ClientSettings()
|
self._clientSettings = gcc.ClientSettings()
|
||||||
self._serverSettings = gcc.ServerSettings()
|
self._serverSettings = gcc.ServerSettings()
|
||||||
#default user Id
|
#default user Id
|
||||||
self._userId = UInt16Be(1)
|
self._userId = 1
|
||||||
#list of channel use in this layer and connection state
|
#list of channel use in this layer and connection state
|
||||||
self._channelIds = {Channel.MCS_GLOBAL_CHANNEL: presentation}
|
self._channelIds = {Channel.MCS_GLOBAL_CHANNEL: presentation}
|
||||||
#use to record already requested channel
|
#use to record already requested channel
|
||||||
@@ -137,7 +129,7 @@ class MCS(LayerAutomata):
|
|||||||
Connection send for client mode
|
Connection send for client mode
|
||||||
a write connect initial packet
|
a write connect initial packet
|
||||||
"""
|
"""
|
||||||
self._clientSettings.core.serverSelectedProtocol = self._transport._selectedProtocol
|
self._clientSettings.core.serverSelectedProtocol.value = self._transport._selectedProtocol
|
||||||
self.sendConnectInitial()
|
self.sendConnectInitial()
|
||||||
|
|
||||||
def connectNextChannel(self):
|
def connectNextChannel(self):
|
||||||
@@ -173,7 +165,7 @@ class MCS(LayerAutomata):
|
|||||||
self.writeDomainParams(1, 1, 1, 0x420),
|
self.writeDomainParams(1, 1, 1, 0x420),
|
||||||
self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff),
|
self.writeDomainParams(0xffff, 0xfc17, 0xffff, 0xffff),
|
||||||
ber.writeOctetstring(ccReqStream.getvalue()))
|
ber.writeOctetstring(ccReqStream.getvalue()))
|
||||||
self._transport.send((ber.writeApplicationTag(Message.MCS_TYPE_CONNECT_INITIAL, sizeof(tmp)), tmp))
|
self._transport.send((ber.writeApplicationTag(UInt8(Message.MCS_TYPE_CONNECT_INITIAL), sizeof(tmp)), tmp))
|
||||||
#we must receive a connect response
|
#we must receive a connect response
|
||||||
self.setNextState(self.recvConnectResponse)
|
self.setNextState(self.recvConnectResponse)
|
||||||
|
|
||||||
@@ -181,26 +173,26 @@ class MCS(LayerAutomata):
|
|||||||
"""
|
"""
|
||||||
Send a formated erect domain request for RDP connection
|
Send a formated erect domain request for RDP connection
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(DomainMCSPDU.ERECT_DOMAIN_REQUEST), per.writeInteger(0), per.writeInteger(0)))
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.ERECT_DOMAIN_REQUEST)), per.writeInteger(0), per.writeInteger(0)))
|
||||||
|
|
||||||
def sendAttachUserRequest(self):
|
def sendAttachUserRequest(self):
|
||||||
"""
|
"""
|
||||||
Send a formated attach user request for RDP connection
|
Send a formated attach user request for RDP connection
|
||||||
"""
|
"""
|
||||||
self._transport.send(self.writeMCSPDUHeader(DomainMCSPDU.ATTACH_USER_REQUEST))
|
self._transport.send(self.writeMCSPDUHeader(UInt8(DomainMCSPDU.ATTACH_USER_REQUEST)))
|
||||||
|
|
||||||
def sendChannelJoinRequest(self, channelId):
|
def sendChannelJoinRequest(self, channelId):
|
||||||
"""
|
"""
|
||||||
Send a formated Channel join request from client to server
|
Send a formated Channel join request from client to server
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(DomainMCSPDU.CHANNEL_JOIN_REQUEST), self._userId, channelId))
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)), UInt16Be(self._userId), UInt16Be(channelId)))
|
||||||
|
|
||||||
def recvConnectResponse(self, data):
|
def recvConnectResponse(self, data):
|
||||||
"""
|
"""
|
||||||
receive MCS connect response from server
|
receive MCS connect response from server
|
||||||
@param data: Stream
|
@param data: Stream
|
||||||
"""
|
"""
|
||||||
ber.readApplicationTag(data, Message.MCS_TYPE_CONNECT_RESPONSE)
|
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE))
|
||||||
ber.readEnumerated(data)
|
ber.readEnumerated(data)
|
||||||
ber.readInteger(data)
|
ber.readInteger(data)
|
||||||
self.readDomainParams(data)
|
self.readDomainParams(data)
|
||||||
@@ -225,13 +217,15 @@ class MCS(LayerAutomata):
|
|||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
confirm = UInt8()
|
confirm = UInt8()
|
||||||
|
userId = UInt16Be()
|
||||||
data.readType((opcode, confirm))
|
data.readType((opcode, confirm))
|
||||||
if not self.readMCSPDUHeader(opcode, DomainMCSPDU.ATTACH_USER_CONFIRM):
|
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.ATTACH_USER_CONFIRM):
|
||||||
raise InvalidExpectedDataException("invalid MCS PDU")
|
raise InvalidExpectedDataException("invalid MCS PDU")
|
||||||
if confirm != 0:
|
if confirm != 0:
|
||||||
raise Exception("server reject user")
|
raise Exception("server reject user")
|
||||||
if opcode & UInt8(2) == UInt8(2):
|
if opcode & UInt8(2) == UInt8(2):
|
||||||
data.readType(self._userId)
|
data.readType(userId)
|
||||||
|
self._userId = userId.value
|
||||||
|
|
||||||
#build channel list because we have user id
|
#build channel list because we have user id
|
||||||
#add default channel + channels accepted by gcc connection sequence
|
#add default channel + channels accepted by gcc connection sequence
|
||||||
@@ -247,7 +241,7 @@ class MCS(LayerAutomata):
|
|||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
confirm = UInt8()
|
confirm = UInt8()
|
||||||
data.readType((opcode, confirm))
|
data.readType((opcode, confirm))
|
||||||
if not self.readMCSPDUHeader(opcode, DomainMCSPDU.CHANNEL_JOIN_CONFIRM):
|
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.CHANNEL_JOIN_CONFIRM):
|
||||||
raise InvalidExpectedDataException("invalid MCS PDU")
|
raise InvalidExpectedDataException("invalid MCS PDU")
|
||||||
userId = UInt16Be()
|
userId = UInt16Be()
|
||||||
channelId = UInt16Be()
|
channelId = UInt16Be()
|
||||||
@@ -269,11 +263,11 @@ class MCS(LayerAutomata):
|
|||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
|
|
||||||
if self.readMCSPDUHeader(opcode, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
|
if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
|
||||||
print "receive DISCONNECT_PROVIDER_ULTIMATUM"
|
print "receive DISCONNECT_PROVIDER_ULTIMATUM"
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
elif not self.readMCSPDUHeader(opcode, DomainMCSPDU.SEND_DATA_INDICATION):
|
elif not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.SEND_DATA_INDICATION):
|
||||||
raise InvalidExpectedDataException("invalid expected mcs opcode")
|
raise InvalidExpectedDataException("invalid expected mcs opcode")
|
||||||
|
|
||||||
userId = UInt16Be()
|
userId = UInt16Be()
|
||||||
@@ -306,7 +300,7 @@ class MCS(LayerAutomata):
|
|||||||
@param channelId: Channel use to send
|
@param channelId: Channel use to send
|
||||||
@param data: message to send
|
@param data: message to send
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(DomainMCSPDU.SEND_DATA_REQUEST), self._userId, channelId, UInt8(0x70), UInt16Be(sizeof(data)) | UInt16Be(0x8000), data))
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.SEND_DATA_REQUEST)), UInt16Be(self._userId), UInt16Be(channelId), UInt8(0x70), UInt16Be(sizeof(data)) | UInt16Be(0x8000), data))
|
||||||
|
|
||||||
|
|
||||||
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
||||||
@@ -336,7 +330,7 @@ class MCS(LayerAutomata):
|
|||||||
def readMCSPDUHeader(self, opcode, mcsPdu):
|
def readMCSPDUHeader(self, opcode, mcsPdu):
|
||||||
"""
|
"""
|
||||||
Read mcsPdu header and return options parameter
|
Read mcsPdu header and return options parameter
|
||||||
@param opcode: UInt8 opcode
|
@param opcode: opcode
|
||||||
@param mcsPdu: mcsPdu will be checked
|
@param mcsPdu: mcsPdu will be checked
|
||||||
@return: true if opcode is correct
|
@return: true if opcode is correct
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,6 +1,27 @@
|
|||||||
'''
|
#
|
||||||
@author: citronneur
|
# Copyright (c) 2014 Sylvain Peyrefitte
|
||||||
'''
|
#
|
||||||
|
# This file is part of rdpy.
|
||||||
|
#
|
||||||
|
# rdpy is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
Implement the main graphic layer
|
||||||
|
|
||||||
|
In this layer are managed all mains bitmap update orders end user inputs
|
||||||
|
"""
|
||||||
|
|
||||||
from rdpy.network.layer import LayerAutomata
|
from rdpy.network.layer import LayerAutomata
|
||||||
from rdpy.network.type import CompositeType, UniString, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
|
from rdpy.network.type import CompositeType, UniString, String, UInt8, UInt16Le, UInt32Le, sizeof, ArrayType, FactoryType
|
||||||
@@ -12,18 +33,18 @@ import gcc, lic, caps
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class SecurityFlag(object):
|
class SecurityFlag(object):
|
||||||
'''
|
"""
|
||||||
microsoft security flags
|
Microsoft security flags
|
||||||
'''
|
"""
|
||||||
SEC_INFO_PKT = 0x0040
|
SEC_INFO_PKT = 0x0040
|
||||||
SEC_LICENSE_PKT = 0x0080
|
SEC_LICENSE_PKT = 0x0080
|
||||||
|
|
||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt32Le)
|
@TypeAttributes(UInt32Le)
|
||||||
class InfoFlag(object):
|
class InfoFlag(object):
|
||||||
'''
|
"""
|
||||||
client capabilities informations
|
Client capabilities informations
|
||||||
'''
|
"""
|
||||||
INFO_MOUSE = 0x00000001
|
INFO_MOUSE = 0x00000001
|
||||||
INFO_DISABLECTRLALTDEL = 0x00000002
|
INFO_DISABLECTRLALTDEL = 0x00000002
|
||||||
INFO_AUTOLOGON = 0x00000008
|
INFO_AUTOLOGON = 0x00000008
|
||||||
@@ -47,9 +68,9 @@ class InfoFlag(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt32Le)
|
@TypeAttributes(UInt32Le)
|
||||||
class PerfFlag(object):
|
class PerfFlag(object):
|
||||||
'''
|
"""
|
||||||
network performances flag
|
Network performances flag
|
||||||
'''
|
"""
|
||||||
PERF_DISABLE_WALLPAPER = 0x00000001
|
PERF_DISABLE_WALLPAPER = 0x00000001
|
||||||
PERF_DISABLE_FULLWINDOWDRAG = 0x00000002
|
PERF_DISABLE_FULLWINDOWDRAG = 0x00000002
|
||||||
PERF_DISABLE_MENUANIMATIONS = 0x00000004
|
PERF_DISABLE_MENUANIMATIONS = 0x00000004
|
||||||
@@ -62,16 +83,19 @@ class PerfFlag(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class AfInet(object):
|
class AfInet(object):
|
||||||
|
"""
|
||||||
|
IPv4 or IPv6 adress style
|
||||||
|
"""
|
||||||
AF_INET = 0x00002
|
AF_INET = 0x00002
|
||||||
AF_INET6 = 0x0017
|
AF_INET6 = 0x0017
|
||||||
|
|
||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class PDUType(object):
|
class PDUType(object):
|
||||||
'''
|
"""
|
||||||
data pdu type primary index
|
Data PDU type primary index
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240576.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240576.aspx
|
||||||
'''
|
"""
|
||||||
PDUTYPE_DEMANDACTIVEPDU = 0x11
|
PDUTYPE_DEMANDACTIVEPDU = 0x11
|
||||||
PDUTYPE_CONFIRMACTIVEPDU = 0x13
|
PDUTYPE_CONFIRMACTIVEPDU = 0x13
|
||||||
PDUTYPE_DEACTIVATEALLPDU = 0x16
|
PDUTYPE_DEACTIVATEALLPDU = 0x16
|
||||||
@@ -81,10 +105,10 @@ class PDUType(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt8)
|
@TypeAttributes(UInt8)
|
||||||
class PDUType2(object):
|
class PDUType2(object):
|
||||||
'''
|
"""
|
||||||
data pdu type secondary index
|
Data PDU type secondary index
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
||||||
'''
|
"""
|
||||||
PDUTYPE2_UPDATE = 0x02
|
PDUTYPE2_UPDATE = 0x02
|
||||||
PDUTYPE2_CONTROL = 0x14
|
PDUTYPE2_CONTROL = 0x14
|
||||||
PDUTYPE2_POINTER = 0x1B
|
PDUTYPE2_POINTER = 0x1B
|
||||||
@@ -113,10 +137,10 @@ class PDUType2(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt8)
|
@TypeAttributes(UInt8)
|
||||||
class StreamId(object):
|
class StreamId(object):
|
||||||
'''
|
"""
|
||||||
stream priority
|
Stream priority
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
||||||
'''
|
"""
|
||||||
STREAM_UNDEFINED = 0x00
|
STREAM_UNDEFINED = 0x00
|
||||||
STREAM_LOW = 0x01
|
STREAM_LOW = 0x01
|
||||||
STREAM_MED = 0x02
|
STREAM_MED = 0x02
|
||||||
@@ -125,10 +149,10 @@ class StreamId(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt8)
|
@TypeAttributes(UInt8)
|
||||||
class CompressionOrder(object):
|
class CompressionOrder(object):
|
||||||
'''
|
"""
|
||||||
pdu compression order
|
PDU compression order
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
||||||
'''
|
"""
|
||||||
CompressionTypeMask = 0x0F
|
CompressionTypeMask = 0x0F
|
||||||
PACKET_COMPRESSED = 0x20
|
PACKET_COMPRESSED = 0x20
|
||||||
PACKET_AT_FRONT = 0x40
|
PACKET_AT_FRONT = 0x40
|
||||||
@@ -137,10 +161,10 @@ class CompressionOrder(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt8)
|
@TypeAttributes(UInt8)
|
||||||
class CompressionType(object):
|
class CompressionType(object):
|
||||||
'''
|
"""
|
||||||
pdu compression type
|
PDU compression type
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
||||||
'''
|
"""
|
||||||
PACKET_COMPR_TYPE_8K = 0x0
|
PACKET_COMPR_TYPE_8K = 0x0
|
||||||
PACKET_COMPR_TYPE_64K = 0x1
|
PACKET_COMPR_TYPE_64K = 0x1
|
||||||
PACKET_COMPR_TYPE_RDP6 = 0x2
|
PACKET_COMPR_TYPE_RDP6 = 0x2
|
||||||
@@ -149,10 +173,10 @@ class CompressionType(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class Action(object):
|
class Action(object):
|
||||||
'''
|
"""
|
||||||
Action flag use in Control PDU packet
|
Action flag use in Control PDU packet
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240492.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240492.aspx
|
||||||
'''
|
"""
|
||||||
CTRLACTION_REQUEST_CONTROL = 0x0001
|
CTRLACTION_REQUEST_CONTROL = 0x0001
|
||||||
CTRLACTION_GRANTED_CONTROL = 0x0002
|
CTRLACTION_GRANTED_CONTROL = 0x0002
|
||||||
CTRLACTION_DETACH = 0x0003
|
CTRLACTION_DETACH = 0x0003
|
||||||
@@ -161,30 +185,30 @@ class Action(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class PersistentKeyListFlag(object):
|
class PersistentKeyListFlag(object):
|
||||||
'''
|
"""
|
||||||
use to determine the number of persistent key packet
|
Use to determine the number of persistent key packet
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240495.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240495.aspx
|
||||||
'''
|
"""
|
||||||
PERSIST_FIRST_PDU = 0x01
|
PERSIST_FIRST_PDU = 0x01
|
||||||
PERSIST_LAST_PDU = 0x02
|
PERSIST_LAST_PDU = 0x02
|
||||||
|
|
||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class BitmapFlag(object):
|
class BitmapFlag(object):
|
||||||
'''
|
"""
|
||||||
use in bitmap update PDU
|
Use in bitmap update PDU
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240612.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240612.aspx
|
||||||
'''
|
"""
|
||||||
BITMAP_COMPRESSION = 0x0001
|
BITMAP_COMPRESSION = 0x0001
|
||||||
NO_BITMAP_COMPRESSION_HDR = 0x0400
|
NO_BITMAP_COMPRESSION_HDR = 0x0400
|
||||||
|
|
||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class UpdateType(object):
|
class UpdateType(object):
|
||||||
'''
|
"""
|
||||||
use in update pdu to determine which type of update
|
Use in update PDU to determine which type of update
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240608.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240608.aspx
|
||||||
'''
|
"""
|
||||||
UPDATETYPE_ORDERS = 0x0000
|
UPDATETYPE_ORDERS = 0x0000
|
||||||
UPDATETYPE_BITMAP = 0x0001
|
UPDATETYPE_BITMAP = 0x0001
|
||||||
UPDATETYPE_PALETTE = 0x0002
|
UPDATETYPE_PALETTE = 0x0002
|
||||||
@@ -193,10 +217,10 @@ class UpdateType(object):
|
|||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt32Le)
|
@TypeAttributes(UInt32Le)
|
||||||
class ErrorInfo(object):
|
class ErrorInfo(object):
|
||||||
'''
|
"""
|
||||||
Error code use in Error info pdu
|
Error code use in Error info PDU
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240544.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240544.aspx
|
||||||
'''
|
"""
|
||||||
ERRINFO_RPC_INITIATED_DISCONNECT = 0x00000001
|
ERRINFO_RPC_INITIATED_DISCONNECT = 0x00000001
|
||||||
ERRINFO_RPC_INITIATED_LOGOFF = 0x00000002
|
ERRINFO_RPC_INITIATED_LOGOFF = 0x00000002
|
||||||
ERRINFO_IDLE_TIMEOUT = 0x00000003
|
ERRINFO_IDLE_TIMEOUT = 0x00000003
|
||||||
@@ -404,11 +428,11 @@ class ErrorInfo(object):
|
|||||||
}
|
}
|
||||||
|
|
||||||
class RDPInfo(CompositeType):
|
class RDPInfo(CompositeType):
|
||||||
'''
|
"""
|
||||||
client informations
|
Client informations
|
||||||
contains credentials (very important packet)
|
Contains credentials (very important packet)
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240475.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240475.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, extendedInfoConditional):
|
def __init__(self, extendedInfoConditional):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
#code page
|
#code page
|
||||||
@@ -431,10 +455,10 @@ class RDPInfo(CompositeType):
|
|||||||
self.extendedInfo = RDPExtendedInfo(conditional = extendedInfoConditional)
|
self.extendedInfo = RDPExtendedInfo(conditional = extendedInfoConditional)
|
||||||
|
|
||||||
class RDPExtendedInfo(CompositeType):
|
class RDPExtendedInfo(CompositeType):
|
||||||
'''
|
"""
|
||||||
add more client informations
|
Add more client informations
|
||||||
use for performance flag!!!
|
Use for performance flag!!!
|
||||||
'''
|
"""
|
||||||
def __init__(self, conditional):
|
def __init__(self, conditional):
|
||||||
CompositeType.__init__(self, conditional = conditional)
|
CompositeType.__init__(self, conditional = conditional)
|
||||||
self.clientAddressFamily = AfInet.AF_INET
|
self.clientAddressFamily = AfInet.AF_INET
|
||||||
@@ -446,10 +470,10 @@ class RDPExtendedInfo(CompositeType):
|
|||||||
#self.performanceFlags = PerfFlag.PERF_DISABLE_WALLPAPER | PerfFlag.PERF_DISABLE_MENUANIMATIONS | PerfFlag.PERF_DISABLE_CURSOR_SHADOW
|
#self.performanceFlags = PerfFlag.PERF_DISABLE_WALLPAPER | PerfFlag.PERF_DISABLE_MENUANIMATIONS | PerfFlag.PERF_DISABLE_CURSOR_SHADOW
|
||||||
|
|
||||||
class ShareControlHeader(CompositeType):
|
class ShareControlHeader(CompositeType):
|
||||||
'''
|
"""
|
||||||
PDU share control header
|
PDU share control header
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240576.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240576.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, totalLength, pduType, userId):
|
def __init__(self, totalLength, pduType, userId):
|
||||||
'''
|
'''
|
||||||
constructor
|
constructor
|
||||||
@@ -462,10 +486,10 @@ class ShareControlHeader(CompositeType):
|
|||||||
self.PDUSource = UInt16Le(userId.value + 1001)
|
self.PDUSource = UInt16Le(userId.value + 1001)
|
||||||
|
|
||||||
class ShareDataHeader(CompositeType):
|
class ShareDataHeader(CompositeType):
|
||||||
'''
|
"""
|
||||||
PDU share data header
|
PDU share data header
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240577.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, size, pduType2 = None, userId = UInt16Le(), shareId = UInt32Le()):
|
def __init__(self, size, pduType2 = None, userId = UInt16Le(), shareId = UInt32Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.shareControlHeader = ShareControlHeader(size, PDUType.PDUTYPE_DATAPDU, userId)
|
self.shareControlHeader = ShareControlHeader(size, PDUType.PDUTYPE_DATAPDU, userId)
|
||||||
@@ -478,10 +502,10 @@ class ShareDataHeader(CompositeType):
|
|||||||
self.compressedLength = UInt16Le()
|
self.compressedLength = UInt16Le()
|
||||||
|
|
||||||
class DemandActivePDU(CompositeType):
|
class DemandActivePDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240485.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240485.aspx
|
||||||
main use for capabilities exchange server -> client
|
Main use for capabilities exchange server -> client
|
||||||
'''
|
"""
|
||||||
def __init__(self, userId = UInt16Le()):
|
def __init__(self, userId = UInt16Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_DEMANDACTIVEPDU, userId)
|
self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_DEMANDACTIVEPDU, userId)
|
||||||
@@ -495,10 +519,10 @@ class DemandActivePDU(CompositeType):
|
|||||||
self.sessionId = UInt32Le()
|
self.sessionId = UInt32Le()
|
||||||
|
|
||||||
class ConfirmActivePDU(CompositeType):
|
class ConfirmActivePDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240488.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240488.aspx
|
||||||
main use for capabilities confirm client -> sever
|
Main use for capabilities confirm client -> sever
|
||||||
'''
|
"""
|
||||||
def __init__(self, userId = UInt16Le()):
|
def __init__(self, userId = UInt16Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_CONFIRMACTIVEPDU, userId)
|
self.shareControlHeader = ShareControlHeader(lambda:sizeof(self), PDUType.PDUTYPE_CONFIRMACTIVEPDU, userId)
|
||||||
@@ -512,21 +536,21 @@ class ConfirmActivePDU(CompositeType):
|
|||||||
self.capabilitySets = ArrayType(caps.Capability, readLen = self.numberCapabilities)
|
self.capabilitySets = ArrayType(caps.Capability, readLen = self.numberCapabilities)
|
||||||
|
|
||||||
class PersistentListEntry(CompositeType):
|
class PersistentListEntry(CompositeType):
|
||||||
'''
|
"""
|
||||||
use to record persistent key in PersistentListPDU
|
Use to record persistent key in PersistentListPDU
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240496.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240496.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.key1 = UInt32Le()
|
self.key1 = UInt32Le()
|
||||||
self.key2 = UInt32Le()
|
self.key2 = UInt32Le()
|
||||||
|
|
||||||
class PersistentListPDU(CompositeType):
|
class PersistentListPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Use to indicate that bitmap cache was already
|
Use to indicate that bitmap cache was already
|
||||||
fill with some keys from previous session
|
Fill with some keys from previous session
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240495.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240495.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, userId = UInt16Le(), shareId = UInt32Le()):
|
def __init__(self, userId = UInt16Le(), shareId = UInt32Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), PDUType2.PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST, userId, shareId)
|
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), PDUType2.PDUTYPE2_BITMAPCACHE_PERSISTENT_LIST, userId, shareId)
|
||||||
@@ -546,9 +570,9 @@ class PersistentListPDU(CompositeType):
|
|||||||
self.entries = ArrayType(PersistentListEntry, readLen = UInt16Le(lambda:(self.numEntriesCache0 + self.numEntriesCache1 + self.numEntriesCache2 + self.numEntriesCache3 + self.numEntriesCache4)))
|
self.entries = ArrayType(PersistentListEntry, readLen = UInt16Le(lambda:(self.numEntriesCache0 + self.numEntriesCache1 + self.numEntriesCache2 + self.numEntriesCache3 + self.numEntriesCache4)))
|
||||||
|
|
||||||
class DataPDU(CompositeType):
|
class DataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Generic pdu packet use after connection sequence
|
Generic pdu packet use after connection sequence
|
||||||
'''
|
"""
|
||||||
def __init__(self, pduType = None, pduData = None, userId = UInt16Le(), shareId = UInt32Le()):
|
def __init__(self, pduType = None, pduData = None, userId = UInt16Le(), shareId = UInt32Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), pduType, userId, shareId)
|
self.shareDataHeader = ShareDataHeader(lambda:sizeof(self), pduType, userId, shareId)
|
||||||
@@ -576,18 +600,18 @@ class DataPDU(CompositeType):
|
|||||||
self.pduData = FactoryType(pduData)
|
self.pduData = FactoryType(pduData)
|
||||||
|
|
||||||
class SynchronizeDataPDU(CompositeType):
|
class SynchronizeDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
@see http://msdn.microsoft.com/en-us/library/cc240490.aspx
|
@see http://msdn.microsoft.com/en-us/library/cc240490.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, targetUser = UInt16Le()):
|
def __init__(self, targetUser = UInt16Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.messageType = UInt16Le(1, constant = True)
|
self.messageType = UInt16Le(1, constant = True)
|
||||||
self.targetUser = targetUser
|
self.targetUser = targetUser
|
||||||
|
|
||||||
class ControlDataPDU(CompositeType):
|
class ControlDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
@see http://msdn.microsoft.com/en-us/library/cc240492.aspx
|
@see http://msdn.microsoft.com/en-us/library/cc240492.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, action = None):
|
def __init__(self, action = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.action = UInt16Le(action.value, constant = True) if not action is None else UInt16Le()
|
self.action = UInt16Le(action.value, constant = True) if not action is None else UInt16Le()
|
||||||
@@ -595,21 +619,21 @@ class ControlDataPDU(CompositeType):
|
|||||||
self.controlId = UInt32Le()
|
self.controlId = UInt32Le()
|
||||||
|
|
||||||
class ErrorInfoDataPDU(CompositeType):
|
class ErrorInfoDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Use to inform error in PDU layer
|
Use to inform error in PDU layer
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240544.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240544.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, errorInfo = UInt32Le()):
|
def __init__(self, errorInfo = UInt32Le()):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
#use to collect error info pdu
|
#use to collect error info pdu
|
||||||
self.errorInfo = errorInfo
|
self.errorInfo = errorInfo
|
||||||
|
|
||||||
class FontListDataPDU(CompositeType):
|
class FontListDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Use to indicate list of font. Deprecated packet
|
Use to indicate list of font. Deprecated packet
|
||||||
client -> server
|
client -> server
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240498.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240498.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.numberFonts = UInt16Le()
|
self.numberFonts = UInt16Le()
|
||||||
@@ -618,11 +642,11 @@ class FontListDataPDU(CompositeType):
|
|||||||
self.entrySize = UInt16Le(0x0032)
|
self.entrySize = UInt16Le(0x0032)
|
||||||
|
|
||||||
class FontMapDataPDU(CompositeType):
|
class FontMapDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Use to indicate map of font. Deprecated packet (maybe the same as FontListDataPDU)
|
Use to indicate map of font. Deprecated packet (maybe the same as FontListDataPDU)
|
||||||
server -> client
|
server -> client
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240498.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240498.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.numberEntries = UInt16Le()
|
self.numberEntries = UInt16Le()
|
||||||
@@ -631,11 +655,11 @@ class FontMapDataPDU(CompositeType):
|
|||||||
self.entrySize = UInt16Le(0x0004)
|
self.entrySize = UInt16Le(0x0004)
|
||||||
|
|
||||||
class UpdateDataPDU(CompositeType):
|
class UpdateDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
Update data pdu use by server to inform update img or palette
|
Update data PDU use by server to inform update img or palette
|
||||||
for example
|
for example
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240608.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240608.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, updateType = UInt16Le(), updateData = None):
|
def __init__(self, updateType = UInt16Le(), updateData = None):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.updateType = updateType
|
self.updateType = updateType
|
||||||
@@ -652,20 +676,20 @@ class UpdateDataPDU(CompositeType):
|
|||||||
self.updateData = FactoryType(updateData, conditional = lambda:(self.updateType != UpdateType.UPDATETYPE_SYNCHRONIZE))
|
self.updateData = FactoryType(updateData, conditional = lambda:(self.updateType != UpdateType.UPDATETYPE_SYNCHRONIZE))
|
||||||
|
|
||||||
class BitmapUpdateDataPDU(CompositeType):
|
class BitmapUpdateDataPDU(CompositeType):
|
||||||
'''
|
"""
|
||||||
PDU use to send raw bitmap compressed or not
|
PDU use to send raw bitmap compressed or not
|
||||||
@see: http://msdn.microsoft.com/en-us/library/dd306368.aspx
|
@see: http://msdn.microsoft.com/en-us/library/dd306368.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.numberRectangles = UInt16Le()
|
self.numberRectangles = UInt16Le()
|
||||||
self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles)
|
self.rectangles = ArrayType(BitmapData, readLen = self.numberRectangles)
|
||||||
|
|
||||||
class BitmapCompressedDataHeader(CompositeType):
|
class BitmapCompressedDataHeader(CompositeType):
|
||||||
'''
|
"""
|
||||||
Compressed header of bitmap
|
Compressed header of bitmap
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240644.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240644.aspx
|
||||||
'''
|
"""
|
||||||
def __init__(self, conditional = lambda:True):
|
def __init__(self, conditional = lambda:True):
|
||||||
CompositeType.__init__(self, conditional = conditional)
|
CompositeType.__init__(self, conditional = conditional)
|
||||||
self.cbCompFirstRowSize = UInt16Le(0x0000, constant = True)
|
self.cbCompFirstRowSize = UInt16Le(0x0000, constant = True)
|
||||||
@@ -676,9 +700,9 @@ class BitmapCompressedDataHeader(CompositeType):
|
|||||||
self.cbUncompressedSize = UInt16Le()
|
self.cbUncompressedSize = UInt16Le()
|
||||||
|
|
||||||
class BitmapData(CompositeType):
|
class BitmapData(CompositeType):
|
||||||
'''
|
"""
|
||||||
Bitmap data here the screen capture
|
Bitmap data here the screen capture
|
||||||
'''
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.destLeft = UInt16Le()
|
self.destLeft = UInt16Le()
|
||||||
@@ -694,16 +718,15 @@ class BitmapData(CompositeType):
|
|||||||
self.bitmapDataStream = String(readLen = UInt16Le(lambda:(self.bitmapLength.value if (self.flags | BitmapFlag.NO_BITMAP_COMPRESSION_HDR) else self.bitmapComprHdr.cbCompMainBodySize.value)))
|
self.bitmapDataStream = String(readLen = UInt16Le(lambda:(self.bitmapLength.value if (self.flags | BitmapFlag.NO_BITMAP_COMPRESSION_HDR) else self.bitmapComprHdr.cbCompMainBodySize.value)))
|
||||||
|
|
||||||
class PDU(LayerAutomata):
|
class PDU(LayerAutomata):
|
||||||
'''
|
"""
|
||||||
Global channel for mcs that handle session
|
Global channel for mcs that handle session
|
||||||
identification user, licensing management, and capabilities exchange
|
identification user, licensing management, and capabilities exchange
|
||||||
'''
|
"""
|
||||||
def __init__(self, mode, controller):
|
def __init__(self, mode, controller):
|
||||||
'''
|
"""
|
||||||
Constructor
|
|
||||||
@param mode: LayerMode
|
@param mode: LayerMode
|
||||||
@param controller: controller use to inform orders
|
@param controller: controller use to inform orders
|
||||||
'''
|
"""
|
||||||
LayerAutomata.__init__(self, mode, None)
|
LayerAutomata.__init__(self, mode, None)
|
||||||
#logon info send from client to server
|
#logon info send from client to server
|
||||||
self._info = RDPInfo(extendedInfoConditional = lambda:self._transport.getGCCServerSettings().core.rdpVersion == gcc.Version.RDP_VERSION_5_PLUS)
|
self._info = RDPInfo(extendedInfoConditional = lambda:self._transport.getGCCServerSettings().core.rdpVersion == gcc.Version.RDP_VERSION_5_PLUS)
|
||||||
@@ -745,26 +768,32 @@ class PDU(LayerAutomata):
|
|||||||
self._controller = controller
|
self._controller = controller
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
'''
|
"""
|
||||||
connect event in client mode send logon info
|
Connect event in client mode send logon info
|
||||||
next state recv licence pdu
|
Next state recv licence pdu
|
||||||
'''
|
"""
|
||||||
self.sendInfoPkt()
|
self.sendInfoPkt()
|
||||||
#next state is licence info PDU
|
#next state is licence info PDU
|
||||||
self.setNextState(self.recvLicenceInfo)
|
self.setNextState(self.recvLicenceInfo)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""
|
||||||
|
Send PDU close packet and call close method on transport method
|
||||||
|
"""
|
||||||
|
self._transport.send(ShareDataHeader(PDUType2.PDUTYPE2_SHUTDOWN_REQUEST, UInt16Le(self._transport.getUserId()), self._shareId))
|
||||||
|
|
||||||
def sendInfoPkt(self):
|
def sendInfoPkt(self):
|
||||||
'''
|
"""
|
||||||
send a logon info packet
|
Send a logon info packet
|
||||||
'''
|
"""
|
||||||
#always send extended info because rdpy only accept rdp version 5 and more
|
#always send extended info because rdpy only accept rdp version 5 and more
|
||||||
self._transport.send((SecurityFlag.SEC_INFO_PKT, UInt16Le(), self._info))
|
self._transport.send((SecurityFlag.SEC_INFO_PKT, UInt16Le(), self._info))
|
||||||
|
|
||||||
def recvLicenceInfo(self, data):
|
def recvLicenceInfo(self, data):
|
||||||
'''
|
"""
|
||||||
read license info packet and check if is a valid client info
|
Read license info packet and check if is a valid client info
|
||||||
@param data: Stream
|
@param data: Stream
|
||||||
'''
|
"""
|
||||||
securityFlag = UInt16Le()
|
securityFlag = UInt16Le()
|
||||||
securityFlagHi = UInt16Le()
|
securityFlagHi = UInt16Le()
|
||||||
data.readType((securityFlag, securityFlagHi))
|
data.readType((securityFlag, securityFlagHi))
|
||||||
@@ -784,11 +813,11 @@ class PDU(LayerAutomata):
|
|||||||
self.setNextState(self.recvDemandActivePDU)
|
self.setNextState(self.recvDemandActivePDU)
|
||||||
|
|
||||||
def readDataPDU(self, data):
|
def readDataPDU(self, data):
|
||||||
'''
|
"""
|
||||||
Read a DataPdu struct. If is an error pdu log and close layer
|
Read a DataPdu struct. If is an error pdu log and close layer
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
@return:
|
@return:
|
||||||
'''
|
"""
|
||||||
#maybe an error message
|
#maybe an error message
|
||||||
dataPDU = DataPDU()
|
dataPDU = DataPDU()
|
||||||
data.readType(dataPDU)
|
data.readType(dataPDU)
|
||||||
@@ -803,13 +832,13 @@ class PDU(LayerAutomata):
|
|||||||
|
|
||||||
|
|
||||||
def recvDemandActivePDU(self, data):
|
def recvDemandActivePDU(self, data):
|
||||||
'''
|
"""
|
||||||
receive demand active PDU which contains
|
Receive demand active PDU which contains
|
||||||
server capabilities. In this version of RDPY only
|
Server capabilities. In this version of RDPY only
|
||||||
restricted group of capabilities are used.
|
Restricted group of capabilities are used.
|
||||||
send confirm active PDU
|
Send confirm active PDU
|
||||||
@param data: Stream
|
@param data: Stream
|
||||||
'''
|
"""
|
||||||
demandActivePDU = DemandActivePDU()
|
demandActivePDU = DemandActivePDU()
|
||||||
data.readType(demandActivePDU)
|
data.readType(demandActivePDU)
|
||||||
|
|
||||||
@@ -821,40 +850,40 @@ class PDU(LayerAutomata):
|
|||||||
self.sendConfirmActivePDU()
|
self.sendConfirmActivePDU()
|
||||||
|
|
||||||
def recvServerSynchronizePDU(self, data):
|
def recvServerSynchronizePDU(self, data):
|
||||||
'''
|
"""
|
||||||
receive from server
|
Receive from server
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
"""
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SYNCHRONIZE:
|
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_SYNCHRONIZE:
|
||||||
raise InvalidExpectedDataException("Error in PDU layer automata : expected synchronizePDU")
|
raise InvalidExpectedDataException("Error in PDU layer automata : expected synchronizePDU")
|
||||||
self.setNextState(self.recvServerControlCooperatePDU)
|
self.setNextState(self.recvServerControlCooperatePDU)
|
||||||
|
|
||||||
def recvServerControlCooperatePDU(self, data):
|
def recvServerControlCooperatePDU(self, data):
|
||||||
'''
|
"""
|
||||||
receive control cooperate pdu from server
|
Receive control cooperate pdu from server
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
"""
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_COOPERATE:
|
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_COOPERATE:
|
||||||
raise InvalidExpectedDataException("Error in PDU layer automata : expected controlCooperatePDU")
|
raise InvalidExpectedDataException("Error in PDU layer automata : expected controlCooperatePDU")
|
||||||
self.setNextState(self.recvServerControlGrantedPDU)
|
self.setNextState(self.recvServerControlGrantedPDU)
|
||||||
|
|
||||||
def recvServerControlGrantedPDU(self, data):
|
def recvServerControlGrantedPDU(self, data):
|
||||||
'''
|
"""
|
||||||
receive last control pdu the granted control pdu
|
Receive last control pdu the granted control pdu
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
"""
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_GRANTED_CONTROL:
|
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_CONTROL or dataPDU.pduData._value.action != Action.CTRLACTION_GRANTED_CONTROL:
|
||||||
raise InvalidExpectedDataException("Error in PDU layer automata : expected controlGrantedPDU")
|
raise InvalidExpectedDataException("Error in PDU layer automata : expected controlGrantedPDU")
|
||||||
self.setNextState(self.recvServerFontMapPDU)
|
self.setNextState(self.recvServerFontMapPDU)
|
||||||
|
|
||||||
def recvServerFontMapPDU(self, data):
|
def recvServerFontMapPDU(self, data):
|
||||||
'''
|
"""
|
||||||
last useless connection packet from server to client
|
Last useless connection packet from server to client
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
"""
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_FONTMAP:
|
if dataPDU.shareDataHeader.pduType2 != PDUType2.PDUTYPE2_FONTMAP:
|
||||||
raise InvalidExpectedDataException("Error in PDU layer automata : expected fontMapPDU")
|
raise InvalidExpectedDataException("Error in PDU layer automata : expected fontMapPDU")
|
||||||
@@ -864,19 +893,19 @@ class PDU(LayerAutomata):
|
|||||||
self.setNextState(self.recvDataPDU)
|
self.setNextState(self.recvDataPDU)
|
||||||
|
|
||||||
def recvDataPDU(self, data):
|
def recvDataPDU(self, data):
|
||||||
'''
|
"""
|
||||||
main receive function after connection sequence
|
Main receive function after connection sequence
|
||||||
@param data: Stream from transport layer
|
@param data: Stream from transport layer
|
||||||
'''
|
"""
|
||||||
dataPDU = self.readDataPDU(data)
|
dataPDU = self.readDataPDU(data)
|
||||||
if dataPDU.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType == UpdateType.UPDATETYPE_BITMAP:
|
if dataPDU.shareDataHeader.pduType2 == PDUType2.PDUTYPE2_UPDATE and dataPDU.pduData._value.updateType == UpdateType.UPDATETYPE_BITMAP:
|
||||||
self._controller.recvBitmapUpdateDataPDU(dataPDU.pduData._value.updateData._value)
|
self._controller.recvBitmapUpdateDataPDU(dataPDU.pduData._value.updateData._value)
|
||||||
|
|
||||||
|
|
||||||
def sendConfirmActivePDU(self):
|
def sendConfirmActivePDU(self):
|
||||||
'''
|
"""
|
||||||
send all client capabilities
|
Send all client capabilities
|
||||||
'''
|
"""
|
||||||
#init general capability
|
#init general capability
|
||||||
generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability._value
|
generalCapability = self._clientCapabilities[caps.CapsType.CAPSTYPE_GENERAL].capability._value
|
||||||
generalCapability.osMajorType = caps.MajorType.OSMAJORTYPE_WINDOWS
|
generalCapability.osMajorType = caps.MajorType.OSMAJORTYPE_WINDOWS
|
||||||
@@ -903,7 +932,7 @@ class PDU(LayerAutomata):
|
|||||||
inputCapability.imeFileName = self._transport.getGCCClientSettings().core.imeFileName
|
inputCapability.imeFileName = self._transport.getGCCClientSettings().core.imeFileName
|
||||||
|
|
||||||
#make active PDU packet
|
#make active PDU packet
|
||||||
confirmActivePDU = ConfirmActivePDU(self._transport.getUserId())
|
confirmActivePDU = ConfirmActivePDU(UInt16Le(self._transport.getUserId()))
|
||||||
confirmActivePDU.shareId = self._shareId
|
confirmActivePDU.shareId = self._shareId
|
||||||
confirmActivePDU.capabilitySets._array = self._clientCapabilities.values()
|
confirmActivePDU.capabilitySets._array = self._clientCapabilities.values()
|
||||||
self._transport.send(confirmActivePDU)
|
self._transport.send(confirmActivePDU)
|
||||||
@@ -911,18 +940,18 @@ class PDU(LayerAutomata):
|
|||||||
self.sendClientFinalizeSynchronizePDU()
|
self.sendClientFinalizeSynchronizePDU()
|
||||||
|
|
||||||
def sendClientFinalizeSynchronizePDU(self):
|
def sendClientFinalizeSynchronizePDU(self):
|
||||||
'''
|
"""
|
||||||
send a synchronize PDU from client to server
|
send a synchronize PDU from client to server
|
||||||
'''
|
"""
|
||||||
synchronizePDU = DataPDU(PDUType2.PDUTYPE2_SYNCHRONIZE, SynchronizeDataPDU(UInt16Le(self._transport.getChannelId().value)), self._transport.getUserId(), self._shareId)
|
synchronizePDU = DataPDU(PDUType2.PDUTYPE2_SYNCHRONIZE, SynchronizeDataPDU(UInt16Le(self._transport.getChannelId())), UInt16Le(self._transport.getUserId()), self._shareId)
|
||||||
self._transport.send(synchronizePDU)
|
self._transport.send(synchronizePDU)
|
||||||
|
|
||||||
#ask for cooperation
|
#ask for cooperation
|
||||||
controlCooperatePDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_COOPERATE), self._transport.getUserId(), self._shareId)
|
controlCooperatePDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_COOPERATE), UInt16Le(self._transport.getUserId()), self._shareId)
|
||||||
self._transport.send(controlCooperatePDU)
|
self._transport.send(controlCooperatePDU)
|
||||||
|
|
||||||
#request control
|
#request control
|
||||||
controlRequestPDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_REQUEST_CONTROL), self._transport.getUserId(), self._shareId)
|
controlRequestPDU = DataPDU(PDUType2.PDUTYPE2_CONTROL, ControlDataPDU(Action.CTRLACTION_REQUEST_CONTROL), UInt16Le(self._transport.getUserId()), self._shareId)
|
||||||
self._transport.send(controlRequestPDU)
|
self._transport.send(controlRequestPDU)
|
||||||
|
|
||||||
#send persistent list pdu I don't know why this packet is rejected maybe beacause we made a 0 size bitmapcache capability
|
#send persistent list pdu I don't know why this packet is rejected maybe beacause we made a 0 size bitmapcache capability
|
||||||
@@ -931,7 +960,7 @@ class PDU(LayerAutomata):
|
|||||||
#self._transport.send(persistentListPDU)
|
#self._transport.send(persistentListPDU)
|
||||||
|
|
||||||
#deprecated font list pdu
|
#deprecated font list pdu
|
||||||
fontListPDU = DataPDU(PDUType2.PDUTYPE2_FONTLIST, FontListDataPDU(), self._transport.getUserId(), self._shareId)
|
fontListPDU = DataPDU(PDUType2.PDUTYPE2_FONTLIST, FontListDataPDU(), UInt16Le(self._transport.getUserId()), self._shareId)
|
||||||
self._transport.send(fontListPDU)
|
self._transport.send(fontListPDU)
|
||||||
|
|
||||||
self.setNextState(self.recvServerSynchronizePDU)
|
self.setNextState(self.recvServerSynchronizePDU)
|
||||||
|
|||||||
@@ -18,22 +18,19 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Implement transport pdu layer
|
Implement transport PDU layer
|
||||||
|
|
||||||
This layer have main goal to negociate ssl transport
|
This layer have main goal to negociate SSL transport
|
||||||
RDP basic security is not supported by RDPY (because is not a true security layer...)
|
RDP basic security is not supported by RDPY (because is not a true security layer...)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
from rdpy.network.layer import LayerAutomata, LayerMode, StreamSender
|
||||||
from rdpy.network.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof
|
from rdpy.network.type import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof
|
||||||
from rdpy.network.error import InvalidExpectedDataException
|
from rdpy.network.error import InvalidExpectedDataException
|
||||||
from rdpy.network.const import ConstAttributes, TypeAttributes
|
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt8)
|
|
||||||
class MessageType(object):
|
class MessageType(object):
|
||||||
"""
|
"""
|
||||||
message type
|
Message type
|
||||||
"""
|
"""
|
||||||
X224_TPDU_CONNECTION_REQUEST = 0xE0
|
X224_TPDU_CONNECTION_REQUEST = 0xE0
|
||||||
X224_TPDU_CONNECTION_CONFIRM = 0xD0
|
X224_TPDU_CONNECTION_CONFIRM = 0xD0
|
||||||
@@ -41,32 +38,26 @@ class MessageType(object):
|
|||||||
X224_TPDU_DATA = 0xF0
|
X224_TPDU_DATA = 0xF0
|
||||||
X224_TPDU_ERROR = 0x70
|
X224_TPDU_ERROR = 0x70
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt8)
|
|
||||||
class NegociationType(object):
|
class NegociationType(object):
|
||||||
"""
|
"""
|
||||||
negotiation header
|
Negotiation header
|
||||||
"""
|
"""
|
||||||
TYPE_RDP_NEG_REQ = 0x01
|
TYPE_RDP_NEG_REQ = 0x01
|
||||||
TYPE_RDP_NEG_RSP = 0x02
|
TYPE_RDP_NEG_RSP = 0x02
|
||||||
TYPE_RDP_NEG_FAILURE = 0x03
|
TYPE_RDP_NEG_FAILURE = 0x03
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt32Le)
|
|
||||||
class Protocols(object):
|
class Protocols(object):
|
||||||
"""
|
"""
|
||||||
protocols available for TPDU layer
|
Protocols available for TPDU layer
|
||||||
"""
|
"""
|
||||||
PROTOCOL_RDP = 0x00000000
|
PROTOCOL_RDP = 0x00000000
|
||||||
PROTOCOL_SSL = 0x00000001
|
PROTOCOL_SSL = 0x00000001
|
||||||
PROTOCOL_HYBRID = 0x00000002
|
PROTOCOL_HYBRID = 0x00000002
|
||||||
PROTOCOL_HYBRID_EX = 0x00000008
|
PROTOCOL_HYBRID_EX = 0x00000008
|
||||||
|
|
||||||
@ConstAttributes
|
|
||||||
@TypeAttributes(UInt32Le)
|
|
||||||
class NegotiationFailureCode(object):
|
class NegotiationFailureCode(object):
|
||||||
"""
|
"""
|
||||||
protocol negotiation failure code
|
Protocol negotiation failure code
|
||||||
"""
|
"""
|
||||||
SSL_REQUIRED_BY_SERVER = 0x00000001
|
SSL_REQUIRED_BY_SERVER = 0x00000001
|
||||||
SSL_NOT_ALLOWED_BY_SERVER = 0x00000002
|
SSL_NOT_ALLOWED_BY_SERVER = 0x00000002
|
||||||
@@ -77,7 +68,7 @@ class NegotiationFailureCode(object):
|
|||||||
|
|
||||||
class TPDUConnectMessage(CompositeType):
|
class TPDUConnectMessage(CompositeType):
|
||||||
"""
|
"""
|
||||||
header of TPDU connection messages
|
Header of TPDU connection messages
|
||||||
"""
|
"""
|
||||||
def __init__(self, code):
|
def __init__(self, code):
|
||||||
"""
|
"""
|
||||||
@@ -85,24 +76,24 @@ class TPDUConnectMessage(CompositeType):
|
|||||||
"""
|
"""
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.len = UInt8(lambda:sizeof(self) - 1)
|
self.len = UInt8(lambda:sizeof(self) - 1)
|
||||||
self.code = UInt8(code.value, constant = True)
|
self.code = UInt8(code, constant = True)
|
||||||
self.padding = (UInt16Be(), UInt16Be(), UInt8())
|
self.padding = (UInt16Be(), UInt16Be(), UInt8())
|
||||||
#read if there is enough data
|
#read if there is enough data
|
||||||
self.protocolNeg = Negotiation(optional = True)
|
self.protocolNeg = Negotiation(optional = True)
|
||||||
|
|
||||||
class TPDUDataHeader(CompositeType):
|
class TPDUDataHeader(CompositeType):
|
||||||
"""
|
"""
|
||||||
header send when tpdu exchange application data
|
Header send when TPDU exchange application data
|
||||||
"""
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
CompositeType.__init__(self)
|
CompositeType.__init__(self)
|
||||||
self.header = UInt8(2, constant = True)
|
self.header = UInt8(2, constant = True)
|
||||||
self.messageType = UInt8(MessageType.X224_TPDU_DATA.value, constant = True)
|
self.messageType = UInt8(MessageType.X224_TPDU_DATA, constant = True)
|
||||||
self.separator = UInt8(0x80, constant = True)
|
self.separator = UInt8(0x80, constant = True)
|
||||||
|
|
||||||
class Negotiation(CompositeType):
|
class Negotiation(CompositeType):
|
||||||
"""
|
"""
|
||||||
negociate request message
|
Negociate request message
|
||||||
@see: request -> http://msdn.microsoft.com/en-us/library/cc240500.aspx
|
@see: request -> http://msdn.microsoft.com/en-us/library/cc240500.aspx
|
||||||
@see: response -> http://msdn.microsoft.com/en-us/library/cc240506.aspx
|
@see: response -> http://msdn.microsoft.com/en-us/library/cc240506.aspx
|
||||||
@see: failure ->http://msdn.microsoft.com/en-us/library/cc240507.aspx
|
@see: failure ->http://msdn.microsoft.com/en-us/library/cc240507.aspx
|
||||||
@@ -113,8 +104,8 @@ class Negotiation(CompositeType):
|
|||||||
self.flag = UInt8(0)
|
self.flag = UInt8(0)
|
||||||
#always 8
|
#always 8
|
||||||
self.len = UInt16Le(0x0008, constant = True)
|
self.len = UInt16Le(0x0008, constant = True)
|
||||||
self.selectedProtocol = UInt32Le(conditional = lambda: self.code == NegociationType.TYPE_RDP_NEG_RSP)
|
self.selectedProtocol = UInt32Le(conditional = lambda: (self.code.value != NegociationType.TYPE_RDP_NEG_FAILURE))
|
||||||
self.failureCode = UInt32Le(conditional = lambda: self.code == NegociationType.TYPE_RDP_NEG_FAILURE)
|
self.failureCode = UInt32Le(conditional = lambda: (self.code.value == NegociationType.TYPE_RDP_NEG_FAILURE))
|
||||||
|
|
||||||
class TPDU(LayerAutomata, StreamSender):
|
class TPDU(LayerAutomata, StreamSender):
|
||||||
"""
|
"""
|
||||||
@@ -134,15 +125,15 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
#server selected selectedProtocol
|
#server selected selectedProtocol
|
||||||
self._selectedProtocol = Protocols.PROTOCOL_SSL
|
self._selectedProtocol = Protocols.PROTOCOL_SSL
|
||||||
|
|
||||||
#Server mode informations for tls connexion
|
#Server mode informations for TLS connection
|
||||||
self._serverPrivateKeyFileName = None
|
self._serverPrivateKeyFileName = None
|
||||||
self._serverCertificateFileName = None
|
self._serverCertificateFileName = None
|
||||||
|
|
||||||
def initTLSServerInfos(self, privateKeyFileName, certificateFileName):
|
def initTLSServerInfos(self, privateKeyFileName, certificateFileName):
|
||||||
"""
|
"""
|
||||||
Init informations for ssl server connexion
|
Initialize informations for SSL server connection
|
||||||
@param privateKeyFileName: file contain server private key
|
@param privateKeyFileName: file contain server private key
|
||||||
@param certficiateFileName: file that contain publi key
|
@param certficiateFileName: file that contain public key
|
||||||
"""
|
"""
|
||||||
self._serverPrivateKeyFileName = privateKeyFileName
|
self._serverPrivateKeyFileName = privateKeyFileName
|
||||||
self._serverCertificateFileName = certificateFileName
|
self._serverCertificateFileName = certificateFileName
|
||||||
@@ -176,7 +167,7 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
if message.protocolNeg.failureCode._is_readed:
|
if message.protocolNeg.failureCode._is_readed:
|
||||||
raise InvalidExpectedDataException("negotiation failure code %x"%message.protocolNeg.failureCode.value)
|
raise InvalidExpectedDataException("negotiation failure code %x"%message.protocolNeg.failureCode.value)
|
||||||
|
|
||||||
self._selectedProtocol = message.protocolNeg.selectedProtocol
|
self._selectedProtocol = message.protocolNeg.selectedProtocol.value
|
||||||
|
|
||||||
if self._selectedProtocol != Protocols.PROTOCOL_SSL:
|
if self._selectedProtocol != Protocols.PROTOCOL_SSL:
|
||||||
raise InvalidExpectedDataException("only ssl protocol is supported in RDPY version")
|
raise InvalidExpectedDataException("only ssl protocol is supported in RDPY version")
|
||||||
@@ -190,8 +181,8 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
|
|
||||||
def recvConnectionRequest(self, data):
|
def recvConnectionRequest(self, data):
|
||||||
"""
|
"""
|
||||||
read connection confirm packet
|
Read connection confirm packet
|
||||||
next state is send connection confirm
|
Next state is send connection confirm
|
||||||
@param data: Stream
|
@param data: Stream
|
||||||
@see : http://msdn.microsoft.com/en-us/library/cc240470.aspx
|
@see : http://msdn.microsoft.com/en-us/library/cc240470.aspx
|
||||||
"""
|
"""
|
||||||
@@ -199,16 +190,16 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
data.readType(message)
|
data.readType(message)
|
||||||
|
|
||||||
if not message.protocolNeg._is_readed or message.protocolNeg.failureCode._is_readed:
|
if not message.protocolNeg._is_readed or message.protocolNeg.failureCode._is_readed:
|
||||||
raise InvalidExpectedDataException("Too older rdp client")
|
raise InvalidExpectedDataException("Too older RDP client")
|
||||||
|
|
||||||
self._requestedProtocol = message.protocolNeg.selectedProtocol
|
self._requestedProtocol = message.protocolNeg.selectedProtocol.value
|
||||||
|
|
||||||
if not self._requestedProtocol & Protocols.PROTOCOL_SSL:
|
if not self._requestedProtocol & Protocols.PROTOCOL_SSL:
|
||||||
#send error message and quit
|
#send error message and quit
|
||||||
message = TPDUConnectMessage()
|
message = TPDUConnectMessage()
|
||||||
message.code = MessageType.X224_TPDU_CONNECTION_CONFIRM
|
message.code.value = MessageType.X224_TPDU_CONNECTION_CONFIRM
|
||||||
message.protocolNeg.code = NegociationType.TYPE_RDP_NEG_FAILURE
|
message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_FAILURE
|
||||||
message.protocolNeg.failureCode = NegotiationFailureCode.SSL_REQUIRED_BY_SERVER
|
message.protocolNeg.failureCode.value = NegotiationFailureCode.SSL_REQUIRED_BY_SERVER
|
||||||
self._transport.send(message)
|
self._transport.send(message)
|
||||||
raise InvalidExpectedDataException("rdpy needs ssl client compliant")
|
raise InvalidExpectedDataException("rdpy needs ssl client compliant")
|
||||||
|
|
||||||
@@ -217,8 +208,8 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
|
|
||||||
def recvData(self, data):
|
def recvData(self, data):
|
||||||
"""
|
"""
|
||||||
read data header from packet
|
Read data header from packet
|
||||||
and pass to presentation layer
|
And pass to presentation layer
|
||||||
@param data: Stream
|
@param data: Stream
|
||||||
"""
|
"""
|
||||||
header = TPDUDataHeader()
|
header = TPDUDataHeader()
|
||||||
@@ -227,25 +218,25 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
|
|
||||||
def sendConnectionRequest(self):
|
def sendConnectionRequest(self):
|
||||||
"""
|
"""
|
||||||
write connection request message
|
Write connection request message
|
||||||
next state is recvConnectionConfirm
|
Next state is recvConnectionConfirm
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240500.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240500.aspx
|
||||||
"""
|
"""
|
||||||
message = TPDUConnectMessage(MessageType.X224_TPDU_CONNECTION_REQUEST)
|
message = TPDUConnectMessage(MessageType.X224_TPDU_CONNECTION_REQUEST)
|
||||||
message.protocolNeg.code = NegociationType.TYPE_RDP_NEG_REQ
|
message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_REQ
|
||||||
message.protocolNeg.selectedProtocol = self._requestedProtocol
|
message.protocolNeg.selectedProtocol.value = self._requestedProtocol
|
||||||
self._transport.send(message)
|
self._transport.send(message)
|
||||||
self.setNextState(self.recvConnectionConfirm)
|
self.setNextState(self.recvConnectionConfirm)
|
||||||
|
|
||||||
def sendConnectionConfirm(self):
|
def sendConnectionConfirm(self):
|
||||||
"""
|
"""
|
||||||
write connection confirm message
|
Write connection confirm message
|
||||||
next state is recvData
|
Next state is recvData
|
||||||
@see : http://msdn.microsoft.com/en-us/library/cc240501.aspx
|
@see : http://msdn.microsoft.com/en-us/library/cc240501.aspx
|
||||||
"""
|
"""
|
||||||
message = TPDUConnectMessage(MessageType.X224_TPDU_CONNECTION_CONFIRM)
|
message = TPDUConnectMessage(MessageType.X224_TPDU_CONNECTION_CONFIRM)
|
||||||
message.protocolNeg.code = NegociationType.TYPE_RDP_NEG_REQ
|
message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_REQ
|
||||||
message.protocolNeg.selectedProtocol = self._selectedProtocol
|
message.protocolNeg.selectedProtocol.value = self._selectedProtocol
|
||||||
self._transport.send(message)
|
self._transport.send(message)
|
||||||
#_transport is TPKT and transport is TCP layer of twisted
|
#_transport is TPKT and transport is TCP layer of twisted
|
||||||
self._transport.transport.startTLS(ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName))
|
self._transport.transport.startTLS(ServerTLSContext(self._serverPrivateKeyFileName, self._serverCertificateFileName))
|
||||||
@@ -254,8 +245,8 @@ class TPDU(LayerAutomata, StreamSender):
|
|||||||
|
|
||||||
def send(self, message):
|
def send(self, message):
|
||||||
"""
|
"""
|
||||||
write message packet for TPDU layer
|
Write message packet for TPDU layer
|
||||||
add TPDU header
|
Add TPDU header
|
||||||
@param message: network.Type message
|
@param message: network.Type message
|
||||||
"""
|
"""
|
||||||
self._transport.send((TPDUDataHeader(), message))
|
self._transport.send((TPDUDataHeader(), message))
|
||||||
@@ -294,7 +285,7 @@ class ClientTLSContext(ssl.ClientContextFactory):
|
|||||||
|
|
||||||
class ServerTLSContext(ssl.DefaultOpenSSLContextFactory):
|
class ServerTLSContext(ssl.DefaultOpenSSLContextFactory):
|
||||||
"""
|
"""
|
||||||
server context factory for open ssl
|
Server context factory for open ssl
|
||||||
@param privateKeyFileName: Name of a file containing a private key
|
@param privateKeyFileName: Name of a file containing a private key
|
||||||
@param certificateFileName: Name of a file containing a certificate
|
@param certificateFileName: Name of a file containing a certificate
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ class TPKT(RawLayer):
|
|||||||
and determine if is a fast path packet
|
and determine if is a fast path packet
|
||||||
"""
|
"""
|
||||||
#first byte of classic tpkt header
|
#first byte of classic tpkt header
|
||||||
TPKT_PACKET = UInt8(3)
|
TPKT_PACKET = 3
|
||||||
|
|
||||||
def __init__(self, presentation):
|
def __init__(self, presentation):
|
||||||
"""
|
"""
|
||||||
@@ -64,7 +64,7 @@ class TPKT(RawLayer):
|
|||||||
#first read packet version
|
#first read packet version
|
||||||
data.readType(self._lastPacketVersion)
|
data.readType(self._lastPacketVersion)
|
||||||
#classic packet
|
#classic packet
|
||||||
if self._lastPacketVersion == TPKT.TPKT_PACKET:
|
if self._lastPacketVersion.value == TPKT.TPKT_PACKET:
|
||||||
#padding
|
#padding
|
||||||
data.readType(UInt8())
|
data.readType(UInt8())
|
||||||
#read end header
|
#read end header
|
||||||
@@ -122,4 +122,4 @@ class TPKT(RawLayer):
|
|||||||
send encompassed data
|
send encompassed data
|
||||||
@param message: network.Type message to send
|
@param message: network.Type message to send
|
||||||
"""
|
"""
|
||||||
RawLayer.send(self, (TPKT.TPKT_PACKET, UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
RawLayer.send(self, (UInt8(TPKT.TPKT_PACKET), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
||||||
@@ -153,16 +153,23 @@ class RDPClientQt(RDPClientObserver, QAdaptor):
|
|||||||
if bitsPerPixel == 16:
|
if bitsPerPixel == 16:
|
||||||
if isCompress:
|
if isCompress:
|
||||||
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB16)
|
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB16)
|
||||||
data = rle.rle_decode_uint16(image.bits(), width, height, data, len(data))
|
data = rle.bitmap_decompress(image.bits(), width, height, data, len(data), 2)
|
||||||
else:
|
else:
|
||||||
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB16)
|
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB16)
|
||||||
|
|
||||||
elif bitsPerPixel == 24:
|
elif bitsPerPixel == 24:
|
||||||
if isCompress:
|
if isCompress:
|
||||||
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB888)
|
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB24)
|
||||||
data = rle.rle_decode_uint24(image.bits(), width, height, data, len(data))
|
data = rle.bitmap_decompress(image.bits(), width, height, data, len(data), 3)
|
||||||
else:
|
else:
|
||||||
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB24)
|
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB24)
|
||||||
|
|
||||||
|
elif bitsPerPixel == 32:
|
||||||
|
if isCompress:
|
||||||
|
image = QtGui.QImage(width, height, QtGui.QImage.Format_RGB32)
|
||||||
|
data = rle.bitmap_decompress(image.bits(), width, height, data, len(data), 4)
|
||||||
|
else:
|
||||||
|
image = QtGui.QImage(data, width, height, QtGui.QImage.Format_RGB32)
|
||||||
else:
|
else:
|
||||||
print "Receive image in bad format"
|
print "Receive image in bad format"
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user