server: send MCS Connect Response PDU.

This commit is contained in:
Vic Lee 2011-08-19 23:56:47 +08:00
parent ccc86b8773
commit 0607a08b61
13 changed files with 186 additions and 2 deletions

View File

@ -170,6 +170,7 @@ struct rdp_settings
uint32 kbd_subtype;
uint32 kbd_fn_keys;
uint32 client_build;
uint32 requested_protocols;
uint32 selected_protocol;
uint32 encryption_method;
uint32 encryption_level;

View File

@ -251,6 +251,13 @@ boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count)
return True;
}
void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count)
{
ber_write_universal_tag(s, BER_TAG_ENUMERATED, False);
ber_write_length(s, 1);
stream_write_uint8(s, enumerated);
}
boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding)
{
ber_read_universal_tag(s, BER_TAG_BIT_STRING, False);

View File

@ -60,6 +60,7 @@ boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length);
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 count);
void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count);
boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc);
int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc);
int ber_skip_contextual_tag(int length);

View File

@ -182,6 +182,11 @@ boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
}
printf("\n");
if (!mcs_send_connect_response(rdp->mcs))
return False;
rdp->state = CONNECTION_STATE_MCS_CONNECT;
return True;
}

View File

@ -34,7 +34,8 @@
enum CONNECTION_STATE
{
CONNECTION_STATE_INITIAL = 0,
CONNECTION_STATE_NEGO
CONNECTION_STATE_NEGO,
CONNECTION_STATE_MCS_CONNECT
};
boolean rdp_client_connect(rdpRdp* rdp);

View File

