finish 128 bit basic rdp security layer

This commit is contained in:
speyrefitte
2014-12-10 18:32:10 +01:00
parent 47a9f75fa6
commit f3a3ad8ac3
10 changed files with 175 additions and 80 deletions

View File

@@ -34,7 +34,7 @@ h221_sc_key = "McDn";
class MessageType(object): class MessageType(object):
""" """
Server to Client block @summary: Server to Client block
GCC conference messages GCC conference messages
@see: http://msdn.microsoft.com/en-us/library/cc240509.aspx @see: http://msdn.microsoft.com/en-us/library/cc240509.aspx
""" """
@@ -52,7 +52,7 @@ class MessageType(object):
class ColorDepth(object): class ColorDepth(object):
""" """
Depth color @summary: Depth color
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
RNS_UD_COLOR_8BPP = 0xCA01 RNS_UD_COLOR_8BPP = 0xCA01
@@ -62,7 +62,7 @@ class ColorDepth(object):
class HighColor(object): class HighColor(object):
""" """
High color of client @summary: High color of client
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
HIGH_COLOR_4BPP = 0x0004 HIGH_COLOR_4BPP = 0x0004
@@ -73,7 +73,7 @@ class HighColor(object):
class Support(object): class Support(object):
""" """
Supported depth flag @summary: Supported depth flag
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
RNS_UD_24BPP_SUPPORT = 0x0001 RNS_UD_24BPP_SUPPORT = 0x0001
@@ -83,7 +83,7 @@ class Support(object):
class CapabilityFlags(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 @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001 RNS_UD_CS_SUPPORT_ERRINFO_PDU = 0x0001
@@ -100,7 +100,7 @@ class CapabilityFlags(object):
class ConnectionType(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 RNS_UD_CS_VALID_CONNECTION_TYPE flag is set on capabilityFlag
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
@@ -114,7 +114,7 @@ class ConnectionType(object):
class Version(object): class Version(object):
""" """
Supported version of RDP @summary: Supported version of RDP
@see: http://msdn.microsoft.com/en-us/library/cc240510.aspx @see: http://msdn.microsoft.com/en-us/library/cc240510.aspx
""" """
RDP_VERSION_4 = 0x00080001 RDP_VERSION_4 = 0x00080001
@@ -125,7 +125,7 @@ class Sequence(object):
class Encryption(object): class Encryption(object):
""" """
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
""" """
ENCRYPTION_FLAG_40BIT = 0x00000001 ENCRYPTION_FLAG_40BIT = 0x00000001
@@ -135,7 +135,7 @@ class Encryption(object):
class ChannelOptions(object): class ChannelOptions(object):
""" """
Channel options @summary: Channel options
@see: http://msdn.microsoft.com/en-us/library/cc240513.aspx @see: http://msdn.microsoft.com/en-us/library/cc240513.aspx
""" """
CHANNEL_OPTION_INITIALIZED = 0x80000000 CHANNEL_OPTION_INITIALIZED = 0x80000000
@@ -152,8 +152,8 @@ class ChannelOptions(object):
class KeyboardType(object): class KeyboardType(object):
""" """
Keyboard type @summary: Keyboard type
IBM_101_102_KEYS is the most common keyboard type @see: IBM_101_102_KEYS is the most common keyboard type
""" """
IBM_PC_XT_83_KEY = 0x00000001 IBM_PC_XT_83_KEY = 0x00000001
OLIVETTI = 0x00000002 OLIVETTI = 0x00000002
@@ -165,7 +165,7 @@ class KeyboardType(object):
class KeyboardLayout(object): class KeyboardLayout(object):
""" """
Keyboard layout definition @summary: Keyboard layout definition
@see: http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx @see: http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx
""" """
ARABIC = 0x00000401 ARABIC = 0x00000401
@@ -197,7 +197,7 @@ class CertificateType(object):
class DataBlock(CompositeType): class DataBlock(CompositeType):
""" """
Block settings @summary: Block settings
""" """
def __init__(self, dataBlock = None): def __init__(self, dataBlock = None):
CompositeType.__init__(self) CompositeType.__init__(self)

View File

@@ -275,6 +275,7 @@ class LicenseManager(object):
sessionKeyBlob = sec.generateMicrosoftKeyABBCCC(masterSecret, self._serverRandom, self._clientRandom) sessionKeyBlob = sec.generateMicrosoftKeyABBCCC(masterSecret, self._serverRandom, self._clientRandom)
self._macSalt = sessionKeyBlob[:16] self._macSalt = sessionKeyBlob[:16]
self._licenseKey = sec.finalHash(sessionKeyBlob[16:32], self._clientRandom, self._serverRandom) self._licenseKey = sec.finalHash(sessionKeyBlob[16:32], self._clientRandom, self._serverRandom)
self._rc4LicenseKey = rc4.RC4Key(self._licenseKey)
def recv(self, s): def recv(self, s):
""" """
@@ -324,7 +325,7 @@ class LicenseManager(object):
""" """
#decrypt server challenge #decrypt server challenge
#it should be TEST word in unicode format #it should be TEST word in unicode format
serverChallenge = rc4.crypt(self._licenseKey, self._serverEncryptedChallenge) serverChallenge = rc4.crypt(self._rc4LicenseKey, self._serverEncryptedChallenge)
#generate hwid #generate hwid
s = Stream() s = Stream()
@@ -333,7 +334,7 @@ class LicenseManager(object):
message = ClientPLatformChallengeResponse() message = ClientPLatformChallengeResponse()
message.encryptedPlatformChallengeResponse.blobData.value = self._serverEncryptedChallenge 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) message.MACData.value = sec.macData(self._macSalt, serverChallenge + hwid)
self._transport.sendFlagged(sec.SecurityFlag.SEC_LICENSE_PKT, LicPacket(message)) self._transport.sendFlagged(sec.SecurityFlag.SEC_LICENSE_PKT, LicPacket(message))

View File

@@ -362,8 +362,9 @@ class PointerCapability(CompositeType):
def __init__(self, readLen = None): def __init__(self, readLen = None):
CompositeType.__init__(self, readLen = readLen) CompositeType.__init__(self, readLen = readLen)
self.colorPointerFlag = UInt16Le() self.colorPointerFlag = UInt16Le()
self.colorPointerCacheSize = UInt16Le() self.colorPointerCacheSize = UInt16Le(20)
self.pointerCacheSize = UInt16Le() #old version of rdp doesn't support ...
#self.pointerCacheSize = UInt16Le()
class InputCapability(CompositeType): class InputCapability(CompositeType):
""" """

View File

@@ -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.layer import LayerAutomata
from rdpy.core.error import InvalidExpectedDataException, CallPureVirtualFuntion from rdpy.core.error import CallPureVirtualFuntion
from rdpy.core.type import UInt16Le
import rdpy.core.log as log import rdpy.core.log as log
import rdpy.protocol.rdp.gcc as gcc import rdpy.protocol.rdp.gcc as gcc
import rdpy.protocol.rdp.tpkt as tpkt 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")) 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 @summary: Global channel for MCS that handle session
identification user, licensing management, and capabilities exchange identification user, licensing management, and capabilities exchange
@@ -106,6 +105,15 @@ class PDULayer(LayerAutomata):
} }
#share id between client and server #share id between client and server
self._shareId = 0x103EA 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): def sendPDU(self, pduMessage):
""" """
@@ -121,7 +129,7 @@ class PDULayer(LayerAutomata):
""" """
self.sendPDU(data.DataPDU(pduData, self._shareId)) self.sendPDU(data.DataPDU(pduData, self._shareId))
class Client(PDULayer, tpkt.IFastPathListener): class Client(PDULayer):
""" """
@summary: Client automata of PDU layer @summary: Client automata of PDU layer
""" """
@@ -131,8 +139,6 @@ class Client(PDULayer, tpkt.IFastPathListener):
""" """
PDULayer.__init__(self) PDULayer.__init__(self)
self._listener = listener self._listener = listener
#enable or not fast path
self._fastPathSender = None
def connect(self): def connect(self):
""" """
@@ -149,13 +155,6 @@ class Client(PDULayer, tpkt.IFastPathListener):
""" """
self._transport.close() self._transport.close()
#self.sendDataPDU(data.ShutdownRequestPDU()) #self.sendDataPDU(data.ShutdownRequestPDU())
def setFastPathSender(self, fastPathSender):
"""
@param fastPathSender: tpkt.FastPathSender
@note: implement tpkt.IFastPathListener
"""
self._fastPathSender = fastPathSender
def recvDemandActivePDU(self, s): def recvDemandActivePDU(self, s):
""" """
@@ -267,11 +266,12 @@ class Client(PDULayer, tpkt.IFastPathListener):
#http://msdn.microsoft.com/en-us/library/cc240454.aspx #http://msdn.microsoft.com/en-us/library/cc240454.aspx
self.setNextState(self.recvDemandActivePDU) self.setNextState(self.recvDemandActivePDU)
def recvFastPath(self, fastPathS): def recvFastPath(self, secFlag, fastPathS):
""" """
@summary: 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
@param secFlag: {SecFlags}
""" """
fastPathPDU = data.FastPathUpdatePDU() fastPathPDU = data.FastPathUpdatePDU()
fastPathS.readType(fastPathPDU) fastPathS.readType(fastPathPDU)
@@ -343,7 +343,7 @@ class Client(PDULayer, tpkt.IFastPathListener):
def sendClientFinalizeSynchronizePDU(self): 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()) synchronizePDU = data.SynchronizeDataPDU(self._transport._transport.getChannelId())
self.sendDataPDU(synchronizePDU) self.sendDataPDU(synchronizePDU)
@@ -371,7 +371,7 @@ class Client(PDULayer, tpkt.IFastPathListener):
pdu.slowPathInputEvents._array = [data.SlowPathInputEvent(x) for x in pointerEvents] pdu.slowPathInputEvents._array = [data.SlowPathInputEvent(x) for x in pointerEvents]
self.sendDataPDU(pdu) self.sendDataPDU(pdu)
class Server(PDULayer, tpkt.IFastPathListener): class Server(PDULayer):
""" """
Server Automata of PDU layer Server Automata of PDU layer
""" """
@@ -389,14 +389,7 @@ class Server(PDULayer, tpkt.IFastPathListener):
Connect message for server automata Connect message for server automata
""" """
self.sendDemandActivePDU() self.sendDemandActivePDU()
self.setNextState(self.recvConfirmActivePDU) self.setNextState(self.recvConfirmActivePDU)
def setFastPathSender(self, fastPathSender):
"""
@param fastPathSender: tpkt.FastPathSender
@note: implement tpkt.IFastPathListener
"""
self._fastPathSender = fastPathSender
def recvConfirmActivePDU(self, s): def recvConfirmActivePDU(self, s):
""" """
@@ -588,7 +581,8 @@ class Server(PDULayer, tpkt.IFastPathListener):
#fast path case #fast path case
fastPathUpdateDataPDU = data.FastPathBitmapUpdateDataPDU() fastPathUpdateDataPDU = data.FastPathBitmapUpdateDataPDU()
fastPathUpdateDataPDU.rectangles._array = bitmapDatas fastPathUpdateDataPDU.rectangles._array = bitmapDatas
self._fastPathSender.sendFastPath(data.FastPathUpdatePDU(fastPathUpdateDataPDU)) self._fastPathSender.sendFastPath(0, data.FastPathUpdatePDU(fastPathUpdateDataPDU))
else: else:
#slow path case #slow path case
updateDataPDU = data.BitmapUpdateDataPDU() updateDataPDU = data.BitmapUpdateDataPDU()

