libfreerdp-core: MCS initialization messages
This commit is contained in:
parent
eb18fd0897
commit
ca09499ff1
@ -78,9 +78,15 @@ int main(int argc, char* argv[])
|
||||
transport_connect_nla(transport);
|
||||
|
||||
mcs = mcs_new(transport);
|
||||
|
||||
mcs_send_connect_initial(mcs);
|
||||
|
||||
mcs_recv_connect_response(mcs);
|
||||
|
||||
mcs_send_erect_domain_request(mcs);
|
||||
mcs_send_attach_user_request(mcs);
|
||||
|
||||
mcs_recv_attach_user_confirm(mcs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ void ber_write_sequence_of_tag(STREAM* s, int length)
|
||||
ber_write_length(s, length);
|
||||
}
|
||||
|
||||
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 max)
|
||||
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count)
|
||||
{
|
||||
int length;
|
||||
|
||||
@ -172,7 +172,7 @@ boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 max)
|
||||
return False;
|
||||
|
||||
/* check that enumerated value falls within expected range */
|
||||
if (*enumerated > max)
|
||||
if (*enumerated + 1 > count)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
|
@ -50,7 +50,7 @@ void ber_write_length(STREAM* s, int length);
|
||||
void ber_write_universal_tag(STREAM* s, uint8 tag);
|
||||
void ber_write_application_tag(STREAM* s, uint8 tag, int length);
|
||||
boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length);
|
||||
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 max);
|
||||
boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count);
|
||||
boolean ber_read_sequence_of_tag(STREAM* s, int* length);
|
||||
void ber_write_sequence_of_tag(STREAM* s, int length);
|
||||
boolean ber_read_octet_string(STREAM* s, int* length);
|
||||
|
@ -185,7 +185,7 @@ void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings)
|
||||
per_read_integer(s, &tag);
|
||||
|
||||
/* ConferenceCreateResponse::result (ENUMERATED) */
|
||||
per_read_enumerated(s, &result);
|
||||
per_read_enumerated(s, &result, MCS_Result_enum_length);
|
||||
|
||||
/* number of UserData sets */
|
||||
per_read_number_of_sets(s, &number);
|
||||
@ -198,11 +198,18 @@ void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings)
|
||||
|
||||
/* userData (OCTET_STRING) */
|
||||
per_read_length(s, &length);
|
||||
|
||||
printf("server core data, length:%d\n", length);
|
||||
gcc_read_server_data_blocks(s, settings, length);
|
||||
}
|
||||
|
||||
void gcc_write_client_data_blocks(STREAM* s, rdpSettings *settings)
|
||||
{
|
||||
gcc_write_client_core_data(s, settings);
|
||||
gcc_write_client_cluster_data(s, settings);
|
||||
gcc_write_client_security_data(s, settings);
|
||||
gcc_write_client_network_data(s, settings);
|
||||
gcc_write_client_monitor_data(s, settings);
|
||||
}
|
||||
|
||||
void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length)
|
||||
{
|
||||
uint16 type;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define __GCC_H
|
||||
|
||||
#include "per.h"
|
||||
#include "mcs.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
@ -101,6 +102,7 @@
|
||||
|
||||
void gcc_write_conference_create_request(STREAM* s, STREAM* user_data);
|
||||
void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings);
|
||||
void gcc_write_client_data_blocks(STREAM* s, rdpSettings *settings);
|
||||
void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length);
|
||||
void gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length);
|
||||
void gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length);
|
||||
|
@ -80,6 +80,36 @@
|
||||
* rt-user-rejected (15)
|
||||
* }
|
||||
*
|
||||
* ErectDomainRequest ::= [APPLICATION 1] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* subHeight INTEGER (0..MAX),
|
||||
* subInterval INTEGER (0..MAX)
|
||||
* }
|
||||
*
|
||||
* AttachUserRequest ::= [APPPLICATION 10] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* AttachUserConfirm ::= [APPLICATION 11] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* result Result,
|
||||
* initiator UserId OPTIONAL
|
||||
* }
|
||||
*
|
||||
* ChannelJoinRequest ::= [APPLICATION 14] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* initiator UserId,
|
||||
* channelId ChannelId
|
||||
* }
|
||||
*
|
||||
* ChannelJoinConfirm ::= [APPLICATION 15] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* result Result,
|
||||
* initiator UserId,
|
||||
* requested ChannelId,
|
||||
* channelId ChannelId OPTIONAL
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
uint8 callingDomainSelector[1] = "\x01";
|
||||
@ -114,7 +144,7 @@ uint8 mcs_result_enumerated[16][32] =
|
||||
* @param maxMCSPDUsize max MCS PDU size
|
||||
*/
|
||||
|
||||
static void mcs_init_domain_parameters(DOMAIN_PARAMETERS* domainParameters,
|
||||
static void mcs_init_domain_parameters(DomainParameters* domainParameters,
|
||||
uint32 maxChannelIds, uint32 maxUserIds, uint32 maxTokenIds, uint32 maxMCSPDUsize)
|
||||
{
|
||||
domainParameters->maxChannelIds = maxChannelIds;
|
||||
@ -128,7 +158,7 @@ static void mcs_init_domain_parameters(DOMAIN_PARAMETERS* domainParameters,
|
||||
domainParameters->protocolVersion = 2;
|
||||
}
|
||||
|
||||
static void mcs_read_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainParameters)
|
||||
static void mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters)
|
||||
{
|
||||
int length;
|
||||
ber_read_sequence_of_tag(s, &length);
|
||||
@ -148,7 +178,7 @@ static void mcs_read_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainParam
|
||||
* @param domainParameters domain parameters
|
||||
*/
|
||||
|
||||
static void mcs_write_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainParameters)
|
||||
static void mcs_write_domain_parameters(STREAM* s, DomainParameters* domainParameters)
|
||||
{
|
||||
int length;
|
||||
uint8 *bm, *em;
|
||||
@ -173,7 +203,7 @@ static void mcs_write_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainPara
|
||||
stream_set_mark(s, em);
|
||||
}
|
||||
|
||||
static void mcs_print_domain_parameters(DOMAIN_PARAMETERS* domainParameters)
|
||||
void mcs_print_domain_parameters(DomainParameters* domainParameters)
|
||||
{
|
||||
printf("DomainParameters {\n");
|
||||
printf("\tmaxChannelIds:%d\n", domainParameters->maxChannelIds);
|
||||
@ -243,11 +273,7 @@ void mcs_send_connect_initial(rdpMcs* mcs)
|
||||
STREAM* client_data;
|
||||
|
||||
client_data = stream_new(512);
|
||||
gcc_write_client_core_data(client_data, mcs->transport->settings);
|
||||
gcc_write_client_cluster_data(client_data, mcs->transport->settings);
|
||||
gcc_write_client_security_data(client_data, mcs->transport->settings);
|
||||
gcc_write_client_network_data(client_data, mcs->transport->settings);
|
||||
gcc_write_client_monitor_data(client_data, mcs->transport->settings);
|
||||
gcc_write_client_data_blocks(client_data, mcs->transport->settings);
|
||||
|
||||
gcc_CCrq = stream_new(512);
|
||||
gcc_write_conference_create_request(gcc_CCrq, client_data);
|
||||
@ -283,19 +309,106 @@ void mcs_recv_connect_response(rdpMcs* mcs)
|
||||
tpdu_read_data(s);
|
||||
|
||||
ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length);
|
||||
ber_read_enumerated(s, &result, 15);
|
||||
ber_read_enumerated(s, &result, MCS_Result_enum_length);
|
||||
ber_read_integer(s, &calledConnectId);
|
||||
|
||||
printf("MCS Connect-Response Result: %s\n", mcs_result_enumerated[result]);
|
||||
|
||||
mcs_read_domain_parameters(s, &(mcs->domainParameters));
|
||||
mcs_print_domain_parameters(&(mcs->domainParameters));
|
||||
|
||||
ber_read_octet_string(s, &length);
|
||||
|
||||
gcc_read_conference_create_response(s, mcs->transport->settings);
|
||||
}
|
||||
|
||||
void mcs_send_erect_domain_request(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
int length = 12;
|
||||
s = stream_new(length);
|
||||
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s, length - 5);
|
||||
|
||||
/* DomainMCSPDU, ErectDomainRequest */
|
||||
per_write_choice(s, DomainMCSPDU_ErectDomainRequest << 2);
|
||||
per_write_integer(s, 0); /* subHeight (INTEGER) */
|
||||
per_write_integer(s, 0); /* subInterval (INTEGER) */
|
||||
|
||||
tls_write(mcs->transport->tls, s->data, stream_get_length(s));
|
||||
}
|
||||
|
||||
void mcs_send_attach_user_request(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
int length = 8;
|
||||
s = stream_new(length);
|
||||
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s, length - 5);
|
||||
|
||||
/* DomainMCSPDU, AttachUserRequest */
|
||||
per_write_choice(s, DomainMCSPDU_AttachUserRequest << 2);
|
||||
|
||||
tls_write(mcs->transport->tls, s->data, stream_get_length(s));
|
||||
}
|
||||
|
||||
void mcs_recv_attach_user_confirm(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
int length;
|
||||
uint8 result;
|
||||
uint8 choice;
|
||||
|
||||
s = stream_new(32);
|
||||
tls_read(mcs->transport->tls, s->data, s->size);
|
||||
|
||||
tpkt_read_header(s);
|
||||
tpdu_read_data(s);
|
||||
|
||||
per_read_choice(s, &choice);
|
||||
per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */
|
||||
per_read_integer16(s, &(mcs->user_id), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
}
|
||||
|
||||
void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id)
|
||||
{
|
||||
STREAM* s;
|
||||
int length = 8;
|
||||
s = stream_new(length);
|
||||
|
||||
tpkt_write_header(s, length);
|
||||
tpdu_write_data(s, length - 5);
|
||||
|
||||
/* DomainMCSPDU, ChannelJoinRequest*/
|
||||
per_write_choice(s, DomainMCSPDU_ChannelJoinRequest << 2);
|
||||
per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID);
|
||||
per_write_integer16(s, channel_id + MCS_BASE_CHANNEL_ID, 0);
|
||||
|
||||
tls_write(mcs->transport->tls, s->data, stream_get_length(s));
|
||||
}
|
||||
|
||||
void mcs_recv_channel_join_confirm(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
int length;
|
||||
uint8 choice;
|
||||
uint8 result;
|
||||
uint16 initiator;
|
||||
uint16 requested;
|
||||
uint16 channelId;
|
||||
|
||||
s = stream_new(32);
|
||||
tls_read(mcs->transport->tls, s->data, s->size);
|
||||
|
||||
tpkt_read_header(s);
|
||||
tpdu_read_data(s);
|
||||
|
||||
per_read_choice(s, &choice);
|
||||
per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */
|
||||
per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */
|
||||
per_read_integer16(s, &requested, 0); /* requested (ChannelId) */
|
||||
per_read_integer16(s, &channelId, 0); /* channelId */
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate new MCS module.
|
||||
* @param transport transport
|
||||
|
@ -26,6 +26,77 @@
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
#define MCS_BASE_CHANNEL_ID 1001
|
||||
|
||||
enum MCS_Result
|
||||
{
|
||||
MCS_Result_successful = 0,
|
||||
MCS_Result_domain_merging = 1,
|
||||
MCS_Result_domain_not_hierarchical = 2,
|
||||
MCS_Result_no_such_channel = 3,
|
||||
MCS_Result_no_such_domain = 4,
|
||||
MCS_Result_no_such_user = 5,
|
||||
MCS_Result_not_admitted = 6,
|
||||
MCS_Result_other_user_id = 7,
|
||||
MCS_Result_parameters_unacceptable = 8,
|
||||
MCS_Result_token_not_available = 9,
|
||||
MCS_Result_token_not_possessed = 10,
|
||||
MCS_Result_too_many_channels = 11,
|
||||
MCS_Result_too_many_tokens = 12,
|
||||
MCS_Result_too_many_users = 13,
|
||||
MCS_Result_unspecified_failure = 14,
|
||||
MCS_Result_user_rejected = 15,
|
||||
MCS_Result_enum_length = 16
|
||||
};
|
||||
|
||||
enum DomainMCSPDU
|
||||
{
|
||||
DomainMCSPDU_PlumbDomainIndication = 0,
|
||||
DomainMCSPDU_ErectDomainRequest = 1,
|
||||
DomainMCSPDU_MergeChannelsRequest = 2,
|
||||
DomainMCSPDU_MergeChannelsConfirm = 3,
|
||||
DomainMCSPDU_PurgeChannelsIndication = 4,
|
||||
DomainMCSPDU_MergeTokensRequest = 5,
|
||||
DomainMCSPDU_MergeTokensConfirm = 6,
|
||||
DomainMCSPDU_PurgeTokensIndication = 7,
|
||||
DomainMCSPDU_DisconnectProviderUltimatum = 8,
|
||||
DomainMCSPDU_RejectMCSPDUUltimatum = 9,
|
||||
DomainMCSPDU_AttachUserRequest = 10,
|
||||
DomainMCSPDU_AttachUserConfirm = 11,
|
||||
DomainMCSPDU_DetachUserRequest = 12,
|
||||
DomainMCSPDU_DetachUserIndication = 13,
|
||||
DomainMCSPDU_ChannelJoinRequest = 14,
|
||||
DomainMCSPDU_ChannelJoinConfirm = 15,
|
||||
DomainMCSPDU_ChannelLeaveRequest = 16,
|
||||
DomainMCSPDU_ChannelConveneRequest = 17,
|
||||
DomainMCSPDU_ChannelConveneConfirm = 18,
|
||||
DomainMCSPDU_ChannelDisbandRequest = 19,
|
||||
DomainMCSPDU_ChannelDisbandIndication = 20,
|
||||
DomainMCSPDU_ChannelAdmitRequest = 21,
|
||||
DomainMCSPDU_ChannelAdmitIndication = 22,
|
||||
DomainMCSPDU_ChannelExpelRequest = 23,
|
||||
DomainMCSPDU_ChannelExpelIndication = 24,
|
||||
DomainMCSPDU_SendDataRequest = 25,
|
||||
DomainMCSPDU_SendDataIndication = 26,
|
||||
DomainMCSPDU_UniformSendDataRequest = 27,
|
||||
DomainMCSPDU_UniformSendDataIndication = 28,
|
||||
DomainMCSPDU_TokenGrabRequest = 29,
|
||||
DomainMCSPDU_TokenGrabConfirm = 30,
|
||||
DomainMCSPDU_TokenInhibitRequest = 31,
|
||||
DomainMCSPDU_TokenInhibitConfirm = 32,
|
||||
DomainMCSPDU_TokenGiveRequest = 33,
|
||||
DomainMCSPDU_TokenGiveIndication = 34,
|
||||
DomainMCSPDU_TokenGiveResponse = 35,
|
||||
DomainMCSPDU_TokenGiveConfirm = 36,
|
||||
DomainMCSPDU_TokenPleaseRequest = 37,
|
||||
DomainMCSPDU_TokenPleaseConfirm = 38,
|
||||
DomainMCSPDU_TokenReleaseRequest = 39,
|
||||
DomainMCSPDU_TokenReleaseConfirm = 40,
|
||||
DomainMCSPDU_TokenTestRequest = 41,
|
||||
DomainMCSPDU_TokenTestConfirm = 42,
|
||||
DomainMCSPDU_enum_length = 43
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 maxChannelIds;
|
||||
@ -36,15 +107,16 @@ typedef struct
|
||||
uint32 maxHeight;
|
||||
uint32 maxMCSPDUsize;
|
||||
uint32 protocolVersion;
|
||||
} DOMAIN_PARAMETERS;
|
||||
} DomainParameters;
|
||||
|
||||
struct rdp_mcs
|
||||
{
|
||||
uint16 user_id;
|
||||
struct rdp_transport* transport;
|
||||
DOMAIN_PARAMETERS domainParameters;
|
||||
DOMAIN_PARAMETERS targetParameters;
|
||||
DOMAIN_PARAMETERS minimumParameters;
|
||||
DOMAIN_PARAMETERS maximumParameters;
|
||||
DomainParameters domainParameters;
|
||||
DomainParameters targetParameters;
|
||||
DomainParameters minimumParameters;
|
||||
DomainParameters maximumParameters;
|
||||
};
|
||||
typedef struct rdp_mcs rdpMcs;
|
||||
|
||||
@ -55,6 +127,10 @@ void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data);
|
||||
|
||||
void mcs_send_connect_initial(rdpMcs* mcs);
|
||||
void mcs_recv_connect_response(rdpMcs* mcs);
|
||||
void mcs_send_erect_domain_request(rdpMcs* mcs);
|
||||
void mcs_recv_attach_user_confirm(rdpMcs* mcs);
|
||||
void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id);
|
||||
void mcs_recv_channel_join_confirm(rdpMcs* mcs);
|
||||
|
||||
rdpMcs* mcs_new(rdpTransport* transport);
|
||||
void mcs_free(rdpMcs* mcs);
|
||||
|
@ -146,9 +146,40 @@ boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min)
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean per_read_enumerated(STREAM* s, uint8* enumerated)
|
||||
void per_write_integer(STREAM* s, uint32 integer)
|
||||
{
|
||||
int length;
|
||||
|
||||
if (integer <= 0xFF)
|
||||
{
|
||||
per_write_length(s, 1);
|
||||
stream_write_uint8(s, integer);
|
||||
}
|
||||
else if (integer <= 0xFFFF)
|
||||
{
|
||||
per_write_length(s, 2);
|
||||
stream_write_uint16_be(s, integer);
|
||||
}
|
||||
else if (integer <= 0xFFFFFFFF)
|
||||
{
|
||||
per_write_length(s, 4);
|
||||
stream_write_uint32_be(s, integer);
|
||||
}
|
||||
}
|
||||
|
||||
void per_write_integer16(STREAM* s, uint16 integer, uint16 min)
|
||||
{
|
||||
stream_write_uint16_be(s, integer - min);
|
||||
}
|
||||
|
||||
boolean per_read_enumerated(STREAM* s, uint8* enumerated, uint8 count)
|
||||
{
|
||||
stream_read_uint8(s, *enumerated);
|
||||
|
||||
/* check that enumerated value falls within expected range */
|
||||
if (*enumerated + 1 > count)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,9 @@ void per_write_number_of_sets(STREAM* s, uint8 number);
|
||||
void per_write_padding(STREAM* s, int length);
|
||||
boolean per_read_integer(STREAM* s, uint32* integer);
|
||||
boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min);
|
||||
boolean per_read_enumerated(STREAM* s, uint8* enumerated);
|
||||
void per_write_integer(STREAM* s, uint32 integer);
|
||||
void per_write_integer16(STREAM* s, uint16 integer, uint16 min);
|
||||
boolean per_read_enumerated(STREAM* s, uint8* enumerated, uint8 count);
|
||||
void per_write_object_identifier(STREAM* s, uint8 oid[6]);
|
||||
boolean per_read_object_identifier(STREAM* s, uint8 oid[6]);
|
||||
boolean per_read_octet_string(STREAM* s, uint8* oct_str, int length, int min);
|
||||
|
Loading…
Reference in New Issue
Block a user