libfreerdp-core: parsing of GCC Conference Create Response
This commit is contained in:
parent
6074f887d8
commit
9df9a3382a
@ -39,7 +39,7 @@ int add_gcc_suite(void)
|
||||
{
|
||||
add_test_suite(gcc);
|
||||
|
||||
add_test_function(gcc_write_create_conference_request);
|
||||
add_test_function(gcc_write_conference_create_request);
|
||||
add_test_function(gcc_write_client_core_data);
|
||||
add_test_function(gcc_write_client_security_data);
|
||||
add_test_function(gcc_write_client_cluster_data);
|
||||
@ -68,7 +68,7 @@ uint8 gcc_user_data[284] =
|
||||
"\x00\x00\x80\x80\x63\x6c\x69\x70\x72\x64\x72\x00\x00\x00\xA0\xC0"
|
||||
"\x72\x64\x70\x73\x6e\x64\x00\x00\x00\x00\x00\xc0";
|
||||
|
||||
uint8 gcc_create_conference_request_expected[307] =
|
||||
uint8 gcc_conference_create_request_expected[307] =
|
||||
"\x00\x05\x00\x14\x7C\x00\x01\x81\x2A\x00\x08\x00\x10\x00\x01\xC0"
|
||||
"\x00\x44\x75\x63\x61\x81\x1c\x01\xc0\xd8\x00\x04\x00\x08\x00\x00"
|
||||
"\x05\x00\x04\x01\xCA\x03\xAA\x09\x04\x00\x00\xCE\x0E\x00\x00\x45"
|
||||
@ -90,7 +90,7 @@ uint8 gcc_create_conference_request_expected[307] =
|
||||
"\x64\x72\x00\x00\x00\xA0\xC0\x72\x64\x70\x73\x6e\x64\x00\x00\x00"
|
||||
"\x00\x00\xc0";
|
||||
|
||||
void test_gcc_write_create_conference_request(void)
|
||||
void test_gcc_write_conference_create_request(void)
|
||||
{
|
||||
STREAM* s;
|
||||
STREAM user_data;
|
||||
@ -99,10 +99,10 @@ void test_gcc_write_create_conference_request(void)
|
||||
user_data.size = sizeof(gcc_user_data);
|
||||
user_data.p = user_data.data + user_data.size;
|
||||
|
||||
s = stream_new(sizeof(gcc_create_conference_request_expected));
|
||||
s = stream_new(sizeof(gcc_conference_create_request_expected));
|
||||
|
||||
gcc_write_create_conference_request(s, &user_data);
|
||||
ASSERT_STREAM(s, (uint8*) gcc_create_conference_request_expected, sizeof(gcc_create_conference_request_expected));
|
||||
gcc_write_conference_create_request(s, &user_data);
|
||||
ASSERT_STREAM(s, (uint8*) gcc_conference_create_request_expected, sizeof(gcc_conference_create_request_expected));
|
||||
}
|
||||
|
||||
uint8 gcc_client_core_data_expected[216] =
|
||||
|
@ -23,7 +23,7 @@ int init_gcc_suite(void);
|
||||
int clean_gcc_suite(void);
|
||||
int add_gcc_suite(void);
|
||||
|
||||
void test_gcc_write_create_conference_request(void);
|
||||
void test_gcc_write_conference_create_request(void);
|
||||
void test_gcc_write_client_core_data(void);
|
||||
void test_gcc_write_client_security_data(void);
|
||||
void test_gcc_write_client_cluster_data(void);
|
||||
|
@ -72,6 +72,22 @@
|
||||
* conferenceMode ConferenceMode OPTIONAL
|
||||
* }
|
||||
*
|
||||
* ConferenceCreateResponse ::= SEQUENCE
|
||||
* {
|
||||
* nodeID UserID,
|
||||
* tag INTEGER,
|
||||
* result ENUMERATED
|
||||
* {
|
||||
* success (0),
|
||||
* userRejected (1),
|
||||
* resourcesNotAvailable (2),
|
||||
* rejectedForSymmetryBreaking (3),
|
||||
* lockedConferenceNotSupported (4)
|
||||
* },
|
||||
* userData UserData OPTIONAL,
|
||||
* ...
|
||||
* }
|
||||
*
|
||||
* ConferenceName ::= SEQUENCE
|
||||
* {
|
||||
* numeric SimpleNumericString
|
||||
@ -89,6 +105,12 @@
|
||||
*
|
||||
* H221NonStandardIdentifier ::= OCTET STRING (SIZE (4..255))
|
||||
*
|
||||
* UserID ::= DynamicChannelID
|
||||
*
|
||||
* ChannelID ::= INTEGER (1..65535)
|
||||
* StaticChannelID ::= INTEGER (1..1000)
|
||||
* DynamicChannelID ::= INTEGER (1001..65535)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -98,6 +120,9 @@
|
||||
*/
|
||||
uint8 t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
|
||||
|
||||
uint8 h221_cs_key[4] = "Duca";
|
||||
uint8 h221_sc_key[4] = "McDn";
|
||||
|
||||
/**
|
||||
* Write a GCC Conference Create Request.\n
|
||||
* @msdn{cc240836}
|
||||
@ -105,7 +130,7 @@ uint8 t124_02_98_oid[6] = { 0, 0, 20, 124, 0, 1 };
|
||||
* @param user_data client data blocks
|
||||
*/
|
||||
|
||||
void gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
|
||||
void gcc_write_conference_create_request(STREAM* s, STREAM* user_data)
|
||||
{
|
||||
/* ConnectData */
|
||||
per_write_choice(s, 0); /* From Key select object (0) of type OBJECT_IDENTIFIER */
|
||||
@ -127,12 +152,56 @@ void gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
|
||||
per_write_choice(s, 0xC0); /* UserData::value present + select h221NonStandard (1) */
|
||||
|
||||
/* h221NonStandard */
|
||||
per_write_octet_string(s, "Duca", 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */
|
||||
per_write_octet_string(s, h221_cs_key, 4, 4); /* h221NonStandard, client-to-server H.221 key, "Duca" */
|
||||
|
||||
/* userData::value (OCTET_STRING) */
|
||||
per_write_octet_string(s, user_data->data, stream_get_length(user_data), 0); /* array of client data blocks */
|
||||
}
|
||||
|
||||
void gcc_read_conference_create_response(STREAM* s)
|
||||
{
|
||||
int length;
|
||||
uint32 tag;
|
||||
uint16 nodeID;
|
||||
uint8 result;
|
||||
uint8 choice;
|
||||
uint8 selection;
|
||||
uint8 number;
|
||||
|
||||
/* ConnectData */
|
||||
per_read_choice(s, &choice);
|
||||
per_read_object_identifier(s, t124_02_98_oid);
|
||||
|
||||
/* ConnectData::connectPDU (OCTET_STRING) */
|
||||
per_read_length(s, &length);
|
||||
|
||||
/* ConnectGCCPDU */
|
||||
per_read_choice(s, &choice);
|
||||
|
||||
/* ConferenceCreateResponse::nodeID (UserID) */
|
||||
per_read_integer16(s, &nodeID, 1001);
|
||||
|
||||
/* ConferenceCreateResponse::tag (INTEGER) */
|
||||
per_read_integer(s, &tag);
|
||||
|
||||
/* ConferenceCreateResponse::result (ENUMERATED) */
|
||||
per_read_enumerated(s, &result);
|
||||
|
||||
/* number of UserData sets */
|
||||
per_read_number_of_sets(s, &number);
|
||||
|
||||
/* UserData::value present + select h221NonStandard (1) */
|
||||
per_read_choice(s, &choice);
|
||||
|
||||
/* h221NonStandard */
|
||||
per_read_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */
|
||||
|
||||
/* userData (OCTET_STRING) */
|
||||
per_read_length(s, &length);
|
||||
|
||||
printf("server core data, length:%d\n", length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a user data header (TS_UD_HEADER).\n
|
||||
* @msdn{cc240509}
|
||||
|
@ -99,7 +99,8 @@
|
||||
/* Monitor Flags */
|
||||
#define MONITOR_PRIMARY 0x00000001
|
||||
|
||||
void gcc_write_create_conference_request(STREAM* s, STREAM* user_data);
|
||||
void gcc_write_conference_create_request(STREAM* s, STREAM* user_data);
|
||||
void gcc_read_conference_create_response(STREAM* s);
|
||||
|
||||
void gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length);
|
||||
void gcc_write_client_core_data(STREAM* s, rdpSettings *settings);
|
||||
|
@ -250,7 +250,7 @@ void mcs_send_connect_initial(rdpMcs* mcs)
|
||||
gcc_write_client_monitor_data(client_data, mcs->transport->settings);
|
||||
|
||||
gcc_CCrq = stream_new(512);
|
||||
gcc_write_create_conference_request(gcc_CCrq, client_data);
|
||||
gcc_write_conference_create_request(gcc_CCrq, client_data);
|
||||
length = stream_get_length(gcc_CCrq) + 7;
|
||||
|
||||
s = stream_new(512);
|
||||
@ -293,7 +293,7 @@ void mcs_recv_connect_response(rdpMcs* mcs)
|
||||
|
||||
ber_read_octet_string(s, &length);
|
||||
|
||||
printf("userData, length:%d\n", length);
|
||||
gcc_read_conference_create_response(s);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,26 @@
|
||||
|
||||
#include "per.h"
|
||||
|
||||
boolean per_read_length(STREAM* s, int* length)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte & 0x80)
|
||||
{
|
||||
*length = (byte << 8);
|
||||
stream_read_uint8(s, byte);
|
||||
*length += byte;
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = byte;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER length.
|
||||
* @param s stream
|
||||
@ -33,6 +53,12 @@ void per_write_length(STREAM* s, int length)
|
||||
stream_write_uint8(s, length);
|
||||
}
|
||||
|
||||
boolean per_read_choice(STREAM* s, uint8* choice)
|
||||
{
|
||||
stream_read_uint8(s, *choice);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER CHOICE.
|
||||
* @param s stream
|
||||
@ -44,6 +70,12 @@ void per_write_choice(STREAM* s, uint8 choice)
|
||||
stream_write_uint8(s, choice);
|
||||
}
|
||||
|
||||
boolean per_read_selection(STREAM* s, uint8* selection)
|
||||
{
|
||||
stream_read_uint8(s, *selection);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER selection for OPTIONAL fields.
|
||||
* @param s stream
|
||||
@ -55,6 +87,12 @@ void per_write_selection(STREAM* s, uint8 selection)
|
||||
stream_write_uint8(s, selection);
|
||||
}
|
||||
|
||||
boolean per_read_number_of_sets(STREAM* s, uint8* number)
|
||||
{
|
||||
stream_read_uint8(s, *number);
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER number of sets for SET OF.
|
||||
* @param s stream
|
||||
@ -80,6 +118,73 @@ void per_write_padding(STREAM* s, int length)
|
||||
stream_write_uint8(s, 0);
|
||||
}
|
||||
|
||||
boolean per_read_integer(STREAM* s, uint32* integer)
|
||||
{
|
||||
int length;
|
||||
|
||||
per_read_length(s, &length);
|
||||
|
||||
if (length == 1)
|
||||
stream_read_uint8(s, *integer);
|
||||
else if (length == 2)
|
||||
stream_read_uint16_be(s, *integer);
|
||||
else
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min)
|
||||
{
|
||||
stream_read_uint16_be(s, *integer);
|
||||
|
||||
if (*integer + min > 0xFFFF)
|
||||
return False;
|
||||
|
||||
*integer += min;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean per_read_enumerated(STREAM* s, uint8* enumerated)
|
||||
{
|
||||
stream_read_uint8(s, *enumerated);
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean per_read_object_identifier(STREAM* s, uint8 oid[6])
|
||||
{
|
||||
uint8 t12;
|
||||
int length;
|
||||
uint8 a_oid[6];
|
||||
boolean status;
|
||||
|
||||
per_read_length(s, &length); /* length */
|
||||
|
||||
if (length != 5)
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, t12); /* first two tuples */
|
||||
a_oid[0] = (t12 >> 4);
|
||||
a_oid[1] = (t12 & 0x0F);
|
||||
|
||||
stream_read_uint8(s, a_oid[2]); /* tuple 3 */
|
||||
stream_read_uint8(s, a_oid[3]); /* tuple 4 */
|
||||
stream_read_uint8(s, a_oid[4]); /* tuple 5 */
|
||||
stream_read_uint8(s, a_oid[5]); /* tuple 6 */
|
||||
|
||||
if ((a_oid[0] == oid[0]) && (a_oid[1] == oid[1]) &&
|
||||
(a_oid[2] == oid[2]) && (a_oid[3] == oid[3]) &&
|
||||
(a_oid[4] == oid[4]) && (a_oid[5] == oid[5]))
|
||||
{
|
||||
return True;
|
||||
}
|
||||
else
|
||||
{
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER OBJECT_IDENTIFIER (OID)
|
||||
* @param s stream
|
||||
@ -112,6 +217,29 @@ void per_write_string(STREAM* s, uint8* str, int length)
|
||||
stream_write_uint8(s, str[i]);
|
||||
}
|
||||
|
||||
boolean per_read_octet_string(STREAM* s, uint8* oct_str, int length, int min)
|
||||
{
|
||||
int i;
|
||||
int mlength;
|
||||
uint8* a_oct_str;
|
||||
|
||||
per_read_length(s, &mlength);
|
||||
|
||||
if (mlength + min != length)
|
||||
return False;
|
||||
|
||||
a_oct_str = s->p;
|
||||
stream_seek(s, length);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
if (a_oct_str[i] != oct_str[i])
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write PER OCTET_STRING
|
||||
* @param s stream
|
||||
|
@ -22,12 +22,21 @@
|
||||
|
||||
#include <freerdp/utils/stream.h>
|
||||
|
||||
boolean per_read_length(STREAM* s, int* length);
|
||||
void per_write_length(STREAM* s, int length);
|
||||
boolean per_read_choice(STREAM* s, uint8* choice);
|
||||
void per_write_choice(STREAM* s, uint8 choice);
|
||||
boolean per_read_selection(STREAM* s, uint8* selection);
|
||||
void per_write_selection(STREAM* s, uint8 selection);
|
||||
boolean per_read_number_of_sets(STREAM* s, uint8* number);
|
||||
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_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);
|
||||
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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user