add connect response reading

This commit is contained in:
speyrefitte
2013-10-28 17:04:38 +01:00
parent 963e20dc9f
commit d7cbf887e5
6 changed files with 179 additions and 94 deletions

View File

@@ -24,6 +24,6 @@ if __name__ == '__main__':
from twisted.internet import reactor from twisted.internet import reactor
#reactor.connectTCP("127.0.0.1", 5901, factory.RfbFactory(protocol)) #reactor.connectTCP("127.0.0.1", 5901, factory.RfbFactory(protocol))
#reactor.connectTCP("192.168.1.90", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU(mcs.MCS())))) #reactor.connectTCP("192.168.1.90", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU(mcs.MCS()))))
reactor.connectTCP("192.168.135.73", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU(mcs.MCS())))) reactor.connectTCP("192.168.135.50", 3389, factory.RfbFactory(tpkt.TPKT(tpdu.TPDU(mcs.MCS()))))
reactor.run() reactor.run()
#sys.exit(app.exec_()) #sys.exit(app.exec_())

View File

@@ -450,6 +450,13 @@ class Stream(StringIO):
''' '''
return self.len - self.pos return self.len - self.pos
def readLen(self):
'''
compute already read size
@return: read size of stream
'''
return self.pos
def readType(self, value): def readType(self, value):
''' '''
call specific read on type object call specific read on type object

View File

@@ -2,35 +2,37 @@
@author: sylvain @author: sylvain
''' '''
from rdpy.protocol.network.type import UInt8, UInt16Be, UInt32Be, String from rdpy.protocol.network.type import UInt8, UInt16Be, UInt32Be, String
from rdpy.utils.const import ConstAttributes from rdpy.utils.const import ConstAttributes, TypeAttributes
from rdpy.protocol.network.error import InvalidExpectedDataException,\ from rdpy.protocol.network.error import InvalidExpectedDataException, InvalidSize
InvalidSize
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt8)
class BerPc(object): class BerPc(object):
BER_PC_MASK = UInt8(0x20) BER_PC_MASK = 0x20
BER_PRIMITIVE = UInt8(0x00) BER_PRIMITIVE = 0x00
BER_CONSTRUCT = UInt8(0x20) BER_CONSTRUCT = 0x20
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt8)
class Class(object): class Class(object):
BER_CLASS_MASK = UInt8(0xC0) BER_CLASS_MASK = 0xC0
BER_CLASS_UNIV = UInt8(0x00) BER_CLASS_UNIV = 0x00
BER_CLASS_APPL = UInt8(0x40) BER_CLASS_APPL = 0x40
BER_CLASS_CTXT = UInt8(0x80) BER_CLASS_CTXT = 0x80
BER_CLASS_PRIV = UInt8(0xC0) BER_CLASS_PRIV = 0xC0
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt8)
class Tag(object): class Tag(object):
BER_TAG_MASK = UInt8(0x1F) BER_TAG_MASK = 0x1F
BER_TAG_BOOLEAN = UInt8(0x01) BER_TAG_BOOLEAN = 0x01
BER_TAG_INTEGER = UInt8(0x02) BER_TAG_INTEGER = 0x02
BER_TAG_BIT_STRING = UInt8(0x03) BER_TAG_BIT_STRING = 0x03
BER_TAG_OCTET_STRING = UInt8(0x04) BER_TAG_OCTET_STRING = 0x04
BER_TAG_OBJECT_IDENFIER = UInt8(0x06) BER_TAG_OBJECT_IDENFIER = 0x06
BER_TAG_ENUMERATED = UInt8(0x0A) BER_TAG_ENUMERATED = 0x0A
BER_TAG_SEQUENCE = UInt8(0x10) BER_TAG_SEQUENCE = 0x10
BER_TAG_SEQUENCE_OF = UInt8(0x10) BER_TAG_SEQUENCE_OF = 0x10
def berPC(pc): def berPC(pc):
''' '''
@@ -222,7 +224,7 @@ def writeOctetstring(value):
return (writeUniversalTag(Tag.BER_TAG_OCTET_STRING, False), writeLength(len(value)), String(value)) return (writeUniversalTag(Tag.BER_TAG_OCTET_STRING, False), writeLength(len(value)), String(value))
def readEnumerated(s): def readEnumerated(s):
'''rt-successful '''
read enumerated structure read enumerated structure
@param s: Stream @param s: Stream
@return: int or long @return: int or long

