libfreerdp-core: parsing of GCC Conference Create Response

This commit is contained in:
Marc-André Moreau 2011-07-09 17:28:30 -04:00
parent 6074f887d8
commit 9df9a3382a
7 changed files with 219 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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