mirror of https://github.com/FreeRDP/FreeRDP
Merge branch 'master' of git@github.com:FreeRDP/FreeRDP-1.0
This commit is contained in:
commit
dfc6cc3a06
|
@ -80,7 +80,7 @@ int main(int argc, char* argv[])
|
|||
mcs = mcs_new(transport);
|
||||
mcs_send_connect_initial(mcs);
|
||||
|
||||
mcs_recv(mcs);
|
||||
mcs_recv_connect_response(mcs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,25 @@
|
|||
|
||||
#include "ber.h"
|
||||
|
||||
void ber_read_length(STREAM* s, int* length)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte & 0x80)
|
||||
{
|
||||
if (byte & ~(0x80) == 2)
|
||||
{
|
||||
stream_read_uint16_be(s, *length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = byte;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write BER length.
|
||||
* @param s stream
|
||||
|
@ -38,6 +57,18 @@ void ber_write_length(STREAM* s, int length)
|
|||
}
|
||||
}
|
||||
|
||||
boolean ber_read_universal_tag(STREAM* s, uint8 tag)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte != (BER_CLASS_UNIV | BER_PRIMITIVE) | (BER_TAG_MASK & tag))
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write BER Universal tag.
|
||||
* @param s stream
|
||||
|
@ -71,6 +102,51 @@ void ber_write_application_tag(STREAM* s, uint8 tag, int length)
|
|||
}
|
||||
}
|
||||
|
||||
boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
if (tag > 30)
|
||||
{
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK))
|
||||
return False;
|
||||
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte != tag)
|
||||
return False;
|
||||
|
||||
ber_read_length(s, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag)))
|
||||
return False;
|
||||
|
||||
ber_read_length(s, length);
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean ber_read_sequence_of_tag(STREAM* s, int* length)
|
||||
{
|
||||
uint8 byte;
|
||||
|
||||
stream_read_uint8(s, byte);
|
||||
|
||||
if (byte != ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF)))
|
||||
return False;
|
||||
|
||||
ber_read_length(s, length);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write BER SEQUENCE OF tag.
|
||||
* @param s stream
|
||||
|
@ -83,6 +159,33 @@ 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)
|
||||
{
|
||||
int length;
|
||||
|
||||
ber_read_universal_tag(s, BER_TAG_ENUMERATED);
|
||||
ber_read_length(s, &length);
|
||||
|
||||
if (length == 1)
|
||||
stream_read_uint8(s, *enumerated);
|
||||
else
|
||||
return False;
|
||||
|
||||
/* check that enumerated value falls within expected range */
|
||||
if (*enumerated > max)
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
boolean ber_read_octet_string(STREAM* s, int* length)
|
||||
{
|
||||
ber_read_universal_tag(s, BER_TAG_OCTET_STRING);
|
||||
ber_read_length(s, length);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a BER OCTET_STRING
|
||||
* @param s stream
|
||||
|
@ -110,6 +213,30 @@ void ber_write_boolean(STREAM* s, boolean value)
|
|||
stream_write_uint8(s, (value == True) ? 0xFF : 0);
|
||||
}
|
||||
|
||||
boolean ber_read_integer(STREAM* s, uint32* value)
|
||||
{
|
||||
int length;
|
||||
|
||||
ber_read_universal_tag(s, BER_TAG_INTEGER);
|
||||
ber_read_length(s, &length);
|
||||
|
||||
if (length == 1)
|
||||
stream_read_uint8(s, *value);
|
||||
else if (length == 2)
|
||||
stream_read_uint16_be(s, *value);
|
||||
else if (length == 3)
|
||||
{
|
||||
uint8 byte;
|
||||
stream_read_uint8(s, byte);
|
||||
stream_read_uint16_be(s, *value);
|
||||
*value += (byte << 16);
|
||||
}
|
||||
else
|
||||
return False;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a BER INTEGER
|
||||
* @param s
|
||||
|
|
|
@ -42,14 +42,21 @@
|
|||
#define BER_TAG_BOOLEAN 0x01
|
||||
#define BER_TAG_INTEGER 0x02
|
||||
#define BER_TAG_OCTET_STRING 0x04
|
||||
#define BER_TAG_ENUMERATED 0x0A
|
||||
#define BER_TAG_SEQUENCE_OF 0x10
|
||||
|
||||
void ber_read_length(STREAM* s, int* length);
|
||||
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_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);
|
||||
void ber_write_octet_string(STREAM* s, uint8* oct_str, int length);
|
||||
void ber_write_boolean(STREAM* s, boolean value);
|
||||
boolean ber_read_integer(STREAM* s, uint32* value);
|
||||
void ber_write_integer(STREAM* s, uint32 value);
|
||||
|
||||
#endif /* __BER_H */
|
||||
|
|
|
@ -52,11 +52,59 @@
|
|||
* protocolVersion INTEGER (0..MAX)
|
||||
* }
|
||||
*
|
||||
* Connect-Response ::= [APPLICATION 102] IMPLICIT SEQUENCE
|
||||
* {
|
||||
* result Result,
|
||||
* calledConnectId INTEGER (0..MAX),
|
||||
* domainParameters DomainParameters,
|
||||
* userData OCTET_STRING
|
||||
* }
|
||||
*
|
||||
* Result ::= ENUMERATED
|
||||
* {
|
||||
* rt-successful (0),
|
||||
* rt-domain-merging (1),
|
||||
* rt-domain-not-hierarchical (2),
|
||||
* rt-no-such-channel (3),
|
||||
* rt-no-such-domain (4),
|
||||
* rt-no-such-user (5),
|
||||
* rt-not-admitted (6),
|
||||
* rt-other-user-id (7),
|
||||
* rt-parameters-unacceptable (8),
|
||||
* rt-token-not-available (9),
|
||||
* rt-token-not-possessed (10),
|
||||
* rt-too-many-channels (11),
|
||||
* rt-too-many-tokens (12),
|
||||
* rt-too-many-users (13),
|
||||
* rt-unspecified-failure (14),
|
||||
* rt-user-rejected (15)
|
||||
* }
|
||||
*
|
||||
*/
|
||||
|
||||
uint8 callingDomainSelector[1] = "\x01";
|
||||
uint8 calledDomainSelector[1] = "\x01";
|
||||
|
||||
uint8 mcs_result_enumerated[16][32] =
|
||||
{
|
||||
"rt-successful",
|
||||
"rt-domain-merging",
|
||||
"rt-domain-not-hierarchical",
|
||||
"rt-no-such-channel",
|
||||
"rt-no-such-domain",
|
||||
"rt-no-such-user",
|
||||
"rt-not-admitted",
|
||||
"rt-other-user-id",
|
||||
"rt-parameters-unacceptable",
|
||||
"rt-token-not-available",
|
||||
"rt-token-not-possessed",
|
||||
"rt-too-many-channels",
|
||||
"rt-too-many-tokens",
|
||||
"rt-too-many-users",
|
||||
"rt-unspecified-failure",
|
||||
"rt-user-rejected"
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize MCS Domain Parameters.
|
||||
* @param domainParameters domain parameters
|
||||
|
@ -80,6 +128,20 @@ static void mcs_init_domain_parameters(DOMAIN_PARAMETERS* domainParameters,
|
|||
domainParameters->protocolVersion = 2;
|
||||
}
|
||||
|
||||
static void mcs_read_domain_parameters(STREAM* s, DOMAIN_PARAMETERS* domainParameters)
|
||||
{
|
||||
int length;
|
||||
ber_read_sequence_of_tag(s, &length);
|
||||
ber_read_integer(s, &(domainParameters->maxChannelIds));
|
||||
ber_read_integer(s, &(domainParameters->maxUserIds));
|
||||
ber_read_integer(s, &(domainParameters->maxTokenIds));
|
||||
ber_read_integer(s, &(domainParameters->numPriorities));
|
||||
ber_read_integer(s, &(domainParameters->minThroughput));
|
||||
ber_read_integer(s, &(domainParameters->maxHeight));
|
||||
ber_read_integer(s, &(domainParameters->maxMCSPDUsize));
|
||||
ber_read_integer(s, &(domainParameters->protocolVersion));
|
||||
}
|
||||
|
||||
/**
|
||||
* Write MCS Domain Parameters.
|
||||
* @param s stream
|
||||
|
@ -111,6 +173,20 @@ 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)
|
||||
{
|
||||
printf("DomainParameters {\n");
|
||||
printf("\tmaxChannelIds:%d\n", domainParameters->maxChannelIds);
|
||||
printf("\tmaxUserIds:%d\n", domainParameters->maxUserIds);
|
||||
printf("\tmaxTokenIds:%d\n", domainParameters->maxTokenIds);
|
||||
printf("\tnumPriorities:%d\n", domainParameters->numPriorities);
|
||||
printf("\tminThroughput:%d\n", domainParameters->minThroughput);
|
||||
printf("\tmaxHeight:%d\n", domainParameters->maxHeight);
|
||||
printf("\tmaxMCSPDUsize:%d\n", domainParameters->maxMCSPDUsize);
|
||||
printf("\tprotocolVersion:%d\n", domainParameters->protocolVersion);
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write an MCS Connect Initial PDU.
|
||||
* @param s stream
|
||||
|
@ -158,18 +234,6 @@ void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data)
|
|||
stream_set_mark(s, em);
|
||||
}
|
||||
|
||||
int mcs_recv(rdpMcs* mcs)
|
||||
{
|
||||
int bytes_read;
|
||||
int size = 2048;
|
||||
char *recv_buffer;
|
||||
|
||||
recv_buffer = xmalloc(size);
|
||||
bytes_read = tls_read(mcs->transport->tls, recv_buffer, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mcs_send_connect_initial(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
|
@ -205,6 +269,33 @@ void mcs_send_connect_initial(rdpMcs* mcs)
|
|||
tls_write(mcs->transport->tls, s->data, stream_get_length(s));
|
||||
}
|
||||
|
||||
void mcs_recv_connect_response(rdpMcs* mcs)
|
||||
{
|
||||
STREAM* s;
|
||||
int length;
|
||||
uint8 result;
|
||||
uint32 calledConnectId;
|
||||
|
||||
s = stream_new(1024);
|
||||
tls_read(mcs->transport->tls, s->data, s->size);
|
||||
|
||||
tpkt_read_header(s);
|
||||
tpdu_read_data(s);
|
||||
|
||||
ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length);
|
||||
ber_read_enumerated(s, &result, 15);
|
||||
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);
|
||||
|
||||
printf("userData, length:%d\n", length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate new MCS module.
|
||||
* @param transport transport
|
||||
|
|
|
@ -28,19 +28,20 @@
|
|||
|
||||
typedef struct
|
||||
{
|
||||
uint16 maxChannelIds;
|
||||
uint16 maxUserIds;
|
||||
uint16 maxTokenIds;
|
||||
uint16 numPriorities;
|
||||
uint16 minThroughput;
|
||||
uint16 maxHeight;
|
||||
uint16 maxMCSPDUsize;
|
||||
uint16 protocolVersion;
|
||||
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 domainParameters;
|
||||
DOMAIN_PARAMETERS targetParameters;
|
||||
DOMAIN_PARAMETERS minimumParameters;
|
||||
DOMAIN_PARAMETERS maximumParameters;
|
||||
|
@ -53,8 +54,7 @@ typedef struct rdp_mcs rdpMcs;
|
|||
void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data);
|
||||
|
||||
void mcs_send_connect_initial(rdpMcs* mcs);
|
||||
|
||||
int mcs_recv(rdpMcs* mcs);
|
||||
void mcs_recv_connect_response(rdpMcs* mcs);
|
||||
|
||||
rdpMcs* mcs_new(rdpTransport* transport);
|
||||
void mcs_free(rdpMcs* mcs);
|
||||
|
|
|
@ -70,16 +70,18 @@ tpdu_read_header(STREAM* s, uint8* code)
|
|||
stream_read_uint8(s, li); /* LI */
|
||||
stream_read_uint8(s, *code); /* Code */
|
||||
|
||||
/* DST-REF (2 bytes) */
|
||||
/* SRC-REF (2 bytes) */
|
||||
/* Class 0 (1 byte) */
|
||||
stream_seek(s, 5);
|
||||
|
||||
if (*code == X224_TPDU_DATA)
|
||||
{
|
||||
/* EOT (1 byte) */
|
||||
stream_seek(s, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DST-REF (2 bytes) */
|
||||
/* SRC-REF (2 bytes) */
|
||||
/* Class 0 (1 byte) */
|
||||
stream_seek(s, 5);
|
||||
}
|
||||
|
||||
return li;
|
||||
}
|
||||
|
@ -166,3 +168,25 @@ tpdu_write_data(STREAM* s)
|
|||
{
|
||||
tpdu_write_header(s, 2, X224_TPDU_DATA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read Data TPDU.
|
||||
* @param s stream
|
||||
*/
|
||||
|
||||
uint16
|
||||
tpdu_read_data(STREAM* s)
|
||||
{
|
||||
uint8 code;
|
||||
uint16 li;
|
||||
|
||||
li = tpdu_read_header(s, &code);
|
||||
|
||||
if (code != X224_TPDU_DATA)
|
||||
{
|
||||
printf("expected X224_TPDU_DATA\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return li;
|
||||
}
|
||||
|
|
|
@ -35,17 +35,12 @@ enum X224_TPDU_TYPE
|
|||
#define TPDU_CONNECTION_CONFIRM_LENGTH 7
|
||||
#define TPDU_DISCONNECT_REQUEST_LENGTH 7
|
||||
|
||||
uint8
|
||||
tpdu_read_header(STREAM* s, uint8* code);
|
||||
void
|
||||
tpdu_write_header(STREAM* s, uint16 length, uint8 code);
|
||||
void
|
||||
tpdu_write_connection_request(STREAM* s, uint16 length);
|
||||
uint8
|
||||
tpdu_read_connection_confirm(STREAM* s);
|
||||
void
|
||||
tpdu_write_disconnect_request(STREAM* s, uint16 length);
|
||||
void
|
||||
tpdu_write_data(STREAM* s);
|
||||
uint8 tpdu_read_header(STREAM* s, uint8* code);
|
||||
void tpdu_write_header(STREAM* s, uint16 length, uint8 code);
|
||||
void tpdu_write_connection_request(STREAM* s, uint16 length);
|
||||
uint8 tpdu_read_connection_confirm(STREAM* s);
|
||||
void tpdu_write_disconnect_request(STREAM* s, uint16 length);
|
||||
uint16 tpdu_read_data(STREAM* s);
|
||||
void tpdu_write_data(STREAM* s);
|
||||
|
||||
#endif /* __TPDU_H */
|
||||
|
|
Loading…
Reference in New Issue