View File

@@ -3,117 +3,133 @@
@summary gcc language @summary gcc language
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx @contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
''' '''
from rdpy.utils.const import ConstAttributes from rdpy.utils.const import ConstAttributes, TypeAttributes
from rdpy.protocol.network.type import * from rdpy.protocol.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
import per import per
from rdpy.protocol.network.error import InvalidExpectedDataException
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 ) t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
h221_cs_key = "Duca"; h221_cs_key = "Duca";
h221_sc_key = "McDn"; h221_sc_key = "McDn";
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class ServerToClientMessage(object): class ServerToClientMessage(object):
SC_CORE = UInt16Le(0x0C01) '''
SC_SECURITY = UInt16Le(0x0C02) Server to Client block
SC_NET = UInt16Le(0x0C03) gcc conference messages
'''
SC_CORE = 0x0C01
SC_SECURITY = 0x0C02
SC_NET = 0x0C03
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class ClientToServerMessage(object): class ClientToServerMessage(object):
''' '''
Client to Server message Client to Server block
gcc conference messages
''' '''
CS_CORE = UInt16Le(0xC001) CS_CORE = 0xC001
CS_SECURITY = UInt16Le(0xC002) CS_SECURITY = 0xC002
CS_NET = UInt16Le(0xC003) CS_NET = 0xC003
CS_CLUSTER = UInt16Le(0xC004) CS_CLUSTER = 0xC004
CS_MONITOR = UInt16Le(0xC005) CS_MONITOR = 0xC005
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class ColorDepth(object): class ColorDepth(object):
''' '''
depth color depth color
''' '''
RNS_UD_COLOR_8BPP = UInt16Le(0xCA01) RNS_UD_COLOR_8BPP = 0xCA01
RNS_UD_COLOR_16BPP_555 = UInt16Le(0xCA02) RNS_UD_COLOR_16BPP_555 = 0xCA02
RNS_UD_COLOR_16BPP_565 = UInt16Le(0xCA03) RNS_UD_COLOR_16BPP_565 = 0xCA03
RNS_UD_COLOR_24BPP = UInt16Le(0xCA04) RNS_UD_COLOR_24BPP = 0xCA04
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class HighColor(object): class HighColor(object):
''' '''
high color of client high color of client
''' '''
HIGH_COLOR_4BPP = UInt16Le(0x0004) HIGH_COLOR_4BPP = 0x0004
HIGH_COLOR_8BPP = UInt16Le(0x0008) HIGH_COLOR_8BPP = 0x0008
HIGH_COLOR_15BPP = UInt16Le(0x000f) HIGH_COLOR_15BPP = 0x000f
HIGH_COLOR_16BPP = UInt16Le(0x0010) HIGH_COLOR_16BPP = 0x0010
HIGH_COLOR_24BPP = UInt16Le(0x0018) HIGH_COLOR_24BPP = 0x0018
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class Support(object): class Support(object):
''' '''
support depth flag support depth flag
''' '''
RNS_UD_24BPP_SUPPORT = UInt16Le(0x0001) RNS_UD_24BPP_SUPPORT = 0x0001
RNS_UD_16BPP_SUPPORT = UInt16Le(0x0002) RNS_UD_16BPP_SUPPORT = 0x0002
RNS_UD_15BPP_SUPPORT = UInt16Le(0x0004) RNS_UD_15BPP_SUPPORT = 0x0004
RNS_UD_32BPP_SUPPORT = UInt16Le(0x0008) RNS_UD_32BPP_SUPPORT = 0x0008
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class CapabilityFlags(object): class CapabilityFlags(object):
''' '''
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx @contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
for more details on each flags click above for more details on each flags click above
''' '''
RNS_UD_CS_SUPPORT_ERRINFO_PDU = UInt16Le(0x0001) RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
RNS_UD_CS_WANT_32BPP_SESSION = UInt16Le(0x0002) RNS_UD_CS_WANT_32BPP_SESSION = 0x0002
RNS_UD_CS_SUPPORT_STATUSINFO_PDU = UInt16Le(0x0004) RNS_UD_CS_SUPPORT_STATUSINFO_PDU = 0x0004
RNS_UD_CS_STRONG_ASYMMETRIC_KEYS = UInt16Le(0x0008) RNS_UD_CS_STRONG_ASYMMETRIC_KEYS = 0x0008
RN_UD_CS_UNUSED = UInt16Le(0x0010) RN_UD_CS_UNUSED = 0x0010
RNS_UD_CS_VALID_CONNECTION_TYPE = UInt16Le(0x0020) RNS_UD_CS_VALID_CONNECTION_TYPE = 0x0020
RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU = UInt16Le(0x0040) RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU = 0x0040
RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT = UInt16Le(0x0080) RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT = 0x0080
RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL = UInt16Le(0x0100) RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL = 0x0100
RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE = UInt16Le(0x0200) RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE = 0x0200
RNS_UD_CS_SUPPORT_HEARTBEAT_PDU = UInt16Le(0x0400) RNS_UD_CS_SUPPORT_HEARTBEAT_PDU = 0x0400
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt8)
class ConnectionType(object): class ConnectionType(object):
''' '''
this information is correct if this information is correct if
RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx @contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
''' '''
CONNECTION_TYPE_MODEM = UInt8(0x01) CONNECTION_TYPE_MODEM = 0x01
CONNECTION_TYPE_BROADBAND_LOW = UInt8(0x02) CONNECTION_TYPE_BROADBAND_LOW = 0x02
CONNECTION_TYPE_SATELLITE = UInt8(0x03) CONNECTION_TYPE_SATELLITE = 0x03
CONNECTION_TYPE_BROADBAND_HIGH = UInt8(0x04) CONNECTION_TYPE_BROADBAND_HIGH = 0x04
CONNECTION_TYPE_WAN = UInt8(0x05) CONNECTION_TYPE_WAN = 0x05
CONNECTION_TYPE_LAN = UInt8(0x06) CONNECTION_TYPE_LAN = 0x06
CONNECTION_TYPE_AUTODETECT = UInt8(0x07) CONNECTION_TYPE_AUTODETECT = 0x07
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt32Le)
class Version(object): class Version(object):
''' '''
supported version of RDP supported version of RDP
''' '''
RDP_VERSION_4 = UInt32Le(0x00080001) RDP_VERSION_4 = 0x00080001
RDP_VERSION_5_PLUS = UInt32Le(0x00080004) RDP_VERSION_5_PLUS = 0x00080004
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt16Le)
class Sequence(object): class Sequence(object):
RNS_UD_SAS_DEL = UInt16Le(0xAA03) RNS_UD_SAS_DEL = 0xAA03
@ConstAttributes @ConstAttributes
@TypeAttributes(UInt32Le)
class Encryption(object): class Encryption(object):
''' '''
encryption method supported encryption method supported
@deprecated: because rdpy use ssl but need to send to server... @deprecated: because rdpy use ssl but need to send to server...
''' '''
ENCRYPTION_FLAG_40BIT = UInt32Le(0x00000001) ENCRYPTION_FLAG_40BIT = 0x00000001
ENCRYPTION_FLAG_128BIT = UInt32Le(0x00000002) ENCRYPTION_FLAG_128BIT = 0x00000002
ENCRYPTION_FLAG_56BIT = UInt32Le(0x00000008) ENCRYPTION_FLAG_56BIT = 0x00000008
FIPS_ENCRYPTION_FLAG = UInt32Le(0x00000010) FIPS_ENCRYPTION_FLAG = 0x00000010
class ClientCoreSettings(CompositeType): class ClientCoreSettings(CompositeType):
@@ -152,6 +168,7 @@ class ServerCoreSettings(CompositeType):
def __init__(self): def __init__(self):
CompositeType.__init__(self) CompositeType.__init__(self)
self.rdpVersion = Version.RDP_VERSION_5_PLUS self.rdpVersion = Version.RDP_VERSION_5_PLUS
self.clientRequestedProtocol = UInt32Le()
class ClientSecuritySettings(CompositeType): class ClientSecuritySettings(CompositeType):
''' '''
@@ -160,7 +177,7 @@ class ClientSecuritySettings(CompositeType):
''' '''
def __init__(self): def __init__(self):
CompositeType.__init__(self) CompositeType.__init__(self)
self.encryptionMethods = UInt32Le()#Encryption.ENCRYPTION_FLAG_128BIT | Encryption.ENCRYPTION_FLAG_40BIT | Encryption.ENCRYPTION_FLAG_56BIT | Encryption.FIPS_ENCRYPTION_FLAG self.encryptionMethods = UInt32Le()
self.extEncryptionMethods = UInt32Le() self.extEncryptionMethods = UInt32Le()
class Channel(object): class Channel(object):
@@ -188,6 +205,14 @@ class ClientSettings(object):
self.networkChannels = [] self.networkChannels = []
self.security = ClientSecuritySettings() self.security = ClientSecuritySettings()
class ServerSettings(object):
'''
server settings
'''
def __init__(self):
#core settings of server
self.core = ServerCoreSettings()
def writeConferenceCreateRequest(settings): def writeConferenceCreateRequest(settings):
''' '''
write conference create request structure write conference create request structure
@@ -204,6 +229,26 @@ def writeConferenceCreateRequest(settings):
per.writeNumberOfSet(1), per.writeChoice(0xc0), per.writeNumberOfSet(1), per.writeChoice(0xc0),
per.writeOctetStream(h221_cs_key, 4), per.writeOctetStream(userDataStream.getvalue())) per.writeOctetStream(h221_cs_key, 4), per.writeOctetStream(userDataStream.getvalue()))
def readConferenceCreateResponse(s):
'''
read response from server
and return server settings read from this response
@param s: Stream
@return: ServerSettings
'''
per.readChoice(s)
per.readObjectIdentifier(s, t124_02_98_oid)
per.readLength(s)
per.readChoice(s)
per.readInteger16(s, 1001)
per.readInteger(s)
per.readEnumerates(s)
per.readNumberOfSet(s)
per.readChoice(s)
if not per.readOctetStream(s, h221_sc_key, 4):
raise InvalidExpectedDataException("cannot read h221_sc_key")
return readServerDataBlocks(s)
def writeClientDataBlocks(settings): def writeClientDataBlocks(settings):
''' '''
@@ -212,9 +257,35 @@ def writeClientDataBlocks(settings):
@param settings: ClientSettings @param settings: ClientSettings
''' '''
return (writeClientCoreData(settings.core), return (writeClientCoreData(settings.core),
#writeClientNetworkData(settings.networkChannels), writeClientNetworkData(settings.networkChannels),
writeClientSecurityData(settings.security)) writeClientSecurityData(settings.security))
def readServerDataBlocks(s):
'''
read gcc server data blocks
and return result in Server Settings object
@param s: Stream
@return: ServerSettings
'''
settings = ServerSettings()
length = per.readLength(s)
while length > 0:
marker = s.readLen()
blockType = UInt16Le()
blockLength = UInt16Le()
s.readType((blockType, blockLength))
if blockType == ServerToClientMessage.SC_CORE:
s.readType(settings.core)
elif blockType == ServerToClientMessage.SC_NET:
pass
elif blockType == ServerToClientMessage.SC_SECURITY:
pass
else:
print "Unknow server block %s"%hex(type)
length -= blockLength.value
s.seek(marker + blockLength.value)
def writeClientCoreData(core): def writeClientCoreData(core):
''' '''
write client settings in GCC language write client settings in GCC language

