mcs user connection
This commit is contained in:
@@ -94,9 +94,12 @@ class SimpleType(Type):
|
|||||||
'''
|
'''
|
||||||
compare inner value
|
compare inner value
|
||||||
magic function of python use for any compare operators
|
magic function of python use for any compare operators
|
||||||
@param other: Type value which will be compared with self value
|
@param other: SimpleType value which will be compared with self value
|
||||||
|
or try to construct same type as self around other value
|
||||||
@return: python value compare
|
@return: python value compare
|
||||||
'''
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
return self.value.__cmp__(other.value)
|
return self.value.__cmp__(other.value)
|
||||||
|
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
@@ -159,38 +162,68 @@ class SimpleType(Type):
|
|||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
'''
|
'''
|
||||||
implement addition operator
|
implement addition operator
|
||||||
@attention: type overflow are not handle
|
@param other: SimpleType value or try to construct same type as self
|
||||||
@param other: SimpleType value
|
around other value
|
||||||
@return: self.__class__ object with add result
|
@return: self.__class__ object with add result
|
||||||
@raise InvalidValue: if new value is out of bound
|
@raise InvalidValue: if new value is out of bound
|
||||||
'''
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__add__(other.value))
|
return self.__class__(self.value.__add__(other.value))
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
'''
|
'''
|
||||||
implement sub operator
|
implement sub operator
|
||||||
@attention: type overflow are not handle
|
@param other: SimpleType value or try to construct same type as self
|
||||||
@param other: SimpleType value
|
around other value
|
||||||
@return: self.__class__ object with sub result
|
@return: self.__class__ object with sub result
|
||||||
@raise InvalidValue: if new value is out of bound
|
@raise InvalidValue: if new value is out of bound
|
||||||
'''
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__sub__(other.value))
|
return self.__class__(self.value.__sub__(other.value))
|
||||||
|
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
'''
|
'''
|
||||||
implement bitwise and operator
|
implement bitwise and operator
|
||||||
@param other: SimpleType value
|
@param other: SimpleType value or try to construct same type as self
|
||||||
|
around other value
|
||||||
@return: self.__class__ object with and result
|
@return: self.__class__ object with and result
|
||||||
'''
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__and__(other.value))
|
return self.__class__(self.value.__and__(other.value))
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
'''
|
'''
|
||||||
implement bitwise and operator
|
implement bitwise and operator
|
||||||
@param other: SimpleType value
|
@param other: SimpleType value or try to construct same type as self
|
||||||
|
around other value
|
||||||
@return: self.__class__ object with or result
|
@return: self.__class__ object with or result
|
||||||
'''
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
return self.__class__(self.value.__or__(other.value))
|
return self.__class__(self.value.__or__(other.value))
|
||||||
|
|
||||||
|
def __lshift__(self, other):
|
||||||
|
'''
|
||||||
|
left shift operator
|
||||||
|
@param other: python int
|
||||||
|
@return: self.__class__ object with or result
|
||||||
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
|
return self.__class__(self.value.__lshift__(other.value))
|
||||||
|
|
||||||
|
def __rshift__(self, other):
|
||||||
|
'''
|
||||||
|
left shift operator
|
||||||
|
@param other: python int
|
||||||
|
@return: self.__class__ object with or result
|
||||||
|
'''
|
||||||
|
if not isinstance(other, SimpleType):
|
||||||
|
other = self.__class__(other)
|
||||||
|
return self.__class__(self.value.__rshift__(other.value))
|
||||||
|
|
||||||
|
|
||||||
class CompositeType(Type):
|
class CompositeType(Type):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'''
|
'''
|
||||||
@author sylvain
|
@author sylvain
|
||||||
@summary gcc language
|
@summary gcc language
|
||||||
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||||
'''
|
'''
|
||||||
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
||||||
from rdpy.protocol.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
|
from rdpy.protocol.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
|
||||||
@@ -74,7 +74,7 @@ class Support(object):
|
|||||||
@TypeAttributes(UInt16Le)
|
@TypeAttributes(UInt16Le)
|
||||||
class CapabilityFlags(object):
|
class CapabilityFlags(object):
|
||||||
'''
|
'''
|
||||||
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||||
for more details on each flags click above
|
for more details on each flags click above
|
||||||
'''
|
'''
|
||||||
RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
|
RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
|
||||||
@@ -95,7 +95,7 @@ class ConnectionType(object):
|
|||||||
'''
|
'''
|
||||||
this information is correct if
|
this information is correct if
|
||||||
RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag
|
RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag
|
||||||
@contact: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||||
'''
|
'''
|
||||||
CONNECTION_TYPE_MODEM = 0x01
|
CONNECTION_TYPE_MODEM = 0x01
|
||||||
CONNECTION_TYPE_BROADBAND_LOW = 0x02
|
CONNECTION_TYPE_BROADBAND_LOW = 0x02
|
||||||
@@ -130,7 +130,25 @@ class Encryption(object):
|
|||||||
ENCRYPTION_FLAG_128BIT = 0x00000002
|
ENCRYPTION_FLAG_128BIT = 0x00000002
|
||||||
ENCRYPTION_FLAG_56BIT = 0x00000008
|
ENCRYPTION_FLAG_56BIT = 0x00000008
|
||||||
FIPS_ENCRYPTION_FLAG = 0x00000010
|
FIPS_ENCRYPTION_FLAG = 0x00000010
|
||||||
|
|
||||||
|
@ConstAttributes
|
||||||
|
@TypeAttributes(UInt32Le)
|
||||||
|
class ChannelOptions(object):
|
||||||
|
'''
|
||||||
|
channel options
|
||||||
|
@see: http://msdn.microsoft.com/en-us/library/cc240513.aspx
|
||||||
|
'''
|
||||||
|
CHANNEL_OPTION_INITIALIZED = 0x80000000
|
||||||
|
CHANNEL_OPTION_ENCRYPT_RDP = 0x40000000
|
||||||
|
CHANNEL_OPTION_ENCRYPT_SC = 0x20000000
|
||||||
|
CHANNEL_OPTION_ENCRYPT_CS = 0x10000000
|
||||||
|
CHANNEL_OPTION_PRI_HIGH = 0x08000000
|
||||||
|
CHANNEL_OPTION_PRI_MED = 0x04000000
|
||||||
|
CHANNEL_OPTION_PRI_LOW = 0x02000000
|
||||||
|
CHANNEL_OPTION_COMPRESS_RDP = 0x00800000
|
||||||
|
CHANNEL_OPTION_COMPRESS = 0x00400000
|
||||||
|
CHANNEL_OPTION_SHOW_PROTOCOL = 0x00200000
|
||||||
|
REMOTE_CONTROL_PERSISTENT = 0x00100000
|
||||||
|
|
||||||
class ClientCoreSettings(CompositeType):
|
class ClientCoreSettings(CompositeType):
|
||||||
'''
|
'''
|
||||||
@@ -212,7 +230,7 @@ class ClientSettings(object):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.core = ClientCoreSettings()
|
self.core = ClientCoreSettings()
|
||||||
#list of ClientRequestedChannel read network gcc packet
|
#list of ClientRequestedChannel read network gcc packet
|
||||||
self.networkChannels = []
|
self.networkChannels = [ClientRequestedChannel("rdpdr", ChannelOptions.CHANNEL_OPTION_INITIALIZED)]
|
||||||
self.security = ClientSecuritySettings()
|
self.security = ClientSecuritySettings()
|
||||||
|
|
||||||
class ServerSettings(object):
|
class ServerSettings(object):
|
||||||
@@ -271,8 +289,8 @@ def writeClientDataBlocks(settings):
|
|||||||
@param settings: ClientSettings
|
@param settings: ClientSettings
|
||||||
'''
|
'''
|
||||||
return (writeClientCoreData(settings.core),
|
return (writeClientCoreData(settings.core),
|
||||||
writeClientNetworkData(settings.networkChannels),
|
writeClientSecurityData(settings.security),
|
||||||
writeClientSecurityData(settings.security))
|
writeClientNetworkData(settings.networkChannels))
|
||||||
|
|
||||||
def readServerDataBlocks(s):
|
def readServerDataBlocks(s):
|
||||||
'''
|
'''
|
||||||
@@ -295,6 +313,7 @@ def readServerDataBlocks(s):
|
|||||||
elif blockType == ServerToClientMessage.SC_NET:
|
elif blockType == ServerToClientMessage.SC_NET:
|
||||||
settings.channelsId = readServerSecurityData(s)
|
settings.channelsId = readServerSecurityData(s)
|
||||||
#read security block
|
#read security block
|
||||||
|
#unused in rdpy because use SSL layer
|
||||||
elif blockType == ServerToClientMessage.SC_SECURITY:
|
elif blockType == ServerToClientMessage.SC_SECURITY:
|
||||||
s.readType(settings.security)
|
s.readType(settings.security)
|
||||||
else:
|
else:
|
||||||
@@ -327,7 +346,7 @@ def writeClientNetworkData(channels):
|
|||||||
'''
|
'''
|
||||||
if len(channels) == 0:
|
if len(channels) == 0:
|
||||||
return ()
|
return ()
|
||||||
return (ClientToServerMessage.CS_NET, UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 4), UInt32Le(len(channels)), tuple(channels))
|
return (ClientToServerMessage.CS_NET, UInt16Le(len(channels) * sizeof(ClientRequestedChannel()) + 8), UInt32Le(len(channels)), tuple(channels))
|
||||||
|
|
||||||
def readServerSecurityData(s):
|
def readServerSecurityData(s):
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
||||||
from rdpy.protocol.network.layer import LayerAutomata
|
from rdpy.protocol.network.layer import LayerAutomata
|
||||||
from rdpy.protocol.network.type import sizeof, Stream, UInt8
|
from rdpy.protocol.network.type import sizeof, Stream, UInt8, UInt16Be
|
||||||
from rdpy.protocol.rdp.ber import writeLength
|
from rdpy.protocol.rdp.ber import writeLength
|
||||||
from rdpy.protocol.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
from rdpy.protocol.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
||||||
|
|
||||||
import ber, gcc
|
import ber, gcc, per
|
||||||
|
|
||||||
@ConstAttributes
|
@ConstAttributes
|
||||||
@TypeAttributes(UInt8)
|
@TypeAttributes(UInt8)
|
||||||
@@ -18,14 +18,16 @@ class Message(object):
|
|||||||
'''
|
'''
|
||||||
MCS_TYPE_CONNECT_INITIAL = 0x65
|
MCS_TYPE_CONNECT_INITIAL = 0x65
|
||||||
MCS_TYPE_CONNECT_RESPONSE = 0x66
|
MCS_TYPE_CONNECT_RESPONSE = 0x66
|
||||||
MCS_EDRQ = 1
|
|
||||||
MCS_DPUM = 8
|
@ConstAttributes
|
||||||
MCS_AURQ = 10
|
@TypeAttributes(UInt8)
|
||||||
MCS_AUCF = 11
|
class DomainMCSPDU:
|
||||||
MCS_CJRQ = 14
|
'''
|
||||||
MCS_CJCF = 15
|
domain mcs pdu header
|
||||||
MCS_SDRQ = 25
|
'''
|
||||||
MCS_SDIN = 26
|
ERECT_DOMAIN_REQUEST = 1
|
||||||
|
ATTACH_USER_REQUEST = 10
|
||||||
|
ATTACH_USER_CONFIRM = 11
|
||||||
|
|
||||||
class Channel:
|
class Channel:
|
||||||
MCS_GLOBAL_CHANNEL = 1003
|
MCS_GLOBAL_CHANNEL = 1003
|
||||||
@@ -37,7 +39,6 @@ class MCS(LayerAutomata):
|
|||||||
the main layer of RDP protocol
|
the main layer of RDP protocol
|
||||||
is why he can do everything and more!
|
is why he can do everything and more!
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __init__(self, presentation = None):
|
def __init__(self, presentation = None):
|
||||||
'''
|
'''
|
||||||
ctor call base class ctor
|
ctor call base class ctor
|
||||||
@@ -45,6 +46,8 @@ class MCS(LayerAutomata):
|
|||||||
'''
|
'''
|
||||||
LayerAutomata.__init__(self, presentation)
|
LayerAutomata.__init__(self, presentation)
|
||||||
self._clientSettings = gcc.ClientSettings()
|
self._clientSettings = gcc.ClientSettings()
|
||||||
|
#default user Id
|
||||||
|
self._userId = UInt16Be(1)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
'''
|
'''
|
||||||
@@ -71,6 +74,18 @@ class MCS(LayerAutomata):
|
|||||||
#we must receive a connect response
|
#we must receive a connect response
|
||||||
self.setNextState(self.recvConnectResponse)
|
self.setNextState(self.recvConnectResponse)
|
||||||
|
|
||||||
|
def sendErectDomainRequest(self):
|
||||||
|
'''
|
||||||
|
send a formated erect domain request for RDP connection
|
||||||
|
'''
|
||||||
|
self._transport.send((self.writeMCSPDUHeader(DomainMCSPDU.ERECT_DOMAIN_REQUEST), per.writeInteger(0), per.writeInteger(0)))
|
||||||
|
|
||||||
|
def sendAttachUserRequest(self):
|
||||||
|
'''
|
||||||
|
send a formated attach user request for RDP connection
|
||||||
|
'''
|
||||||
|
self._transport.send(self.writeMCSPDUHeader(DomainMCSPDU.ATTACH_USER_REQUEST))
|
||||||
|
|
||||||
def recvConnectResponse(self, data):
|
def recvConnectResponse(self, data):
|
||||||
'''
|
'''
|
||||||
receive mcs connect response from server
|
receive mcs connect response from server
|
||||||
@@ -81,11 +96,32 @@ 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 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")
|
||||||
gcc.readConferenceCreateResponse(data)
|
gcc.readConferenceCreateResponse(data)
|
||||||
|
#send domain request
|
||||||
|
self.sendErectDomainRequest()
|
||||||
|
#send attach user request
|
||||||
|
self.sendAttachUserRequest()
|
||||||
|
#now wait user confirm from server
|
||||||
|
self.setNextState(self.recvAttachUserConfirm)
|
||||||
|
|
||||||
|
def recvAttachUserConfirm(self, data):
|
||||||
|
'''
|
||||||
|
recaive a attach user confirm
|
||||||
|
@param data: Stream
|
||||||
|
'''
|
||||||
|
opcode = UInt8()
|
||||||
|
confirm = UInt8()
|
||||||
|
data.readType((opcode, confirm))
|
||||||
|
if not self.readMCSPDUHeader(opcode, DomainMCSPDU.ATTACH_USER_CONFIRM):
|
||||||
|
raise InvalidExpectedDataException("invalid MCS PDU")
|
||||||
|
if confirm != 0:
|
||||||
|
raise Exception("server reject user")
|
||||||
|
if opcode & UInt8(2) == UInt8(2):
|
||||||
|
data.readType(self._userId)
|
||||||
|
|
||||||
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
def writeDomainParams(self, maxChannels, maxUsers, maxTokens, maxPduSize):
|
||||||
'''
|
'''
|
||||||
@@ -102,6 +138,24 @@ class MCS(LayerAutomata):
|
|||||||
ber.writeInteger(maxPduSize), ber.writeInteger(2))
|
ber.writeInteger(maxPduSize), ber.writeInteger(2))
|
||||||
return (ber.writeUniversalTag(ber.Tag.BER_TAG_SEQUENCE, True), writeLength(sizeof(domainParam)), domainParam)
|
return (ber.writeUniversalTag(ber.Tag.BER_TAG_SEQUENCE, True), writeLength(sizeof(domainParam)), domainParam)
|
||||||
|
|
||||||
|
def writeMCSPDUHeader(self, mcsPdu, options = 0):
|
||||||
|
'''
|
||||||
|
write mcs pdu header
|
||||||
|
@param mcsPdu: pdu code
|
||||||
|
@param options: option contains in header
|
||||||
|
@return: UInt8
|
||||||
|
'''
|
||||||
|
return (mcsPdu << 2) | options
|
||||||
|
|
||||||
|
def readMCSPDUHeader(self, opcode, mcsPdu):
|
||||||
|
'''
|
||||||
|
read mcsPdu header and return options parameter
|
||||||
|
@param opcode: UInt8 opcode
|
||||||
|
@param mcsPdu: mcsPdu will be checked
|
||||||
|
@return: true if opcode is correct
|
||||||
|
'''
|
||||||
|
return (opcode >> 2) == mcsPdu
|
||||||
|
|
||||||
def readDomainParams(self, s):
|
def readDomainParams(self, s):
|
||||||
'''
|
'''
|
||||||
read domain params structure
|
read domain params structure
|
||||||
|
|||||||
Reference in New Issue
Block a user