Update: TPKT + x224 asyncio complient

This commit is contained in:
citronneur
2020-04-17 15:52:37 +02:00
parent 3f56b25f46
commit 9cac72a8d2
23 changed files with 447 additions and 795 deletions

View File

@@ -21,261 +21,23 @@
example of use rdpy as rdp client
"""
import sys, os, getopt, socket
import sys
import asyncio
from PyQt5 import QtWidgets
from rdpy.ui.qt4 import RDPClientQt
from rdpy.model.error import RDPSecurityNegoFail
from rdpy.model import rss
from rdpy.core import rdp
from rdpy.core import tpkt, x224
from rdpy.model.type import UInt8
import rdpy.model.log as log
log._LOG_LEVEL = log.Level.INFO
class RDPClientQtRecorder(RDPClientQt):
"""
@summary: Widget with record session
"""
def __init__(self, controller, width, height, rssRecorder):
"""
@param controller: {RDPClientController} RDP controller
@param width: {int} width of widget
@param height: {int} height of widget
@param rssRecorder: {rss.FileRecorder}
"""
RDPClientQt.__init__(self, controller, width, height)
self._screensize = width, height
self._rssRecorder = rssRecorder
def onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data):
"""
@summary: Notify bitmap update
@param destLeft: {int} xmin position
@param destTop: {int} ymin position
@param destRight: {int} xmax position because RDP can send bitmap with padding
@param destBottom: {int} ymax position because RDP can send bitmap with padding
@param width: {int} width of bitmap
@param height: {int} height of bitmap
@param bitsPerPixel: {int} number of bit per pixel
@param isCompress: {bool} use RLE compression
@param data: {str} bitmap data
"""
#record update
self._rssRecorder.update(destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, rss.UpdateFormat.BMP if isCompress else rss.UpdateFormat.RAW, data)
RDPClientQt.onUpdate(self, destLeft, destTop, destRight, destBottom, width, height, bitsPerPixel, isCompress, data)
def onReady(self):
"""
@summary: Call when stack is ready
"""
self._rssRecorder.screen(self._screensize[0], self._screensize[1], self._controller.getColorDepth())
RDPClientQt.onReady(self)
def onClose(self):
"""
@summary: Call when stack is close
"""
self._rssRecorder.close()
RDPClientQt.onClose(self)
def closeEvent(self, e):
"""
@summary: Convert Qt close widget event into close stack event
@param e: QCloseEvent
"""
self._rssRecorder.close()
RDPClientQt.closeEvent(self, e)
class RDPClientQtFactory(rdp.ClientFactory):
"""
@summary: Factory create a RDP GUI client
"""
def __init__(self, width, height, username, password, domain, fullscreen, keyboardLayout, optimized, security, recodedPath):
"""
@param width: {integer} width of client
@param heigth: {integer} heigth of client
@param username: {str} username present to the server
@param password: {str} password present to the server
@param domain: {str} microsoft domain
@param fullscreen: {bool} show widget in fullscreen mode
@param keyboardLayout: {str} (fr|en) keyboard layout
@param optimized: {bool} enable optimized session orders
@param security: {str} (ssl | rdp | nego)
@param recodedPath: {str | None} Rss file Path
"""
self._width = width
self._height = height
self._username = username
self._passwod = password
self._domain = domain
self._fullscreen = fullscreen
self._keyboardLayout = keyboardLayout
self._optimized = optimized
self._nego = security == "nego"
self._recodedPath = recodedPath
if self._nego:
#compute start nego nla need credentials
if username != "" and password != "":
self._security = rdp.SecurityLevel.RDP_LEVEL_NLA
else:
self._security = rdp.SecurityLevel.RDP_LEVEL_SSL
else:
self._security = security
self._w = None
def buildObserver(self, controller, addr):
"""
@summary: Build RFB observer
We use a RDPClientQt as RDP observer
@param controller: build factory and needed by observer
@param addr: destination address
@return: RDPClientQt
"""
#create client observer
if self._recodedPath is None:
self._client = RDPClientQt(controller, self._width, self._height)
else:
self._client = RDPClientQtRecorder(controller, self._width, self._height, rss.createRecorder(self._recodedPath))
#create qt widget
self._w = self._client.getWidget()
self._w.setWindowTitle('rdpy-rdpclient')
if self._fullscreen:
self._w.showFullScreen()
else:
self._w.show()
controller.setUsername(self._username)
controller.setPassword(self._passwod)
controller.setDomain(self._domain)
controller.setKeyboardLayout(self._keyboardLayout)
controller.setHostname(socket.gethostname())
if self._optimized:
controller.setPerformanceSession()
controller.setSecurityLevel(self._security)
return self._client
def clientConnectionLost(self, connector, reason):
"""
@summary: Connection lost event
@param connector: twisted connector use for rdp connection (use reconnect to restart connection)
@param reason: str use to advertise reason of lost connection
"""
#try reconnect with basic RDP security
if reason.type == RDPSecurityNegoFail and self._nego:
#stop nego
log.info("due to security nego error back to standard RDP security layer")
self._nego = False
self._security = rdp.SecurityLevel.RDP_LEVEL_RDP
self._client._widget.hide()
connector.connect()
return
log.info("Lost connection : %s"%reason)
reactor.stop()
app.exit()
def clientConnectionFailed(self, connector, reason):
"""
@summary: Connection failed event
@param connector: twisted connector use for rdp connection (use reconnect to restart connection)
@param reason: str use to advertise reason of lost connection
"""
log.info("Connection failed : %s"%reason)
reactor.stop()
app.exit()
def autoDetectKeyboardLayout():
"""
@summary: try to auto detect keyboard layout
"""
try:
if os.name == 'posix':
from subprocess import check_output
result = check_output(["setxkbmap", "-print"])
if 'azerty' in result:
return "fr"
elif os.name == 'nt':
import win32api, win32con, win32process
from ctypes import windll
w = windll.user32.GetForegroundWindow()
tid = windll.user32.GetWindowThreadProcessId(w, 0)
result = windll.user32.GetKeyboardLayout(tid)
log.info(result)
if result == 0x40c040c:
return "fr"
except Exception as e:
log.info("failed to auto detect keyboard layout " + str(e))
pass
return "en"
def help():
print("""
Usage: rdpy-rdpclient [options] ip[:port]"
\t-u: user name
\t-p: password
\t-d: domain
\t-w: width of screen [default : 1024]
\t-l: height of screen [default : 800]
\t-f: enable full screen mode [default : False]
\t-k: keyboard layout [en|fr] [default : en]
\t-o: optimized session (disable costly effect) [default : False]
\t-r: rss_filepath Recorded Session Scenario [default : None]
""")
if __name__ == '__main__':
#default script argument
username = ""
password = ""
domain = ""
width = 1024
height = 800
fullscreen = False
optimized = False
recodedPath = None
keyboardLayout = autoDetectKeyboardLayout()
try:
opts, args = getopt.getopt(sys.argv[1:], "hfou:p:d:w:l:k:r:")
except getopt.GetoptError:
help()
for opt, arg in opts:
if opt == "-h":
help()
sys.exit()
elif opt == "-u":
username = arg
elif opt == "-p":
password = arg
elif opt == "-d":
domain = arg
elif opt == "-w":
width = int(arg)
elif opt == "-l":
height = int(arg)
elif opt == "-f":
fullscreen = True
elif opt == "-o":
optimized = True
elif opt == "-k":
keyboardLayout = arg
elif opt == "-r":
recodedPath = arg
if ':' in args[0]:
ip, port = args[0].split(':')
else:
ip, port = args[0], "3389"
#create application
app = QtWidgets.QApplication(sys.argv)
if fullscreen:
width = QtWidgets.QDesktopWidget().screenGeometry().width()
height = QtWidgets.QDesktopWidget().screenGeometry().height()
log.info("keyboard layout set to %s"%keyboardLayout)
sys.exit(app.exec_())
#sys.exit(app.exec_())
async def tcp_echo_client(message):
reader, writer = await asyncio.open_connection(
'127.0.0.1', 33389)
x224_layer = await x224.connect(tpkt.Tpkt(reader, writer))
await x224_layer.write(UInt8(8))
await asyncio.sleep(1000)
print("foooooooooooooooooooo")
asyncio.run(tcp_echo_client('Hello World!'))

View File

@@ -272,7 +272,7 @@ class LicenseManager(object):
@return true when license automata is finish
"""
licPacket = LicPacket()
s.readType(licPacket)
s.read_type(licPacket)
#end of automata
if licPacket.bMsgtype.value == MessageType.ERROR_ALERT and licPacket.licensingMessage.dwErrorCode.value == ErrorCode.STATUS_VALID_CLIENT and licPacket.licensingMessage.dwStateTransition.value == StateTransition.ST_NO_TRANSITION:
@@ -308,7 +308,7 @@ class LicenseManager(object):
else:
s = Stream(licenseRequest.serverCertificate.blobData.value)
serverCertificate = gcc.ServerCertificate()
s.readType(serverCertificate)
s.read_type(serverCertificate)
#generate crypto values
clientRandom = rsa.random(256)
@@ -340,7 +340,7 @@ class LicenseManager(object):
#generate hwid
s = Stream()
s.writeType((UInt32Le(2), String(self._hostname + self._username + "\x00" * 16)))
s.write_type((UInt32Le(2), String(self._hostname + self._username + "\x00" * 16)))
hwid = s.getvalue()[:20]
message = ClientPLatformChallengeResponse()

View File

