code refactoring + integrate rdesktop code for bitmap decompression

This commit is contained in:
speyrefitte
2014-06-30 18:04:51 +02:00
parent cbb9976866
commit c53841ac57
13 changed files with 1083 additions and 1023 deletions

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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