finish 128 bit basic rdp security layer
This commit is contained in:
@@ -34,7 +34,7 @@ h221_sc_key = "McDn";
|
||||
|
||||
class MessageType(object):
|
||||
"""
|
||||
Server to Client block
|
||||
@summary: Server to Client block
|
||||
GCC conference messages
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240509.aspx
|
||||
"""
|
||||
@@ -52,7 +52,7 @@ class MessageType(object):
|
||||
|
||||
class ColorDepth(object):
|
||||
"""
|
||||
Depth color
|
||||
@summary: Depth color
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
RNS_UD_COLOR_8BPP = 0xCA01
|
||||
@@ -62,7 +62,7 @@ class ColorDepth(object):
|
||||
|
||||
class HighColor(object):
|
||||
"""
|
||||
High color of client
|
||||
@summary: High color of client
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
HIGH_COLOR_4BPP = 0x0004
|
||||
@@ -73,7 +73,7 @@ class HighColor(object):
|
||||
|
||||
class Support(object):
|
||||
"""
|
||||
Supported depth flag
|
||||
@summary: Supported depth flag
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
RNS_UD_24BPP_SUPPORT = 0x0001
|
||||
@@ -83,7 +83,7 @@ class Support(object):
|
||||
|
||||
class CapabilityFlags(object):
|
||||
"""
|
||||
For more details on each flags click above
|
||||
@summary: For more details on each flags click above
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
|
||||
@@ -100,7 +100,7 @@ class CapabilityFlags(object):
|
||||
|
||||
class ConnectionType(object):
|
||||
"""
|
||||
This information is correct if
|
||||
@summary: This information is correct if
|
||||
RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
@@ -114,7 +114,7 @@ class ConnectionType(object):
|
||||
|
||||
class Version(object):
|
||||
"""
|
||||
Supported version of RDP
|
||||
@summary: Supported version of RDP
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
"""
|
||||
RDP_VERSION_4 = 0x00080001
|
||||
@@ -125,7 +125,7 @@ class Sequence(object):
|
||||
|
||||
class Encryption(object):
|
||||
"""
|
||||
Encryption methods supported
|
||||
@summary: Encryption methods supported
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240511.aspx
|
||||
"""
|
||||
ENCRYPTION_FLAG_40BIT = 0x00000001
|
||||
@@ -135,7 +135,7 @@ class Encryption(object):
|
||||
|
||||
class ChannelOptions(object):
|
||||
"""
|
||||
Channel options
|
||||
@summary: Channel options
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240513.aspx
|
||||
"""
|
||||
CHANNEL_OPTION_INITIALIZED = 0x80000000
|
||||
@@ -152,8 +152,8 @@ class ChannelOptions(object):
|
||||
|
||||
class KeyboardType(object):
|
||||
"""
|
||||
Keyboard type
|
||||
IBM_101_102_KEYS is the most common keyboard type
|
||||
@summary: Keyboard type
|
||||
@see: IBM_101_102_KEYS is the most common keyboard type
|
||||
"""
|
||||
IBM_PC_XT_83_KEY = 0x00000001
|
||||
OLIVETTI = 0x00000002
|
||||
@@ -165,7 +165,7 @@ class KeyboardType(object):
|
||||
|
||||
class KeyboardLayout(object):
|
||||
"""
|
||||
Keyboard layout definition
|
||||
@summary: Keyboard layout definition
|
||||
@see: http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx
|
||||
"""
|
||||
ARABIC = 0x00000401
|
||||
@@ -197,7 +197,7 @@ class CertificateType(object):
|
||||
|
||||
class DataBlock(CompositeType):
|
||||
"""
|
||||
Block settings
|
||||
@summary: Block settings
|
||||
"""
|
||||
def __init__(self, dataBlock = None):
|
||||
CompositeType.__init__(self)
|
||||
|
||||
@@ -275,6 +275,7 @@ class LicenseManager(object):
|
||||
sessionKeyBlob = sec.generateMicrosoftKeyABBCCC(masterSecret, self._serverRandom, self._clientRandom)
|
||||
self._macSalt = sessionKeyBlob[:16]
|
||||
self._licenseKey = sec.finalHash(sessionKeyBlob[16:32], self._clientRandom, self._serverRandom)
|
||||
self._rc4LicenseKey = rc4.RC4Key(self._licenseKey)
|
||||
|
||||
def recv(self, s):
|
||||
"""
|
||||
@@ -324,7 +325,7 @@ class LicenseManager(object):
|
||||
"""
|
||||
#decrypt server challenge
|
||||
#it should be TEST word in unicode format
|
||||
serverChallenge = rc4.crypt(self._licenseKey, self._serverEncryptedChallenge)
|
||||
serverChallenge = rc4.crypt(self._rc4LicenseKey, self._serverEncryptedChallenge)
|
||||
|
||||
#generate hwid
|
||||
s = Stream()
|
||||
@@ -333,7 +334,7 @@ class LicenseManager(object):
|
||||
|
||||
message = ClientPLatformChallengeResponse()
|
||||
message.encryptedPlatformChallengeResponse.blobData.value = self._serverEncryptedChallenge
|
||||
message.encryptedHWID.blobData.value = rc4.crypt(self._licenseKey, hwid)
|
||||
message.encryptedHWID.blobData.value = rc4.crypt(self._rc4LicenseKey, hwid)
|
||||
message.MACData.value = sec.macData(self._macSalt, serverChallenge + hwid)
|
||||
|
||||
self._transport.sendFlagged(sec.SecurityFlag.SEC_LICENSE_PKT, LicPacket(message))
|
||||
@@ -362,8 +362,9 @@ class PointerCapability(CompositeType):
|
||||
def __init__(self, readLen = None):
|
||||
CompositeType.__init__(self, readLen = readLen)
|
||||
self.colorPointerFlag = UInt16Le()
|
||||
self.colorPointerCacheSize = UInt16Le()
|
||||
self.pointerCacheSize = UInt16Le()
|
||||
self.colorPointerCacheSize = UInt16Le(20)
|
||||
#old version of rdp doesn't support ...
|
||||
#self.pointerCacheSize = UInt16Le()
|
||||
|
||||
class InputCapability(CompositeType):
|
||||
"""
|
||||
|
||||
@@ -24,8 +24,7 @@ In this layer are managed all mains bitmap update orders end user inputs
|
||||
"""
|
||||
|
||||
from rdpy.core.layer import LayerAutomata
|
||||
from rdpy.core.error import InvalidExpectedDataException, CallPureVirtualFuntion
|
||||
from rdpy.core.type import UInt16Le
|
||||
from rdpy.core.error import CallPureVirtualFuntion
|
||||
import rdpy.core.log as log
|
||||
import rdpy.protocol.rdp.gcc as gcc
|
||||
import rdpy.protocol.rdp.tpkt as tpkt
|
||||
@@ -71,7 +70,7 @@ class PDUServerListener(object):
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "onSlowPathInput", "PDUServerListener"))
|
||||
|
||||
class PDULayer(LayerAutomata):
|
||||
class PDULayer(LayerAutomata, tpkt.IFastPathListener):
|
||||
"""
|
||||
@summary: Global channel for MCS that handle session
|
||||
identification user, licensing management, and capabilities exchange
|
||||
@@ -106,6 +105,15 @@ class PDULayer(LayerAutomata):
|
||||
}
|
||||
#share id between client and server
|
||||
self._shareId = 0x103EA
|
||||
#enable or not fast path
|
||||
self._fastPathSender = None
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: {tpkt.FastPathSender}
|
||||
@note: implement tpkt.IFastPathListener
|
||||
"""
|
||||
self._fastPathSender = fastPathSender
|
||||
|
||||
def sendPDU(self, pduMessage):
|
||||
"""
|
||||
@@ -121,7 +129,7 @@ class PDULayer(LayerAutomata):
|
||||
"""
|
||||
self.sendPDU(data.DataPDU(pduData, self._shareId))
|
||||
|
||||
class Client(PDULayer, tpkt.IFastPathListener):
|
||||
class Client(PDULayer):
|
||||
"""
|
||||
@summary: Client automata of PDU layer
|
||||
"""
|
||||
@@ -131,8 +139,6 @@ class Client(PDULayer, tpkt.IFastPathListener):
|
||||
"""
|
||||
PDULayer.__init__(self)
|
||||
self._listener = listener
|
||||
#enable or not fast path
|
||||
self._fastPathSender = None
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@@ -149,13 +155,6 @@ class Client(PDULayer, tpkt.IFastPathListener):
|
||||
"""
|
||||
self._transport.close()
|
||||
#self.sendDataPDU(data.ShutdownRequestPDU())
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: tpkt.FastPathSender
|
||||
@note: implement tpkt.IFastPathListener
|
||||
"""
|
||||
self._fastPathSender = fastPathSender
|
||||
|
||||
def recvDemandActivePDU(self, s):
|
||||
"""
|
||||
@@ -267,11 +266,12 @@ class Client(PDULayer, tpkt.IFastPathListener):
|
||||
#http://msdn.microsoft.com/en-us/library/cc240454.aspx
|
||||
self.setNextState(self.recvDemandActivePDU)
|
||||
|
||||
def recvFastPath(self, fastPathS):
|
||||
def recvFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@summary: Implement IFastPathListener interface
|
||||
Fast path is needed by RDP 8.0
|
||||
@param fastPathS: Stream that contain fast path data
|
||||
@param fastPathS: {Stream} that contain fast path data
|
||||
@param secFlag: {SecFlags}
|
||||
"""
|
||||
fastPathPDU = data.FastPathUpdatePDU()
|
||||
fastPathS.readType(fastPathPDU)
|
||||
@@ -343,7 +343,7 @@ class Client(PDULayer, tpkt.IFastPathListener):
|
||||
|
||||
def sendClientFinalizeSynchronizePDU(self):
|
||||
"""
|
||||
send a synchronize PDU from client to server
|
||||
@summary: send a synchronize PDU from client to server
|
||||
"""
|
||||
synchronizePDU = data.SynchronizeDataPDU(self._transport._transport.getChannelId())
|
||||
self.sendDataPDU(synchronizePDU)
|
||||
@@ -371,7 +371,7 @@ class Client(PDULayer, tpkt.IFastPathListener):
|
||||
pdu.slowPathInputEvents._array = [data.SlowPathInputEvent(x) for x in pointerEvents]
|
||||
self.sendDataPDU(pdu)
|
||||
|
||||
class Server(PDULayer, tpkt.IFastPathListener):
|
||||
class Server(PDULayer):
|
||||
"""
|
||||
Server Automata of PDU layer
|
||||
"""
|
||||
@@ -389,14 +389,7 @@ class Server(PDULayer, tpkt.IFastPathListener):
|
||||
Connect message for server automata
|
||||
"""
|
||||
self.sendDemandActivePDU()
|
||||
self.setNextState(self.recvConfirmActivePDU)
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: tpkt.FastPathSender
|
||||
@note: implement tpkt.IFastPathListener
|
||||
"""
|
||||
self._fastPathSender = fastPathSender
|
||||
self.setNextState(self.recvConfirmActivePDU)
|
||||
|
||||
def recvConfirmActivePDU(self, s):
|
||||
"""
|
||||
@@ -588,7 +581,8 @@ class Server(PDULayer, tpkt.IFastPathListener):
|
||||
#fast path case
|
||||
fastPathUpdateDataPDU = data.FastPathBitmapUpdateDataPDU()
|
||||
fastPathUpdateDataPDU.rectangles._array = bitmapDatas
|
||||
self._fastPathSender.sendFastPath(data.FastPathUpdatePDU(fastPathUpdateDataPDU))
|
||||
self._fastPathSender.sendFastPath(0, data.FastPathUpdatePDU(fastPathUpdateDataPDU))
|
||||
|
||||
else:
|
||||
#slow path case
|
||||
updateDataPDU = data.BitmapUpdateDataPDU()
|
||||
|
||||
@@ -50,7 +50,8 @@ def RC4(key):
|
||||
S = KSA(key)
|
||||
return PRGA(S)
|
||||
|
||||
def crypt(key, plaintext):
|
||||
keystream = RC4([ord(c) for c in key])
|
||||
|
||||
def RC4Key(key):
|
||||
return RC4([ord(c) for c in key])
|
||||
|
||||
def crypt(keystream, plaintext):
|
||||
return "".join([chr(ord(c) ^ keystream.next()) for c in plaintext])
|
||||
@@ -45,7 +45,10 @@ class RDPClientController(pdu.layer.PDUClientListener):
|
||||
#transport pdu layer
|
||||
self._x224Layer = x224.Client(self._mcsLayer)
|
||||
#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)
|
||||
#is pdu layer is ready to send
|
||||
self._isReady = False
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
Some use full methods for security in RDP
|
||||
"""
|
||||
|
||||
import sha, md5, rsa, gcc, rc4, lic
|
||||
import sha, md5, rsa, rc4
|
||||
import gcc, lic, tpkt
|
||||
from rdpy.core.type import CompositeType, Stream, UInt32Le, UInt16Le, String, sizeof, UInt8
|
||||
from rdpy.core.layer import LayerAutomata, IStreamSender
|
||||
from rdpy.core.error import InvalidExpectedDataException
|
||||
@@ -238,7 +239,7 @@ class RDPExtendedInfo(CompositeType):
|
||||
self.clientSessionId = UInt32Le()
|
||||
self.performanceFlags = UInt32Le()
|
||||
|
||||
class SecLayer(LayerAutomata, IStreamSender):
|
||||
class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastPathSender):
|
||||
"""
|
||||
@summary: Basic RDP security manager
|
||||
This layer is Transparent as possible for upper layer
|
||||
@@ -248,10 +249,25 @@ class SecLayer(LayerAutomata, IStreamSender):
|
||||
@param presentation: Layer (generally pdu layer)
|
||||
"""
|
||||
LayerAutomata.__init__(self, presentation)
|
||||
#thios layer is like a fastpath proxy
|
||||
self._fastPathTransport = None
|
||||
self._fastPathPresentation = None
|
||||
|
||||
#credentials
|
||||
self._info = RDPInfo(extendedInfoConditional = lambda:(self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_CORE).rdpVersion.value == gcc.Version.RDP_VERSION_5_PLUS))
|
||||
|
||||
#True if classic encryption is enable
|
||||
self._enableEncryption = False
|
||||
|
||||
#crypto random
|
||||
self._clientRandom = None
|
||||
self._serverRandom = None
|
||||
#initialise decrypt and encrypt keys
|
||||
self._decryt = None
|
||||
self._encrypt = None
|
||||
#current rc4 map key
|
||||
self._decryptRc4 = None
|
||||
self._encryptRc4 = None
|
||||
|
||||
def generateKeys(self):
|
||||
"""
|
||||
@@ -273,7 +289,12 @@ class SecLayer(LayerAutomata, IStreamSender):
|
||||
signature = String(readLen = UInt8(8))
|
||||
encryptedPayload = String()
|
||||
s.readType((signature, encryptedPayload))
|
||||
return Stream(rc4.crypt(self._decrypt, encryptedPayload.value))
|
||||
decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value)
|
||||
#ckeck signature
|
||||
if macData(self._macKey128, decrypted)[:8] != signature.value:
|
||||
raise InvalidExpectedDataException("Bad packet signature")
|
||||
|
||||
return Stream(decrypted)
|
||||
|
||||
def writeEncryptedPayload(self, data):
|
||||
"""
|
||||
@@ -283,7 +304,7 @@ class SecLayer(LayerAutomata, IStreamSender):
|
||||
"""
|
||||
s = Stream()
|
||||
s.writeType(data)
|
||||
return (String(macData(self._macKey128, s.getvalue())[:8]), String(rc4.crypt(self._encrypt, s.getvalue())))
|
||||
return (String(macData(self._macKey128, s.getvalue())[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
|
||||
|
||||
def recv(self, data):
|
||||
"""
|
||||
@@ -301,7 +322,7 @@ class SecLayer(LayerAutomata, IStreamSender):
|
||||
|
||||
if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
|
||||
data = self.readEncryptedPayload(data)
|
||||
|
||||
|
||||
self._presentation.recv(data)
|
||||
|
||||
def send(self, data):
|
||||
@@ -324,16 +345,44 @@ class SecLayer(LayerAutomata, IStreamSender):
|
||||
@param flag: {integer} security flag
|
||||
@param data: {Type | Tuple}
|
||||
"""
|
||||
if self._enableEncryption:
|
||||
flag |= SecurityFlag.SEC_ENCRYPT
|
||||
if flag & SecurityFlag.SEC_ENCRYPT:
|
||||
data = self.writeEncryptedPayload(data)
|
||||
self.__sendFlagged__(flag, data)
|
||||
|
||||
def __sendFlagged__(self, flag, data):
|
||||
"""
|
||||
@summary: format basic message of security layer
|
||||
"""
|
||||
self._transport.send((UInt16Le(flag), UInt16Le(), data))
|
||||
|
||||
def recvFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@summary: Call when fast path packet is received
|
||||
@param secFlag: {SecFlags}
|
||||
@param fastPathS: {Stream}
|
||||
"""
|
||||
if self._enableEncryption and secFlag & tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED:
|
||||
fastPathS = self.readEncryptedPayload(fastPathS)
|
||||
|
||||
self._fastPathPresentation.recvFastPath(secFlag, fastPathS)
|
||||
|
||||
def setFastPathListener(self, fastPathListener):
|
||||
"""
|
||||
@param fastPathListener : {IFastPathListener}
|
||||
"""
|
||||
self._fastPathPresentation = fastPathListener
|
||||
|
||||
def sendFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@summary: Send fastPathS Type as fast path packet
|
||||
@param secFlag: {SecFlags}
|
||||
@param fastPathS: {Stream} type transform to stream and send as fastpath
|
||||
"""
|
||||
if self._enableEncryption:
|
||||
secFlag |= tpkt.SecFlags.FASTPATH_OUTPUT_ENCRYPTED
|
||||
fastPathS = self.writeEncryptedPayload(fastPathS)
|
||||
|
||||
self._fastPathTransport.sendFastPath(secFlag, fastPathS)
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@param fastPathSender: {tpkt.FastPathSender}
|
||||
"""
|
||||
self._fastPathTransport = fastPathSender
|
||||
|
||||
class Client(SecLayer):
|
||||
"""
|
||||
@@ -352,19 +401,27 @@ class Client(SecLayer):
|
||||
self._clientRandom = rsa.randnum.read_random_bits(256)
|
||||
self._serverRandom = self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_SECURITY).serverRandom.value
|
||||
self._decrypt, self._encrypt = self.generateKeys()
|
||||
self._decryptRc4 = rc4.RC4Key(self._decrypt)
|
||||
self._encryptRc4 = rc4.RC4Key(self._encrypt)
|
||||
|
||||
#send client random encrypted with
|
||||
certificate = self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_SECURITY).serverCertificate.certData
|
||||
#reverse because bignum in little endian
|
||||
serverPublicKey = rsa.PublicKey(bin2bn(certificate.PublicKeyBlob.modulus.value[::-1]), certificate.PublicKeyBlob.pubExp.value)
|
||||
|
||||
message = ClientSecurityExchangePDU()
|
||||
#reverse because bignum in little endian
|
||||
message.encryptedClientRandom.value = rsa.encrypt(self._clientRandom[::-1], serverPublicKey)[::-1]
|
||||
self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
|
||||
|
||||
#now all messages must be encrypted
|
||||
self._enableEncryption = True
|
||||
|
||||
self.sendFlagged(SecurityFlag.SEC_INFO_PKT, self._info)
|
||||
|
||||
secFlag = SecurityFlag.SEC_INFO_PKT
|
||||
if self._enableEncryption:
|
||||
secFlag |= SecurityFlag.SEC_ENCRYPT
|
||||
self.sendFlagged(secFlag, self._info)
|
||||
|
||||
self.setNextState(self.recvLicenceInfo)
|
||||
|
||||
def recvLicenceInfo(self, s):
|
||||
|
||||
@@ -33,36 +33,67 @@ class Action(object):
|
||||
"""
|
||||
FASTPATH_ACTION_FASTPATH = 0x0
|
||||
FASTPATH_ACTION_X224 = 0x3
|
||||
|
||||
class SecFlags(object):
|
||||
"""
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240621.aspx
|
||||
"""
|
||||
#hihi 'secure' checksum but private key is public !!!
|
||||
FASTPATH_OUTPUT_SECURE_CHECKSUM = 0x1
|
||||
FASTPATH_OUTPUT_ENCRYPTED = 0x2
|
||||
|
||||
class IFastPathListener(object):
|
||||
"""
|
||||
@summary: Fast path packet listener
|
||||
Usually X224 layer
|
||||
"""
|
||||
def recvFastPath(self, fastPathS):
|
||||
def recvFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@summary: Call when fast path packet is received
|
||||
@param fastPathS: Stream
|
||||
@param secFlag: {SecFlags}
|
||||
@param fastPathS: {Stream}
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recvFastPath", "recvFastPath"))
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "recvFastPath", "IFastPathListener"))
|
||||
|
||||
def initFastPath(self, fastPathSender):
|
||||
"""
|
||||
@summary: initialize stack
|
||||
@param fastPathSender: {IFastPathSender}
|
||||
"""
|
||||
self.setFastPathSender(fastPathSender)
|
||||
fastPathSender.setFastPathListener(self)
|
||||
|
||||
def setFastPathSender(self, fastPathSender):
|
||||
"""
|
||||
@summary: Call to set a fast path sender to listener
|
||||
@param fastPathSender: IFastPathSender
|
||||
@param fastPathSender : {IFastPathSender}
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "setFastPathSender", "recvFastPath"))
|
||||
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "setFastPathSender", "IFastPathListener"))
|
||||
|
||||
class IFastPathSender(object):
|
||||
"""
|
||||
@summary: Fast path send capability
|
||||
"""
|
||||
def sendFastPath(self, fastPathS):
|
||||
def sendFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@summary: Send fastPathS Type as fast path packet
|
||||
@param secFlag: {SecFlags}
|
||||
@param fastPathS: type transform to stream and send as fastpath
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "sendFastPath", "IFastPathSender"))
|
||||
|
||||
def initFastPath(self, fastPathListener):
|
||||
"""
|
||||
@summary: initialize stack
|
||||
@param fastPathListener: {IFastPathListener}
|
||||
"""
|
||||
self.setFastPathListener(fastPathListener)
|
||||
fastPathListener.setFastPathSender(self)
|
||||
|
||||
def setFastPathListener(self, fastPathListener):
|
||||
"""
|
||||
@param fastPathListener: {IFastPathListener}
|
||||
"""
|
||||
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "setFastPathListener", "IFastPathSender"))
|
||||
|
||||
class TPKT(RawLayer, IFastPathSender):
|
||||
"""
|
||||
@@ -70,21 +101,25 @@ class TPKT(RawLayer, IFastPathSender):
|
||||
represent the Raw Layer in stack (first layer)
|
||||
This layer only handle size of packet and determine if is a fast path packet
|
||||
"""
|
||||
def __init__(self, presentation, fastPathListener = None):
|
||||
def __init__(self, presentation):
|
||||
"""
|
||||
@param presentation: presentation layer, in RDP case is x224 layer
|
||||
@param fastPathListener: IFastPathListener
|
||||
"""
|
||||
RawLayer.__init__(self, presentation)
|
||||
#length may be coded on more than 1 bytes
|
||||
self._lastShortLength = UInt8()
|
||||
#fast path listener
|
||||
self._fastPathListener = None
|
||||
#last secure flag
|
||||
self._secFlag = 0
|
||||
|
||||
def setFastPathListener(self, fastPathListener):
|
||||
"""
|
||||
@param fastPathListener : {IFastPathListener}
|
||||
@note: implement IFastPathSender
|
||||
"""
|
||||
self._fastPathListener = fastPathListener
|
||||
|
||||
if not fastPathListener is None:
|
||||
#set me as fast path sender
|
||||
fastPathListener.setFastPathSender(self)
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@summary: Call when transport layer connection
|
||||
@@ -112,6 +147,7 @@ class TPKT(RawLayer, IFastPathSender):
|
||||
self.expect(2, self.readExtendedHeader)
|
||||
else:
|
||||
#is fast path packet
|
||||
self._secFlag = version.value >> 6
|
||||
data.readType(self._lastShortLength)
|
||||
if self._lastShortLength.value & 0x80:
|
||||
#size is 1 byte more
|
||||
@@ -147,7 +183,7 @@ class TPKT(RawLayer, IFastPathSender):
|
||||
Fast path data
|
||||
@param data: Stream from twisted layer
|
||||
"""
|
||||
self._fastPathListener.recvFastPath(data)
|
||||
self._fastPathListener.recvFastPath(self._secFlag, data)
|
||||
self.expect(2, self.readHeader)
|
||||
|
||||
def readData(self, data):
|
||||
@@ -166,8 +202,9 @@ class TPKT(RawLayer, IFastPathSender):
|
||||
"""
|
||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
|
||||
|
||||
def sendFastPath(self, fastPathS):
|
||||
def sendFastPath(self, secFlag, fastPathS):
|
||||
"""
|
||||
@param fastPathS: type transform to stream and send as fastpath
|
||||
@param secFlag: {SecFlags}
|
||||
"""
|
||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
|
||||
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH | secFlag), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
|
||||
@@ -132,7 +132,7 @@ class X224Layer(LayerAutomata, IStreamSender):
|
||||
LayerAutomata.__init__(self, presentation)
|
||||
#default selectedProtocol is SSl
|
||||
#client requested selectedProtocol
|
||||
self._requestedProtocol = Protocols.PROTOCOL_RDP
|
||||
self._requestedProtocol = Protocols.PROTOCOL_RDP | Protocols.PROTOCOL_SSL
|
||||
#server selected selectedProtocol
|
||||
self._selectedProtocol = Protocols.PROTOCOL_SSL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user