@@ -27,6 +27,7 @@ import pyasn1.codec.der.encoder as der_encoder
import pyasn1.codec.der.decoder as der_decoder
import pyasn1.codec.ber.encoder as ber_encoder
from rdpy.core.nla import sspi
from rdpy.model.type import Stream
from rdpy.security import x509
from rdpy.model import error
@@ -113,21 +114,22 @@ class OpenSSLRSAPublicKey(univ.Sequence):
namedtype.NamedType('publicExponent', univ.Integer()),
)
def encodeDERTRequest(negoTypes = [], authInfo = None, pubKeyAuth = None):
def encode_der_trequest(nego_types=[], auth_info=None, pub_key_auth=None):
"""
@summary: create TSRequest from list of Type
@param negoTypes: {list(Type)}
@param authInfo: {str} authentication info TSCredentials encrypted with authentication protocol
@param pubKeyAuth: {str} public key encrypted with authentication protocol
@param nego_types: {list(Type)}
@param auth_info: {str} authentication info TSCredentials encrypted with authentication protocol
@param pub_key_auth: {str} public key encrypted with authentication protocol
@return: {str} TRequest der encoded
"""
negoData = NegoData().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))
#fill nego data tokens
i = 0
for negoType in negoTypes:
for negoType in nego_types:
s = Stream()
s.writeType(negoType)
s.write_type(negoType)
negoToken = NegoToken()
negoToken.setComponentByPosition(0, s.getvalue())
negoData.setComponentByPosition(i, negoToken)
@@ -139,21 +141,23 @@ def encodeDERTRequest(negoTypes = [], authInfo = None, pubKeyAuth = None):
if i > 0:
request.setComponentByName("negoTokens", negoData)
if not authInfo is None:
request.setComponentByName("authInfo", univ.OctetString(authInfo).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)))
if not auth_info is None:
request.setComponentByName("authInfo", univ.OctetString(auth_info).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2)))
if not pubKeyAuth is None:
request.setComponentByName("pubKeyAuth", univ.OctetString(pubKeyAuth).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)))
if not pub_key_auth is None:
request.setComponentByName("pubKeyAuth", univ.OctetString(pub_key_auth).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3)))
return der_encoder.encode(request)
def decodeDERTRequest(s):
def decode_der_trequest(s):
"""
@summary: Decode the stream as
@param s: {str}
"""
return der_decoder.decode(s, asn1Spec=TSRequest())[0]
def getNegoTokens(tRequest):
negoData = tRequest.getComponentByName("negoTokens")
return [Stream(negoData.getComponentByPosition(i).getComponentByPosition(0).asOctets()) for i in range(len(negoData))]
@@ -173,117 +177,53 @@ def encodeDERTCredentials(domain, username, password):
return der_encoder.encode(credentials)
class CSSP:
async def connect(reader, writer, authentication_protocol: sspi.IAuthenticationProtocol):
"""
@summary: Handle CSSP connection
Proxy class for authentication
"""
def __init__(self, layer, authenticationProtocol):
"""
@param layer: {type.Layer.RawLayer}
@param authenticationProtocol: {sspi.IAuthenticationProtocol}
"""
self._layer = layer
self._authenticationProtocol = authenticationProtocol
#IGenericSecurityService
self._interface = None
#function call at the end of nego
self._callback = None
def setFactory(self, factory):
"""
@summary: Call by RawLayer Factory
@param param: RawLayerClientFactory or RawLayerFactory
"""
self._layer.setFactory(factory)
def dataReceived(self, data):
"""
@summary: Inherit from twisted.protocol class
main event of received data
@param data: string data receive from twisted
"""
self._layer.dataReceived(data)
def connectionLost(self, reason):
"""
@summary: Call from twisted engine when protocol is closed
@param reason: str represent reason of close connection
"""
self._layer._factory.connectionLost(self, reason)
def connectionMade(self):
"""
@summary: install proxy
"""
self._layer.transport = self
self._layer.getDescriptor = lambda:self.transport
self._layer.connectionMade()
def write(self, data):
"""
@summary: write data on transport layer
@param data: {str}
"""
self.transport.write(data)
def startTLS(self, sslContext):
"""
@summary: start TLS protocol
@param sslContext: {ssl.ClientContextFactory | ssl.DefaultOpenSSLContextFactory} context use for TLS protocol
"""
self.transport.startTLS(sslContext)
def startNLA(self, sslContext, callback = None):
"""
@summary: start NLA authentication
@param sslContext: {ssl.ClientContextFactory | ssl.DefaultOpenSSLContextFactory} context use for TLS protocol
@param callback: {function} function call when cssp layer is read
"""
self._callback = callback
self.startTLS(sslContext)
#send negotiate message
self.transport.write(encodeDERTRequest( negoTypes = [ self._authenticationProtocol.getNegotiateMessage() ] ))
#next state is receive a challenge
self.dataReceived = self.recvChallenge
def recvChallenge(self, data):
"""
@summary: second state in cssp automata
@param data : {str} all data available on buffer
"""
request = decodeDERTRequest(data)
message, self._interface = self._authenticationProtocol.getAuthenticateMessage(getNegoTokens(request)[0])
#get back public key
#convert from der to ber...
pubKeyDer = crypto.dump_privatekey(crypto.FILETYPE_ASN1, self.transport.protocol._tlsConnection.get_peer_certificate().get_pubkey())
pubKey = der_decoder.decode(pubKeyDer, asn1Spec=OpenSSLRSAPublicKey())[0]
rsa = x509.RSAPublicKey()
rsa.setComponentByName("modulus", univ.Integer(pubKey.getComponentByName('modulus')._value))
rsa.setComponentByName("publicExponent", univ.Integer(pubKey.getComponentByName('publicExponent')._value))
self._pubKeyBer = ber_encoder.encode(rsa)
#send authenticate message with public key encoded
self.transport.write(encodeDERTRequest( negoTypes = [ message ], pubKeyAuth = self._interface.GSS_WrapEx(self._pubKeyBer)))
#next step is received public key incremented by one
self.dataReceived = self.recvPubKeyInc
def recvPubKeyInc(self, data):
"""
@summary: the server send the pubKeyBer + 1
@param data : {str} all data available on buffer
"""
request = decodeDERTRequest(data)
pubKeyInc = self._interface.GSS_UnWrapEx(getPubKeyAuth(request))
#check pubKeyInc = self._pubKeyBer + 1
if not (self._pubKeyBer[1:] == pubKeyInc[1:] and ord(self._pubKeyBer[0]) + 1 == ord(pubKeyInc[0])):
raise error.InvalidExpectedDataException("CSSP : Invalid public key increment")
domain, user, password = self._authenticationProtocol.getEncodedCredentials()
#send credentials
self.transport.write(encodeDERTRequest( authInfo = self._interface.GSS_WrapEx(encodeDERTCredentials(domain, user, password))))
#reset state back to normal state
self.dataReceived = lambda x: self.__class__.dataReceived(self, x)
if not self._callback is None:
self._callback()
# send negotiate message
writer.write(encode_der_trequest(nego_types=[authentication_protocol.getNegotiateMessage()]))
await writer.drain()
print("toto")
trequest = decode_der_trequest(await reader.read(1500))
print("yahoo")
message, interface = authentication_protocol.getAuthenticateMessage(getNegoTokens(trequest)[0])
def recvChallenge(self, data):
"""
@summary: second state in cssp automata
@param data : {str} all data available on buffer
"""
request = decode_der_trequest(data)
message, self._interface = self._authenticationProtocol.getAuthenticateMessage(getNegoTokens(request)[0])
#get back public key
#convert from der to ber...
pubKeyDer = crypto.dump_privatekey(crypto.FILETYPE_ASN1, self.transport.protocol._tlsConnection.get_peer_certificate().get_pubkey())
pubKey = der_decoder.decode(pubKeyDer, asn1Spec=OpenSSLRSAPublicKey())[0]
rsa = x509.RSAPublicKey()
rsa.setComponentByName("modulus", univ.Integer(pubKey.getComponentByName('modulus')._value))
rsa.setComponentByName("publicExponent", univ.Integer(pubKey.getComponentByName('publicExponent')._value))
self._pubKeyBer = ber_encoder.encode(rsa)
#send authenticate message with public key encoded
self.transport.write(encode_der_trequest(nego_types= [message], pub_key_auth= self._interface.GSS_WrapEx(self._pubKeyBer)))
#next step is received public key incremented by one
self.dataReceived = self.recvPubKeyInc
def recvPubKeyInc(self, data):
"""
@summary: the server send the pubKeyBer + 1
@param data : {str} all data available on buffer
"""
request = decode_der_trequest(data)
pubKeyInc = self._interface.GSS_UnWrapEx(getPubKeyAuth(request))
#check pubKeyInc = self._pubKeyBer + 1
if not (self._pubKeyBer[1:] == pubKeyInc[1:] and ord(self._pubKeyBer[0]) + 1 == ord(pubKeyInc[0])):
raise error.InvalidExpectedDataException("CSSP : Invalid public key increment")
domain, user, password = self._authenticationProtocol.getEncodedCredentials()
#send credentials
self.transport.write(encode_der_trequest(
auth_info= self._interface.GSS_WrapEx(encodeDERTCredentials(domain, user, password))))

View File

