libfreerdp-core: MCS initialization messages

This commit is contained in:
Marc-André Moreau 2011-07-09 23:54:23 -04:00
parent eb18fd0897
commit ca09499ff1
9 changed files with 263 additions and 26 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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