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

View File

@@ -27,6 +27,7 @@ import per
from rdpy.network.error import InvalidExpectedDataException
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
h221_cs_key = "Duca";
h221_sc_key = "McDn";
@@ -292,21 +293,27 @@ class ServerSettings(object):
#channel id accepted by server
self.channelsId = []
def writeConferenceCreateRequest(settings):
def readConferenceCreateRequest(s):
"""
Write conference create request structure
@param settings: ClientSettings
@return: structure that represent
Read a response from client
GCC create request
@param s: Stream
"""
userData = writeClientDataBlocks(settings)
userDataStream = Stream()
userDataStream.writeType(userData)
per.readChoice(s)
per.readObjectIdentifier(s, t124_02_98_oid)
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),
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()))
if per.readNumberOfSet(s) != 1:
raise InvalidExpectedDataException("Invalid number of set in readConferenceCreateRequest")
if per.readChoice(s) != 0xc0:
raise InvalidExpectedDataException("Invalid choice in readConferenceCreateRequest")
per.readOctetStream(s, h221_cs_key, 4)
def readConferenceCreateResponse(s):
"""
@@ -328,17 +335,6 @@ def readConferenceCreateResponse(s):
raise InvalidExpectedDataException("cannot read h221_sc_key")
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):
"""
Read GCC server data blocks
@@ -370,6 +366,50 @@ def readServerDataBlocks(s):
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):
"""
Write client settings in GCC language
@@ -395,22 +435,4 @@ def writeClientNetworkData(channels):
if len(channels) == 0:
return ()
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.
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.error import InvalidExpectedDataException, InvalidValue, InvalidSize
from rdpy.protocol.rdp.ber import writeLength
@@ -135,8 +135,11 @@ class MCS(LayerAutomata):
Connection send for client mode
a write connect initial packet
"""
self._clientSettings.core.serverSelectedProtocol.value = self._transport._selectedProtocol
self.sendConnectInitial()
if self._mode == LayerMode.CLIENT:
self._clientSettings.core.serverSelectedProtocol.value = self._transport._selectedProtocol
self.sendConnectInitial()
else:
self.setNextState(self.recvConnectInitial)
def connectNextChannel(self):
"""
@@ -192,10 +195,27 @@ class MCS(LayerAutomata):
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)))
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):
"""
receive MCS connect response from server
Receive MCS connect response from server
@param data: Stream
"""
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE))
@@ -203,7 +223,7 @@ class MCS(LayerAutomata):
ber.readInteger(data)
self.readDomainParams(data)
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)
if data.dataLen() != gccRequestLength:
raise InvalidSize("bad size of gcc request")

View File

@@ -13,15 +13,15 @@ def readLength(s):
'''
byte = UInt8()
s.readType(byte)
size = None
if (byte & UInt8(0x80)) == UInt8(0x80):
byte &= ~UInt8(0x80)
size = UInt16Be(byte.value << 8)
size = 0
if byte.value & 0x80:
byte.value &= 0x80
size = byte.value << 8
s.readType(byte)
size += s.value + byte
size += byte.value
else:
size = UInt16Be(byte.value)
return size.value
size = byte.value
return size
def writeLength(value):
'''
@@ -187,13 +187,23 @@ def readObjectIdentifier(s, oid):
raise InvalidExpectedDataException("invalid object identifier")
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
@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]))
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):
'''
write string in per format