@@ -203,7 +203,7 @@ class ChallengeMessage(CompositeType):
s = Stream(self.getTargetInfo())
while(True):
avPair = AvPair()
s.readType(avPair)
s.read_type(avPair)
if avPair.AvId.value == AvId.MsvAvEOL:
return result
result[avPair.AvId.value] = avPair.Value.value
@@ -469,7 +469,7 @@ def MAC(handle, SigningKey, SeqNum, Message):
#write the SeqNum
s = Stream()
s.writeType(signature.SeqNum)
s.write_type(signature.SeqNum)
signature.Checksum.value = rc4.crypt(handle, HMAC_MD5(SigningKey, s.getvalue() + Message)[:8])
@@ -485,7 +485,7 @@ def MIC(ExportedSessionKey, negotiateMessage, challengeMessage, authenticateMess
@see: https://msdn.microsoft.com/en-us/library/cc236676.aspx
"""
s = Stream()
s.writeType((negotiateMessage, challengeMessage, authenticateMessage))
s.write_type((negotiateMessage, challengeMessage, authenticateMessage))
return HMAC_MD5(ExportedSessionKey, s.getvalue())
class NTLMv2(sspi.IAuthenticationProtocol):
@@ -530,7 +530,7 @@ class NTLMv2(sspi.IAuthenticationProtocol):
@see: https://msdn.microsoft.com/en-us/library/cc236676.aspx
"""
self._challengeMessage = ChallengeMessage()
s.readType(self._challengeMessage)
s.read_type(self._challengeMessage)
ServerChallenge = self._challengeMessage.ServerChallenge.value
ClientChallenge = random(64)
@@ -608,7 +608,7 @@ class NTLMv2SecurityInterface(sspi.IGenericSecurityService):
signature = MAC(self._encryptHandle, self._signingKey, self._seqNum, data)
self._seqNum += 1
s = Stream()
s.writeType(signature)
s.write_type(signature)
return s.getvalue() + encryptedData
def GSS_UnWrapEx(self, data):
@@ -619,7 +619,7 @@ class NTLMv2SecurityInterface(sspi.IGenericSecurityService):
signature = MessageSignatureEx()
message = String()
s = Stream(data)
s.readType((signature, message))
s.read_type((signature, message))
#decrypt message
plaintextMessage = rc4.crypt(self._decryptHandle, message.value)
@@ -627,7 +627,7 @@ class NTLMv2SecurityInterface(sspi.IGenericSecurityService):
#recompute checksum
t = Stream()
t.writeType(signature.SeqNum)
t.write_type(signature.SeqNum)
verify = HMAC_MD5(self._verifyKey, t.getvalue() + plaintextMessage)[:8]
if verify != checksum:
raise error.InvalidExpectedDataException("NTLMv2SecurityInterface : Invalid checksum")

View File

@@ -176,7 +176,7 @@ class Client(PDULayer):
@param s: Stream
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DEMANDACTIVEPDU:
#not a blocking error because in deactive reactive sequence
@@ -204,7 +204,7 @@ class Client(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_SYNCHRONIZE:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -220,7 +220,7 @@ class Client(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_COOPERATE:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -236,7 +236,7 @@ class Client(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_GRANTED_CONTROL:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -252,7 +252,7 @@ class Client(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_FONTMAP:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -269,7 +269,7 @@ class Client(PDULayer):
@param s: Stream from transport layer
"""
pdus = ArrayType(data.PDU)
s.readType(pdus)
s.read_type(pdus)
for pdu in pdus:
if pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DATAPDU:
self.readDataPDU(pdu.pduMessage)
@@ -287,7 +287,7 @@ class Client(PDULayer):
@param secFlag: {SecFlags}
"""
updates = ArrayType(data.FastPathUpdatePDU)
fastPathS.readType(updates)
fastPathS.read_type(updates)
for update in updates:
if update.updateHeader.value == data.FastPathUpdateType.FASTPATH_UPDATETYPE_BITMAP:
self._listener.onUpdate(update.updateData.rectangles._array)
@@ -419,7 +419,7 @@ class Server(PDULayer):
@param s: Stream
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_CONFIRMACTIVEPDU:
#not a blocking error because in deactive reactive sequence
@@ -445,7 +445,7 @@ class Server(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_SYNCHRONIZE:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -460,7 +460,7 @@ class Server(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_COOPERATE:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -475,7 +475,7 @@ class Server(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_CONTROL or pdu.pduMessage.pduData.action.value != data.Action.CTRLACTION_REQUEST_CONTROL:
#not a blocking error because in deactive reactive sequence
#input can be send too but ignored
@@ -491,7 +491,7 @@ class Server(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value != data.PDUType.PDUTYPE_DATAPDU or pdu.pduMessage.shareDataHeader.pduType2.value != data.PDUType2.PDUTYPE2_FONTLIST:
#not a blocking error because in deactive reactive sequence
#input can be send but ignored
@@ -510,7 +510,7 @@ class Server(PDULayer):
@param s: Stream from transport layer
"""
pdu = data.PDU()
s.readType(pdu)
s.read_type(pdu)
if pdu.shareControlHeader.pduType.value == data.PDUType.PDUTYPE_DATAPDU:
self.readDataPDU(pdu.pduMessage)

View File

@@ -167,7 +167,7 @@ def macData(macSaltKey, data):
#encode length
dataLength = Stream()
dataLength.writeType(UInt32Le(len(data)))
dataLength.write_type(UInt32Le(len(data)))
sha1Digest.update(macSaltKey)
sha1Digest.update("\x36" * 40)
@@ -195,10 +195,10 @@ def macSaltedData(macSaltKey, data, encryptionCount):
#encode length
dataLengthS = Stream()
dataLengthS.writeType(UInt32Le(len(data)))
dataLengthS.write_type(UInt32Le(len(data)))
encryptionCountS = Stream()
encryptionCountS.writeType(UInt32Le(encryptionCount))
encryptionCountS.write_type(UInt32Le(encryptionCount))
sha1Digest.update(macSaltKey)
sha1Digest.update("\x36" * 40)
@@ -412,7 +412,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
signature = String(readLen = CallableValue(8))
encryptedPayload = String()
s.readType((signature, encryptedPayload))
s.read_type((signature, encryptedPayload))
decrypted = rc4.crypt(self._decryptRc4, encryptedPayload.value)
#ckeck signature
@@ -444,7 +444,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
self._nbEncryptedPacket += 1
s = Stream()
s.writeType(data)
s.write_type(data)
if saltedMacGeneration:
return (String(macSaltedData(self._macKey, s.getvalue(), self._nbEncryptedPacket - 1)[:8]), String(rc4.crypt(self._encryptRc4, s.getvalue())))
@@ -463,7 +463,7 @@ class SecLayer(LayerAutomata, IStreamSender, tpkt.IFastPathListener, tpkt.IFastP
securityFlag = UInt16Le()
securityFlagHi = UInt16Le()
data.readType((securityFlag, securityFlagHi))
data.read_type((securityFlag, securityFlagHi))
if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
data = self.readEncryptedPayload(data, securityFlag.value & SecurityFlag.SEC_SECURE_CHECKSUM)
@@ -631,7 +631,7 @@ class Client(SecLayer):
#packet preambule
securityFlag = UInt16Le()
securityFlagHi = UInt16Le()
s.readType((securityFlag, securityFlagHi))
s.read_type((securityFlag, securityFlagHi))
if not (securityFlag.value & SecurityFlag.SEC_LICENSE_PKT):
raise InvalidExpectedDataException("waiting license packet")
@@ -680,13 +680,13 @@ class Server(SecLayer):
#packet preambule
securityFlag = UInt16Le()
securityFlagHi = UInt16Le()
s.readType((securityFlag, securityFlagHi))
s.read_type((securityFlag, securityFlagHi))
if not (securityFlag.value & SecurityFlag.SEC_EXCHANGE_PKT):
raise InvalidExpectedDataException("waiting client random")
message = ClientSecurityExchangePDU()
s.readType(message)
s.read_type(message)
clientRandom = rsa.decrypt(message.encryptedClientRandom.value[::-1], self._rsaPrivateKey)[::-1]
self._macKey, self._initialEncryptKey, self._initialDecrytKey = generateKeys( clientRandom,
@@ -711,7 +711,7 @@ class Server(SecLayer):
"""
securityFlag = UInt16Le()
securityFlagHi = UInt16Le()
s.readType((securityFlag, securityFlagHi))
s.read_type((securityFlag, securityFlagHi))
if not (securityFlag.value & SecurityFlag.SEC_INFO_PKT):
raise InvalidExpectedDataException("Waiting info packet")
@@ -719,7 +719,7 @@ class Server(SecLayer):
if securityFlag.value & SecurityFlag.SEC_ENCRYPT:
s = self.readEncryptedPayload(s, securityFlag.value & SecurityFlag.SEC_SECURE_CHECKSUM)
s.readType(self._info)
s.read_type(self._info)
#next state send error license
self.sendLicensingErrorMessage()
#reinit state

View File

@@ -69,7 +69,7 @@ def readLength(s):
"""
size = None
length = UInt8()
s.readType(length)
s.read_type(length)
byte = length.value
if byte & 0x80:
byte &= ~0x80
@@ -79,7 +79,7 @@ def readLength(s):
size = UInt16Be()
else:
raise InvalidExpectedDataException("BER length may be 1 or 2")
s.readType(size)
s.read_type(size)
else:
size = length
return size.value
@@ -103,7 +103,7 @@ def readUniversalTag(s, tag, pc):
@return: true if tag is correctly read
"""
byte = UInt8()
s.readType(byte)
s.read_type(byte)
return byte.value == ((Class.BER_CLASS_UNIV | berPC(pc)) | (Tag.BER_TAG_MASK & tag))
def writeUniversalTag(tag, pc):
@@ -123,11 +123,11 @@ def readApplicationTag(s, tag):
@return: length of application packet
"""
byte = UInt8()
s.readType(byte)
s.read_type(byte)
if tag.value > 30:
if byte.value != ((Class.BER_CLASS_APPL | BerPc.BER_CONSTRUCT) | Tag.BER_TAG_MASK):
raise InvalidExpectedDataException()
s.readType(byte)
s.read_type(byte)
if byte.value != tag.value:
raise InvalidExpectedDataException("bad tag")
else:
@@ -159,7 +159,7 @@ def readBoolean(s):
if size != 1:
raise InvalidExpectedDataException("bad boolean size")
b = UInt8()
s.readType(b)
s.read_type(b)
return bool(b.value)
def writeBoolean(b):
@@ -186,21 +186,21 @@ def readInteger(s):
if size == 1:
integer = UInt8()
s.readType(integer)
s.read_type(integer)
return integer.value
elif size == 2:
integer = UInt16Be()
s.readType(integer)
s.read_type(integer)
return integer.value
elif size == 3:
integer1 = UInt8()
integer2 = UInt16Be()
s.readType(integer1)
s.readType(integer2)
s.read_type(integer1)
s.read_type(integer2)
return integer2.value + (integer1.value << 16)
elif size == 4:
integer = UInt32Be()
s.readType(integer)
s.read_type(integer)
return integer.value
else:
raise InvalidExpectedDataException("Wrong integer size")
@@ -248,7 +248,7 @@ def readEnumerated(s):
if readLength(s) != 1:
raise InvalidSize("enumerate size is wrong")
enumer = UInt8()
s.readType(enumer)
s.read_type(enumer)
return enumer.value
def writeEnumerated(enumerated):

View File

@@ -371,12 +371,12 @@ class ProprietaryServerCertificate(CompositeType):
@summary: compute hash
"""
s = Stream()
s.writeType(UInt32Le(self.__class__._TYPE_))
s.writeType(self.dwSigAlgId)
s.writeType(self.dwKeyAlgId)
s.writeType(self.wPublicKeyBlobType)
s.writeType(self.wPublicKeyBlobLen)
s.writeType(self.PublicKeyBlob)
s.write_type(UInt32Le(self.__class__._TYPE_))
s.write_type(self.dwSigAlgId)
s.write_type(self.dwKeyAlgId)
s.write_type(self.wPublicKeyBlobType)
s.write_type(self.wPublicKeyBlobLen)
s.write_type(self.PublicKeyBlob)
md5Digest = md5.new()
md5Digest.update(s.getvalue())
@@ -555,7 +555,7 @@ def readConferenceCreateRequest(s):
per.readOctetStream(s, h221_cs_key, 4)
length = per.readLength(s)
clientSettings = Settings(readLen = CallableValue(length))
s.readType(clientSettings)
s.read_type(clientSettings)
return clientSettings
def readConferenceCreateResponse(s):
@@ -579,7 +579,7 @@ def readConferenceCreateResponse(s):
length = per.readLength(s)
serverSettings = Settings(readLen = CallableValue(length))
s.readType(serverSettings)
s.read_type(serverSettings)
return serverSettings
def writeConferenceCreateRequest(userData):
@@ -589,7 +589,7 @@ def writeConferenceCreateRequest(userData):
@return: GCC packet
"""
userDataStream = Stream()
userDataStream.writeType(userData)
userDataStream.write_type(userData)
return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
per.writeLength(len(userDataStream.getvalue()) + 14), per.writeChoice(0),
@@ -604,7 +604,7 @@ def writeConferenceCreateResponse(serverData):
@return: gcc packet
"""
serverDataStream = Stream()
serverDataStream.writeType(serverData)
serverDataStream.write_type(serverData)
return (per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
per.writeLength(len(serverDataStream.getvalue()) + 14), per.writeChoice(0x14),

View File

@@ -216,7 +216,7 @@ class MCSLayer(LayerAutomata):
@param data: {Stream}
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if self.readMCSPDUHeader(opcode.value, DomainMCSPDU.DISCONNECT_PROVIDER_ULTIMATUM):
log.info("MCS DISCONNECT_PROVIDER_ULTIMATUM")
@@ -367,7 +367,7 @@ class Client(MCSLayer):
if not ber.readUniversalTag(data, ber.Tag.BER_TAG_OCTET_STRING, False):
raise InvalidExpectedDataException("invalid expected BER tag")
gccRequestLength = ber.readLength(data)
if data.dataLen() != gccRequestLength:
if data.data_len() != gccRequestLength:
raise InvalidSize("bad size of GCC request")
self._serverSettings = gcc.readConferenceCreateResponse(data)
@@ -385,7 +385,7 @@ class Client(MCSLayer):
@param data: {Stream}
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.ATTACH_USER_CONFIRM):
raise InvalidExpectedDataException("Invalid MCS PDU : ATTACH_USER_CONFIRM expected")
@@ -404,7 +404,7 @@ class Client(MCSLayer):
@param data: {Stream}
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.CHANNEL_JOIN_CONFIRM):
raise InvalidExpectedDataException("Invalid MCS PDU : CHANNEL_JOIN_CONFIRM expected")
@@ -435,7 +435,7 @@ class Client(MCSLayer):
"""
ccReq = gcc.writeConferenceCreateRequest(self._clientSettings)
ccReqStream = Stream()
ccReqStream.writeType(ccReq)
ccReqStream.write_type(ccReq)
tmp = (ber.writeOctetstring("\x01"), ber.writeOctetstring("\x01"), ber.writeBoolean(True),
self.writeDomainParams(34, 2, 0, 0xffff),
@@ -536,7 +536,7 @@ class Server(MCSLayer):
@param data: {Stream}
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.ERECT_DOMAIN_REQUEST):
raise InvalidExpectedDataException("Invalid MCS PDU : ERECT_DOMAIN_REQUEST expected")
@@ -554,7 +554,7 @@ class Server(MCSLayer):
@param data: {Stream}
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.ATTACH_USER_REQUEST):
raise InvalidExpectedDataException("Invalid MCS PDU : ATTACH_USER_REQUEST expected")
@@ -570,7 +570,7 @@ class Server(MCSLayer):
"""
opcode = UInt8()
data.readType(opcode)
data.read_type(opcode)
if not self.readMCSPDUHeader(opcode.value, DomainMCSPDU.CHANNEL_JOIN_REQUEST):
raise InvalidExpectedDataException("Invalid MCS PDU : CHANNEL_JOIN_REQUEST expected")
@@ -593,7 +593,7 @@ class Server(MCSLayer):
"""
ccReq = gcc.writeConferenceCreateResponse(self._serverSettings)
ccReqStream = Stream()
ccReqStream.writeType(ccReq)
ccReqStream.write_type(ccReq)
tmp = (ber.writeEnumerated(0), ber.writeInteger(0), self.writeDomainParams(22, 3, 0, 0xfff8),
ber.writeOctetstring(ccReqStream.getvalue()))

View File

@@ -31,12 +31,12 @@ def readLength(s):
@return: int python
"""
byte = UInt8()
s.readType(byte)
s.read_type(byte)
size = 0
if byte.value & 0x80:
byte.value &= ~0x80
size = byte.value << 8
s.readType(byte)
s.read_type(byte)
size += byte.value
else:
size = byte.value
@@ -60,7 +60,7 @@ def readChoice(s):
@return: int that represent choice
"""
choice = UInt8()
s.readType(choice)
s.read_type(choice)
return choice.value
def writeChoice(choice):
@@ -78,7 +78,7 @@ def readSelection(s):
@return: int that represent selection
"""
choice = UInt8()
s.readType(choice)
s.read_type(choice)
return choice.value
def writeSelection(selection):
@@ -96,7 +96,7 @@ def readNumberOfSet(s):
@return: int that represent numberOfSet
"""
choice = UInt8()
s.readType(choice)
s.read_type(choice)
return choice.value
def writeNumberOfSet(numberOfSet):
@@ -114,7 +114,7 @@ def readEnumerates(s):
@return: int that represent enumerate
"""
choice = UInt8()
s.readType(choice)
s.read_type(choice)
return choice.value
def writeEnumerates(enumer):
@@ -142,7 +142,7 @@ def readInteger(s):
result = UInt32Be()
else:
raise InvalidValue("invalid integer size %d"%size)
s.readType(result)
s.read_type(result)
return result.value
def writeInteger(value):
@@ -166,7 +166,7 @@ def readInteger16(s, minimum = 0):
@return: int or long python value
"""
result = UInt16Be()
s.readType(result)
s.read_type(result)
return result.value + minimum
def writeInteger16(value, minimum = 0):
@@ -190,16 +190,16 @@ def readObjectIdentifier(s, oid):
raise InvalidValue("size of stream oid is wrong %d != 5"%size)
a_oid = [0, 0, 0, 0, 0, 0]
t12 = UInt8()
s.readType(t12)
s.read_type(t12)
a_oid[0] = t12.value >> 4
a_oid[1] = t12.value & 0x0f
s.readType(t12)
s.read_type(t12)
a_oid[2] = t12.value
s.readType(t12)
s.read_type(t12)
a_oid[3] = t12.value
s.readType(t12)
s.read_type(t12)
a_oid[4] = t12.value
s.readType(t12)
s.read_type(t12)
a_oid[5] = t12.value
if list(oid) != a_oid:
@@ -279,7 +279,7 @@ def readOctetStream(s, octetStream, minValue = 0):
raise InvalidValue("incompatible size %d != %d"(len(octetStream), size))
for i in range(0, size):
c = UInt8()
s.readType(c)
s.read_type(c)
if ord(octetStream[i]) != c.value:
return False

View File

@@ -22,8 +22,12 @@ Transport packet layer implementation
Use to build correct size packet and handle slow path and fast path mode
"""
import asyncio
import ssl
from rdpy.core.nla import cssp, ntlm
from rdpy.model.layer import RawLayer
from rdpy.model.type import UInt8, UInt16Be, sizeof
from rdpy.model.type import UInt8, UInt16Be, sizeof, Stream
from rdpy.model.error import CallPureVirtualFuntion
@@ -34,104 +38,27 @@ 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, secFlag, fastPathS):
"""
@summary: Call when fast path packet is received
@param secFlag: {SecFlags}
@param fastPathS: {Stream}
"""
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):
"""
@param fastPathSender : {IFastPathSender}
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "setFastPathSender", "IFastPathListener"))
class IFastPathSender(object):
"""
@summary: Fast path send capability
"""
def sendFastPath(self, secFlag, fastPathS):
"""
@summary: Send fastPathS Type as fast path packet
@param secFlag: {integer} Security flag for fastpath packet
@param fastPathS: {Type | Tuple} 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):
class Tpkt:
"""
@summary: TPKT layer in RDP protocol stack
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):
"""
@param presentation: {Layer} presentation layer, in RDP case is x224 layer
"""
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
def connect(self):
"""
@summary: Call when transport layer connection
is made (inherit from RawLayer)
"""
#header is on two bytes
self.expect(2, self.readHeader)
#no connection automata on this layer
if not self._presentation is None:
self._presentation.connect()
def __init__(self, reader, writer):
self.reader = reader
self.writer = writer
def readHeader(self, data):
"""
@summary: Read header of TPKT packet
@@ -139,17 +66,17 @@ class TPKT(RawLayer, IFastPathSender):
"""
#first read packet version
version = UInt8()
data.readType(version)
data.read_type(version)
#classic packet
if version.value == Action.FASTPATH_ACTION_X224:
#padding
data.readType(UInt8())
data.read_type(UInt8())
#read end header
self.expect(2, self.readExtendedHeader)
else:
#is fast path packet
self._secFlag = ((version.value >> 6) & 0x3)
data.readType(self._lastShortLength)
data.read_type(self._lastShortLength)
if self._lastShortLength.value & 0x80:
#size is 1 byte more
self.expect(1, self.readExtendedFastPathHeader)
@@ -164,7 +91,7 @@ class TPKT(RawLayer, IFastPathSender):
"""
#next state is read data
size = UInt16Be()
data.readType(size)
data.read_type(size)
self.expect(size.value - 4, self.readData)
def readExtendedFastPathHeader(self, data):
@@ -173,7 +100,7 @@ class TPKT(RawLayer, IFastPathSender):
@param data: {Stream} from twisted layer
"""
leftPart = UInt8()
data.readType(leftPart)
data.read_type(leftPart)
self._lastShortLength.value &= ~0x80
packetSize = (self._lastShortLength.value << 8) + leftPart.value
#next state is fast patn data
@@ -196,13 +123,32 @@ class TPKT(RawLayer, IFastPathSender):
self._presentation.recv(data)
self.expect(2, self.readHeader)
def send(self, message):
async def write(self, message):
"""
@summary: Send encompassed data
@param message: {network.Type} message to send
"""
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
s = Stream()
s.write_type((UInt8(Action.FASTPATH_ACTION_X224), UInt8(0), UInt16Be(sizeof(message) + 4), message))
self.writer.write(s.getvalue())
await self.writer.drain()
async def read(self):
"""
Read an entire payload from the reader stream
"""
header = Stream(await self.reader.readexactly(2))
action = UInt8()
header.read_type(action)
if action.value == Action.FASTPATH_ACTION_X224:
# read padding
header.read_type(UInt8())
size = UInt16Be()
Stream(await self.reader.readexactly(2)).read_type(size)
return Stream(await self.reader.readexactly(size.value - 4))
def sendFastPath(self, secFlag, fastPathS):
"""
@param fastPathS: {Type | Tuple} type transform to stream and send as fastpath
@@ -210,16 +156,20 @@ class TPKT(RawLayer, IFastPathSender):
"""
RawLayer.send(self, (UInt8(Action.FASTPATH_ACTION_FASTPATH | ((secFlag & 0x3) << 6)), UInt16Be((sizeof(fastPathS) + 3) | 0x8000), fastPathS))
def startTLS(self, sslContext):
async def start_tls(self):
"""
@summary: start TLS protocol
@param sslContext: {ssl.ClientContextFactory | ssl.DefaultOpenSSLContextFactory} context use for TLS protocol
Start TLS protocol
"""
self.transport.startTLS(sslContext)
ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.VerifyMode.CERT_NONE
reader, writer = await asyncio.open_connection(sock=self.writer.transport._sock, ssl=ssl_ctx, server_hostname="")
return Tpkt(reader, writer)
def startNLA(self, sslContext, callback):
async def start_nla(self):
"""
@summary: use to start NLA (NTLM over SSL) protocol
must be called after startTLS function
use to start NLA (NTLM over SSL) protocol
must be called after startTLS function
"""
self.transport.startNLA(sslContext, callback)
tpkt = await self.start_tls()
await cssp.connect(tpkt.reader, tpkt.writer, ntlm.NTLMv2("", "sylvain", "sylvain"))

View File

@@ -23,6 +23,7 @@ Implement transport PDU layer
This layer have main goal to negociate SSL transport
RDP basic security is supported only on client side
"""
from rdpy.core import tpkt
from rdpy.model import log
from rdpy.model.layer import LayerAutomata, IStreamSender
@@ -67,7 +68,8 @@ class NegotiationFailureCode(object):
INCONSISTENT_FLAGS = 0x00000004
HYBRID_REQUIRED_BY_SERVER = 0x00000005
SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 0x00000006
class ClientConnectionRequestPDU(CompositeType):
"""
@summary: Connection request
@@ -83,6 +85,7 @@ class ClientConnectionRequestPDU(CompositeType):
#read if there is enough data
self.protocolNeg = Negotiation(optional = True)
class ServerConnectionConfirm(CompositeType):
"""
@summary: Server response
@@ -95,7 +98,8 @@ class ServerConnectionConfirm(CompositeType):
self.padding = (UInt16Be(), UInt16Be(), UInt8())
#read if there is enough data
self.protocolNeg = Negotiation(optional = True)
class X224DataHeader(CompositeType):
"""
@summary: Header send when x224 exchange application data
@@ -105,7 +109,8 @@ class X224DataHeader(CompositeType):
self.header = UInt8(2)
self.messageType = UInt8(MessageType.X224_TPDU_DATA, constant = True)
self.separator = UInt8(0x80, constant = True)
class Negotiation(CompositeType):
"""
@summary: Negociate request message
@@ -122,117 +127,90 @@ class Negotiation(CompositeType):
self.selectedProtocol = UInt32Le(conditional = lambda: (self.code.value != NegociationType.TYPE_RDP_NEG_FAILURE))
self.failureCode = UInt32Le(conditional = lambda: (self.code.value == NegociationType.TYPE_RDP_NEG_FAILURE))
class X224Layer(LayerAutomata, IStreamSender):
class X224:
"""
@summary: x224 layer management
there is an connection automata
"""
def __init__(self, presentation):
def __init__(self, tpkt: tpkt.Tpkt):
"""
@param presentation: upper layer, MCS layer in RDP case
@param tpkt: TPKT layer
"""
LayerAutomata.__init__(self, presentation)
#client requested selectedProtocol
self._requestedProtocol = Protocols.PROTOCOL_SSL | Protocols.PROTOCOL_HYBRID
#server selected selectedProtocol
self._selectedProtocol = Protocols.PROTOCOL_SSL
self.tpkt = tpkt
def recvData(self, data):
async def read(self):
"""
@summary: Read data header from packet
And pass to presentation layer
@param data: Stream
"""
header = X224DataHeader()
data.readType(header)
self._presentation.recv(data)
payload = await self.tpkt.read()
payload.read_type(header)
return payload
def send(self, message):
async def write(self, message):
"""
@summary: Write message packet for TPDU layer
Add TPDU header
@param message: network.Type message
@summary: Write message packet for TPDU layer
Add TPDU header
@param message:
"""
self._transport.send((X224DataHeader(), message))
class Client(X224Layer):
"""
@summary: Client automata of TPDU layer
"""
def __init__(self, presentation):
"""
@param presentation: upper layer, MCS layer in RDP case
"""
X224Layer.__init__(self, presentation)
def connect(self):
"""
@summary: Connection request for client send a connection request packet
"""
self.sendConnectionRequest()
def sendConnectionRequest(self):
"""
@summary: Write connection request message
Next state is recvConnectionConfirm
@see: http://msdn.microsoft.com/en-us/library/cc240500.aspx
"""
message = ClientConnectionRequestPDU()
message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_REQ
message.protocolNeg.selectedProtocol.value = self._requestedProtocol
self._transport.send(message)
self.setNextState(self.recvConnectionConfirm)
def recvConnectionConfirm(self, data):
"""
@summary: Receive connection confirm message
Next state is recvData
Call connect on presentation layer if all is good
@param data: Stream that contain connection confirm
@see: response -> http://msdn.microsoft.com/en-us/library/cc240506.aspx
@see: failure ->http://msdn.microsoft.com/en-us/library/cc240507.aspx
"""
message = ServerConnectionConfirm()
data.readType(message)
if message.protocolNeg.failureCode._is_readed:
raise RDPSecurityNegoFail("negotiation failure code %x"%message.protocolNeg.failureCode.value)
#check presence of negotiation response
if message.protocolNeg._is_readed:
self._selectedProtocol = message.protocolNeg.selectedProtocol.value
else:
self._selectedProtocol = Protocols.PROTOCOL_RDP
#NLA protocol doesn't support in actual version of RDPY
if self._selectedProtocol in [ Protocols.PROTOCOL_HYBRID_EX ]:
raise InvalidExpectedDataException("RDPY doesn't support PROTOCOL_HYBRID_EX security Layer")
#now i'm ready to receive data
self.setNextState(self.recvData)
if self._selectedProtocol == Protocols.PROTOCOL_RDP:
log.warning("*" * 43)
log.warning("*" + " " * 10 + "RDP Security selected" + " " * 10 + "*")
log.warning("*" * 43)
#connection is done send to presentation
self._presentation.connect()
elif self._selectedProtocol == Protocols.PROTOCOL_SSL:
log.info("*" * 43)
log.info("*" + " " * 10 + "SSL Security selected" + " " * 10 + "*")
log.info("*" * 43)
self._transport.startTLS(ClientTLSContext())
#connection is done send to presentation
self._presentation.connect()
elif self._selectedProtocol == Protocols.PROTOCOL_HYBRID:
log.info("*" * 43)
log.info("*" + " " * 10 + "NLA Security selected" + " " * 10 + "*")
log.info("*" * 43)
self._transport.startNLA(ClientTLSContext(), lambda:self._presentation.connect())
await self.tpkt.write((X224DataHeader(), message))
class Server(X224Layer):
async def connect(tpkt: tpkt.Tpkt) -> X224:
"""
@summary: Write connection request message
Next state is recvConnectionConfirm
@see: http://msdn.microsoft.com/en-us/library/cc240500.aspx
"""
message = ClientConnectionRequestPDU()
message.protocolNeg.code.value = NegociationType.TYPE_RDP_NEG_REQ
message.protocolNeg.selectedProtocol.value = Protocols.PROTOCOL_HYBRID | Protocols.PROTOCOL_SSL
await tpkt.write(message)
selected_protocol = await read_connection_confirm(await tpkt.read())
if selected_protocol in [Protocols.PROTOCOL_HYBRID_EX]:
raise InvalidExpectedDataException("RDPY doesn't support PROTOCOL_HYBRID_EX security Layer")
if selected_protocol == Protocols.PROTOCOL_RDP:
log.warning("*" * 43)
log.warning("*" + " " * 10 + "RDP Security selected" + " " * 10 + "*")
log.warning("*" * 43)
return X224(tpkt)
elif selected_protocol == Protocols.PROTOCOL_SSL:
log.info("*" * 43)
log.info("*" + " " * 10 + "SSL Security selected" + " " * 10 + "*")
log.info("*" * 43)
return X224(await tpkt.start_tls())
elif selected_protocol == Protocols.PROTOCOL_HYBRID:
log.info("*" * 43)
log.info("*" + " " * 10 + "NLA Security selected" + " " * 10 + "*")
log.info("*" * 43)
return X224(await tpkt.start_nla())
async def read_connection_confirm(data) -> int:
"""
Read connection confirm and return the negotiated protocol
:ivar data: Stream that contain connection confirm
:see: response -> https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/b2975bdc-6d56-49ee-9c57-f2ff3a0b6817
:see: failure -> https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/1b3920e7-0116-4345-bc45-f2c4ad012761
"""
message = ServerConnectionConfirm()
data.read_type(message)
if message.protocolNeg.failureCode._is_readed:
raise RDPSecurityNegoFail("negotiation failure code %x"%message.protocolNeg.failureCode.value)
# check presence of negotiation response
if message.protocolNeg._is_readed:
return message.protocolNeg.selectedProtocol.value
else:
return Protocols.PROTOCOL_RDP
class Server(X224):
"""
@summary: Server automata of X224 layer
"""
@@ -263,7 +241,7 @@ class Server(X224Layer):
@see : http://msdn.microsoft.com/en-us/library/cc240470.aspx
"""
message = ClientConnectionRequestPDU()
data.readType(message)
data.read_type(message)
if not message.protocolNeg._is_readed:
self._requestedProtocol = Protocols.PROTOCOL_RDP

View File

@@ -256,5 +256,5 @@ class RawLayer(asyncio.Protocol, LayerAutomata, IStreamSender):
@param message: (tuple | Type)
"""
s = Stream()
s.writeType(message)
s.write_type(message)
self.transport.write(s.getvalue())

View File

@@ -177,7 +177,7 @@ class FileRecorder(object):
self._lastEventTimer = now
s = Stream()
s.writeType(e)
s.write_type(e)
self._file.write(s.getvalue())
@@ -276,10 +276,10 @@ class FileReader(object):
"""
@summary: read next event and return it
"""
if self._s.dataLen() == 0:
if self._s.data_len() == 0:
return None
e = Event()
self._s.readType(e)
self._s.read_type(e)
return e
def createRecorder(path):

View File

@@ -47,12 +47,13 @@ def sizeof(element):
return element.__sizeof__()
return 0
class Type(object):
class Type:
"""
@summary: Root type object inheritance
Record conditional optional of constant mechanism
"""
def __init__(self, conditional = lambda:True, optional = False, constant = False):
def __init__(self, conditional=lambda:True, optional=False, constant=False):
"""
@param conditional : Callable object
Read and Write operation depend on return of this function
@@ -63,11 +64,11 @@ class Type(object):
self._conditional = conditional
self._optional = optional
self._constant = constant
#use to record read state
#if type is optional and not present during read
#this boolean stay false
# use to record read state
# if type is optional and not present during read
# this boolean stay false
self._is_readed = False
#use to know if type was written
# use to know if type was written
self._is_writed = False
def write(self, s):
@@ -93,18 +94,18 @@ class Type(object):
if not self._is_readed:
return
#not constant mode direct reading
# not constant mode direct reading
if not self._constant:
self.__read__(s)
return
#constant mode
# constant mode
old = deepcopy(self)
self.__read__(s)
#check constant value
# check constant value
if old != self:
#rollback read value
s.pos -= sizeof(self)
# rollback read value
s.seek(-sizeof(self), 1)
raise InvalidExpectedDataException("%s const value expected %s != %s"%(self.__class__, old.value, self.value))
def __read__(self, s):
@@ -127,8 +128,9 @@ class Type(object):
@return: size in byte of type
"""
raise CallPureVirtualFuntion("%s:%s defined by interface %s"%(self.__class__, "__sizeof__", "Type"))
class CallableValue(object):
class CallableValue:
"""
@summary: Expression evaluate when is get or set
Ex: Type contain length of array and array
@@ -181,6 +183,7 @@ class CallableValue(object):
"""
self.__setValue__(value)
class SimpleType(Type, CallableValue):
"""
@summary: Non composite type
@@ -257,7 +260,7 @@ class SimpleType(Type, CallableValue):
@param s: Stream that will be read
@raise InvalidSize: if there is not enough data in stream
"""
if s.dataLen() < self._typeSize:
if s.data_len() < self._typeSize:
raise InvalidSize("Stream is too small to read expected SimpleType")
self.value = struct.unpack(self._structFormat, s.read(self._typeSize))[0]
@@ -267,7 +270,7 @@ class SimpleType(Type, CallableValue):
Because in Python all numbers are Int long or float
Cache result in self._mask field
"""
if not self.__dict__.has_key("_mask"):
if "_mask" not in self.__dict__.keys():
mask = 0xff
for _ in range(1, self._typeSize):
mask = mask << 8 | 0xff
@@ -292,7 +295,7 @@ class SimpleType(Type, CallableValue):
"""
return self._typeSize
def __cmp__(self, other):
def __eq__(self, other):
"""
@summary: Compare two simple type
Call inner value compare operator
@@ -302,7 +305,19 @@ class SimpleType(Type, CallableValue):
"""
if not isinstance(other, SimpleType):
other = self.__class__(other)
return self.value.__cmp__(other.value)
return self.value.__eq__(other.value)
def __ne__(self, other):
"""
@summary: Compare two simple type
Call inner value compare operator
@param other: SimpleType value or try to build same type as self
around value
@return: python value compare
"""
if not isinstance(other, SimpleType):
other = self.__class__(other)
return self.value.__ne__(other.value)
def __invert__(self):
"""
@@ -458,7 +473,7 @@ class CompositeType(Type):
readLen = 0
for name in self._typeName:
try:
s.readType(self.__dict__[name])
s.read_type(self.__dict__[name])
readLen += sizeof(self.__dict__[name])
#read is ok but read out of bound
if not self._readLen is None and readLen > self._readLen.value:
@@ -474,7 +489,7 @@ class CompositeType(Type):
for tmpName in self._typeName:
if tmpName == name:
break
s.pos -= sizeof(self.__dict__[tmpName])
s.seek(-sizeof(self.__dict__[tmpName]), 1)
raise e
if not self._readLen is None and readLen < self._readLen.value:
@@ -489,7 +504,7 @@ class CompositeType(Type):
"""
for name in self._typeName:
try:
s.writeType(self.__dict__[name])
s.write_type(self.__dict__[name])
except Exception as e:
log.error("Error during write %s::%s"%(self.__class__, name))
raise e
@@ -736,13 +751,14 @@ class UInt24Le(SimpleType):
@param s: Stream
"""
self.value = struct.unpack(self._structFormat, s.read(self._typeSize) + '\x00')[0]
class String(Type, CallableValue):
"""
@summary: String type
Leaf in Type tree
"""
def __init__(self, value = "", readLen = None, conditional = lambda:True, optional = False, constant = False, unicode = False, until = None):
def __init__(self, value=b"", readLen = None, encoding=None, conditional=lambda:True, optional=False, constant=False, until=None):
"""
@param value: python string use for inner value
@param readLen: length use to read in stream (SimpleType) if 0 read entire stream
@@ -754,20 +770,24 @@ class String(Type, CallableValue):
@param unicode: Encode and decode value as unicode
@param until: read until sequence is readed or write sequence at the end of string
"""
Type.__init__(self, conditional = conditional, optional = optional, constant = constant)
Type.__init__(self, conditional=conditional, optional=optional, constant=constant)
CallableValue.__init__(self, value)
#type use to know read length
self._readLen = readLen
self._unicode = unicode
self._encoding = encoding
self._until = until
def __cmp__(self, other):
def __eq__(self, other):
"""
@summary: call raw compare value
@param other: other String parameter
@return: if two inner value are equals
"""
return cmp(self.value, other.value)
return self.value.__eq__(other.value)
def __ne__(self, other):
"""
"""
return self.value.__ne__(other.value)
def __hash__(self):
"""
@@ -796,9 +816,9 @@ class String(Type, CallableValue):
toWrite += self._until
if self._unicode:
s.write(encodeUnicode(self.value))
s.write(bytes(self.value.encode("utf-16le"), "utf-16le"))
else:
s.write(self.value)
s.write(bytes(self.value, "ascii"))
def __read__(self, s):
"""
@@ -809,16 +829,16 @@ class String(Type, CallableValue):
"""
if self._readLen is None:
if self._until is None:
self.value = s.getvalue()[s.pos:]
self.value = s.getvalue()[s.tell():]
else:
self.value = ""
while self.value[-len(self._until):] != self._until and s.dataLen() != 0:
while self.value[-len(self._until):] != self._until and s.data_len() != 0:
self.value += s.read(1)
else:
self.value = s.read(self._readLen.value)
if self._unicode:
self.value = decodeUnicode(self.value)
self.value = self.value.decode("utf-16le")
def __sizeof__(self):
"""
@@ -858,33 +878,33 @@ class Stream(BytesIO):
"""
@summary: Stream use to read all types
"""
def dataLen(self):
def data_len(self) -> int:
"""
@return: not yet read length
:returns: not yet read length
"""
return self.len - self.pos
return len(self.getvalue()) - self.tell()
def readLen(self):
def read_len(self) -> int:
"""
@summary: compute already read size
@return: read size of stream
Compute already read size
:returns: read size of stream
"""
return self.pos
return self.seek()
def readType(self, value):
def read_type(self, value: Type):
"""
@summary: call specific read on type object
or iterate over tuple elements
rollback read if error occurred during read value
@param value: (tuple | Type) object
Call specific read on type object
or iterate over tuple elements
rollback read if error occurred during read value
:ivar tuple | Type object
"""
#read each tuple
# read each tuple
if isinstance(value, tuple) or isinstance(value, list):
for element in value:
try:
self.readType(element)
self.read_type(element)
except Exception as e:
#rollback already readed elements
# rollback already readed elements
for tmpElement in value:
if tmpElement == element:
break
@@ -892,8 +912,8 @@ class Stream(BytesIO):
raise e
return
#optional value not present
if self.dataLen() == 0 and value._optional:
# optional value not present
if self.data_len() == 0 and value._optional:
return
value.read(self)
@@ -903,22 +923,24 @@ class Stream(BytesIO):
@summary: read next type but didn't consume it
@param t: Type element
"""
self.readType(t)
self.read_type(t)
self.pos -= sizeof(t)
def writeType(self, value):
def write_type(self, value: Type):
"""
@summary: Call specific write on type object
or iterate over tuple element
@param value: (tuple | Type)
Call specific write on type object
or iterate over tuple element
:ivar Type: Type to write
"""
#write each element of tuple
# write each element of tuple
if isinstance(value, tuple) or isinstance(value, list):
for element in value:
self.writeType(element)
self.write_type(element)
return
value.write(self)
class ArrayType(Type):
"""
@summary: Factory af n element
@@ -952,7 +974,7 @@ class ArrayType(Type):
while self._readLen is None or i < self._readLen.value:
element = self._typeFactory()
element._optional = self._readLen is None
s.readType(element)
s.read_type(element)
if not element._is_readed:
break
self._array.append(element)
@@ -963,7 +985,7 @@ class ArrayType(Type):
@summary: Just write array
@param s: Stream
"""
s.writeType(self._array)
s.write_type(self._array)
def __getitem__(self, item):
"""
@@ -1005,7 +1027,7 @@ class FactoryType(Type):
@param s: Stream
"""
self._value = self._factory()
s.readType(self._value)
s.read_type(self._value)
def __write__(self, s):
"""
@@ -1013,7 +1035,7 @@ class FactoryType(Type):
@param s: Stream
"""
self._value = self._factory()
s.writeType(self._value)
s.write_type(self._value)
def __getattr__(self, name):
"""

View File

@@ -56,7 +56,7 @@ class LayerTest(unittest.TestCase):
"""
class TestAutomata(rdpy.core.layer.RawLayer):
def expectedCallBack(self, data):
if data.dataLen() == 4:
if data.data_len() == 4:
raise LayerTest.LayerCaseException()
t = TestAutomata()
@@ -69,7 +69,7 @@ class LayerTest(unittest.TestCase):
"""
class TestAutomata(rdpy.core.layer.RawLayer):
def expectedCallBack(self, data):
if data.dataLen() == 4:
if data.data_len() == 4:
raise LayerTest.LayerCaseException()
t = TestAutomata()

View File

@@ -56,7 +56,7 @@ class TypeTest(unittest.TestCase):
def __write__(self, s):
raise Exception()
s = rdpy.core.type.Stream()
self.assertRaises(Exception, s.writeType, TestType(conditional = lambda:True))
self.assertRaises(Exception, s.write_type, TestType(conditional = lambda:True))
@unittest.expectedFailure
def test_type_write_conditional_false(self):
@@ -67,7 +67,7 @@ class TypeTest(unittest.TestCase):
def __write__(self, s):
raise Exception()
s = rdpy.core.type.Stream()
self.assertRaises(Exception, s.writeType, TestType(conditional = lambda:False))
self.assertRaises(Exception, s.write_type, TestType(conditional = lambda:False))
def test_type_read_conditional_true(self):
"""
@@ -77,7 +77,7 @@ class TypeTest(unittest.TestCase):
def __read__(self, s):
raise Exception()
s = rdpy.core.type.Stream()
self.assertRaises(Exception, s.readType, TestType(conditional = lambda:True))
self.assertRaises(Exception, s.read_type, TestType(conditional = lambda:True))
@unittest.expectedFailure
def test_type_read_conditional_false(self):
@@ -88,7 +88,7 @@ class TypeTest(unittest.TestCase):
def __read__(self, s):
raise Exception()
s = rdpy.core.type.Stream()
self.assertRaises(Exception, s.readType, TestType(conditional = lambda:False))
self.assertRaises(Exception, s.read_type, TestType(conditional = lambda:False))
def test_sizeof_conditional_true(self):
@@ -138,7 +138,7 @@ class TypeTest(unittest.TestCase):
@summary: test write uint8 in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt8(1))
s.write_type(rdpy.core.type.UInt8(1))
self.assertEqual(''.join(s.buflist), '\x01', "invalid stream write")
def test_stream_write_uint16Le_type(self):
@@ -146,7 +146,7 @@ class TypeTest(unittest.TestCase):
@summary: test write UInt16Le in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt16Le(1))
s.write_type(rdpy.core.type.UInt16Le(1))
self.assertEqual(''.join(s.buflist), '\x01\x00', "invalid stream write")
def test_stream_write_uint16Be_type(self):
@@ -154,7 +154,7 @@ class TypeTest(unittest.TestCase):
@summary: test write UInt16Be in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt16Be(1))
s.write_type(rdpy.core.type.UInt16Be(1))
self.assertEqual(''.join(s.buflist), '\x00\x01', "invalid stream write")
def test_stream_write_uint24Le_type(self):
@@ -162,7 +162,7 @@ class TypeTest(unittest.TestCase):
@summary: test write UInt24Le in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt24Le(1))
s.write_type(rdpy.core.type.UInt24Le(1))
self.assertEqual(''.join(s.buflist), '\x01\x00\x00', "invalid stream write")
def test_stream_write_uint24Be_type(self):
@@ -170,7 +170,7 @@ class TypeTest(unittest.TestCase):
@summary: test write uint24Be in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt24Be(1))
s.write_type(rdpy.core.type.UInt24Be(1))
self.assertEqual(''.join(s.buflist), '\x00\x00\x01', "invalid stream write")
def test_stream_write_uint32Le_type(self):
@@ -178,7 +178,7 @@ class TypeTest(unittest.TestCase):
@summary: test write UInt32Le in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt32Le(1))
s.write_type(rdpy.core.type.UInt32Le(1))
self.assertEqual(''.join(s.buflist), '\x01\x00\x00\x00', "invalid stream write")
def test_stream_write_uint32Be_type(self):
@@ -186,7 +186,7 @@ class TypeTest(unittest.TestCase):
@summary: test write UInt32Be in stream
"""
s = rdpy.core.type.Stream()
s.writeType(rdpy.core.type.UInt32Be(1))
s.write_type(rdpy.core.type.UInt32Be(1))
self.assertEqual(''.join(s.buflist), '\x00\x00\x00\x01', "invalid stream write")
def test_stream_read_uint8_type(self):
@@ -195,9 +195,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x01')
t = rdpy.core.type.UInt8()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read value")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint16Le_type(self):
"""
@@ -205,9 +205,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x01\x00')
t = rdpy.core.type.UInt16Le()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read value")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint16Be_type(self):
"""
@@ -215,9 +215,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x00\x01')
t = rdpy.core.type.UInt16Be()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read value")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint24Le_type(self):
"""
@@ -225,9 +225,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x01\x00\x00')
t = rdpy.core.type.UInt24Le()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read value")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint24Be_type(self):
"""
@@ -235,9 +235,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x00\x00\x01')
t = rdpy.core.type.UInt24Be()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint32Le_type(self):
"""
@@ -245,9 +245,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x01\x00\x00\x00')
t = rdpy.core.type.UInt32Le()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read value")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_uint32Be_type(self):
"""
@@ -255,9 +255,9 @@ class TypeTest(unittest.TestCase):
"""
s = rdpy.core.type.Stream('\x00\x00\x00\x01')
t = rdpy.core.type.UInt32Be()
s.readType(t)
s.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read")
self.assertEqual(s.dataLen(), 0, "not read all stream")
self.assertEqual(s.data_len(), 0, "not read all stream")
def test_stream_read_optional_singletype(self):
"""
@@ -267,7 +267,7 @@ class TypeTest(unittest.TestCase):
t = rdpy.core.type.SimpleType("I", 4, False, 0, optional = True)
#empty stream
s1 = rdpy.core.type.Stream()
s1.readType(t)
s1.read_type(t)
self.assertEqual(t.value, 0, "invalid stream read optional value")
def test_stream_read_conditional_singletype_false(self):
@@ -277,7 +277,7 @@ class TypeTest(unittest.TestCase):
#unsigned int case
t = rdpy.core.type.SimpleType("I", 4, False, 0, conditional = lambda:False)
s1 = rdpy.core.type.Stream("\x01\x00\x00\x00")
s1.readType(t)
s1.read_type(t)
self.assertEqual(t.value, 0, "invalid stream read conditional value")
def test_stream_read_conditional_singletype_true(self):
@@ -287,7 +287,7 @@ class TypeTest(unittest.TestCase):
#unsigned int case
t = rdpy.core.type.SimpleType("I", 4, False, 0, conditional = lambda:True)
s1 = rdpy.core.type.Stream("\x01\x00\x00\x00")
s1.readType(t)
s1.read_type(t)
self.assertEqual(t.value, 1, "invalid stream read conditional value")
def test_stream_read_rollback_constant_constraint(self):
@@ -302,9 +302,9 @@ class TypeTest(unittest.TestCase):
s = rdpy.core.type.Stream("\x00\x00\x00\x00\x00\x00\x00\x00")
try:
s.readType(TestComposite())
s.read_type(TestComposite())
except Exception:
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
self.assertEqual(s.read_len(), 0, "invalid stream roll back operation")
return
self.assertTrue(False, "Constant constraint fail")
@@ -327,9 +327,9 @@ class TypeTest(unittest.TestCase):
s = rdpy.core.type.Stream("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
try:
s.readType(TestComposite())
s.read_type(TestComposite())
except Exception:
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
self.assertEqual(s.read_len(), 0, "invalid stream roll back operation")
return
self.assertTrue(False, "Constant constraint fail")
@@ -352,9 +352,9 @@ class TypeTest(unittest.TestCase):
s = rdpy.core.type.Stream("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
try:
s.readType(TestComposite())
s.read_type(TestComposite())
except Exception:
self.assertEqual(s.readLen(), 0, "invalid stream roll back operation")
self.assertEqual(s.read_len(), 0, "invalid stream roll back operation")
return
self.assertTrue(False, "Constant constraint fail")
@@ -369,8 +369,8 @@ class TypeTest(unittest.TestCase):
rdpy.core.type.CompositeType.__init__(self, readLen = readLen)
self.padding = rdpy.core.type.UInt32Le(0)
s = rdpy.core.type.Stream("\x00" * 10)
s.readType(TestReadLength(rdpy.core.type.UInt8(10)))
self.assertEqual(s.dataLen(), 0, "invalid stream read trash data as padding")
s.read_type(TestReadLength(rdpy.core.type.UInt8(10)))
self.assertEqual(s.data_len(), 0, "invalid stream read trash data as padding")
def test_stream_read_with_static_length_inferior(self):
"""
@@ -383,7 +383,7 @@ class TypeTest(unittest.TestCase):
rdpy.core.type.CompositeType.__init__(self, readLen = readLen)
self.padding = rdpy.core.type.UInt32Le(0)
s = rdpy.core.type.Stream("\x00" * 10)
self.assertRaises(InvalidSize, s.readType, TestReadLength(rdpy.core.type.UInt8(2)))
self.assertRaises(InvalidSize, s.read_type, TestReadLength(rdpy.core.type.UInt8(2)))
def test_stream_read_string(self):
"""

View File

@@ -40,7 +40,7 @@ class BERTest(unittest.TestCase):
@summary: test readLength function in ber module
"""
s1 = type.Stream()
s1.writeType(type.UInt8(0x1a))
s1.write_type(type.UInt8(0x1a))
s1.pos = 0
l1 = ber.readLength(s1)
@@ -48,7 +48,7 @@ class BERTest(unittest.TestCase):
self.assertTrue(l1 == 0x1a, "readLength fail in small format")
s2 = type.Stream()
s2.writeType((type.UInt8(0x81),type.UInt8(0xab)))
s2.write_type((type.UInt8(0x81), type.UInt8(0xab)))
s2.pos = 0
l2 = ber.readLength(s2)
@@ -56,7 +56,7 @@ class BERTest(unittest.TestCase):
self.assertTrue(l2 == 0xab, "readLength fail in big format of size 1")
s3 = type.Stream()
s3.writeType((type.UInt8(0x82),type.UInt16Be(0xabab)))
s3.write_type((type.UInt8(0x82), type.UInt16Be(0xabab)))
s3.pos = 0
l3 = ber.readLength(s3)

