libfreerdp-core: server-side mcs message channel.
This commit is contained in:
parent
2de73e0243
commit
0e7797ffca
@ -33,6 +33,14 @@ typedef struct
|
||||
UINT16 requestType;
|
||||
} AUTODETECT_REQ_PDU;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 headerLength;
|
||||
UINT8 headerTypeId;
|
||||
UINT16 sequenceNumber;
|
||||
UINT16 responseType;
|
||||
} AUTODETECT_RSP_PDU;
|
||||
|
||||
static BOOL autodetect_send_rtt_measure_response(rdpRdp* rdp, UINT16 sequenceNumber)
|
||||
{
|
||||
wStream* s;
|
||||
@ -218,7 +226,7 @@ static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, AUTODETECT_R
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rdp_recv_autodetect_packet(rdpRdp* rdp, wStream* s)
|
||||
int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
AUTODETECT_REQ_PDU autodetectReqPdu;
|
||||
BOOL success = FALSE;
|
||||
@ -232,7 +240,7 @@ int rdp_recv_autodetect_packet(rdpRdp* rdp, wStream* s)
|
||||
Stream_Read_UINT16(s, autodetectReqPdu.requestType); /* requestType (2 bytes) */
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG,
|
||||
"rdp_recv_autodetect_packet: headerLength=%u, headerTypeId=%u, sequenceNumber=%u, requestType=%04x",
|
||||
"rdp_recv_autodetect_request_packet: headerLength=%u, headerTypeId=%u, sequenceNumber=%u, requestType=%04x",
|
||||
autodetectReqPdu.headerLength, autodetectReqPdu.headerTypeId,
|
||||
autodetectReqPdu.sequenceNumber, autodetectReqPdu.requestType);
|
||||
|
||||
@ -280,6 +288,30 @@ int rdp_recv_autodetect_packet(rdpRdp* rdp, wStream* s)
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
|
||||
int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
AUTODETECT_RSP_PDU autodetectRspPdu;
|
||||
BOOL success = FALSE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 6)
|
||||
return -1;
|
||||
|
||||
Stream_Read_UINT8(s, autodetectRspPdu.headerLength); /* headerLength (1 byte) */
|
||||
Stream_Read_UINT8(s, autodetectRspPdu.headerTypeId); /* headerTypeId (1 byte) */
|
||||
Stream_Read_UINT16(s, autodetectRspPdu.sequenceNumber); /* sequenceNumber (2 bytes) */
|
||||
Stream_Read_UINT16(s, autodetectRspPdu.responseType); /* responseType (2 bytes) */
|
||||
|
||||
WLog_DBG(AUTODETECT_TAG,
|
||||
"rdp_recv_autodetect_response_packet: headerLength=%u, headerTypeId=%u, sequenceNumber=%u, requestType=%04x",
|
||||
autodetectRspPdu.headerLength, autodetectRspPdu.headerTypeId,
|
||||
autodetectRspPdu.sequenceNumber, autodetectRspPdu.responseType);
|
||||
|
||||
if (autodetectRspPdu.headerTypeId != TYPE_ID_AUTODETECT_RESPONSE)
|
||||
return -1;
|
||||
|
||||
return success ? 0 : -1;
|
||||
}
|
||||
|
||||
rdpAutoDetect* autodetect_new(void)
|
||||
{
|
||||
rdpAutoDetect* autoDetect = (rdpAutoDetect*) calloc(1, sizeof(rdpAutoDetect));
|
||||
|
@ -45,7 +45,8 @@ struct rdp_autodetect
|
||||
UINT32 netCharAverageRTT;
|
||||
};
|
||||
|
||||
int rdp_recv_autodetect_packet(rdpRdp* rdp, wStream* s);
|
||||
int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s);
|
||||
int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s);
|
||||
|
||||
rdpAutoDetect* autodetect_new(void);
|
||||
void autodetect_free(rdpAutoDetect* autodetect);
|
||||
|
@ -1090,6 +1090,8 @@ BOOL rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, wStream* s)
|
||||
mcs->userChannelJoined = TRUE;
|
||||
else if (channelId == MCS_GLOBAL_CHANNEL_ID)
|
||||
mcs->globalChannelJoined = TRUE;
|
||||
else if (channelId == mcs->messageChannelId)
|
||||
mcs->messageChannelJoined = TRUE;
|
||||
|
||||
for (i = 0; i < mcs->channelCount; i++)
|
||||
{
|
||||
@ -1100,7 +1102,7 @@ BOOL rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, wStream* s)
|
||||
allJoined = FALSE;
|
||||
}
|
||||
|
||||
if ((mcs->userChannelJoined) && (mcs->globalChannelJoined) && allJoined)
|
||||
if ((mcs->userChannelJoined) && (mcs->globalChannelJoined) && (mcs->messageChannelId == 0 || mcs->messageChannelJoined) && allJoined)
|
||||
{
|
||||
rdp_server_transition_to_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT);
|
||||
}
|
||||
|
@ -514,9 +514,9 @@ void gcc_write_server_data_blocks(wStream* s, rdpMcs* mcs)
|
||||
gcc_write_server_core_data(s, mcs); /* serverCoreData */
|
||||
gcc_write_server_network_data(s, mcs); /* serverNetworkData */
|
||||
gcc_write_server_security_data(s, mcs); /* serverSecurityData */
|
||||
gcc_write_server_message_channel_data(s, mcs); /* serverMessageChannelData */
|
||||
|
||||
/* TODO: Send these GCC data blocks only when the client sent them */
|
||||
//gcc_write_server_message_channel_data(s, settings); /* serverMessageChannelData */
|
||||
//gcc_write_server_multitransport_channel_data(s, settings); /* serverMultitransportChannelData */
|
||||
}
|
||||
|
||||
@ -1252,7 +1252,7 @@ BOOL gcc_read_client_network_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
/* CHANNEL_DEF */
|
||||
Stream_Read(s, mcs->channels[i].Name, 8); /* name (8 bytes) */
|
||||
Stream_Read_UINT32(s, mcs->channels[i].options); /* options (4 bytes) */
|
||||
mcs->channels[i].ChannelId = MCS_GLOBAL_CHANNEL_ID + 1 + i;
|
||||
mcs->channels[i].ChannelId = mcs->baseChannelId++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1542,6 +1542,8 @@ BOOL gcc_read_client_message_channel_data(wStream* s, rdpMcs* mcs, UINT16 blockL
|
||||
|
||||
Stream_Read_UINT32(s, flags);
|
||||
|
||||
mcs->messageChannelId = mcs->baseChannelId++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1583,11 +1585,12 @@ BOOL gcc_read_server_message_channel_data(wStream* s, rdpMcs* mcs)
|
||||
|
||||
void gcc_write_server_message_channel_data(wStream* s, rdpMcs* mcs)
|
||||
{
|
||||
UINT16 mcsChannelId = 0;
|
||||
if (mcs->messageChannelId == 0)
|
||||
return;
|
||||
|
||||
gcc_write_user_data_header(s, SC_MCS_MSGCHANNEL, 6);
|
||||
|
||||
Stream_Write_UINT16(s, mcsChannelId); /* mcsChannelId (2 bytes) */
|
||||
Stream_Write_UINT16(s, mcs->messageChannelId); /* mcsChannelId (2 bytes) */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -853,7 +853,7 @@ BOOL mcs_send_attach_user_confirm(rdpMcs* mcs)
|
||||
s = Stream_New(NULL, length);
|
||||
settings = mcs->transport->settings;
|
||||
|
||||
mcs->userId = MCS_GLOBAL_CHANNEL_ID + 1 + mcs->channelCount;
|
||||
mcs->userId = mcs->baseChannelId++;
|
||||
|
||||
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserConfirm, length, 2);
|
||||
|
||||
|
@ -360,12 +360,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
|
||||
}
|
||||
}
|
||||
|
||||
if (channelId != MCS_GLOBAL_CHANNEL_ID)
|
||||
{
|
||||
if (!freerdp_channel_peer_process(client, s, channelId))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
if (channelId == MCS_GLOBAL_CHANNEL_ID)
|
||||
{
|
||||
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
|
||||
return -1;
|
||||
@ -389,6 +384,15 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (rdp->mcs->messageChannelId && channelId == rdp->mcs->messageChannelId)
|
||||
{
|
||||
return rdp_recv_message_channel_pdu(rdp, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!freerdp_channel_peer_process(client, s, channelId))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 sh
|
||||
Stream_Write_UINT16(s, 0); /* compressedLength (2 bytes) */
|
||||
}
|
||||
|
||||
static int rdp_security_stream_init(rdpRdp* rdp, wStream* s)
|
||||
static int rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
|
||||
{
|
||||
if (rdp->do_crypt)
|
||||
{
|
||||
@ -184,7 +184,7 @@ static int rdp_security_stream_init(rdpRdp* rdp, wStream* s)
|
||||
if (rdp->do_secure_checksum)
|
||||
rdp->sec_flags |= SEC_SECURE_CHECKSUM;
|
||||
}
|
||||
else if (rdp->sec_flags != 0)
|
||||
else if (rdp->sec_flags != 0 || sec_header)
|
||||
{
|
||||
Stream_Seek(s, 4);
|
||||
}
|
||||
@ -195,7 +195,7 @@ static int rdp_security_stream_init(rdpRdp* rdp, wStream* s)
|
||||
int rdp_init_stream(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s, FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -210,7 +210,7 @@ wStream* rdp_send_stream_init(rdpRdp* rdp)
|
||||
int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s, FALSE);
|
||||
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
@ -218,7 +218,7 @@ int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s)
|
||||
int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s, FALSE);
|
||||
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
|
||||
Stream_Seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
|
||||
return 0;
|
||||
@ -261,7 +261,7 @@ wStream* rdp_message_channel_pdu_init(rdpRdp* rdp)
|
||||
wStream* s;
|
||||
s = transport_send_stream_init(rdp->transport, 2048);
|
||||
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
rdp_security_stream_init(rdp, s);
|
||||
rdp_security_stream_init(rdp, s, TRUE);
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -471,7 +471,7 @@ static UINT32 rdp_security_stream_out(rdpRdp* rdp, wStream* s, int length, UINT3
|
||||
return pad;
|
||||
}
|
||||
|
||||
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp)
|
||||
static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
|
||||
{
|
||||
UINT32 sec_bytes;
|
||||
|
||||
@ -482,7 +482,7 @@ static UINT32 rdp_get_sec_bytes(rdpRdp* rdp)
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
sec_bytes += 4;
|
||||
}
|
||||
else if (rdp->sec_flags != 0)
|
||||
else if (rdp->sec_flags != 0 || sec_flags != 0)
|
||||
{
|
||||
sec_bytes = 4;
|
||||
}
|
||||
@ -525,7 +525,7 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp, 0);
|
||||
sec_hold = Stream_GetPosition(s);
|
||||
Stream_Seek(s, sec_bytes);
|
||||
rdp_write_share_control_header(s, length - sec_bytes, type, channel_id);
|
||||
@ -548,7 +548,7 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp, 0);
|
||||
sec_hold = Stream_GetPosition(s);
|
||||
Stream_Seek(s, sec_bytes);
|
||||
rdp_write_share_control_header(s, length - sec_bytes, PDU_TYPE_DATA, channel_id);
|
||||
@ -572,7 +572,7 @@ BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
|
||||
length = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
rdp_write_header(rdp, s, length, rdp->mcs->messageChannelId);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp);
|
||||
sec_bytes = rdp_get_sec_bytes(rdp, sec_flags);
|
||||
sec_hold = Stream_GetPosition(s);
|
||||
Stream_Seek(s, sec_bytes);
|
||||
Stream_SetPosition(s, sec_hold);
|
||||
@ -853,7 +853,13 @@ int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s)
|
||||
if (securityFlags & SEC_AUTODETECT_REQ)
|
||||
{
|
||||
/* Server Auto-Detect Request PDU */
|
||||
return rdp_recv_autodetect_packet(rdp, s);
|
||||
return rdp_recv_autodetect_request_packet(rdp, s);
|
||||
}
|
||||
|
||||
if (securityFlags & SEC_AUTODETECT_RSP)
|
||||
{
|
||||
/* Client Auto-Detect Response PDU */
|
||||
return rdp_recv_autodetect_response_packet(rdp, s);
|
||||
}
|
||||
|
||||
if (securityFlags & SEC_HEARTBEAT)
|
||||
|
Loading…
Reference in New Issue
Block a user