@ -257,6 +257,40 @@ void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings)
gcc_read_server_data_blocks(s, settings, length);
}
void gcc_write_conference_create_response(STREAM* s, STREAM* user_data)
{
/* ConnectData */
per_write_choice(s, 0);
per_write_object_identifier(s, t124_02_98_oid);
/* ConnectData::connectPDU (OCTET_STRING) */
per_write_length(s, stream_get_length(user_data) + 2);
/* ConnectGCCPDU */
per_write_choice(s, 0x14);
/* ConferenceCreateResponse::nodeID (UserID) */
per_write_integer16(s, 0x79F3, 1001);
/* ConferenceCreateResponse::tag (INTEGER) */
per_write_integer(s, 1);
/* ConferenceCreateResponse::result (ENUMERATED) */
per_write_enumerated(s, 0, MCS_Result_enum_length);
/* number of UserData sets */
per_write_number_of_sets(s, 1);
/* UserData::value present + select h221NonStandard (1) */
per_write_choice(s, 0xC0);
/* h221NonStandard */
per_write_octet_string(s, h221_sc_key, 4, 4); /* h221NonStandard, server-to-client H.221 key, "McDn" */
/* userData (OCTET_STRING) */
per_write_octet_string(s, user_data->data, stream_get_length(user_data), 0); /* array of server data blocks */
}
boolean gcc_read_client_data_blocks(STREAM* s, rdpSettings *settings, int length)
{
uint16 type;
@ -347,6 +381,13 @@ void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length)
}
}
void gcc_write_server_data_blocks(STREAM* s, rdpSettings *settings)
{
gcc_write_server_core_data(s, settings);
gcc_write_server_network_data(s, settings);
gcc_write_server_security_data(s, settings);
}
void gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length)
{
stream_read_uint16(s, *type); /* type */
@ -390,7 +431,7 @@ boolean gcc_read_client_core_data(STREAM* s, rdpSettings *settings, uint16 block
return False;
stream_read_uint32(s, version); /* version */
settings->rdp_version = (version == RDP_VERSION_4 ? 5 : 4);
settings->rdp_version = (version == RDP_VERSION_4 ? 4 : 7);
stream_read_uint16(s, settings->width); /* desktopWidth */
stream_read_uint16(s, settings->height); /* desktopHeight */
@ -634,6 +675,14 @@ void gcc_read_server_core_data(STREAM* s, rdpSettings *settings)
settings->rdp_version = 7;
}
void gcc_write_server_core_data(STREAM* s, rdpSettings *settings)
{
gcc_write_user_data_header(s, SC_CORE, 12);
stream_write_uint32(s, settings->rdp_version == 4 ? RDP_VERSION_4 : RDP_VERSION_5_PLUS);
stream_write_uint32(s, settings->requested_protocols); /* clientRequestedProtocols */
}
/**
* Read a client security data block (TS_UD_CS_SEC).\n
* @msdn{cc240511}
@ -712,6 +761,18 @@ void gcc_read_server_security_data(STREAM* s, rdpSettings *settings)
}
}
void gcc_write_server_security_data(STREAM* s, rdpSettings *settings)
{
gcc_write_user_data_header(s, SC_SECURITY, 12);
stream_write_uint32(s, ENCRYPTION_METHOD_NONE); /* encryptionMethod */
stream_write_uint32(s, ENCRYPTION_LEVEL_NONE); /* encryptionLevel */
#if 0
stream_write_uint32(s, 0); /* serverRandomLen */
stream_write_uint32(s, 0); /* serverCertLen */
#endif
}
/**
* Read a client network data block (TS_UD_CS_NET).\n
* @msdn{cc240512}
@ -738,6 +799,7 @@ boolean gcc_read_client_network_data(STREAM* s, rdpSettings *settings, uint16 bl
/* CHANNEL_DEF */
stream_read(s, settings->channels[i].name, 8); /* name (8 bytes) */
stream_read_uint32(s, settings->channels[i].options); /* options (4 bytes) */
settings->channels[i].chan_id = MCS_GLOBAL_CHANNEL_ID + 1 + i;
}
return True;
@ -798,6 +860,24 @@ void gcc_read_server_network_data(STREAM* s, rdpSettings *settings)
stream_seek(s, 2); /* padding */
}
void gcc_write_server_network_data(STREAM* s, rdpSettings *settings)
{
int i;
gcc_write_user_data_header(s, SC_NET, 8 + settings->num_channels * 2 + (settings->num_channels % 2 == 1 ? 2 : 0));
stream_write_uint16(s, MCS_GLOBAL_CHANNEL_ID); /* MCSChannelId */
stream_write_uint16(s, settings->num_channels); /* channelCount */
for (i = 0; i < settings->num_channels; i++)
{
stream_write_uint16(s, settings->channels[i].chan_id);
}
if (settings->num_channels % 2 == 1)
stream_write_uint16(s, 0);
}
/**
* Read a client cluster data block (TS_UD_CS_CLUSTER).\n
* @msdn{cc240514}

View File

@ -103,20 +103,25 @@
boolean gcc_read_conference_create_request(STREAM* s, rdpSettings* settings);
void gcc_write_conference_create_request(STREAM* s, STREAM* user_data);
void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings);
void gcc_write_conference_create_response(STREAM* s, STREAM* user_data);
boolean gcc_read_client_data_blocks(STREAM* s, rdpSettings *settings, int length);
void gcc_write_client_data_blocks(STREAM* s, rdpSettings *settings);
void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length);
void gcc_write_server_data_blocks(STREAM* s, rdpSettings *settings);
void gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length);
void gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length);
boolean gcc_read_client_core_data(STREAM* s, rdpSettings *settings, uint16 blockLength);
void gcc_write_client_core_data(STREAM* s, rdpSettings *settings);
void gcc_read_server_core_data(STREAM* s, rdpSettings *settings);
void gcc_write_server_core_data(STREAM* s, rdpSettings *settings);
boolean gcc_read_client_security_data(STREAM* s, rdpSettings *settings, uint16 blockLength);
void gcc_write_client_security_data(STREAM* s, rdpSettings *settings);
void gcc_read_server_security_data(STREAM* s, rdpSettings *settings);
void gcc_write_server_security_data(STREAM* s, rdpSettings *settings);
boolean gcc_read_client_network_data(STREAM* s, rdpSettings *settings, uint16 blockLength);
void gcc_write_client_network_data(STREAM* s, rdpSettings *settings);
void gcc_read_server_network_data(STREAM* s, rdpSettings *settings);
void gcc_write_server_network_data(STREAM* s, rdpSettings *settings);
boolean gcc_read_client_cluster_data(STREAM* s, rdpSettings *settings, uint16 blockLength);
void gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings);
boolean gcc_read_client_monitor_data(STREAM* s, rdpSettings *settings, uint16 blockLength);

View File

@ -447,6 +447,41 @@ void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data)
stream_set_mark(s, em);
}
/**
* Write an MCS Connect Response PDU.\n
* @msdn{cc240508}
* @param s stream
* @param mcs MCS module
* @param user_data GCC Conference Create Response
*/
void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data)
{
int length;
uint8 *bm, *em;
int gcc_CCrsp_length = stream_get_length(user_data);
stream_get_mark(s, bm);
stream_seek(s, 3);
ber_write_enumerated(s, 0, MCS_Result_enum_length);
ber_write_integer(s, 0); /* calledConnectId */
mcs->domainParameters = mcs->targetParameters;
mcs_write_domain_parameters(s, &(mcs->domainParameters));
/* userData (OCTET_STRING) */
ber_write_octet_string(s, user_data->data, gcc_CCrsp_length);
stream_get_mark(s, em);
length = (em - bm) - 3;
stream_set_mark(s, bm);
ber_write_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, length);
stream_set_mark(s, em);
}
/**
* Send MCS Connect Initial.\n
* @msdn{cc240508}
@ -527,6 +562,37 @@ void mcs_recv_connect_response(rdpMcs* mcs)
boolean mcs_send_connect_response(rdpMcs* mcs)
{
STREAM* s;
int length;
uint8 *bm, *em;
STREAM* gcc_CCrsp;
STREAM* server_data;
server_data = stream_new(512);
gcc_write_server_data_blocks(server_data, mcs->transport->settings);
gcc_CCrsp = stream_new(512);
gcc_write_conference_create_response(gcc_CCrsp, server_data);
length = stream_get_length(gcc_CCrsp) + 7;
s = transport_send_stream_init(mcs->transport, 1024);
stream_get_mark(s, bm);
stream_seek(s, 7);
mcs_write_connect_response(s, mcs, gcc_CCrsp);
stream_get_mark(s, em);
length = (em - bm);
stream_set_mark(s, bm);
tpkt_write_header(s, length);
tpdu_write_data(s);
stream_set_mark(s, em);
transport_write(mcs->transport, s);
stream_free(gcc_CCrsp);
stream_free(server_data);
return True;
}

View File

@ -129,6 +129,7 @@ typedef struct rdp_mcs rdpMcs;
boolean mcs_connect(rdpMcs* mcs);
void mcs_write_connect_initial(STREAM* s, rdpMcs* mcs, STREAM* user_data);
void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data);
boolean mcs_read_connect_initial(rdpMcs* mcs, STREAM* s);
void mcs_send_connect_initial(rdpMcs* mcs);

View File

@ -82,6 +82,7 @@ boolean nego_connect(rdpNego* nego)
DEBUG_NEGO("Negotiated %s security", PROTOCOL_SECURITY_STRINGS[nego->selected_protocol]);
/* update settings with negotiated protocol security */
nego->transport->settings->requested_protocols = nego->requested_protocols;
nego->transport->settings->selected_protocol = nego->selected_protocol;
return True;
@ -510,6 +511,7 @@ void nego_send_negotiation_response(rdpNego* nego)
transport_write(nego->transport, s);
/* update settings with negotiated protocol security */
nego->transport->settings->requested_protocols = nego->requested_protocols;
nego->transport->settings->selected_protocol = nego->selected_protocol;
}

View File

@ -259,6 +259,19 @@ boolean per_read_enumerated(STREAM* s, uint8* enumerated, uint8 count)
return True;
}
/**
* Write PER ENUMERATED.
* @param s stream
* @param enumerated enumerated
* @param count enumeration count
* @return
*/
void per_write_enumerated(STREAM* s, uint8 enumerated, uint8 count)
{
stream_write_uint8(s, enumerated);
}
/**
* Read PER OBJECT_IDENTIFIER (OID).
* @param s stream

View File

@ -37,6 +37,7 @@ boolean per_read_integer16(STREAM* s, uint16* integer, uint16 min);
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_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);

View File

@ -42,6 +42,7 @@ static void* test_peer_mainloop(void* arg)
client->settings->cert_file = xstrdup("server.crt");
client->settings->privatekey_file = xstrdup("server.key");
client->settings->nla_security = False;
client->Initialize(client);
while (1)