View File

@@ -73,25 +73,25 @@ class TestCsspNtlm(unittest.TestCase):
@summary: test generate ntlmv2 over cssp authentication protocol
"""
def testCSSPNTLMAuthentication(self):
negotiate_data_request = cssp.decodeDERTRequest(peer0_0.decode('base64'))
challenge_data_request = cssp.decodeDERTRequest(peer1_0.decode('base64'))
authenticate_data_request = cssp.decodeDERTRequest(peer0_1.decode('base64'))
negotiate_data_request = cssp.decode_der_trequest(peer0_0.decode('base64'))
challenge_data_request = cssp.decode_der_trequest(peer1_0.decode('base64'))
authenticate_data_request = cssp.decode_der_trequest(peer0_1.decode('base64'))
negotiate_data = cssp.getNegoTokens(negotiate_data_request)[0]
challenge_data = cssp.getNegoTokens(challenge_data_request)[0]
authenticate_data = cssp.getNegoTokens(authenticate_data_request)[0]
negotiate = ntlm.NegotiateMessage()
negotiate_data.readType(negotiate)
negotiate_data.read_type(negotiate)
challenge = ntlm.ChallengeMessage()
challenge_data.readType(challenge)
challenge_data.read_type(challenge)
ServerChallenge = challenge.ServerChallenge.value
ServerName = challenge.getTargetInfo()
authenticate = ntlm.AuthenticateMessage()
authenticate_data.readType(authenticate)
authenticate_data.read_type(authenticate)
NtChallengeResponseTemp = authenticate.getNtChallengeResponse()
NTProofStr = NtChallengeResponseTemp[:16]

View File

@@ -91,7 +91,7 @@ class TestLic(unittest.TestCase):
def test_valid_client_licensing_error_message(self):
l = lic.LicenseManager(None)
s = type.Stream()
s.writeType(lic.createValidClientLicensingErrorMessage())
s.write_type(lic.createValidClientLicensingErrorMessage())
#reinit position
s.pos = 0
@@ -105,9 +105,9 @@ class TestLic(unittest.TestCase):
if flag != sec.SecurityFlag.SEC_LICENSE_PKT:
return
s = type.Stream()
s.writeType(message)
s.write_type(message)
s.pos = 0
s.readType(lic.LicPacket(lic.ClientNewLicenseRequest()))
s.read_type(lic.LicPacket(lic.ClientNewLicenseRequest()))
self._state = True
def getGCCServerSettings(self):
class A:

View File

@@ -40,7 +40,7 @@ class PERTest(unittest.TestCase):
@summary: test readLength function in per module
"""
s1 = type.Stream()
s1.writeType(type.UInt8(0x1a))
s1.write_type(type.UInt8(0x1a))
s1.pos = 0
l1 = per.readLength(s1)
@@ -48,7 +48,7 @@ class PERTest(unittest.TestCase):
self.assertTrue(l1 == 0x1a, "readLength fail in small format")
s2 = type.Stream()
s2.writeType(type.UInt16Be(0x1abc | 0x8000))
s2.write_type(type.UInt16Be(0x1abc | 0x8000))
s2.pos = 0
l2 = per.readLength(s2)
@@ -78,7 +78,7 @@ class PERTest(unittest.TestCase):
for t in [type.UInt8, type.UInt16Be, type.UInt32Be]:
v = t(3)
s = type.Stream()
s.writeType((per.writeLength(type.sizeof(v)), v))
s.write_type((per.writeLength(type.sizeof(v)), v))
s.pos = 0
self.assertTrue(per.readInteger(s) == 3, "invalid readLength for type %s" % t)
@@ -86,7 +86,7 @@ class PERTest(unittest.TestCase):
#error case
for l in [0, 3, 5]:
s = type.Stream()
s.writeType(per.writeLength(l))
s.write_type(per.writeLength(l))
s.pos = 0
self.assertRaises(error.InvalidValue, per.readInteger, s)