View File

@@ -71,6 +71,22 @@ class MCS(LayerAutomata):
#we must receive a connect response #we must receive a connect response
self.setNextState(self.recvConnectResponse) self.setNextState(self.recvConnectResponse)
def recvConnectResponse(self, data):
'''
receive mcs connect response from server
@param data: Stream
'''
ber.readApplicationTag(data, Message.MCS_TYPE_CONNECT_RESPONSE)
ber.readEnumerated(data)
ber.readInteger(data)
self.readDomainParams(data)
if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False):
raise InvalidExpectedDataException("invalid expected tag")
gccRequestLength = ber.readLength(data)
if data.dataLen() != gccRequestLength:
raise InvalidSize("bad size of gcc request")
gcc.readConferenceCreateResponse(data)
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize): def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
''' '''
write a special domain param structure write a special domain param structure
@@ -89,10 +105,11 @@ class MCS(LayerAutomata):
def readDomainParams(self, s): def readDomainParams(self, s):
''' '''
read domain params structure read domain params structure
@return: (max_channels, max_users, max_tokens, max_pdu_size)
''' '''
if not ber.readUniversalTag(s, ber.Tag.BER_TAG_SEQUENCE, True): if not ber.readUniversalTag(s, ber.Tag.BER_TAG_SEQUENCE, True):
raise InvalidValue("bad BER tags") raise InvalidValue("bad BER tags")
length = ber.readLength(s) ber.readLength(s)#length
max_channels = ber.readInteger(s) max_channels = ber.readInteger(s)
max_users = ber.readInteger(s) max_users = ber.readInteger(s)
max_tokens = ber.readInteger(s) max_tokens = ber.readInteger(s)
@@ -101,18 +118,6 @@ class MCS(LayerAutomata):
ber.readInteger(s) ber.readInteger(s)
max_pdu_size = ber.readInteger(s) max_pdu_size = ber.readInteger(s)
ber.readInteger(s) ber.readInteger(s)
return (max_channels, max_users, max_tokens, max_pdu_size)
def recvConnectResponse(self, data):
ber.readApplicationTag(data, Message.MCS_TYPE_CONNECT_RESPONSE)
ber.readEnumerated(data)
ber.readInteger(data)
self.readDomainParams(data)
if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False):
raise InvalidExpectedDataException("invalid expected tag")
gccRequestLength = ber.readLength(data)
if data.dataLen() != gccRequestLength:
raise InvalidSize("gcc request have ")
from rdpy.protocol.network.type import hexDump
hexDump(data.getvalue())

