mcs user connection
This commit is contained in:
@@ -94,9 +94,12 @@ class SimpleType(Type):
|
||||
'''
|
||||
compare inner value
|
||||
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
|
||||
'''
|
||||
if not isinstance(other, SimpleType):
|
||||
other = self.__class__(other)
|
||||
return self.value.__cmp__(other.value)
|
||||
|
||||
def write(self, s):
|
||||
@@ -159,38 +162,68 @@ class SimpleType(Type):
|
||||
def __add__(self, other):
|
||||
'''
|
||||
implement addition operator
|
||||
@attention: type overflow are not handle
|
||||
@param other: SimpleType value
|
||||
@param other: SimpleType value or try to construct same type as self
|
||||
around other value
|
||||
@return: self.__class__ object with add result
|
||||
@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))
|
||||
|
||||
def __sub__(self, other):
|
||||
'''
|
||||
implement sub operator
|
||||
@attention: type overflow are not handle
|
||||
@param other: SimpleType value
|
||||
@param other: SimpleType value or try to construct same type as self
|
||||
around other value
|
||||
@return: self.__class__ object with sub result
|
||||
@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))
|
||||
|
||||
def __and__(self, other):
|
||||
'''
|
||||
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
|
||||
'''
|
||||
if not isinstance(other, SimpleType):
|
||||
other = self.__class__(other)
|
||||
return self.__class__(self.value.__and__(other.value))
|
||||
|
||||
def __or__(self, other):
|
||||
'''
|
||||
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
|
||||
'''
|
||||
if not isinstance(other, SimpleType):
|
||||
other = self.__class__(other)
|
||||
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):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'''
|
||||
@author sylvain
|
||||
@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.protocol.network.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, UniString, Stream, sizeof
|
||||
@@ -74,7 +74,7 @@ class Support(object):
|
||||
@TypeAttributes(UInt16Le)
|
||||
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
|
||||
'''
|
||||
RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
|
||||
@@ -95,7 +95,7 @@ class ConnectionType(object):
|
||||
'''
|
||||
this information is correct if
|
||||
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_BROADBAND_LOW = 0x02
|
||||
@@ -130,7 +130,25 @@ class Encryption(object):
|
||||
ENCRYPTION_FLAG_128BIT = 0x00000002
|
||||
ENCRYPTION_FLAG_56BIT = 0x00000008
|
||||
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):
|
||||
'''
|
||||
@@ -212,7 +230,7 @@ class ClientSettings(object):
|
||||
def __init__(self):
|
||||
self.core = ClientCoreSettings()
|
||||
#list of ClientRequestedChannel read network gcc packet
|
||||
self.networkChannels = []
|
||||
self.networkChannels = [ClientRequestedChannel("rdpdr", ChannelOptions.CHANNEL_OPTION_INITIALIZED)]
|
||||
self.security = ClientSecuritySettings()
|
||||
|
||||
class ServerSettings(object):
|
||||
@@ -271,8 +289,8 @@ def writeClientDataBlocks(settings):
|
||||
@param settings: ClientSettings
|
||||
'''
|
||||
return (writeClientCoreData(settings.core),
|
||||
writeClientNetworkData(settings.networkChannels),
|
||||
writeClientSecurityData(settings.security))
|
||||
writeClientSecurityData(settings.security),
|
||||
writeClientNetworkData(settings.networkChannels))
|
||||
|
||||
def readServerDataBlocks(s):
|
||||
'''
|
||||
@@ -295,6 +313,7 @@ def readServerDataBlocks(s):
|
||||
elif blockType == ServerToClientMessage.SC_NET:
|
||||
settings.channelsId = readServerSecurityData(s)
|
||||
#read security block
|
||||
#unused in rdpy because use SSL layer
|
||||
elif blockType == ServerToClientMessage.SC_SECURITY:
|
||||
s.readType(settings.security)
|
||||
else:
|
||||
@@ -327,7 +346,7 @@ def writeClientNetworkData(channels):
|
||||
'''
|
||||
if len(channels) == 0:
|
||||
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):
|
||||
'''
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
|
||||
from rdpy.utils.const import ConstAttributes, TypeAttributes
|
||||
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.network.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
||||
|
||||
import ber, gcc
|
||||
import ber, gcc, per
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt8)
|
||||
@@ -18,14 +18,16 @@ class Message(object):
|
||||
'''
|
||||
MCS_TYPE_CONNECT_INITIAL = 0x65
|
||||
MCS_TYPE_CONNECT_RESPONSE = 0x66
|
||||
MCS_EDRQ = 1
|
||||
MCS_DPUM = 8
|
||||
MCS_AURQ = 10
|
||||
MCS_AUCF = 11
|
||||
MCS_CJRQ = 14
|
||||
MCS_CJCF = 15
|
||||
MCS_SDRQ = 25
|
||||
MCS_SDIN = 26
|
||||
|
||||
@ConstAttributes
|
||||
@TypeAttributes(UInt8)
|
||||
class DomainMCSPDU:
|
||||
'''
|
||||
domain mcs pdu header
|
||||
'''
|
||||
ERECT_DOMAIN_REQUEST = 1
|
||||
ATTACH_USER_REQUEST = 10
|
||||
ATTACH_USER_CONFIRM = 11
|
||||
|
||||
class Channel:
|
||||
MCS_GLOBAL_CHANNEL = 1003
|
||||
@@ -37,7 +39,6 @@ class MCS(LayerAutomata):
|
||||
the main layer of RDP protocol
|
||||
is why he can do everything and more!
|
||||
'''
|
||||
|
||||
def __init__(self, presentation = None):
|
||||
'''
|
||||
ctor call base class ctor
|
||||
@@ -45,6 +46,8 @@ class MCS(LayerAutomata):
|
||||
'''
|
||||
LayerAutomata.__init__(self, presentation)
|
||||
self._clientSettings = gcc.ClientSettings()
|
||||
#default user Id
|
||||
self._userId = UInt16Be(1)
|
||||
|
||||
def connect(self):
|
||||
'''
|
||||
@@ -71,6 +74,18 @@ class MCS(LayerAutomata):
|
||||
#we must receive a connect response
|
||||
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):
|
||||
'''
|
||||
receive mcs connect response from server
|
||||
@@ -81,11 +96,32 @@ 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 tag")
|
||||
raise InvalidExpectedDataException("invalid expected ber tag")
|
||||
gccRequestLength = ber.readLength(data)
|
||||
if data.dataLen() != gccRequestLength:
|
||||
raise InvalidSize("bad size of gcc request")
|
||||
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):
|
||||
'''
|
||||
@@ -102,6 +138,24 @@ class MCS(LayerAutomata):
|
||||
ber.writeInteger(maxPduSize), ber.writeInteger(2))
|
||||
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):
|
||||
'''
|
||||
read domain params structure
|
||||
|
||||
Reference in New Issue
Block a user