View File

@@ -50,7 +50,8 @@ def RC4(key):
S = KSA(key) S = KSA(key)
return PRGA(S) return PRGA(S)
def crypt(key, plaintext): def RC4Key(key):
keystream = RC4([ord(c) for c in key]) return RC4([ord(c) for c in key])
def crypt(keystream, plaintext):
return "".join([chr(ord(c) ^ keystream.next()) for c in plaintext]) return "".join([chr(ord(c) ^ keystream.next()) for c in plaintext])

View File

@@ -45,7 +45,10 @@ class RDPClientController(pdu.layer.PDUClientListener):
#transport pdu layer #transport pdu layer
self._x224Layer = x224.Client(self._mcsLayer) self._x224Layer = x224.Client(self._mcsLayer)
#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)
#is pdu layer is ready to send #is pdu layer is ready to send
self._isReady = False self._isReady = False

View File

@@ -21,7 +21,8 @@
Some use full methods for security in RDP 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.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
@@ -238,7 +239,7 @@ class RDPExtendedInfo(CompositeType):
self.clientSessionId = UInt32Le() self.clientSessionId = UInt32Le()
self.performanceFlags = UInt32Le() self.performanceFlags = UInt32Le()
class SecLayer(LayerAutomata, IStreamSender): class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastPathSender):
""" """
@summary: Basic RDP security manager @summary: Basic RDP security manager
This layer is Transparent as possible for upper layer This layer is Transparent as possible for upper layer
@@ -248,10 +249,25 @@ class SecLayer(LayerAutomata, IStreamSender):
@param presentation: Layer (generally pdu layer) @param presentation: Layer (generally pdu layer)
""" """
LayerAutomata.__init__(self, presentation) 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)) 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 self._enableEncryption = False
#crypto random
self._clientRandom = None
self._serverRandom = None
#initialise decrypt and encrypt keys
self._decryt = None self._decryt = None
self._encrypt = None self._encrypt = None
#current rc4 map key
self._decryptRc4 = None
self._encryptRc4 = None
def generateKeys(self): def generateKeys(self):
""" """
@@ -273,7 +289,12 @@ class SecLayer(LayerAutomata, IStreamSender):
signature = String(readLen = UInt8(8)) signature = String(readLen = UInt8(8))
encryptedPayload = String() encryptedPayload = String()
s.readType((signature, encryptedPayload)) 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): def writeEncryptedPayload(self, data):
""" """
@@ -283,7 +304,7 @@ class SecLayer(LayerAutomata, IStreamSender):
""" """
s = Stream() s = Stream()
s.writeType(data) 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): def recv(self, data):
""" """
@@ -301,7 +322,7 @@ class SecLayer(LayerAutomata, IStreamSender):
if securityFlag.value & SecurityFlag.SEC_ENCRYPT: if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
data = self.readEncryptedPayload(data) data = self.readEncryptedPayload(data)
self._presentation.recv(data) self._presentation.recv(data)
def send(self, data): def send(self, data):
@@ -324,16 +345,44 @@ class SecLayer(LayerAutomata, IStreamSender):
@param flag: {integer} security flag @param flag: {integer} security flag
@param data: {Type | Tuple} @param data: {Type | Tuple}
""" """
if self._enableEncryption: if flag & SecurityFlag.SEC_ENCRYPT:
flag |= SecurityFlag.SEC_ENCRYPT
data = self.writeEncryptedPayload(data) 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)) 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): class Client(SecLayer):
""" """
@@ -352,19 +401,27 @@ class Client(SecLayer):
self._clientRandom = rsa.randnum.read_random_bits(256) self._clientRandom = rsa.randnum.read_random_bits(256)
self._serverRandom = self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_SECURITY).serverRandom.value self._serverRandom = self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_SECURITY).serverRandom.value
self._decrypt, self._encrypt = self.generateKeys() self._decrypt, self._encrypt = self.generateKeys()
self._decryptRc4 = rc4.RC4Key(self._decrypt)
self._encryptRc4 = rc4.RC4Key(self._encrypt)
#send client random encrypted with #send client random encrypted with
certificate = self._transport.getGCCServerSettings().getBlock(gcc.MessageType.SC_SECURITY).serverCertificate.certData 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) serverPublicKey = rsa.PublicKey(bin2bn(certificate.PublicKeyBlob.modulus.value[::-1]), certificate.PublicKeyBlob.pubExp.value)
message = ClientSecurityExchangePDU() message = ClientSecurityExchangePDU()
#reverse because bignum in little endian
message.encryptedClientRandom.value = rsa.encrypt(self._clientRandom[::-1], serverPublicKey)[::-1] message.encryptedClientRandom.value = rsa.encrypt(self._clientRandom[::-1], serverPublicKey)[::-1]
self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message) self.sendFlagged(SecurityFlag.SEC_EXCHANGE_PKT, message)
#now all messages must be encrypted #now all messages must be encrypted
self._enableEncryption = True 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) self.setNextState(self.recvLicenceInfo)
def recvLicenceInfo(self, s): def recvLicenceInfo(self, s):

