mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-12-05 07:43:58 +08:00
server: send MCS Connect Response PDU.
This commit is contained in:
parent
ccc86b8773
commit
0607a08b61
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user