add server side function in per and gcc
This commit is contained in:
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user