From a05be813becc463afb2660c1b52d766f94908b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 7 Jul 2011 15:35:09 -0400 Subject: [PATCH] libfreerdp-core: MCS Connect-Initial --- libfreerdp-core/ber.c | 58 ++++++++++++++-- libfreerdp-core/ber.h | 13 ++-- libfreerdp-core/credssp.c | 6 +- libfreerdp-core/mcs.c | 139 ++++++++++++++++++++++++++++++++++++++ libfreerdp-core/mcs.h | 31 ++++++++- libfreerdp-core/per.c | 27 +++----- libfreerdp-core/per.h | 24 +++---- 7 files changed, 246 insertions(+), 52 deletions(-) diff --git a/libfreerdp-core/ber.c b/libfreerdp-core/ber.c index 033ac8dd6..ea041a086 100644 --- a/libfreerdp-core/ber.c +++ b/libfreerdp-core/ber.c @@ -25,8 +25,7 @@ * @param length length */ -void -ber_write_length(STREAM* s, int length) +void ber_write_length(STREAM* s, int length) { if (length > 0x7F) { @@ -46,8 +45,7 @@ ber_write_length(STREAM* s, int length) * @param length length */ -void -ber_write_universal_tag(STREAM* s, uint8 tag, int length) +void ber_write_universal_tag(STREAM* s, uint8 tag, int length) { stream_write_uint8(s, (BER_CLASS_UNIV | BER_PRIMITIVE) | (BER_TAG_MASK & tag)); ber_write_length(s, length); @@ -60,8 +58,7 @@ ber_write_universal_tag(STREAM* s, uint8 tag, int length) * @param length length */ -void -ber_write_application_tag(STREAM* s, uint8 tag, int length) +void ber_write_application_tag(STREAM* s, uint8 tag, int length) { if (tag > 30) { @@ -75,3 +72,52 @@ ber_write_application_tag(STREAM* s, uint8 tag, int length) ber_write_length(s, length); } } + +/** + * Write a BER OCTET_STRING + * @param s stream + * @param oct_str octet string + * @param length string length + */ + +void ber_write_octet_string(STREAM* s, uint8* oct_str, int length) +{ + ber_write_universal_tag(s, BER_TAG_OCTET_STRING); + stream_write(s, oct_str, length); +} + +/** + * Write a BER BOOLEAN + * @param s + * @param value + */ + +void ber_write_boolean(STREAM* s, boolean value) +{ + ber_write_universal_tag(s, BER_TAG_BOOLEAN); + stream_write_uint8(s, (value == True) ? 0xFF : 0); +} + +/** + * Write a BER INTEGER + * @param s + * @param value + */ + +void ber_write_integer(STREAM* s, uint32 value) +{ + ber_write_universal_tag(s, BER_TAG_INTEGER); + + if (value <= 0xFF) + { + stream_write_uint8(s, value); + } + else if (value <= 0xFFFF) + { + stream_write_uint16_be(s, value); + } + else if (value <= 0xFFFFFFFF) + { + stream_write_uint32_be(s, value); + } +} diff --git a/libfreerdp-core/ber.h b/libfreerdp-core/ber.h index 2bbfa2713..00de431c7 100644 --- a/libfreerdp-core/ber.h +++ b/libfreerdp-core/ber.h @@ -20,6 +20,7 @@ #ifndef __BER_H #define __BER_H +#include #include /* BER type */ @@ -42,11 +43,11 @@ #define BER_TAG_INTEGER 0x02 #define BER_TAG_OCTET_STRING 0x04 -void -ber_write_length(STREAM* s, int length); -void -ber_write_universal_tag(STREAM* s, uint8 tag, int length); -void -ber_write_application_tag(STREAM* s, uint8 tag, int length); +void ber_write_length(STREAM* s, int length); +void ber_write_universal_tag(STREAM* s, uint8 tag, int length); +void ber_write_application_tag(STREAM* s, uint8 tag, int length); +void ber_write_octet_string(STREAM* s, uint8* oct_str, int length); +void ber_write_boolean(STREAM* s, boolean value); +void ber_write_integer(STREAM* s, uint32 value); #endif /* __BER_H */ diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index c1712d8c9..231e480cf 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -492,8 +492,7 @@ void credssp_current_time(uint8* timestamp) * @return new CredSSP state machine. */ -rdpCredssp* -credssp_new(rdpTransport* transport) +rdpCredssp* credssp_new(rdpTransport* transport) { rdpCredssp* self; @@ -514,8 +513,7 @@ credssp_new(rdpTransport* transport) * @param credssp */ -void -credssp_free(rdpCredssp* credssp) +void credssp_free(rdpCredssp* credssp) { if (credssp != NULL) { diff --git a/libfreerdp-core/mcs.c b/libfreerdp-core/mcs.c index 5a2004fa6..d6b6c4120 100644 --- a/libfreerdp-core/mcs.c +++ b/libfreerdp-core/mcs.c @@ -26,3 +26,142 @@ * ITU-T T.125 Multipoint Communication Service Protocol Specification */ +/** + * Connect-Initial ::= [APPLICATION 101] IMPLICIT SEQUENCE + * { + * callingDomainSelector OCTET_STRING, + * calledDomainSelector OCTET_STRING, + * upwardFlag BOOLEAN, + * targetParameters DomainParameters, + * minimumParameters DomainParameters, + * maximumParameters DomainParameters, + * userData OCTET_STRING + * } + * + * DomainParameters ::= SEQUENCE + * { + * maxChannelIds INTEGER (0..MAX), + * maxUserIds INTEGER (0..MAX), + * maxTokenIds INTEGER (0..MAX), + * numPriorities INTEGER (0..MAX), + * minThroughput INTEGER (0..MAX), + * maxHeight INTEGER (0..MAX), + * maxMCSPDUsize INTEGER (0..MAX), + * protocolVersion INTEGER (0..MAX) + * } + * + */ + +uint8 callingDomainSelector[1] = "\x01"; +uint8 calledDomainSelector[1] = "\x01"; + +/** + * Initialize MCS Domain Parameters. + * @param domainParameters domain parameters + * @param maxChannelIds max channel ids + * @param maxUserIds max user ids + * @param maxTokenIds max token ids + * @param maxMCSPDUsize max MCS PDU size + */ + +static void mcs_init_domain_parameters(DOMAIN_PARAMETERS* domainParameters, + uint32 maxChannelIds, uint32 maxUserIds, uint32 maxTokenIds, uint32 maxMCSPDUsize) +{ + domainParameters->maxChannelIds = maxChannelIds; + domainParameters->maxUserIds = maxUserIds; + domainParameters->maxTokenIds = maxTokenIds; + domainParameters->maxMCSPDUsize = maxMCSPDUsize; +} + +/** + * Write MCS Domain Parameters. + * @param s stream + * @param domainParameters domain parameters + */ + +static void mcs_write_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainParameters) +{ + ber_write_integer(domainParameters->maxChannelIds); + ber_write_integer(domainParameters->maxUserIds); + ber_write_integer(domainParameters->maxTokenIds); + ber_write_integer(domainParameters->numPriorities); + ber_write_integer(domainParameters->minThroughput); + ber_write_integer(domainParameters->maxHeight); + ber_write_integer(domainParameters->maxMCSPDUsize); + ber_write_integer(domainParameters->protocolVersion); +} + +/** + * Write an MCS Connect Initial PDU. + * @param s stream + * @param mcs MCS module + * @param user_data GCC Conference Create Request + */ + +void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data) +{ + int length; + int gcc_CCrq_length = stream_get_length(user_data); + + length = gcc_CCrq_length + 3 * 34 + 13; + + /* Connect-Initial (APPLICATION 101, IMPLICIT SEQUENCE) */ + ber_write_application_tag(s, MCS_TYPE_CONNECT_INITIAL, length); + + /* callingDomainSelector (OCTET_STRING) */ + ber_write_octet_string(s, callingDomainSelector, sizeof(callingDomainSelector)); + + /* calledDomainSelector (OCTET_STRING) */ + ber_write_octet_string(s, calledDomainSelector, sizeof(calledDomainSelector)); + + /* upwardFlag (BOOLEAN) */ + ber_write_boolean(s, True); + + /* targetParameters (DomainParameters) */ + mcs_write_domain_parameters(s, &mcs->targetParameters); + + /* minimumParameters (DomainParameters) */ + mcs_write_domain_parameters(s, &mcs->minimumParameters); + + /* maximumParameters (DomainParameters) */ + mcs_write_domain_parameters(s, &mcs->maximumParameters); + + /* userData (OCTET_STRING) */ + ber_write_octet_string(s, user_data->data, gcc_CCrq_length); +} + +/** + * Instantiate new MCS module. + * @param transport transport + * @return new MCS module + */ + +rdpMcs* mcs_new(rdpTransport* transport) +{ + rdpMcs* mcs; + + mcs = (rdpMcs*) xzalloc(sizeof(rdpMcs)); + + if (mcs != NULL) + { + mcs->transport = transport; + mcs_init_domain_parameters(&mcs->targetParameters, 34, 2, 0, 0xFFFF); + mcs_init_domain_parameters(&mcs->minimumParameters, 1, 1, 1, 0x420); + mcs_init_domain_parameters(&mcs->maximumParameters, 0xFFFF, 0xFC17, 0xFFFF, 0xFFFF); + } + + return mcs; +} + +/** + * Free MCS module. + * @param mcs MCS module to be freed + */ + +void mcs_free(rdpMcs* mcs) +{ + if (mcs != NULL) + { + xfree(mcs); + } +} diff --git a/libfreerdp-core/mcs.h b/libfreerdp-core/mcs.h index 7457b798e..6c053c1bd 100644 --- a/libfreerdp-core/mcs.h +++ b/libfreerdp-core/mcs.h @@ -21,10 +21,37 @@ #define __MCS_H #include "ber.h" +#include "transport.h" #include -#define MCS_BER_CONNECT_INITIAL 0x65 -#define MCS_BER_CONNECT_RESPONSE 0x66 +typedef struct +{ + uint32 maxChannelIds; + uint32 maxUserIds; + uint32 maxTokenIds; + uint32 numPriorities; + uint32 minThroughput; + uint32 maxHeight + uint32 maxMCSPDUsize; + uint32 protocolVersion; +} DOMAIN_PARAMETERS; + +struct rdp_mcs +{ + struct rdp_transport* transport; + DOMAIN_PARAMETERS targetParameters; + DOMAIN_PARAMETERS minimumParameters; + DOMAIN_PARAMETERS maximumParameters; +}; +typedef struct rdp_mcs rdpMcs; + +#define MCS_TYPE_CONNECT_INITIAL 0x65 +#define MCS_TYPE_CONNECT_RESPONSE 0x66 + +void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, int length); + +rdpMcs* mcs_new(rdpTransport* transport); +void mcs_free(rdpMcs* mcs); #endif /* __MCS_H */ diff --git a/libfreerdp-core/per.c b/libfreerdp-core/per.c index 3cc20bf98..58930d168 100644 --- a/libfreerdp-core/per.c +++ b/libfreerdp-core/per.c @@ -25,8 +25,7 @@ * @param length length */ -void -per_write_length(STREAM* s, int length) +void per_write_length(STREAM* s, int length) { if (length > 0x7F) stream_write_uint16_be(s, (length | 0x8000)); @@ -40,8 +39,7 @@ per_write_length(STREAM* s, int length) * @param choice index of chosen field */ -void -per_write_choice(STREAM* s, uint8 choice) +void per_write_choice(STREAM* s, uint8 choice) { stream_write_uint8(s, choice); } @@ -52,8 +50,7 @@ per_write_choice(STREAM* s, uint8 choice) * @param selection bit map of selected fields */ -void -per_write_selection(STREAM* s, uint8 selection) +void per_write_selection(STREAM* s, uint8 selection) { stream_write_uint8(s, selection); } @@ -64,8 +61,7 @@ per_write_selection(STREAM* s, uint8 selection) * @param number number of sets */ -void -per_write_number_of_sets(STREAM* s, uint8 number) +void per_write_number_of_sets(STREAM* s, uint8 number) { stream_write_uint8(s, number); } @@ -76,8 +72,7 @@ per_write_number_of_sets(STREAM* s, uint8 number) * @param length */ -void -per_write_padding(STREAM* s, int length) +void per_write_padding(STREAM* s, int length) { int i; @@ -91,8 +86,7 @@ per_write_padding(STREAM* s, int length) * @param oid object identifier (oid) */ -void -per_write_object_identifier(STREAM* s, uint8 oid[6]) +void per_write_object_identifier(STREAM* s, uint8 oid[6]) { uint8 t12 = (oid[0] << 4) & (oid[1] & 0x0F); stream_write_uint8(s, 5); /* length */ @@ -110,8 +104,7 @@ per_write_object_identifier(STREAM* s, uint8 oid[6]) * @param length string length */ -void -per_write_string(STREAM* s, uint8* str, int length) +void per_write_string(STREAM* s, uint8* str, int length) { int i; @@ -127,8 +120,7 @@ per_write_string(STREAM* s, uint8* str, int length) * @param min minimum string length */ -void -per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min) +void per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min) { int i; int mlength; @@ -149,8 +141,7 @@ per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min) * @param min minimum string length */ -void -per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min) +void per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min) { int i; int mlength; diff --git a/libfreerdp-core/per.h b/libfreerdp-core/per.h index 692f91d38..456e6a011 100644 --- a/libfreerdp-core/per.h +++ b/libfreerdp-core/per.h @@ -22,21 +22,13 @@ #include -void -per_write_length(STREAM* s, int length); -void -per_write_choice(STREAM* s, uint8 choice); -void -per_write_selection(STREAM* s, uint8 selection); -void -per_write_number_of_sets(STREAM* s, uint8 number); -void -per_write_padding(STREAM* s, int length); -void -per_write_object_identifier(STREAM* s, uint8 oid[6]); -void -per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min); -void -per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min); +void per_write_length(STREAM* s, int length); +void per_write_choice(STREAM* s, uint8 choice); +void per_write_selection(STREAM* s, uint8 selection); +void per_write_number_of_sets(STREAM* s, uint8 number); +void per_write_padding(STREAM* s, int length); +void per_write_object_identifier(STREAM* s, uint8 oid[6]); +void per_write_octet_string(STREAM* s, uint8* oct_str, int length, int min); +void per_write_numeric_string(STREAM* s, uint8* num_str, int length, int min); #endif /* __PER_H */