libfreerdp-core: server-side mcs message channel.

This commit is contained in:
Vic Lee 2014-10-28 16:06:04 +08:00
parent 2de73e0243
commit 0e7797ffca
7 changed files with 75 additions and 27 deletions

View File

@ -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));

View File

@ -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);

View File

@ -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);
}

View File

@ -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) */
}
/**

View File

@ -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);

View File

@ -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;
}

View File

@ -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)