Update: TPKT + x224 asyncio complient
This commit is contained in:
@@ -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
|
||||
|
||||
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]
|
||||
""")
|
||||
from rdpy.core import tpkt, x224
|
||||
from rdpy.model.type import UInt8
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
#default script argument
|
||||
username = ""
|
||||
password = ""
|
||||
domain = ""
|
||||
width = 1024
|
||||
height = 800
|
||||
fullscreen = False
|
||||
optimized = False
|
||||
recodedPath = None
|
||||
keyboardLayout = autoDetectKeyboardLayout()
|
||||
#sys.exit(app.exec_())
|
||||
|
||||
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
|
||||
async def tcp_echo_client(message):
|
||||
reader, writer = await asyncio.open_connection(
|
||||
'127.0.0.1', 33389)
|
||||
|
||||
if ':' in args[0]:
|
||||
ip, port = args[0].split(':')
|
||||
else:
|
||||
ip, port = args[0], "3389"
|
||||
x224_layer = await x224.connect(tpkt.Tpkt(reader, writer))
|
||||
await x224_layer.write(UInt8(8))
|
||||
await asyncio.sleep(1000)
|
||||
print("foooooooooooooooooooo")
|
||||
|
||||
#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_())
|
||||
asyncio.run(tcp_echo_client('Hello World!'))
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
# 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 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 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]
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
def connectionMade(self):
|
||||
"""
|
||||
@summary: install proxy
|
||||
"""
|
||||
self._layer.transport = self
|
||||
self._layer.getDescriptor = lambda:self.transport
|
||||
self._layer.connectionMade()
|
||||
#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 write(self, data):
|
||||
"""
|
||||
@summary: write data on transport layer
|
||||
@param data: {str}
|
||||
"""
|
||||
self.transport.write(data)
|
||||
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")
|
||||
|
||||
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()
|
||||
domain, user, password = self._authenticationProtocol.getEncodedCredentials()
|
||||
#send credentials
|
||||
self.transport.write(encode_der_trequest(
|
||||
auth_info= self._interface.GSS_WrapEx(encodeDERTCredentials(domain, user, password))))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -35,102 +39,25 @@ 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):
|
||||
"""
|
||||
@@ -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,12 +123,31 @@ 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):
|
||||
"""
|
||||
@@ -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"))
|
||||
|
||||
@@ -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
|
||||
@@ -68,6 +69,7 @@ class NegotiationFailureCode(object):
|
||||
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
|
||||
@@ -96,6 +99,7 @@ class ServerConnectionConfirm(CompositeType):
|
||||
#read if there is enough data
|
||||
self.protocolNeg = Negotiation(optional = True)
|
||||
|
||||
|
||||
class X224DataHeader(CompositeType):
|
||||
"""
|
||||
@summary: Header send when x224 exchange application data
|
||||
@@ -106,6 +110,7 @@ class X224DataHeader(CompositeType):
|
||||
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))
|
||||
await self.tpkt.write((X224DataHeader(), message))
|
||||
|
||||
class Client(X224Layer):
|
||||
|
||||
async def connect(tpkt: tpkt.Tpkt) -> X224:
|
||||
"""
|
||||
@summary: Client automata of TPDU layer
|
||||
@summary: Write connection request message
|
||||
Next state is recvConnectionConfirm
|
||||
@see: http://msdn.microsoft.com/en-us/library/cc240500.aspx
|
||||
"""
|
||||
def __init__(self, presentation):
|
||||
"""
|
||||
@param presentation: upper layer, MCS layer in RDP case
|
||||
"""
|
||||
X224Layer.__init__(self, presentation)
|
||||
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")
|
||||
|
||||
def connect(self):
|
||||
"""
|
||||
@summary: Connection request for client send a connection request packet
|
||||
"""
|
||||
self.sendConnectionRequest()
|
||||
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())
|
||||
|
||||
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)
|
||||
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)
|
||||
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
|
||||
# check presence of negotiation response
|
||||
if message.protocolNeg._is_readed:
|
||||
return message.protocolNeg.selectedProtocol.value
|
||||
else:
|
||||
return 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())
|
||||
|
||||
class Server(X224Layer):
|
||||
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
|
||||
|
||||
@@ -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())
|
||||
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
@@ -128,7 +129,8 @@ class Type(object):
|
||||
"""
|
||||
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
|
||||
@@ -737,12 +752,13 @@ class UInt24Le(SimpleType):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user