View File

@@ -60,13 +60,13 @@ class TPKTTest(unittest.TestCase):
def connect(self):
pass
def recv(self, data):
data.readType(type.String("test_tpkt_layer_recv", constant = True))
data.read_type(type.String("test_tpkt_layer_recv", constant = True))
raise TPKTTest.TPKT_PASS()
message = type.String("test_tpkt_layer_recv")
s = type.Stream()
s.writeType((type.UInt8(tpkt.Action.FASTPATH_ACTION_X224), type.UInt8(), type.UInt16Be(type.sizeof(message) + 4), message))
s.write_type((type.UInt8(tpkt.Action.FASTPATH_ACTION_X224), type.UInt8(), type.UInt16Be(type.sizeof(message) + 4), message))
layer = tpkt.TPKT(Presentation())
layer.connect()
@@ -80,13 +80,13 @@ class TPKTTest(unittest.TestCase):
def setFastPathSender(self, fastPathSender):
pass
def recvFastPath(self, secFlag, fastPathS):
fastPathS.readType(type.String("test_tpkt_layer_recv_fastpath", constant = True))
fastPathS.read_type(type.String("test_tpkt_layer_recv_fastpath", constant = True))
raise TPKTTest.TPKT_PASS()
message = type.String("test_tpkt_layer_recv_fastpath")
s = type.Stream()
s.writeType((type.UInt8(tpkt.Action.FASTPATH_ACTION_FASTPATH), type.UInt8(type.sizeof(message) + 2), message))
s.write_type((type.UInt8(tpkt.Action.FASTPATH_ACTION_FASTPATH), type.UInt8(type.sizeof(message) + 2), message))
layer = tpkt.TPKT(None)
layer.initFastPath(FastPathLayer())
@@ -101,13 +101,13 @@ class TPKTTest(unittest.TestCase):
def setFastPathSender(self, fastPathSender):
pass
def recvFastPath(self, secflag, fastPathS):
fastPathS.readType(type.String("test_tpkt_layer_recv_fastpath_ext_length", constant = True))
fastPathS.read_type(type.String("test_tpkt_layer_recv_fastpath_ext_length", constant = True))
raise TPKTTest.TPKT_PASS()
message = type.String("test_tpkt_layer_recv_fastpath_ext_length")
s = type.Stream()
s.writeType((type.UInt8(tpkt.Action.FASTPATH_ACTION_FASTPATH), type.UInt16Be((type.sizeof(message) + 3) | 0x8000), message))
s.write_type((type.UInt8(tpkt.Action.FASTPATH_ACTION_FASTPATH), type.UInt16Be((type.sizeof(message) + 3) | 0x8000), message))
layer = tpkt.TPKT(None)
layer.initFastPath(FastPathLayer())

