add server side function in per and gcc

This commit is contained in:
citronneur
2014-07-13 15:20:39 +02:00
parent d32bb1e22b
commit 5712c701ff
4 changed files with 110 additions and 58 deletions

View File

@@ -72,7 +72,7 @@ def readLength(s):
s.readType(length) s.readType(length)
byte = length.value byte = length.value
if (byte & 0x80): if (byte & 0x80):
byte &= 0x80 byte &= ~0x80
if byte == 1: if byte == 1:
size = UInt8() size = UInt8()
elif byte == 2: elif byte == 2:
@@ -227,7 +227,7 @@ def readOctetString(s):
if not readUniversalTag(s, Tag.BER_TAG_OCTET_STRING, False): if not readUniversalTag(s, Tag.BER_TAG_OCTET_STRING, False):
raise InvalidExpectedDataException("Unexpected BER tag") raise InvalidExpectedDataException("Unexpected BER tag")
size = readLength(s) size = readLength(s)
return s.read(size.value) return s.read(size)
def writeOctetstring(value): def writeOctetstring(value):
""" """

View File

@@ -27,6 +27,7 @@ import per
from rdpy.network.error import InvalidExpectedDataException from rdpy.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";
@@ -292,21 +293,27 @@ class ServerSettings(object):
#channel id accepted by server #channel id accepted by server
self.channelsId = [] self.channelsId = []
def writeConferenceCreateRequest(settings): def readConferenceCreateRequest(s):
""" """
Write conference create request structure Read a response from client
@param settings: ClientSettings GCC create request
@return: structure that represent @param s: Stream
""" """
userData = writeClientDataBlocks(settings) per.readChoice(s)
userDataStream = Stream() per.readObjectIdentifier(s, t124_02_98_oid)
userDataStream.writeType(userData) per.readLength(s)
per.readChoice(s)
per.readSelection(s)
per.readNumericString(s, 1)
per.readPadding(s, 1)
return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid), if per.readNumberOfSet(s) != 1:
per.writeLength(len(userDataStream.getvalue()) + 14), per.writeChoice(0), raise InvalidExpectedDataException("Invalid number of set in readConferenceCreateRequest")
per.writeSelection(0x08), per.writeNumericString("1", 1), per.writePadding(1),
per.writeNumberOfSet(1), per.writeChoice(0xc0), if per.readChoice(s) != 0xc0:
per.writeOctetStream(h221_cs_key, 4), per.writeOctetStream(userDataStream.getvalue())) raise InvalidExpectedDataException("Invalid choice in readConferenceCreateRequest")
per.readOctetStream(s, h221_cs_key, 4)
def readConferenceCreateResponse(s): def readConferenceCreateResponse(s):
""" """
@@ -328,17 +335,6 @@ def readConferenceCreateResponse(s):
raise InvalidExpectedDataException("cannot read h221_sc_key") raise InvalidExpectedDataException("cannot read h221_sc_key")
return readServerDataBlocks(s) return readServerDataBlocks(s)
def writeClientDataBlocks(settings):
"""
Write all blocks for client
and return GCC valid structure
@param settings: ClientSettings
"""
return (writeClientCoreData(settings.core),
writeClientSecurityData(settings.security),
writeClientNetworkData(settings.networkChannels))
def readServerDataBlocks(s): def readServerDataBlocks(s):
""" """
Read GCC server data blocks Read GCC server data blocks
@@ -370,6 +366,50 @@ def readServerDataBlocks(s):
return settings return settings
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 channel id selected by server
@see: http://msdn.microsoft.com/en-us/library/cc240522.aspx
"""
channelsId = []
channelId = UInt16Le()
numberOfChannels = UInt16Le()
s.readType((channelId, numberOfChannels))
for _ in range(0, numberOfChannels.value):
channelId = UInt16Le()
s.readType(channelId)
channelsId.append(channelId)
return channelsId
def writeConferenceCreateRequest(settings):
"""
Write conference create request structure
@param settings: ClientSettings
@return: structure that represent
"""
userData = writeClientDataBlocks(settings)
userDataStream = Stream()
userDataStream.writeType(userData)
return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
per.writeLength(len(userDataStream.getvalue()) + 14), per.writeChoice(0),
per.writeSelection(0x08), per.writeNumericString("1", 1), per.writePadding(1),
per.writeNumberOfSet(1), per.writeChoice(0xc0),
per.writeOctetStream(h221_cs_key, 4), per.writeOctetStream(userDataStream.getvalue()))
def writeClientDataBlocks(settings):
"""
Write all blocks for client
and return GCC valid structure
@param settings: ClientSettings
"""
return (writeClientCoreData(settings.core),
writeClientSecurityData(settings.security),
writeClientNetworkData(settings.networkChannels))
def writeClientCoreData(core): def writeClientCoreData(core):
""" """
Write client settings in GCC language Write client settings in GCC language
@@ -395,22 +435,4 @@ def writeClientNetworkData(channels):
if len(channels) == 0: if len(channels) == 0:
return () return ()
return (UInt16Le(ClientToServerMessage.CS_NET), UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 8), UInt32Le(len(channels)), tuple(channels)) return (UInt16Le(ClientToServerMessage.CS_NET), UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 8), 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 channel id selected by server
@see: http://msdn.microsoft.com/en-us/library/cc240522.aspx
"""
channelsId = []
channelId = UInt16Le()
numberOfChannels = UInt16Le()
s.readType((channelId, numberOfChannels))
for _ in range(0, numberOfChannels.value):
channelId = UInt16Le()
s.readType(channelId)
channelsId.append(channelId)
return channelsId

