Update: Finish mcs connect
This commit is contained in:
@@ -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.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.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):
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
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:
|
||||
def __init__(self, x224_layer: x224.X224):
|
||||
self.x224 = x224_layer
|
||||
self.channel_ids = {}
|
||||
|
||||
async def write_connect_initial(self):
|
||||
"""
|
||||
@@ -160,9 +216,21 @@ class Client:
|
||||
raise InvalidSize("bad size of GCC request")
|
||||
gcc.readConferenceCreateResponse(payload)
|
||||
|
||||
|
||||
async def connect(self):
|
||||
await self.write_connect_initial()
|
||||
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):
|
||||
|
||||
@@ -27,7 +27,7 @@ from rdpy.core import tpkt
|
||||
from rdpy.core.nla import sspi
|
||||
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
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ class X224:
|
||||
self.tpkt = tpkt
|
||||
self.selected_protocol = selected_protocol
|
||||
|
||||
async def read(self):
|
||||
async def read(self) -> Stream:
|
||||
"""
|
||||
"""
|
||||
header = X224DataHeader()
|
||||
|
||||
Reference in New Issue
Block a user