View File

@@ -33,36 +33,67 @@ class Action(object):
""" """
FASTPATH_ACTION_FASTPATH = 0x0 FASTPATH_ACTION_FASTPATH = 0x0
FASTPATH_ACTION_X224 = 0x3 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): class IFastPathListener(object):
""" """
@summary: Fast path packet listener @summary: Fast path packet listener
Usually X224 layer Usually X224 layer
""" """
def recvFastPath(self, fastPathS): def recvFastPath(self, secFlag, fastPathS):
""" """
@summary: Call when fast path packet is received @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): 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): class IFastPathSender(object):
""" """
@summary: Fast path send capability @summary: Fast path send capability
""" """
def sendFastPath(self, 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 fastPathS: type transform to stream and send as fastpath @param fastPathS: 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"))
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): class TPKT(RawLayer, IFastPathSender):
""" """
@@ -70,21 +101,25 @@ class TPKT(RawLayer, IFastPathSender):
represent the Raw Layer in stack (first layer) represent the Raw Layer in stack (first layer)
This layer only handle size of packet and determine if is a fast path packet 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 presentation: presentation layer, in RDP case is x224 layer
@param fastPathListener: IFastPathListener
""" """
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
self._lastShortLength = UInt8() self._lastShortLength = UInt8()
#fast path listener #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 self._fastPathListener = fastPathListener
if not fastPathListener is None:
#set me as fast path sender
fastPathListener.setFastPathSender(self)
def connect(self): def connect(self):
""" """
@summary: Call when transport layer connection @summary: Call when transport layer connection
@@ -112,6 +147,7 @@ class TPKT(RawLayer, IFastPathSender):
self.expect(2, self.readExtendedHeader) self.expect(2, self.readExtendedHeader)
else: else:
#is fast path packet #is fast path packet
self._secFlag = version.value >> 6
data.readType(self._lastShortLength) data.readType(self._lastShortLength)
if self._lastShortLength.value & 0x80: if self._lastShortLength.value & 0x80:
#size is 1 byte more #size is 1 byte more
@@ -147,7 +183,7 @@ class TPKT(RawLayer, IFastPathSender):
Fast path data Fast path data
@param data: Stream from twisted layer @param data: Stream from twisted layer
""" """
self._fastPathListener.recvFastPath(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):
@@ -166,8 +202,9 @@ class TPKT(RawLayer, IFastPathSender):
""" """
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, 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}
""" """
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))

View File

@@ -132,7 +132,7 @@ class X224Layer(LayerAutomata, IStreamSender):
LayerAutomata.__init__(self, presentation) LayerAutomata.__init__(self, presentation)
#default selectedProtocol is SSl #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

View File

@@ -35,5 +35,6 @@ setup(name='rdpy',
'pyopenssl', 'pyopenssl',
'service_identity', 'service_identity',
'qt4reactor', 'qt4reactor',
'rsa',
], ],
) )