Update: Finish mcs connect

This commit is contained in:
citronneur
2020-05-27 22:27:24 +02:00
parent 9550734743
commit 1c4b42544c
3 changed files with 71 additions and 3 deletions

View File

@@ -308,7 +308,7 @@ class ServerSecurityData(CompositeType):
self.serverRandomLen = UInt32Le(0x00000020, constant=True, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0)) self.serverRandomLen = UInt32Le(0x00000020, constant=True, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0))
self.serverCertLen = UInt32Le(lambda: sizeof(self.serverCertificate), conditional=lambda:not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0)) self.serverCertLen = UInt32Le(lambda: sizeof(self.serverCertificate), conditional=lambda:not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0))
self.serverRandom = Buffer(read_len=lambda: self.serverRandomLen.value, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0)) self.serverRandom = Buffer(read_len=lambda: self.serverRandomLen.value, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0))
self.serverCertificate = ServerCertificate(readLen=lambda: self.serverCertLen.value, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0)) self.serverCertificate = ServerCertificate(read_len=lambda: self.serverCertLen.value, conditional=lambda: not(self.encryptionMethod.value == 0 and self.encryptionLevel.value == 0))
class ServerCertificate(CompositeType): class ServerCertificate(CompositeType):

View File

@@ -126,9 +126,65 @@ def read_domain_params(stream: Stream) -> Tuple[int, int, int, int]:
return max_channels, max_users, max_tokens, max_pdu_size return max_channels, max_users, max_tokens, max_pdu_size
def mcs_pdu_header(mcs_pdu: UInt8, options=0) -> UInt8:
return (mcs_pdu << 2) | options
def check_mcs_pdu_header(opcode: UInt8, mcs_pdu):
return (opcode >> 2) == mcs_pdu
def erect_domain_request() -> Tuple:
return mcs_pdu_header(UInt8(DomainMCSPDU.ERECT_DOMAIN_REQUEST)), per.writeInteger(0), per.writeInteger(0)
def read_attach_confirm(data: Stream) -> int:
"""
"""
opcode = data.read_type(UInt8())
if not check_mcs_pdu_header(opcode, DomainMCSPDU.ATTACH_USER_CONFIRM):
raise InvalidExpectedDataException("Invalid MCS PDU : ATTACH_USER_CONFIRM expected")
if per.readEnumerates(data) != 0:
raise InvalidExpectedDataException("Server reject user")
return per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE)
def attach_user_request() -> UInt8:
return mcs_pdu_header(UInt8(DomainMCSPDU.ATTACH_USER_REQUEST))
def channel_join_request(user_id: int, channel_id: int):
return (mcs_pdu_header(UInt8(DomainMCSPDU.CHANNEL_JOIN_REQUEST)),
per.writeInteger16(user_id, Channel.MCS_USERCHANNEL_BASE),
per.writeInteger16(channel_id))
def channel_join_confirm(user_id: int, channel_id: int, data: Stream) -> bool:
"""
"""
opcode = data.read_type(UInt8())
if not check_mcs_pdu_header(opcode.value, DomainMCSPDU.CHANNEL_JOIN_CONFIRM):
raise InvalidExpectedDataException("Invalid MCS PDU : CHANNEL_JOIN_CONFIRM expected")
confirm = per.readEnumerates(data)
if user_id != per.readInteger16(data, Channel.MCS_USERCHANNEL_BASE):
raise InvalidExpectedDataException("Invalid MCS User Id")
if channel_id != per.readInteger16(data):
raise InvalidExpectedDataException("Invalid MCS channel id")
return confirm == 0
class Client: class Client:
def __init__(self, x224_layer: x224.X224): def __init__(self, x224_layer: x224.X224):
self.x224 = x224_layer self.x224 = x224_layer
self.channel_ids = {}
async def write_connect_initial(self): async def write_connect_initial(self):
""" """
@@ -160,9 +216,21 @@ class Client:
raise InvalidSize("bad size of GCC request") raise InvalidSize("bad size of GCC request")
gcc.readConferenceCreateResponse(payload) gcc.readConferenceCreateResponse(payload)
async def connect(self): async def connect(self):
await self.write_connect_initial() await self.write_connect_initial()
await self.read_connect_response() await self.read_connect_response()
await self.x224.write(erect_domain_request())
await self.x224.write(attach_user_request())
user_id = read_attach_confirm(await self.x224.read())
self.channel_ids["global"] = 1003
self.channel_ids["user"] = user_id
# connect all channels
for channel_id in self.channel_ids.values():
await self.x224.write(channel_join_request(user_id, channel_id))
if not channel_join_confirm(user_id, channel_id, await self.x224.read()):
print("Server refused channel %s"%channel_id)
class MCSLayer(LayerAutomata): class MCSLayer(LayerAutomata):

View File

@@ -27,7 +27,7 @@ from rdpy.core import tpkt
from rdpy.core.nla import sspi from rdpy.core.nla import sspi
from rdpy.model import log from rdpy.model import log
from rdpy.model.message import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof, Buffer from rdpy.model.message import UInt8, UInt16Le, UInt16Be, UInt32Le, CompositeType, sizeof, Buffer, Stream
from rdpy.model.error import InvalidExpectedDataException, RDPSecurityNegoFail from rdpy.model.error import InvalidExpectedDataException, RDPSecurityNegoFail
@@ -141,7 +141,7 @@ class X224:
self.tpkt = tpkt self.tpkt = tpkt
self.selected_protocol = selected_protocol self.selected_protocol = selected_protocol
async def read(self): async def read(self) -> Stream:
""" """
""" """
header = X224DataHeader() header = X224DataHeader()