View File

@@ -24,7 +24,7 @@ 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.layer import LayerAutomata, StreamSender, Layer from rdpy.network.layer import LayerAutomata, StreamSender, Layer, LayerMode
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
from rdpy.protocol.rdp.ber import writeLength from rdpy.protocol.rdp.ber import writeLength
@@ -135,8 +135,11 @@ 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.value = self._transport._selectedProtocol if self._mode == LayerMode.CLIENT:
self.sendConnectInitial() self._clientSettings.core.serverSelectedProtocol.value = self._transport._selectedProtocol
self.sendConnectInitial()
else:
self.setNextState(self.recvConnectInitial)
def connectNextChannel(self): def connectNextChannel(self):
""" """
@@ -192,10 +195,27 @@ class MCS(LayerAutomata):
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(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)), UInt16Be(self._userId), UInt16Be(channelId))) self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)), UInt16Be(self._userId), UInt16Be(channelId)))
def recvConnectInitial(self, data):
"""
Receive MCS connect initial from client
@param data: Stream
"""
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_INITIAL))
ber.readOctetString(data)
ber.readOctetString(data)
if not ber.readBoolean(data):
raise InvalidExpectedDataException("invalid expected BER boolean tag")
self.readDomainParams(data)
self.readDomainParams(data)
self.readDomainParams(data)
gcc.readConferenceCreateRequest(Stream(ber.readOctetString(data)))
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, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE)) ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE))
@@ -203,7 +223,7 @@ class MCS(LayerAutomata):
ber.readInteger(data) ber.readInteger(data)
self.readDomainParams(data) self.readDomainParams(data)
if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False): if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False):
raise InvalidExpectedDataException("invalid expected ber tag") raise InvalidExpectedDataException("invalid expected BER tag")
gccRequestLength = ber.readLength(data) gccRequestLength = ber.readLength(data)
if data.dataLen() != gccRequestLength: if data.dataLen() != gccRequestLength:
raise InvalidSize("bad size of gcc request") raise InvalidSize("bad size of gcc request")

View File

@@ -13,15 +13,15 @@ def readLength(s):
''' '''
byte = UInt8() byte = UInt8()
s.readType(byte) s.readType(byte)
size = None size = 0
if (byte & UInt8(0x80)) == UInt8(0x80): if byte.value & 0x80:
byte &= ~UInt8(0x80) byte.value &= 0x80
size = UInt16Be(byte.value << 8) size = byte.value << 8
s.readType(byte) s.readType(byte)
size += s.value + byte size += byte.value
else: else:
size = UInt16Be(byte.value) size = byte.value
return size.value return size
def writeLength(value): def writeLength(value):
''' '''
@@ -187,13 +187,23 @@ def readObjectIdentifier(s, oid):
raise InvalidExpectedDataException("invalid object identifier") raise InvalidExpectedDataException("invalid object identifier")
def writeObjectIdentifier(oid): def writeObjectIdentifier(oid):
''' """
create tuble of 6 UInt8 with oid values Create tuple of 6 UInt8 with oid values
@param oid: tuple of 6 int @param oid: tuple of 6 int
@return: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) @return: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
''' """
return (UInt8(5), UInt8((oid[0] << 4) & (oid[1] & 0x0f)), UInt8(oid[2]), UInt8(oid[3]), UInt8(oid[4]), UInt8(oid[5])) return (UInt8(5), UInt8((oid[0] << 4) & (oid[1] & 0x0f)), UInt8(oid[2]), UInt8(oid[3]), UInt8(oid[4]), UInt8(oid[5]))
def readNumericString(s, minValue):
"""
Read numeric string
@param s: Stream
@param minValue: offset
"""
length = readLength(s)
length = (length + minValue + 1) / 2
s.read(length)
def writeNumericString(nStr, minValue): def writeNumericString(nStr, minValue):
''' '''
write string in per format write string in per format