finish RDP basic security layer client side, start server side
This commit is contained in:
@@ -149,10 +149,16 @@ def extractRSAKey(certificate):
|
|||||||
@return: (modulus, public exponent)
|
@return: (modulus, public exponent)
|
||||||
"""
|
"""
|
||||||
#http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html
|
#http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html
|
||||||
#if certificate.getComponentByName('tbsCertificate').getComponentByName('subjectPublicKeyInfo').getComponentByName('algorithm').getComponentByName('algorithm')._value != (1, 2, 840, 113549, 1, 1, 1):
|
#disable check because nobody respect
|
||||||
|
#if certificate.getComponentByName('tbsCertificate').getComponentByName('subjectPublicKeyInfo').getComponentByName('algorithm').getComponentByName('algorithm')._value != (1, 3, 14, 3, 2, 15):
|
||||||
# raise InvalidExpectedDataException("Certificate doesn't contain RSA public key")
|
# raise InvalidExpectedDataException("Certificate doesn't contain RSA public key")
|
||||||
|
|
||||||
rsaKey = decoder.decode(encoder.encode(certificate.getComponentByName('tbsCertificate').getComponentByName('subjectPublicKeyInfo').getComponentByName('subjectPublicKey'))[3:], asn1Spec=RSAPublicKey())[0]
|
#extract binary data
|
||||||
|
l = 0L
|
||||||
|
for b in certificate.getComponentByName('tbsCertificate').getComponentByName('subjectPublicKeyInfo').getComponentByName('subjectPublicKey'):
|
||||||
|
l = (l << 1) | b
|
||||||
|
|
||||||
|
rsaKey = decoder.decode(hex(l)[2:-1].decode('hex'), asn1Spec=RSAPublicKey())[0]
|
||||||
return rsaKey.getComponentByName('modulus')._value , rsaKey.getComponentByName('publicExponent')._value
|
return rsaKey.getComponentByName('modulus')._value , rsaKey.getComponentByName('publicExponent')._value
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ http://msdn.microsoft.com/en-us/library/cc240508.aspx
|
|||||||
from rdpy.core.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, Stream, sizeof, FactoryType, ArrayType
|
from rdpy.core.type import UInt8, UInt16Le, UInt32Le, CompositeType, String, Stream, sizeof, FactoryType, ArrayType
|
||||||
import per, mcs
|
import per, mcs
|
||||||
from rdpy.core.error import InvalidExpectedDataException
|
from rdpy.core.error import InvalidExpectedDataException
|
||||||
import rdpy.core.log as log
|
from rdpy.core import log, x509
|
||||||
|
|
||||||
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
|
t124_02_98_oid = ( 0, 0, 20, 124, 0, 1 )
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ class Version(object):
|
|||||||
class Sequence(object):
|
class Sequence(object):
|
||||||
RNS_UD_SAS_DEL = 0xAA03
|
RNS_UD_SAS_DEL = 0xAA03
|
||||||
|
|
||||||
class Encryption(object):
|
class EncryptionMethod(object):
|
||||||
"""
|
"""
|
||||||
@summary: Encryption methods supported
|
@summary: Encryption methods supported
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240511.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240511.aspx
|
||||||
@@ -133,6 +133,17 @@ class Encryption(object):
|
|||||||
ENCRYPTION_FLAG_56BIT = 0x00000008
|
ENCRYPTION_FLAG_56BIT = 0x00000008
|
||||||
FIPS_ENCRYPTION_FLAG = 0x00000010
|
FIPS_ENCRYPTION_FLAG = 0x00000010
|
||||||
|
|
||||||
|
class EncryptionLevel(object):
|
||||||
|
"""
|
||||||
|
@summary: level of 'security'
|
||||||
|
@see: http://msdn.microsoft.com/en-us/library/cc240518.aspx
|
||||||
|
"""
|
||||||
|
ENCRYPTION_LEVEL_NONE = 0x00000000
|
||||||
|
ENCRYPTION_LEVEL_LOW = 0x00000000
|
||||||
|
ENCRYPTION_LEVEL_CLIENT_COMPATIBLE = 0x00000000
|
||||||
|
ENCRYPTION_LEVEL_HIGH = 0x00000000
|
||||||
|
ENCRYPTION_LEVEL_FIPS = 0x00000000
|
||||||
|
|
||||||
class ChannelOptions(object):
|
class ChannelOptions(object):
|
||||||
"""
|
"""
|
||||||
@summary: Channel options
|
@summary: Channel options
|
||||||
@@ -206,7 +217,7 @@ class DataBlock(CompositeType):
|
|||||||
|
|
||||||
def DataBlockFactory():
|
def DataBlockFactory():
|
||||||
"""
|
"""
|
||||||
build settings in accordance of type self.type.value
|
@summary: build settings in accordance of type self.type.value
|
||||||
"""
|
"""
|
||||||
for c in [ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData]:
|
for c in [ClientCoreData, ClientSecurityData, ClientNetworkData, ServerCoreData, ServerNetworkData, ServerSecurityData]:
|
||||||
if self.type.value == c._TYPE_:
|
if self.type.value == c._TYPE_:
|
||||||
@@ -224,7 +235,7 @@ class DataBlock(CompositeType):
|
|||||||
|
|
||||||
class ClientCoreData(CompositeType):
|
class ClientCoreData(CompositeType):
|
||||||
"""
|
"""
|
||||||
Class that represent core setting of client
|
@summary: Class that represent core setting of client
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||||
"""
|
"""
|
||||||
_TYPE_ = MessageType.CS_CORE
|
_TYPE_ = MessageType.CS_CORE
|
||||||
@@ -256,7 +267,7 @@ class ClientCoreData(CompositeType):
|
|||||||
|
|
||||||
class ServerCoreData(CompositeType):
|
class ServerCoreData(CompositeType):
|
||||||
"""
|
"""
|
||||||
Server side core settings structure
|
@summary: Server side core settings structure
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240517.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240517.aspx
|
||||||
"""
|
"""
|
||||||
_TYPE_ = MessageType.SC_CORE
|
_TYPE_ = MessageType.SC_CORE
|
||||||
@@ -268,19 +279,19 @@ class ServerCoreData(CompositeType):
|
|||||||
|
|
||||||
class ClientSecurityData(CompositeType):
|
class ClientSecurityData(CompositeType):
|
||||||
"""
|
"""
|
||||||
Client security setting
|
@summary: Client security setting
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240511.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240511.aspx
|
||||||
"""
|
"""
|
||||||
_TYPE_ = MessageType.CS_SECURITY
|
_TYPE_ = MessageType.CS_SECURITY
|
||||||
|
|
||||||
def __init__(self, readLen = None):
|
def __init__(self, readLen = None):
|
||||||
CompositeType.__init__(self, readLen = readLen)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.encryptionMethods = UInt32Le(Encryption.ENCRYPTION_FLAG_40BIT)
|
self.encryptionMethods = UInt32Le(EncryptionMethod.ENCRYPTION_FLAG_40BIT | EncryptionMethod.ENCRYPTION_FLAG_56BIT | EncryptionMethod.ENCRYPTION_FLAG_128BIT)
|
||||||
self.extEncryptionMethods = UInt32Le()
|
self.extEncryptionMethods = UInt32Le()
|
||||||
|
|
||||||
class ServerSecurityData(CompositeType):
|
class ServerSecurityData(CompositeType):
|
||||||
"""
|
"""
|
||||||
Server security settings
|
@summary: Server security settings
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240518.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240518.aspx
|
||||||
"""
|
"""
|
||||||
_TYPE_ = MessageType.SC_SECURITY
|
_TYPE_ = MessageType.SC_SECURITY
|
||||||
@@ -314,6 +325,17 @@ class ServerCertificate(CompositeType):
|
|||||||
|
|
||||||
self.certData = FactoryType(CertificateFactory)
|
self.certData = FactoryType(CertificateFactory)
|
||||||
|
|
||||||
|
def bin2bn(b):
|
||||||
|
"""
|
||||||
|
@summary: convert binary string to bignum
|
||||||
|
@param b: {str} binary string
|
||||||
|
@return: {long} bignum
|
||||||
|
"""
|
||||||
|
l = 0L
|
||||||
|
for ch in b:
|
||||||
|
l = (l<<8) | ord(ch)
|
||||||
|
return l
|
||||||
|
|
||||||
class ProprietaryServerCertificate(CompositeType):
|
class ProprietaryServerCertificate(CompositeType):
|
||||||
"""
|
"""
|
||||||
@summary: microsoft proprietary certificate
|
@summary: microsoft proprietary certificate
|
||||||
@@ -332,6 +354,13 @@ class ProprietaryServerCertificate(CompositeType):
|
|||||||
self.wSignatureBlobLen = UInt16Le(lambda:sizeof(self.SignatureBlob))
|
self.wSignatureBlobLen = UInt16Le(lambda:sizeof(self.SignatureBlob))
|
||||||
self.SignatureBlob = String(readLen = self.wSignatureBlobLen)
|
self.SignatureBlob = String(readLen = self.wSignatureBlobLen)
|
||||||
|
|
||||||
|
def getPublicKey(self):
|
||||||
|
"""
|
||||||
|
@return: {Tuple} (modulus, publicExponent)
|
||||||
|
"""
|
||||||
|
#reverse because bignum in little endian
|
||||||
|
return bin2bn(self.PublicKeyBlob.modulus.value[::-1]), self.PublicKeyBlob.pubExp.value
|
||||||
|
|
||||||
class CertBlob(CompositeType):
|
class CertBlob(CompositeType):
|
||||||
"""
|
"""
|
||||||
@summary: certificate blob, contain x509 data
|
@summary: certificate blob, contain x509 data
|
||||||
@@ -355,6 +384,13 @@ class X509CertificateChain(CompositeType):
|
|||||||
self.CertBlobArray = ArrayType(CertBlob, readLen = self.NumCertBlobs)
|
self.CertBlobArray = ArrayType(CertBlob, readLen = self.NumCertBlobs)
|
||||||
self.padding = String(readLen = UInt8(lambda:(8 + 4 * self.NumCertBlobs.value)))
|
self.padding = String(readLen = UInt8(lambda:(8 + 4 * self.NumCertBlobs.value)))
|
||||||
|
|
||||||
|
def getPublicKey(self):
|
||||||
|
"""
|
||||||
|
@return: {Tuple} (modulus, publicExponent)
|
||||||
|
"""
|
||||||
|
#last certifcate contain publi key
|
||||||
|
return x509.extractRSAKey(x509.load(self.CertBlobArray[-1].abCert.value))
|
||||||
|
|
||||||
class RSAPublicKey(CompositeType):
|
class RSAPublicKey(CompositeType):
|
||||||
"""
|
"""
|
||||||
@see: http://msdn.microsoft.com/en-us/library/cc240520.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240520.aspx
|
||||||
|
|||||||
@@ -25,8 +25,8 @@
|
|||||||
from rdpy.core.type import CompositeType, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType, Stream
|
from rdpy.core.type import CompositeType, UInt8, UInt16Le, UInt32Le, String, sizeof, FactoryType, ArrayType, Stream
|
||||||
from rdpy.core.error import InvalidExpectedDataException
|
from rdpy.core.error import InvalidExpectedDataException
|
||||||
import rdpy.core.log as log
|
import rdpy.core.log as log
|
||||||
import rc4, sec, gcc
|
import sec, gcc
|
||||||
from rdpy.core import x509
|
from rdpy.core import x509, rc4
|
||||||
|
|
||||||
class MessageType(object):
|
class MessageType(object):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ It exist channel for file system order, audio channel, clipboard etc...
|
|||||||
"""
|
"""
|
||||||
from rdpy.core.layer import LayerAutomata, IStreamSender, Layer
|
from rdpy.core.layer import LayerAutomata, IStreamSender, Layer
|
||||||
from rdpy.core.type import sizeof, Stream, UInt8, UInt16Le, String
|
from rdpy.core.type import sizeof, Stream, UInt8, UInt16Le, String
|
||||||
from rdpy.core.error import InvalidExpectedDataException, InvalidValue, InvalidSize
|
from rdpy.core.error import InvalidExpectedDataException, InvalidValue, InvalidSize, CallPureVirtualFuntion
|
||||||
from rdpy.protocol.rdp.ber import writeLength
|
from rdpy.protocol.rdp.ber import writeLength
|
||||||
import rdpy.core.log as log
|
import rdpy.core.log as log
|
||||||
|
|
||||||
@@ -59,22 +59,54 @@ class Channel:
|
|||||||
MCS_GLOBAL_CHANNEL = 1003
|
MCS_GLOBAL_CHANNEL = 1003
|
||||||
MCS_USERCHANNEL_BASE = 1001
|
MCS_USERCHANNEL_BASE = 1001
|
||||||
|
|
||||||
|
class IGCCConfig(object):
|
||||||
|
"""
|
||||||
|
@summary: Channel information
|
||||||
|
"""
|
||||||
|
def getUserId(self):
|
||||||
|
"""
|
||||||
|
@return: {integer} mcs user id
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getUserId", "IGCCConfig"))
|
||||||
|
|
||||||
|
def getChannelId(self):
|
||||||
|
"""
|
||||||
|
@return: {integer} return channel id of proxy
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getChannelId", "IGCCConfig"))
|
||||||
|
|
||||||
|
def getGCCClientSettings(self):
|
||||||
|
"""
|
||||||
|
@return: {gcc.Settings} mcs layer gcc client settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getGCCClientSettings", "IGCCConfig"))
|
||||||
|
|
||||||
|
def getGCCServerSettings(self):
|
||||||
|
"""
|
||||||
|
@return: {gcc.Settings} mcs layer gcc server settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "getGCCServerSettings", "IGCCConfig"))
|
||||||
|
|
||||||
class MCSLayer(LayerAutomata):
|
class MCSLayer(LayerAutomata):
|
||||||
"""
|
"""
|
||||||
@summary: Multiple Channel Service layer
|
@summary: Multiple Channel Service layer
|
||||||
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!
|
||||||
"""
|
"""
|
||||||
class MCSProxySender(Layer, IStreamSender):
|
class MCSProxySender(Layer, IStreamSender, IGCCConfig):
|
||||||
"""
|
"""
|
||||||
@summary: Proxy use to set as transport layer for upper channel
|
@summary: Proxy use to set as transport layer for upper channel
|
||||||
use to abstract channel id for presentation layer
|
use to abstract channel id for presentation layer
|
||||||
"""
|
"""
|
||||||
def __init__(self, presentation, mcs, channelId):
|
def __init__(self, presentation, mcs, channelId):
|
||||||
"""
|
"""
|
||||||
@param presentation: presentation layer
|
@param presentation: {Layer} presentation layer
|
||||||
@param mcs: MCS layer use as proxy
|
@param mcs: {MCSLayer} MCS layer use as proxy
|
||||||
@param channelId: channel id for presentation layer
|
@param channelId: {integer} channel id for presentation layer
|
||||||
"""
|
"""
|
||||||
Layer.__init__(self, presentation)
|
Layer.__init__(self, presentation)
|
||||||
self._mcs = mcs
|
self._mcs = mcs
|
||||||
@@ -84,6 +116,7 @@ class MCSLayer(LayerAutomata):
|
|||||||
"""
|
"""
|
||||||
@summary: A send proxy function, use channel id and specific
|
@summary: A send proxy function, use channel id and specific
|
||||||
send function of MCS layer
|
send function of MCS layer
|
||||||
|
@param data: {type.Type | Tuple}
|
||||||
"""
|
"""
|
||||||
self._mcs.send(self._channelId, data)
|
self._mcs.send(self._channelId, data)
|
||||||
|
|
||||||
@@ -95,35 +128,39 @@ class MCSLayer(LayerAutomata):
|
|||||||
|
|
||||||
def getUserId(self):
|
def getUserId(self):
|
||||||
"""
|
"""
|
||||||
@return: mcs user id
|
@return: {integer} mcs user id
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
"""
|
"""
|
||||||
return self._mcs._userId
|
return self._mcs._userId
|
||||||
|
|
||||||
def getChannelId(self):
|
def getChannelId(self):
|
||||||
"""
|
"""
|
||||||
@return: return channel id of proxy
|
@return: {integer} return channel id of proxy
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
"""
|
"""
|
||||||
return self._channelId
|
return self._channelId
|
||||||
|
|
||||||
def getGCCClientSettings(self):
|
def getGCCClientSettings(self):
|
||||||
"""
|
"""
|
||||||
@return: mcs layer gcc client settings
|
@return: {gcc.Settings} mcs layer gcc client settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
"""
|
"""
|
||||||
return self._mcs._clientSettings
|
return self._mcs._clientSettings
|
||||||
|
|
||||||
def getGCCServerSettings(self):
|
def getGCCServerSettings(self):
|
||||||
"""
|
"""
|
||||||
@return: mcs layer gcc server settings
|
@return: {gcc.Settings} mcs layer gcc server settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
"""
|
"""
|
||||||
return self._mcs._serverSettings
|
return self._mcs._serverSettings
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, presentation, receiveOpcode, sendOpcode, virtualChannels = []):
|
def __init__(self, presentation, receiveOpcode, sendOpcode, virtualChannels = []):
|
||||||
"""
|
"""
|
||||||
@param presentation: presentation layer
|
@param presentation: {Layer} presentation layer
|
||||||
@param virtualChannels: list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
@param virtualChannels: {Array(Layer]} list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
||||||
@param receiveOpcode: opcode check when receive data
|
@param receiveOpcode: {integer} opcode check when receive data
|
||||||
@param sendOpcode: opcode use when send data
|
@param sendOpcode: {integer} opcode use when send data
|
||||||
"""
|
"""
|
||||||
LayerAutomata.__init__(self, presentation)
|
LayerAutomata.__init__(self, presentation)
|
||||||
self._clientSettings = gcc.clientSettings()
|
self._clientSettings = gcc.clientSettings()
|
||||||
@@ -163,8 +200,8 @@ class MCSLayer(LayerAutomata):
|
|||||||
def send(self, channelId, data):
|
def send(self, channelId, data):
|
||||||
"""
|
"""
|
||||||
@summary: Specific send function for channelId
|
@summary: Specific send function for channelId
|
||||||
@param channelId: Channel use to send
|
@param channelId: {integer} Channel use to send
|
||||||
@param data: message to send
|
@param data: {type.type | tuple} message to send
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(UInt8(self._sendOpcode)),
|
self._transport.send((self.writeMCSPDUHeader(UInt8(self._sendOpcode)),
|
||||||
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
||||||
@@ -175,7 +212,7 @@ class MCSLayer(LayerAutomata):
|
|||||||
def recvData(self, data):
|
def recvData(self, data):
|
||||||
"""
|
"""
|
||||||
@summary: Main receive method
|
@summary: Main receive method
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
@@ -208,11 +245,11 @@ class MCSLayer(LayerAutomata):
|
|||||||
"""
|
"""
|
||||||
@summary: Write a special domain parameter structure
|
@summary: Write a special domain parameter structure
|
||||||
use in connection sequence
|
use in connection sequence
|
||||||
@param maxChannels: number of MCS channel use
|
@param maxChannels: {integer} number of MCS channel use
|
||||||
@param maxUsers: number of MCS user used (1)
|
@param maxUsers: {integer} number of MCS user used (1)
|
||||||
@param maxTokens: unknown
|
@param maxTokens: {integer} unknown
|
||||||
@param maxPduSize: unknown
|
@param maxPduSize: {integer} unknown
|
||||||
@return: domain parameter structure
|
@return: {Tuple(type)} domain parameter structure
|
||||||
"""
|
"""
|
||||||
domainParam = (ber.writeInteger(maxChannels), ber.writeInteger(maxUsers), ber.writeInteger(maxTokens),
|
domainParam = (ber.writeInteger(maxChannels), ber.writeInteger(maxUsers), ber.writeInteger(maxTokens),
|
||||||
ber.writeInteger(1), ber.writeInteger(0), ber.writeInteger(1),
|
ber.writeInteger(1), ber.writeInteger(0), ber.writeInteger(1),
|
||||||
@@ -222,25 +259,26 @@ class MCSLayer(LayerAutomata):
|
|||||||
def writeMCSPDUHeader(self, mcsPdu, options = 0):
|
def writeMCSPDUHeader(self, mcsPdu, options = 0):
|
||||||
"""
|
"""
|
||||||
@summary: Write MCS PDU header
|
@summary: Write MCS PDU header
|
||||||
@param mcsPdu: PDU code
|
@param mcsPdu: {integer} PDU code
|
||||||
@param options: option contains in header
|
@param options: {integer} option contains in header
|
||||||
@return: UInt8
|
@return: {integer}
|
||||||
"""
|
"""
|
||||||
return (mcsPdu << 2) | options
|
return (mcsPdu << 2) | options
|
||||||
|
|
||||||
def readMCSPDUHeader(self, opcode, mcsPdu):
|
def readMCSPDUHeader(self, opcode, mcsPdu):
|
||||||
"""
|
"""
|
||||||
@summary: Read mcsPdu header and return options parameter
|
@summary: Read mcsPdu header and return options parameter
|
||||||
@param opcode: opcode
|
@param opcode: {integer} opcode
|
||||||
@param mcsPdu: mcsPdu will be checked
|
@param mcsPdu: {integer} mcsPdu will be checked
|
||||||
@return: true if opcode is correct
|
@return: {boolean} true if opcode is correct
|
||||||
"""
|
"""
|
||||||
return (opcode >> 2) == mcsPdu
|
return (opcode >> 2) == mcsPdu
|
||||||
|
|
||||||
def readDomainParams(self, s):
|
def readDomainParams(self, s):
|
||||||
"""
|
"""
|
||||||
@summary: Read domain parameters structure
|
@summary: Read domain parameters structure
|
||||||
@return: (max_channels, max_users, max_tokens, max_pdu_size)
|
@param s: {Stream}
|
||||||
|
@return: {Tuple} (max_channels, max_users, max_tokens, max_pdu_size)
|
||||||
"""
|
"""
|
||||||
if not ber.readUniversalTag(s, ber.Tag.BER_TAG_SEQUENCE, True):
|
if not ber.readUniversalTag(s, ber.Tag.BER_TAG_SEQUENCE, True):
|
||||||
raise InvalidValue("bad BER tags")
|
raise InvalidValue("bad BER tags")
|
||||||
@@ -261,8 +299,8 @@ class Client(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, presentation, virtualChannels = []):
|
def __init__(self, presentation, virtualChannels = []):
|
||||||
"""
|
"""
|
||||||
@param presentation: presentation layer
|
@param presentation: {Layer} presentation layer
|
||||||
@param virtualChannels: list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
@param virtualChannels: {Array(Layer)} list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
||||||
"""
|
"""
|
||||||
MCSLayer.__init__(self, presentation, DomainMCSPDU.SEND_DATA_INDICATION, DomainMCSPDU.SEND_DATA_REQUEST, virtualChannels)
|
MCSLayer.__init__(self, presentation, DomainMCSPDU.SEND_DATA_INDICATION, DomainMCSPDU.SEND_DATA_REQUEST, virtualChannels)
|
||||||
#use to know state of static channel
|
#use to know state of static channel
|
||||||
@@ -277,9 +315,9 @@ class Client(MCSLayer):
|
|||||||
Send ConnectInitial
|
Send ConnectInitial
|
||||||
Wait ConnectResponse
|
Wait ConnectResponse
|
||||||
"""
|
"""
|
||||||
self._clientSettings.getBlock(gcc.MessageType.CS_CORE).serverSelectedProtocol.value = self._transport._selectedProtocol
|
self._clientSettings.CS_CORE.serverSelectedProtocol.value = self._transport._selectedProtocol
|
||||||
#ask for virtual channel
|
#ask for virtual channel
|
||||||
self._clientSettings.getBlock(gcc.MessageType.CS_NET).channelDefArray._array = [x for (x, _) in self._virtualChannels]
|
self._clientSettings.CS_NET.channelDefArray._array = [x for (x, _) in self._virtualChannels]
|
||||||
#send connect initial
|
#send connect initial
|
||||||
self.sendConnectInitial()
|
self.sendConnectInitial()
|
||||||
#next wait response
|
#next wait response
|
||||||
@@ -319,7 +357,7 @@ class Client(MCSLayer):
|
|||||||
Send Erect domain Request
|
Send Erect domain Request
|
||||||
Send Attach User Request
|
Send Attach User Request
|
||||||
Wait Attach User Confirm
|
Wait Attach User Confirm
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE))
|
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_RESPONSE))
|
||||||
ber.readEnumerated(data)
|
ber.readEnumerated(data)
|
||||||
@@ -343,7 +381,7 @@ class Client(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Receive an attach user confirm
|
@summary: Receive an attach user confirm
|
||||||
Send Connect Channel
|
Send Connect Channel
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
@@ -362,7 +400,7 @@ class Client(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Receive a channel join confirm from server
|
@summary: Receive a channel join confirm from server
|
||||||
client automata function
|
client automata function
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
@@ -423,7 +461,7 @@ class Client(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Send a formated Channel join request from client to server
|
@summary: Send a formated Channel join request from client to server
|
||||||
client automata function
|
client automata function
|
||||||
@param channelId: id of channel requested
|
@param channelId: {integer} id of channel requested
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)),
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)),
|
||||||
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
per.writeInteger16(self._userId, Channel.MCS_USERCHANNEL_BASE),
|
||||||
@@ -435,8 +473,8 @@ class Server(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, presentation, virtualChannels = []):
|
def __init__(self, presentation, virtualChannels = []):
|
||||||
"""
|
"""
|
||||||
@param presentation: presentation layer
|
@param presentation: {Layer} presentation layer
|
||||||
@param virtualChannels: list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
@param virtualChannels: {List(Layer)} list additional channels like rdpsnd... [tuple(mcs.ChannelDef, layer)]
|
||||||
"""
|
"""
|
||||||
MCSLayer.__init__(self, presentation, DomainMCSPDU.SEND_DATA_REQUEST, DomainMCSPDU.SEND_DATA_INDICATION, virtualChannels)
|
MCSLayer.__init__(self, presentation, DomainMCSPDU.SEND_DATA_REQUEST, DomainMCSPDU.SEND_DATA_INDICATION, virtualChannels)
|
||||||
#nb channel requested
|
#nb channel requested
|
||||||
@@ -447,7 +485,12 @@ class Server(MCSLayer):
|
|||||||
@summary: Connect message for server automata
|
@summary: Connect message for server automata
|
||||||
Wait Connect Initial
|
Wait Connect Initial
|
||||||
"""
|
"""
|
||||||
self._serverSettings.getBlock(gcc.MessageType.SC_CORE).clientRequestedProtocol.value = self._transport._requestedProtocol
|
#basic rdp security layer
|
||||||
|
if self._transport._selectedProtocol == 0:
|
||||||
|
self._serverSettings.SC_SECURITY.encryptionMethod.value = gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT
|
||||||
|
self._serverSettings.SC_SECURITY.encryptionLevel = gcc.EncryptionLevel.ENCRYPTION_LEVEL_HIGH
|
||||||
|
|
||||||
|
self._serverSettings.SC_CORE.clientRequestedProtocol.value = self._transport._requestedProtocol
|
||||||
self.setNextState(self.recvConnectInitial)
|
self.setNextState(self.recvConnectInitial)
|
||||||
|
|
||||||
def recvConnectInitial(self, data):
|
def recvConnectInitial(self, data):
|
||||||
@@ -455,7 +498,7 @@ class Server(MCSLayer):
|
|||||||
@summary: Receive MCS connect initial from client
|
@summary: Receive MCS connect initial from client
|
||||||
Send Connect Response
|
Send Connect Response
|
||||||
Wait Erect Domain Request
|
Wait Erect Domain Request
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_INITIAL))
|
ber.readApplicationTag(data, UInt8(Message.MCS_TYPE_CONNECT_INITIAL))
|
||||||
ber.readOctetString(data)
|
ber.readOctetString(data)
|
||||||
@@ -485,7 +528,7 @@ class Server(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Receive erect domain request
|
@summary: Receive erect domain request
|
||||||
Wait Attach User Request
|
Wait Attach User Request
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
@@ -503,7 +546,7 @@ class Server(MCSLayer):
|
|||||||
@summary: Receive Attach user request
|
@summary: Receive Attach user request
|
||||||
Send Attach User Confirm
|
Send Attach User Confirm
|
||||||
Wait Channel Join Request
|
Wait Channel Join Request
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
data.readType(opcode)
|
data.readType(opcode)
|
||||||
@@ -518,7 +561,7 @@ class Server(MCSLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Receive for each client channel a request
|
@summary: Receive for each client channel a request
|
||||||
Send Channel Join Confirm or Connect upper layer when all channel are joined
|
Send Channel Join Confirm or Connect upper layer when all channel are joined
|
||||||
@param data: Stream
|
@param data: {Stream}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
opcode = UInt8()
|
opcode = UInt8()
|
||||||
@@ -562,8 +605,8 @@ class Server(MCSLayer):
|
|||||||
def sendChannelJoinConfirm(self, channelId, confirm):
|
def sendChannelJoinConfirm(self, channelId, confirm):
|
||||||
"""
|
"""
|
||||||
@summary: Send a confirm channel (or not) to client
|
@summary: Send a confirm channel (or not) to client
|
||||||
@param channelId: id of channel
|
@param channelId: {integer} id of channel
|
||||||
@param confirm: connection state
|
@param confirm: {boolean} connection state
|
||||||
"""
|
"""
|
||||||
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_CONFIRM), 2),
|
self._transport.send((self.writeMCSPDUHeader(UInt8(DomainMCSPDU.CHANNEL_JOIN_CONFIRM), 2),
|
||||||
per.writeEnumerates(int(confirm)),
|
per.writeEnumerates(int(confirm)),
|
||||||
|
|||||||
@@ -359,12 +359,12 @@ class PointerCapability(CompositeType):
|
|||||||
"""
|
"""
|
||||||
_TYPE_ = CapsType.CAPSTYPE_POINTER
|
_TYPE_ = CapsType.CAPSTYPE_POINTER
|
||||||
|
|
||||||
def __init__(self, readLen = None):
|
def __init__(self, isServer = False, readLen = None):
|
||||||
CompositeType.__init__(self, readLen = readLen)
|
CompositeType.__init__(self, readLen = readLen)
|
||||||
self.colorPointerFlag = UInt16Le()
|
self.colorPointerFlag = UInt16Le()
|
||||||
self.colorPointerCacheSize = UInt16Le(20)
|
self.colorPointerCacheSize = UInt16Le(20)
|
||||||
#old version of rdp doesn't support ...
|
#old version of rdp doesn't support ...
|
||||||
#self.pointerCacheSize = UInt16Le()
|
self.pointerCacheSize = UInt16Le(conditional = lambda:isServer)
|
||||||
|
|
||||||
class InputCapability(CompositeType):
|
class InputCapability(CompositeType):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ In this layer are managed all mains bitmap update orders end user inputs
|
|||||||
from rdpy.core.layer import LayerAutomata
|
from rdpy.core.layer import LayerAutomata
|
||||||
from rdpy.core.error import CallPureVirtualFuntion
|
from rdpy.core.error import CallPureVirtualFuntion
|
||||||
import rdpy.core.log as log
|
import rdpy.core.log as log
|
||||||
import rdpy.protocol.rdp.gcc as gcc
|
|
||||||
import rdpy.protocol.rdp.tpkt as tpkt
|
import rdpy.protocol.rdp.tpkt as tpkt
|
||||||
import data, caps
|
import data, caps
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ class PDULayer(LayerAutomata, tpkt.IFastPathListener):
|
|||||||
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.GeneralCapability()),
|
caps.CapsType.CAPSTYPE_GENERAL : caps.Capability(caps.GeneralCapability()),
|
||||||
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.BitmapCapability()),
|
caps.CapsType.CAPSTYPE_BITMAP : caps.Capability(caps.BitmapCapability()),
|
||||||
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.OrderCapability()),
|
caps.CapsType.CAPSTYPE_ORDER : caps.Capability(caps.OrderCapability()),
|
||||||
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.PointerCapability()),
|
caps.CapsType.CAPSTYPE_POINTER : caps.Capability(caps.PointerCapability(isServer = True)),
|
||||||
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.InputCapability()),
|
caps.CapsType.CAPSTYPE_INPUT : caps.Capability(caps.InputCapability()),
|
||||||
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.VirtualChannelCapability()),
|
caps.CapsType.CAPSTYPE_VIRTUALCHANNEL : caps.Capability(caps.VirtualChannelCapability()),
|
||||||
caps.CapsType.CAPSTYPE_FONT : caps.Capability(caps.FontCapability()),
|
caps.CapsType.CAPSTYPE_FONT : caps.Capability(caps.FontCapability()),
|
||||||
@@ -120,7 +119,7 @@ class PDULayer(LayerAutomata, tpkt.IFastPathListener):
|
|||||||
@summary: Send a PDU data to transport layer
|
@summary: Send a PDU data to transport layer
|
||||||
@param pduMessage: PDU message
|
@param pduMessage: PDU message
|
||||||
"""
|
"""
|
||||||
self._transport.send(data.PDU(self._transport._transport.getUserId(), pduMessage))
|
self._transport.send(data.PDU(self._transport.getUserId(), pduMessage))
|
||||||
|
|
||||||
def sendDataPDU(self, pduData):
|
def sendDataPDU(self, pduData):
|
||||||
"""
|
"""
|
||||||
@@ -144,7 +143,7 @@ class Client(PDULayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Connect message in client automata
|
@summary: Connect message in client automata
|
||||||
"""
|
"""
|
||||||
self._gccCore = self._transport._transport.getGCCClientSettings().CS_CORE
|
self._gccCore = self._transport.getGCCClientSettings().CS_CORE
|
||||||
self.setNextState(self.recvDemandActivePDU)
|
self.setNextState(self.recvDemandActivePDU)
|
||||||
#check if client support fast path message
|
#check if client support fast path message
|
||||||
self._clientFastPathSupported = False
|
self._clientFastPathSupported = False
|
||||||
@@ -299,7 +298,7 @@ class Client(PDULayer):
|
|||||||
"""
|
"""
|
||||||
@summary: Read an update data PDU data
|
@summary: Read an update data PDU data
|
||||||
dispatch update data
|
dispatch update data
|
||||||
@param: UpdateDataPDU object
|
@param: {UpdateDataPDU} object
|
||||||
"""
|
"""
|
||||||
if updateDataPDU.updateType.value == data.UpdateType.UPDATETYPE_BITMAP:
|
if updateDataPDU.updateType.value == data.UpdateType.UPDATETYPE_BITMAP:
|
||||||
self._listener.onUpdate(updateDataPDU.updateData.rectangles._array)
|
self._listener.onUpdate(updateDataPDU.updateData.rectangles._array)
|
||||||
@@ -345,7 +344,7 @@ class Client(PDULayer):
|
|||||||
"""
|
"""
|
||||||
@summary: send a synchronize PDU from client to server
|
@summary: send a synchronize PDU from client to server
|
||||||
"""
|
"""
|
||||||
synchronizePDU = data.SynchronizeDataPDU(self._transport._transport.getChannelId())
|
synchronizePDU = data.SynchronizeDataPDU(self._transport.getChannelId())
|
||||||
self.sendDataPDU(synchronizePDU)
|
self.sendDataPDU(synchronizePDU)
|
||||||
|
|
||||||
#ask for cooperation
|
#ask for cooperation
|
||||||
@@ -364,7 +363,7 @@ class Client(PDULayer):
|
|||||||
|
|
||||||
def sendInputEvents(self, pointerEvents):
|
def sendInputEvents(self, pointerEvents):
|
||||||
"""
|
"""
|
||||||
send client input events
|
@summary: send client input events
|
||||||
@param pointerEvents: list of pointer events
|
@param pointerEvents: list of pointer events
|
||||||
"""
|
"""
|
||||||
pdu = data.ClientInputEventPDU()
|
pdu = data.ClientInputEventPDU()
|
||||||
@@ -373,7 +372,7 @@ class Client(PDULayer):
|
|||||||
|
|
||||||
class Server(PDULayer):
|
class Server(PDULayer):
|
||||||
"""
|
"""
|
||||||
Server Automata of PDU layer
|
@summary: Server Automata of PDU layer
|
||||||
"""
|
"""
|
||||||
def __init__(self, listener):
|
def __init__(self, listener):
|
||||||
"""
|
"""
|
||||||
@@ -386,14 +385,14 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""
|
"""
|
||||||
Connect message for server automata
|
@summary: Connect message for server automata
|
||||||
"""
|
"""
|
||||||
self.sendDemandActivePDU()
|
self.sendDemandActivePDU()
|
||||||
self.setNextState(self.recvConfirmActivePDU)
|
self.setNextState(self.recvConfirmActivePDU)
|
||||||
|
|
||||||
def recvConfirmActivePDU(self, s):
|
def recvConfirmActivePDU(self, s):
|
||||||
"""
|
"""
|
||||||
Receive confirm active PDU from client
|
@summary: Receive confirm active PDU from client
|
||||||
Capabilities exchange
|
Capabilities exchange
|
||||||
Wait Client Synchronize PDU
|
Wait Client Synchronize PDU
|
||||||
@param s: Stream
|
@param s: Stream
|
||||||
@@ -417,7 +416,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def recvClientSynchronizePDU(self, s):
|
def recvClientSynchronizePDU(self, s):
|
||||||
"""
|
"""
|
||||||
Receive from client
|
@summary: Receive from client
|
||||||
Wait Control Cooperate PDU
|
Wait Control Cooperate PDU
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
"""
|
"""
|
||||||
@@ -432,7 +431,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def recvClientControlCooperatePDU(self, s):
|
def recvClientControlCooperatePDU(self, s):
|
||||||
"""
|
"""
|
||||||
Receive control cooperate PDU from client
|
@summary: Receive control cooperate PDU from client
|
||||||
Wait Control Request PDU
|
Wait Control Request PDU
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
"""
|
"""
|
||||||
@@ -447,7 +446,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def recvClientControlRequestPDU(self, s):
|
def recvClientControlRequestPDU(self, s):
|
||||||
"""
|
"""
|
||||||
Receive last control PDU the request control PDU from client
|
@summary: Receive last control PDU the request control PDU from client
|
||||||
Wait Font List PDU
|
Wait Font List PDU
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
"""
|
"""
|
||||||
@@ -462,7 +461,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def recvClientFontListPDU(self, s):
|
def recvClientFontListPDU(self, s):
|
||||||
"""
|
"""
|
||||||
Last synchronize packet from client to server
|
@summary: Last synchronize packet from client to server
|
||||||
Send Server Finalize PDUs
|
Send Server Finalize PDUs
|
||||||
Wait any PDU
|
Wait any PDU
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
@@ -483,7 +482,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def recvPDU(self, s):
|
def recvPDU(self, s):
|
||||||
"""
|
"""
|
||||||
Main receive function after connection sequence
|
@summary: Main receive function after connection sequence
|
||||||
@param s: Stream from transport layer
|
@param s: Stream from transport layer
|
||||||
"""
|
"""
|
||||||
pdu = data.PDU()
|
pdu = data.PDU()
|
||||||
@@ -493,24 +492,25 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def readDataPDU(self, dataPDU):
|
def readDataPDU(self, dataPDU):
|
||||||
"""
|
"""
|
||||||
read a data PDU object
|
@summary: read a data PDU object
|
||||||
@param dataPDU: DataPDU object
|
@param dataPDU: DataPDU object
|
||||||
"""
|
"""
|
||||||
if dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU:
|
if dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SET_ERROR_INFO_PDU:
|
||||||
errorMessage = "Unknown code %s"%hex(dataPDU.pduData.errorInfo.value)
|
errorMessage = "Unknown code %s"%hex(dataPDU.pduData.errorInfo.value)
|
||||||
if data.ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo):
|
if data.ErrorInfo._MESSAGES_.has_key(dataPDU.pduData.errorInfo):
|
||||||
errorMessage = data.ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
errorMessage = data.ErrorInfo._MESSAGES_[dataPDU.pduData.errorInfo]
|
||||||
|
|
||||||
log.error("INFO PDU : %s"%errorMessage)
|
log.error("INFO PDU : %s"%errorMessage)
|
||||||
|
|
||||||
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_INPUT:
|
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_INPUT:
|
||||||
self._listener.onSlowPathInput(dataPDU.pduData.slowPathInputEvents._array)
|
self._listener.onSlowPathInput(dataPDU.pduData.slowPathInputEvents._array)
|
||||||
|
|
||||||
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SHUTDOWN_REQUEST:
|
elif dataPDU.shareDataHeader.pduType2.value == data.PDUType2.PDUTYPE2_SHUTDOWN_REQUEST:
|
||||||
log.debug("Receive Shutdown Request")
|
log.debug("Receive Shutdown Request")
|
||||||
self._transport.close()
|
self._transport.close()
|
||||||
|
|
||||||
def recvFastPath(self, fastPathS):
|
def recvFastPath(self, fastPathS):
|
||||||
"""
|
"""
|
||||||
Implement IFastPathListener interface
|
@summary: Implement IFastPathListener interface
|
||||||
Fast path is needed by RDP 8.0
|
Fast path is needed by RDP 8.0
|
||||||
@param fastPathS: Stream that contain fast path data
|
@param fastPathS: Stream that contain fast path data
|
||||||
"""
|
"""
|
||||||
@@ -536,9 +536,9 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def sendServerFinalizeSynchronizePDU(self):
|
def sendServerFinalizeSynchronizePDU(self):
|
||||||
"""
|
"""
|
||||||
Send last synchronize packet from server to client
|
@summary: Send last synchronize packet from server to client
|
||||||
"""
|
"""
|
||||||
synchronizePDU = data.SynchronizeDataPDU(self._transport._transport.getChannelId())
|
synchronizePDU = data.SynchronizeDataPDU(self._transport.getChannelId())
|
||||||
self.sendDataPDU(synchronizePDU)
|
self.sendDataPDU(synchronizePDU)
|
||||||
|
|
||||||
#ask for cooperation
|
#ask for cooperation
|
||||||
@@ -557,7 +557,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def sendPDU(self, pduMessage):
|
def sendPDU(self, pduMessage):
|
||||||
"""
|
"""
|
||||||
Send a PDU data to transport layer
|
@summary: Send a PDU data to transport layer
|
||||||
@param pduMessage: PDU message
|
@param pduMessage: PDU message
|
||||||
"""
|
"""
|
||||||
PDULayer.sendPDU(self, pduMessage)
|
PDULayer.sendPDU(self, pduMessage)
|
||||||
@@ -568,7 +568,7 @@ class Server(PDULayer):
|
|||||||
|
|
||||||
def sendBitmapUpdatePDU(self, bitmapDatas):
|
def sendBitmapUpdatePDU(self, bitmapDatas):
|
||||||
"""
|
"""
|
||||||
Send bitmap update data
|
@summary: Send bitmap update data
|
||||||
@param bitmapDatas: List of data.BitmapData
|
@param bitmapDatas: List of data.BitmapData
|
||||||
"""
|
"""
|
||||||
#check bitmap header for client that want it (very old client)
|
#check bitmap header for client that want it (very old client)
|
||||||
|
|||||||
@@ -342,7 +342,10 @@ class RDPServerController(pdu.layer.PDUServerListener):
|
|||||||
#transport pdu layer
|
#transport pdu layer
|
||||||
self._x224Layer = x224.Server(self._mcsLayer, privateKeyFileName, certificateFileName)
|
self._x224Layer = x224.Server(self._mcsLayer, privateKeyFileName, certificateFileName)
|
||||||
#transport packet (protocol layer)
|
#transport packet (protocol layer)
|
||||||
self._tpktLayer = tpkt.TPKT(self._x224Layer, self._pduLayer)
|
self._tpktLayer = tpkt.TPKT(self._x224Layer)
|
||||||
|
#fastpath stack
|
||||||
|
self._pduLayer.initFastPath(self._secLayer)
|
||||||
|
self._secLayer.initFastPath(self._tpktLayer)
|
||||||
#set color depth of session
|
#set color depth of session
|
||||||
self.setColorDepth(colorDepth)
|
self.setColorDepth(colorDepth)
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,12 @@
|
|||||||
Some use full methods for security in RDP
|
Some use full methods for security in RDP
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sha, md5, rsa, rc4
|
import sha, md5, rsa
|
||||||
import gcc, lic, tpkt
|
import gcc, lic, tpkt, mcs
|
||||||
from rdpy.core.type import CompositeType, Stream, UInt32Le, UInt16Le, String, sizeof, UInt8
|
from rdpy.core.type import CompositeType, Stream, UInt32Le, UInt16Le, String, sizeof, UInt8
|
||||||
from rdpy.core.layer import LayerAutomata, IStreamSender
|
from rdpy.core.layer import LayerAutomata, IStreamSender
|
||||||
from rdpy.core.error import InvalidExpectedDataException
|
from rdpy.core.error import InvalidExpectedDataException
|
||||||
from rdpy.core import log, x509
|
from rdpy.core import log, x509, rc4
|
||||||
|
|
||||||
class SecurityFlag(object):
|
class SecurityFlag(object):
|
||||||
"""
|
"""
|
||||||
@@ -235,13 +235,13 @@ def generateKeys(clientRandom, serverRandom, method):
|
|||||||
initialSecondKey128 = finalHash(sessionKey[32:48], clientRandom, serverRandom)
|
initialSecondKey128 = finalHash(sessionKey[32:48], clientRandom, serverRandom)
|
||||||
|
|
||||||
#generate valid key
|
#generate valid key
|
||||||
if method == gcc.Encryption.ENCRYPTION_FLAG_40BIT:
|
if method == gcc.EncryptionMethod.ENCRYPTION_FLAG_40BIT:
|
||||||
return gen40bits(macKey128), gen40bits(initialFirstKey128), gen40bits(initialSecondKey128)
|
return gen40bits(macKey128), gen40bits(initialFirstKey128), gen40bits(initialSecondKey128)
|
||||||
|
|
||||||
elif method == gcc.Encryption.ENCRYPTION_FLAG_56BIT:
|
elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_56BIT:
|
||||||
return gen56bits(macKey128), gen56bits(initialFirstKey128), gen56bits(initialSecondKey128)
|
return gen56bits(macKey128), gen56bits(initialFirstKey128), gen56bits(initialSecondKey128)
|
||||||
|
|
||||||
elif method == gcc.Encryption.ENCRYPTION_FLAG_128BIT:
|
elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT:
|
||||||
return macKey128, initialFirstKey128, initialSecondKey128
|
return macKey128, initialFirstKey128, initialSecondKey128
|
||||||
|
|
||||||
raise InvalidExpectedDataException("Bad encryption method")
|
raise InvalidExpectedDataException("Bad encryption method")
|
||||||
@@ -255,29 +255,18 @@ def updateKey(initialKey, currentKey, method):
|
|||||||
@see: http://msdn.microsoft.com/en-us/library/cc240792.aspx
|
@see: http://msdn.microsoft.com/en-us/library/cc240792.aspx
|
||||||
"""
|
"""
|
||||||
#generate valid key
|
#generate valid key
|
||||||
if method == gcc.Encryption.ENCRYPTION_FLAG_40BIT:
|
if method == gcc.EncryptionMethod.ENCRYPTION_FLAG_40BIT:
|
||||||
tempKey128 = tempKey(initialKey[:8], currentKey[:8])
|
tempKey128 = tempKey(initialKey[:8], currentKey[:8])
|
||||||
return gen40bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8]))
|
return gen40bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8]))
|
||||||
|
|
||||||
elif method == gcc.Encryption.ENCRYPTION_FLAG_56BIT:
|
elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_56BIT:
|
||||||
tempKey128 = tempKey(initialKey[:8], currentKey[:8])
|
tempKey128 = tempKey(initialKey[:8], currentKey[:8])
|
||||||
return gen56bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8]))
|
return gen56bits(rc4.crypt(rc4.RC4Key(tempKey128[:8]), tempKey128[:8]))
|
||||||
|
|
||||||
elif method == gcc.Encryption.ENCRYPTION_FLAG_128BIT:
|
elif method == gcc.EncryptionMethod.ENCRYPTION_FLAG_128BIT:
|
||||||
tempKey128 = tempKey(initialKey, currentKey)
|
tempKey128 = tempKey(initialKey, currentKey)
|
||||||
return rc4.crypt(rc4.RC4Key(tempKey128), tempKey128)
|
return rc4.crypt(rc4.RC4Key(tempKey128), tempKey128)
|
||||||
|
|
||||||
def bin2bn(b):
|
|
||||||
"""
|
|
||||||
@summary: convert binary string to bignum
|
|
||||||
@param b: {str} binary string
|
|
||||||
@return: {long} bignum
|
|
||||||
"""
|
|
||||||
l = 0L
|
|
||||||
for ch in b:
|
|
||||||
l = (l<<8) | ord(ch)
|
|
||||||
return l
|
|
||||||
|
|
||||||
class ClientSecurityExchangePDU(CompositeType):
|
class ClientSecurityExchangePDU(CompositeType):
|
||||||
"""
|
"""
|
||||||
@summary: contain client random for basic security
|
@summary: contain client random for basic security
|
||||||
@@ -332,7 +321,7 @@ class RDPExtendedInfo(CompositeType):
|
|||||||
self.clientSessionId = UInt32Le()
|
self.clientSessionId = UInt32Le()
|
||||||
self.performanceFlags = UInt32Le()
|
self.performanceFlags = UInt32Le()
|
||||||
|
|
||||||
class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastPathSender):
|
class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastPathSender, mcs.IGCCConfig):
|
||||||
"""
|
"""
|
||||||
@summary: Standard RDP security layer
|
@summary: Standard RDP security layer
|
||||||
This layer is Transparent as possible for upper layer
|
This layer is Transparent as possible for upper layer
|
||||||
@@ -347,7 +336,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
|
|||||||
self._fastPathPresentation = None
|
self._fastPathPresentation = None
|
||||||
|
|
||||||
#credentials
|
#credentials
|
||||||
self._info = RDPInfo(extendedInfoConditional = lambda:(self._transport.getGCCServerSettings().SC_CORE.rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS))
|
self._info = RDPInfo(extendedInfoConditional = lambda:(self.getGCCServerSettings().SC_CORE.rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS))
|
||||||
|
|
||||||
#True if classic encryption is enable
|
#True if classic encryption is enable
|
||||||
self._enableEncryption = False
|
self._enableEncryption = False
|
||||||
@@ -378,7 +367,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
|
|||||||
if self._nbDecryptedPacket == 4096:
|
if self._nbDecryptedPacket == 4096:
|
||||||
log.info("update decrypt key")
|
log.info("update decrypt key")
|
||||||
self._currentDecrytKey = updateKey( self._initialDecrytKey, self._currentDecrytKey,
|
self._currentDecrytKey = updateKey( self._initialDecrytKey, self._currentDecrytKey,
|
||||||
self._transport.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
||||||
self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
|
self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
|
||||||
self._nbDecryptedPacket = 0
|
self._nbDecryptedPacket = 0
|
||||||
|
|
||||||
@@ -405,7 +394,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
|
|||||||
if self._nbEncryptedPacket == 4096:
|
if self._nbEncryptedPacket == 4096:
|
||||||
log.info("update encrypt key")
|
log.info("update encrypt key")
|
||||||
self._currentEncryptKey = updateKey( self._initialEncryptKey, self._currentEncryptKey,
|
self._currentEncryptKey = updateKey( self._initialEncryptKey, self._currentEncryptKey,
|
||||||
self._transport.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
||||||
self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)
|
self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)
|
||||||
self._nbEncryptedPacket = 0
|
self._nbEncryptedPacket = 0
|
||||||
|
|
||||||
@@ -492,6 +481,34 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
|
|||||||
"""
|
"""
|
||||||
self._fastPathTransport = fastPathSender
|
self._fastPathTransport = fastPathSender
|
||||||
|
|
||||||
|
def getUserId(self):
|
||||||
|
"""
|
||||||
|
@return: {integer} mcs user id
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
return self._transport.getUserId()
|
||||||
|
|
||||||
|
def getChannelId(self):
|
||||||
|
"""
|
||||||
|
@return: {integer} return channel id of proxy
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
return self._transport.getChannelId()
|
||||||
|
|
||||||
|
def getGCCClientSettings(self):
|
||||||
|
"""
|
||||||
|
@return: {gcc.Settings} mcs layer gcc client settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
return self._transport.getGCCClientSettings()
|
||||||
|
|
||||||
|
def getGCCServerSettings(self):
|
||||||
|
"""
|
||||||
|
@return: {gcc.Settings} mcs layer gcc server settings
|
||||||
|
@see: mcs.IGCCConfig
|
||||||
|
"""
|
||||||
|
return self._transport.getGCCServerSettings()
|
||||||
|
|
||||||
class Client(SecLayer):
|
class Client(SecLayer):
|
||||||
"""
|
"""
|
||||||
@summary: Client side of security layer
|
@summary: Client side of security layer
|
||||||
@@ -502,41 +519,20 @@ class Client(SecLayer):
|
|||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""
|
"""
|
||||||
@summary: send client random
|
@summary: send client random if needed and send info packet
|
||||||
"""
|
"""
|
||||||
|
self._enableEncryption = self.getGCCClientSettings().CS_CORE.serverSelectedProtocol == 0
|
||||||
self._enableEncryption = self._transport.getGCCClientSettings().CS_CORE.serverSelectedProtocol == 0
|
|
||||||
|
|
||||||
if self._enableEncryption:
|
if self._enableEncryption:
|
||||||
#generate client random
|
self.sendClientRandom()
|
||||||
clientRandom = rsa.randnum.read_random_bits(256)
|
|
||||||
self._macKey, self._initialDecrytKey, self._initialEncryptKey = generateKeys( clientRandom,
|
|
||||||
self._transport.getGCCServerSettings().SC_SECURITY.serverRandom.value,
|
|
||||||
self._transport.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
|
||||||
#initialize keys
|
|
||||||
self._currentDecrytKey = self._initialDecrytKey
|
|
||||||
self._currentEncryptKey = self._initialEncryptKey
|
|
||||||
self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
|
|
||||||
self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)
|
|
||||||
|
|
||||||
#send client random encrypted with
|
self.sendInfoPkt()
|
||||||
certificate = self._transport.getGCCServerSettings().SC_SECURITY.serverCertificate.certData._value
|
|
||||||
if isinstance(certificate, gcc.ProprietaryServerCertificate):
|
|
||||||
modulus = bin2bn(certificate.PublicKeyBlob.modulus.value[::-1])
|
|
||||||
publicExponent = certificate.PublicKeyBlob.pubExp.value
|
|
||||||
elif isinstance(certificate, gcc.X509CertificateChain):
|
|
||||||
modulus, publicExponent = x509.extractRSAKey(x509.load(certificate.CertBlobArray[-1].abCert.value))
|
|
||||||
else:
|
|
||||||
raise InvalidExpectedDataException("unknown certificate type")
|
|
||||||
|
|
||||||
#reverse because bignum in little endian
|
|
||||||
serverPublicKey = rsa.PublicKey(modulus, publicExponent)
|
|
||||||
|
|
||||||
message = ClientSecurityExchangePDU()
|
|
||||||
#reverse because bignum in little endian
|
|
||||||
message.encryptedClientRandom.value = rsa.encrypt(clientRandom[::-1], serverPublicKey)[::-1]
|
|
||||||
self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
|
|
||||||
|
|
||||||
|
def sendInfoPkt(self):
|
||||||
|
"""
|
||||||
|
@summary: send information packet (with credentials)
|
||||||
|
next state -> recvLicenceInfo
|
||||||
|
"""
|
||||||
secFlag = SecurityFlag.SEC_INFO_PKT
|
secFlag = SecurityFlag.SEC_INFO_PKT
|
||||||
if self._enableEncryption:
|
if self._enableEncryption:
|
||||||
secFlag |= SecurityFlag.SEC_ENCRYPT
|
secFlag |= SecurityFlag.SEC_ENCRYPT
|
||||||
@@ -544,6 +540,29 @@ class Client(SecLayer):
|
|||||||
|
|
||||||
self.setNextState(self.recvLicenceInfo)
|
self.setNextState(self.recvLicenceInfo)
|
||||||
|
|
||||||
|
def sendClientRandom(self):
|
||||||
|
"""
|
||||||
|
@summary: generate and send client random and init session keys
|
||||||
|
"""
|
||||||
|
#generate client random
|
||||||
|
clientRandom = rsa.randnum.read_random_bits(256)
|
||||||
|
self._macKey, self._initialDecrytKey, self._initialEncryptKey = generateKeys( clientRandom,
|
||||||
|
self.getGCCServerSettings().SC_SECURITY.serverRandom.value,
|
||||||
|
self.getGCCServerSettings().SC_SECURITY.encryptionMethod.value)
|
||||||
|
#initialize keys
|
||||||
|
self._currentDecrytKey = self._initialDecrytKey
|
||||||
|
self._currentEncryptKey = self._initialEncryptKey
|
||||||
|
self._decryptRc4 = rc4.RC4Key(self._currentDecrytKey)
|
||||||
|
self._encryptRc4 = rc4.RC4Key(self._currentEncryptKey)
|
||||||
|
|
||||||
|
#send client random encrypted with
|
||||||
|
modulus, publicExponent = self.getGCCServerSettings().SC_SECURITY.serverCertificate.certData.getPublicKey()
|
||||||
|
serverPublicKey = rsa.PublicKey(modulus, publicExponent)
|
||||||
|
message = ClientSecurityExchangePDU()
|
||||||
|
#reverse because bignum in little endian
|
||||||
|
message.encryptedClientRandom.value = rsa.encrypt(clientRandom[::-1], serverPublicKey)[::-1]
|
||||||
|
self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
|
||||||
|
|
||||||
def recvLicenceInfo(self, s):
|
def recvLicenceInfo(self, s):
|
||||||
"""
|
"""
|
||||||
@summary: Read license info packet and check if is a valid client info
|
@summary: Read license info packet and check if is a valid client info
|
||||||
@@ -574,7 +593,20 @@ class Server(SecLayer):
|
|||||||
"""
|
"""
|
||||||
@summary: init automata to wait info packet
|
@summary: init automata to wait info packet
|
||||||
"""
|
"""
|
||||||
self.setNextState(self.recvInfoPkt)
|
self._enableEncryption = self.getGCCClientSettings().CS_CORE.serverSelectedProtocol == 0
|
||||||
|
if self._enableEncryption:
|
||||||
|
self.setNextState(self.recvClientRandom)
|
||||||
|
else:
|
||||||
|
self.setNextState(self.recvInfoPkt)
|
||||||
|
|
||||||
|
def recvClientRandom(self, s):
|
||||||
|
"""
|
||||||
|
@summary: receive client random and generate session keys
|
||||||
|
@param s: {Stream}
|
||||||
|
"""
|
||||||
|
message = ClientSecurityExchangePDU()
|
||||||
|
s.readType(message)
|
||||||
|
|
||||||
|
|
||||||
def recvInfoPkt(self, s):
|
def recvInfoPkt(self, s):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ class IFastPathSender(object):
|
|||||||
def sendFastPath(self, secFlag, fastPathS):
|
def sendFastPath(self, secFlag, fastPathS):
|
||||||
"""
|
"""
|
||||||
@summary: Send fastPathS Type as fast path packet
|
@summary: Send fastPathS Type as fast path packet
|
||||||
@param secFlag: {SecFlags}
|
@param secFlag: {integer} Security flag for fastpath packet
|
||||||
@param fastPathS: type transform to stream and send as fastpath
|
@param fastPathS: {Type | Tuple} type transform to stream and send as fastpath
|
||||||
"""
|
"""
|
||||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendFastPath", "IFastPathSender"))
|
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendFastPath", "IFastPathSender"))
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, presentation):
|
def __init__(self, presentation):
|
||||||
"""
|
"""
|
||||||
@param presentation: presentation layer, in RDP case is x224 layer
|
@param presentation: {Layer} presentation layer, in RDP case is x224 layer
|
||||||
"""
|
"""
|
||||||
RawLayer.__init__(self, presentation)
|
RawLayer.__init__(self, presentation)
|
||||||
#length may be coded on more than 1 bytes
|
#length may be coded on more than 1 bytes
|
||||||
@@ -133,8 +133,8 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
|
|
||||||
def readHeader(self, data):
|
def readHeader(self, data):
|
||||||
"""
|
"""
|
||||||
Read header of TPKT packet
|
@summary: Read header of TPKT packet
|
||||||
@param data: Stream received from twisted layer
|
@param data: {Stream} received from twisted layer
|
||||||
"""
|
"""
|
||||||
#first read packet version
|
#first read packet version
|
||||||
version = UInt8()
|
version = UInt8()
|
||||||
@@ -158,8 +158,8 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
|
|
||||||
def readExtendedHeader(self, data):
|
def readExtendedHeader(self, data):
|
||||||
"""
|
"""
|
||||||
Header may be on 4 bytes
|
@summary: Header may be on 4 bytes
|
||||||
@param data: Stream from twisted layer
|
@param data: {Stream} from twisted layer
|
||||||
"""
|
"""
|
||||||
#next state is read data
|
#next state is read data
|
||||||
size = UInt16Be()
|
size = UInt16Be()
|
||||||
@@ -168,8 +168,8 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
|
|
||||||
def readExtendedFastPathHeader(self, data):
|
def readExtendedFastPathHeader(self, data):
|
||||||
"""
|
"""
|
||||||
Fast path header may be on 1 byte more
|
@summary: Fast path header may be on 1 byte more
|
||||||
@param data: Stream from twisted layer
|
@param data: {Stream} from twisted layer
|
||||||
"""
|
"""
|
||||||
leftPart = UInt8()
|
leftPart = UInt8()
|
||||||
data.readType(leftPart)
|
data.readType(leftPart)
|
||||||
@@ -180,16 +180,16 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
|
|
||||||
def readFastPath(self, data):
|
def readFastPath(self, data):
|
||||||
"""
|
"""
|
||||||
Fast path data
|
@summary: Fast path data
|
||||||
@param data: Stream from twisted layer
|
@param data: {Stream} from twisted layer
|
||||||
"""
|
"""
|
||||||
self._fastPathListener.recvFastPath(self._secFlag, data)
|
self._fastPathListener.recvFastPath(self._secFlag, data)
|
||||||
self.expect(2, self.readHeader)
|
self.expect(2, self.readHeader)
|
||||||
|
|
||||||
def readData(self, data):
|
def readData(self, data):
|
||||||
"""
|
"""
|
||||||
Read classic TPKT packet, last state in tpkt automata
|
@summary: Read classic TPKT packet, last state in tpkt automata
|
||||||
@param data: Stream with correct size
|
@param data: {Stream} with correct size
|
||||||
"""
|
"""
|
||||||
#next state is pass to
|
#next state is pass to
|
||||||
self._presentation.recv(data)
|
self._presentation.recv(data)
|
||||||
@@ -197,14 +197,14 @@ class TPKT(RawLayer, IFastPathSender):
|
|||||||
|
|
||||||
def send(self, message):
|
def send(self, message):
|
||||||
"""
|
"""
|
||||||
Send encompassed data
|
@summary: Send encompassed data
|
||||||
@param message: network.Type message to send
|
@param message: {network.Type} message to send
|
||||||
"""
|
"""
|
||||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
||||||
|
|
||||||
def sendFastPath(self, secFlag, fastPathS):
|
def sendFastPath(self, secFlag, fastPathS):
|
||||||
"""
|
"""
|
||||||
@param fastPathS: type transform to stream and send as fastpath
|
@param fastPathS: type transform to stream and send as fastpath
|
||||||
@param secFlag: {SecFlags}
|
@param secFlag: {integer} Security flag for fastpath packet
|
||||||
"""
|
"""
|
||||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH | secFlag), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
|
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH | secFlag), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
|
||||||
@@ -130,9 +130,8 @@ class X224Layer(LayerAutomata, IStreamSender):
|
|||||||
@param presentation: upper layer, MCS layer in RDP case
|
@param presentation: upper layer, MCS layer in RDP case
|
||||||
"""
|
"""
|
||||||
LayerAutomata.__init__(self, presentation)
|
LayerAutomata.__init__(self, presentation)
|
||||||
#default selectedProtocol is SSl
|
|
||||||
#client requested selectedProtocol
|
#client requested selectedProtocol
|
||||||
self._requestedProtocol = Protocols.PROTOCOL_RDP
|
self._requestedProtocol = Protocols.PROTOCOL_RDP | Protocols.PROTOCOL_SSL
|
||||||
#server selected selectedProtocol
|
#server selected selectedProtocol
|
||||||
self._selectedProtocol = Protocols.PROTOCOL_SSL
|
self._selectedProtocol = Protocols.PROTOCOL_SSL
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user