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