View File

@@ -169,21 +169,21 @@ def readObjectIdentifier(s, oid):
size = readLength(s) size = readLength(s)
if size != 5: if size != 5:
raise InvalidValue("size of stream oid is wrong %d != 5"%size) raise InvalidValue("size of stream oid is wrong %d != 5"%size)
a_oid = (0, 0, 0, 0, 0, 0) a_oid = [0, 0, 0, 0, 0, 0]
t12 = UInt8() t12 = UInt8()
s.readType(t12) s.readType(t12)
a_oid[0] = t12.value >> 4 a_oid[0] = t12.value >> 4
a_oid[1] = t12.value & 0x0f a_oid[1] = t12.value & 0x0f
s.readType(t12) s.readType(t12)
a_oid[2] = t12.value
s.readType(t12)
a_oid[3] = t12.value a_oid[3] = t12.value
s.readType(t12) s.readType(t12)
a_oid[4] = t12.value a_oid[4] = t12.value
s.readType(t12) s.readType(t12)
a_oid[5] = t12.value a_oid[5] = t12.value
s.readType(t12)
a_oid[6] = t12.value
if oid != a_oid: if list(oid) != a_oid:
raise InvalidExpectedDataException("invalid object identifier") raise InvalidExpectedDataException("invalid object identifier")
def writeObjectIdentifier(oid): def writeObjectIdentifier(oid):