View File

@@ -53,12 +53,12 @@ class X224Test(unittest.TestCase):
"""
class Presentation(object):
def recv(self, data):
data.readType(type.String('test_x224_layer_recvData', constant = True))
data.read_type(type.String('test_x224_layer_recvData', constant = True))
raise X224Test.X224_PASS()
layer = x224.X224Layer(Presentation())
s = type.Stream()
s.writeType((x224.X224DataHeader(), type.String('test_x224_layer_recvData')))
s.write_type((x224.X224DataHeader(), type.String('test_x224_layer_recvData')))
#reinit position
s.pos = 0
@@ -71,10 +71,10 @@ class X224Test(unittest.TestCase):
class Transport(object):
def send(self, data):
s = type.Stream()
s.writeType(data)
s.write_type(data)
s.pos = 0
s.readType(x224.X224DataHeader())
s.readType(type.String('test_x224_layer_send', constant = True))
s.read_type(x224.X224DataHeader())
s.read_type(type.String('test_x224_layer_send', constant = True))
raise X224Test.X224_PASS()
layer = x224.X224Layer(None)
@@ -89,10 +89,10 @@ class X224Test(unittest.TestCase):
class Transport(object):
def send(self, data):
s = type.Stream()
s.writeType(data)
s.write_type(data)
s.pos = 0
t = x224.ClientConnectionRequestPDU()
s.readType(t)
s.read_type(t)
if t.protocolNeg.code != x224.NegociationType.TYPE_RDP_NEG_REQ:
raise X224Test.X224_FAIL()
@@ -115,7 +115,7 @@ class X224Test(unittest.TestCase):
message = x224.ServerConnectionConfirm()
message.protocolNeg.code.value = x224.NegociationType.TYPE_RDP_NEG_FAILURE
s = type.Stream()
s.writeType(message)
s.write_type(message)
s.pos = 0
layer = x224.Client(None)
self.assertRaises(error.RDPSecurityNegoFail, layer.recvConnectionConfirm, s)
@@ -145,7 +145,7 @@ class X224Test(unittest.TestCase):
message.protocolNeg.selectedProtocol.value = x224.Protocols.PROTOCOL_SSL
s = type.Stream()
s.writeType(message)
s.write_type(message)
s.pos = 0
layer = x224.Client(Presentation())
layer._transport = Transport()
@@ -175,7 +175,7 @@ class X224Test(unittest.TestCase):
message = x224.ClientConnectionRequestPDU()
message.protocolNeg.selectedProtocol.value = x224.Protocols.PROTOCOL_HYBRID
s = type.Stream()
s.writeType(message)
s.write_type(message)
s.pos = 0
layer = x224.Server(None, "key", "cert", True)
@@ -217,7 +217,7 @@ class X224Test(unittest.TestCase):
message = x224.ClientConnectionRequestPDU()
message.protocolNeg.selectedProtocol.value = x224.Protocols.PROTOCOL_SSL | x224.Protocols.PROTOCOL_RDP
s = type.Stream()
s.writeType(message)
s.write_type(message)
s.pos = 0
layer = x224.Server(Presentation(), "key", "cert")