From dec944ed4c53b6cfac835f9d949d264a165dbc6b Mon Sep 17 00:00:00 2001 From: speyrefitte Date: Tue, 29 Oct 2013 15:06:17 +0100 Subject: [PATCH] add gcc server reading blocks --- rdpy/protocol/rdp/gcc.py | 66 ++++++++++++++++++++++++++++----------- rdpy/protocol/rdp/mcs.py | 2 +- rdpy/protocol/rdp/tpdu.py | 11 ++++--- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/rdpy/protocol/rdp/gcc.py b/rdpy/protocol/rdp/gcc.py index c3989ba..9720275 100644 --- a/rdpy/protocol/rdp/gcc.py +++ b/rdpy/protocol/rdp/gcc.py @@ -179,21 +179,31 @@ class ClientSecuritySettings(CompositeType): CompositeType.__init__(self) self.encryptionMethods = UInt32Le() self.extEncryptionMethods = UInt32Le() + +class ServerSecuritySettings(CompositeType): + ''' + server security settings + may be ignore because rdpy don't use + RDP security level + @deprecated: because we use ssl + ''' + def __init__(self): + CompositeType.__init__(self) + self.encryptionMethod = UInt32Le() + self.encryptionLevel = UInt32Le() + -class Channel(object): +class ClientRequestedChannel(CompositeType): ''' channels structure share between client and server ''' - def __init__(self): + def __init__(self, name = "", options = UInt32Le()): + CompositeType.__init__(self) #name of channel - self.name = "" + self.name = String(name[0:8] + "\x00" * (8 - len(name))) #unknown - self.options = 0 - #id of channel - self.channelId = 0 - #True if channel is connect - self.connect = False + self.options = options class ClientSettings(object): ''' @@ -201,7 +211,7 @@ class ClientSettings(object): ''' def __init__(self): self.core = ClientCoreSettings() - #list of Channel read network gcc packet + #list of ClientRequestedChannel read network gcc packet self.networkChannels = [] self.security = ClientSecuritySettings() @@ -212,6 +222,10 @@ class ServerSettings(object): def __init__(self): #core settings of server self.core = ServerCoreSettings() + #unuse security informations + self.security = ServerSecuritySettings() + #channel id accepted by server + self.channelsId = [] def writeConferenceCreateRequest(settings): ''' @@ -274,12 +288,15 @@ def readServerDataBlocks(s): blockType = UInt16Le() blockLength = UInt16Le() s.readType((blockType, blockLength)) + #read core block if blockType == ServerToClientMessage.SC_CORE: s.readType(settings.core) + #read network block elif blockType == ServerToClientMessage.SC_NET: - pass + settings.channelsId = readServerSecurityData(s) + #read security block elif blockType == ServerToClientMessage.SC_SECURITY: - pass + s.readType(settings.security) else: print "Unknow server block %s"%hex(type) length -= blockLength.value @@ -305,16 +322,27 @@ def writeClientSecurityData(security): def writeClientNetworkData(channels): ''' write network packet whith channels infos - @param channels: list of Channel + @param channels: list of ClientRequestedChannel @return: gcc network packet ''' if len(channels) == 0: return () - result = [] - result.append(UInt32Le(len(channels))) - for channel in channels: - result.append((String(channel.name[0:8] + "\x00" * (8 - len(channel.name))), UInt32Le(channel.options))) - - resultPacket = tuple(result) - return (ClientToServerMessage.CS_NET, UInt16Le(sizeof(resultPacket) + 4), resultPacket) + return (ClientToServerMessage.CS_NET, UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 4), UInt32Le(len(channels)), tuple(channels)) + +def readServerSecurityData(s): + ''' + read server security and fill it in settings + read all channels accepted by server by server + @param s: Stream + @return: list of chaeel id selected by server + ''' + channelsId = [] + channelId = UInt16Le() + numberOfChannels = UInt16Le() + s.readType((channelId, numberOfChannels)) + for i in range(0, numberOfChannels.value): + channelId = UInt16Le() + s.readType(channelId) + channelsId.append(channelId) + return channelsId \ No newline at end of file diff --git a/rdpy/protocol/rdp/mcs.py b/rdpy/protocol/rdp/mcs.py index e489608..d09be3f 100644 --- a/rdpy/protocol/rdp/mcs.py +++ b/rdpy/protocol/rdp/mcs.py @@ -51,7 +51,7 @@ class MCS(LayerAutomata): connection send for client mode a write connect initial packet ''' - self._clientSettings.core.serverSelectedProtocol = self._transport._protocol + self._clientSettings.core.serverSelectedProtocol = self._transport._selectedProtocol self.sendConnectInitial() def sendConnectInitial(self): diff --git a/rdpy/protocol/rdp/tpdu.py b/rdpy/protocol/rdp/tpdu.py index 9fe03f1..7373896 100644 --- a/rdpy/protocol/rdp/tpdu.py +++ b/rdpy/protocol/rdp/tpdu.py @@ -83,7 +83,10 @@ class TPDU(LayerAutomata): LayerAutomata.__init__(self, presentation) #default protocol is SSl because is the only supported #in this version of RDPY - self._protocol = Protocols.PROTOCOL_SSL + #client requested protocol + self._requestedProtocol = Protocols.PROTOCOL_SSL + #server selected protocol + self._selectedProtocol = Protocols.PROTOCOL_SSL def connect(self): ''' @@ -133,7 +136,7 @@ class TPDU(LayerAutomata): write connection request message next state is recvConnectionConfirm ''' - neqReq = (NegociationType.TYPE_RDP_NEG_REQ, Negotiation(self._protocol)) + neqReq = (NegociationType.TYPE_RDP_NEG_REQ, Negotiation(self._requestedProtocol)) self._transport.send((TPDUConnectHeader(MessageType.X224_TPDU_CONNECTION_REQUEST, sizeof(neqReq)), neqReq)) self.setNextState(self.recvConnectionConfirm) @@ -173,9 +176,9 @@ class TPDU(LayerAutomata): if negResp.len != UInt16Le(0x0008): raise InvalidExpectedDataException("invalid size of negotiation response") - self._protocol = negResp.protocol + self._selectedProtocol = negResp.protocol - if self._protocol == Protocols.PROTOCOL_SSL: + if self._selectedProtocol == self._requestedProtocol and self._selectedProtocol == Protocols.PROTOCOL_SSL: #_transport is TPKT and transport is TCP layer of twisted self._transport.transport.startTLS(ClientTLSContext()) else: