From c08fef7d33883643974ba7284b57665dfe01b060 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Mon, 22 Aug 2011 15:03:58 +0800 Subject: [PATCH] libfreerdp-core: change client connection sequence using nonblocking. --- libfreerdp-core/activation.c | 65 +++++----------- libfreerdp-core/activation.h | 15 ++-- libfreerdp-core/capabilities.c | 36 +++++---- libfreerdp-core/capabilities.h | 5 +- libfreerdp-core/connection.c | 164 ++++++++++++++++++++++++++++++++++++++--- libfreerdp-core/connection.h | 8 +- libfreerdp-core/gcc.c | 49 ++++++++---- libfreerdp-core/gcc.h | 12 +-- libfreerdp-core/info.c | 4 +- libfreerdp-core/info.h | 2 +- libfreerdp-core/license.c | 56 +++++++------- libfreerdp-core/license.h | 6 +- libfreerdp-core/mcs.c | 116 +++++++++++------------------ libfreerdp-core/mcs.h | 16 ++-- libfreerdp-core/nego.c | 4 +- libfreerdp-core/nego.h | 2 +- libfreerdp-core/peer.c | 2 +- libfreerdp-core/rdp.c | 122 ++++++++++++++++-------------- libfreerdp-core/rdp.h | 8 +- 19 files changed, 406 insertions(+), 286 deletions(-) diff --git a/libfreerdp-core/activation.c b/libfreerdp-core/activation.c index 94380fc..510f748 100644 --- a/libfreerdp-core/activation.c +++ b/libfreerdp-core/activation.c @@ -28,27 +28,15 @@ uint8 CTRLACTION_STRINGS[][32] = "CTRLACTION_COOPERATE" }; -boolean rdp_client_activate(rdpRdp* rdp) -{ - while (rdp->activated != True) - { - rdp_recv(rdp); - } - - printf("client is activated\n"); - - return True; -} - void rdp_write_synchronize_pdu(STREAM* s, rdpSettings* settings) { stream_write_uint16(s, SYNCMSGTYPE_SYNC); /* messageType (2 bytes) */ stream_write_uint16(s, settings->pdu_source); /* targetUser (2 bytes) */ } -void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) +boolean rdp_read_server_synchronize_pdu(rdpRdp* rdp, STREAM* s) { - rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE); + return True; } boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp) @@ -87,9 +75,7 @@ boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp) rdp_write_synchronize_pdu(s, rdp->settings); - rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id); - - return True; + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id); } boolean rdp_read_control_pdu(STREAM* s, uint16* action) @@ -111,29 +97,13 @@ void rdp_write_client_control_pdu(STREAM* s, uint16 action) stream_write_uint32(s, 0); /* controlId (4 bytes) */ } -void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) +boolean rdp_read_server_control_pdu(rdpRdp* rdp, STREAM* s) { uint16 action; rdp_read_control_pdu(s, &action); - if (action == CTRLACTION_COOPERATE) - { - rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL); - } - else if (action == CTRLACTION_GRANTED_CONTROL) - { - if (rdp->settings->rdp_version >= 5) - { - //rdp_send_client_persistent_key_list_pdu(rdp); - rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST); - } - else - { - rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST); - rdp_send_client_font_list_pdu(rdp, FONTLIST_LAST); - } - } + return True; } boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp) @@ -166,7 +136,7 @@ boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp) return True; } -void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action) +boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action) { STREAM* s; @@ -174,7 +144,7 @@ void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action) rdp_write_client_control_pdu(s, action); - rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id); } void rdp_write_persistent_list_entry(STREAM* s, uint32 key1, uint32 key2) @@ -202,7 +172,7 @@ void rdp_write_client_persistent_key_list_pdu(STREAM* s, rdpSettings* settings) /* entries */ } -void rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) +boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) { STREAM* s; @@ -210,7 +180,7 @@ void rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp) rdp_write_client_persistent_key_list_pdu(s, rdp->settings); - rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id); + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id); } boolean rdp_read_client_font_list_pdu(STREAM* s) @@ -229,7 +199,7 @@ void rdp_write_client_font_list_pdu(STREAM* s, uint16 flags) stream_write_uint16(s, 50); /* entrySize (2 bytes) */ } -void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags) +boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags) { STREAM* s; @@ -237,15 +207,12 @@ void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags) rdp_write_client_font_list_pdu(s, flags); - rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id); + return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id); } -void rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings) +boolean rdp_read_server_font_map_pdu(rdpRdp* rdp, STREAM* s) { - rdp->activated = True; - update_reset_state(rdp->update); - rdp->update->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE; - IFCALL(rdp->update->SwitchSurface, rdp->update, &(rdp->update->switch_surface)); + return True; } boolean rdp_send_server_font_map_pdu(rdpRdp* rdp) @@ -264,7 +231,7 @@ boolean rdp_send_server_font_map_pdu(rdpRdp* rdp) return True; } -void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) +boolean rdp_read_deactivate_all(rdpRdp* rdp, STREAM* s) { uint16 lengthSourceDescriptor; @@ -274,7 +241,9 @@ void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s) stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */ - rdp->activated = False; + rdp->state = CONNECTION_STATE_CAPABILITY; + + return True; } boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s) diff --git a/libfreerdp-core/activation.h b/libfreerdp-core/activation.h index 5df1cbd..a9035a1 100644 --- a/libfreerdp-core/activation.h +++ b/libfreerdp-core/activation.h @@ -38,22 +38,21 @@ #define FONTLIST_FIRST 0x0001 #define FONTLIST_LAST 0x0002 -boolean rdp_client_activate(rdpRdp* rdp); -void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s); +boolean rdp_read_deactivate_all(rdpRdp* rdp, STREAM* s); -void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); +boolean rdp_read_server_synchronize_pdu(rdpRdp* rdp, STREAM* s); boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp); boolean rdp_read_client_synchronize_pdu(STREAM* s); boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp); boolean rdp_read_control_pdu(STREAM* s, uint16* action); -void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); +boolean rdp_read_server_control_pdu(rdpRdp* rdp, STREAM* s); boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp); boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp); -void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action); -void rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp); +boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action); +boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp); boolean rdp_read_client_font_list_pdu(STREAM* s); -void rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags); -void rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings); +boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags); +boolean rdp_read_server_font_map_pdu(rdpRdp* rdp, STREAM* s); boolean rdp_send_server_font_map_pdu(rdpRdp* rdp); boolean rdp_server_accept_client_control_pdu(rdpRdp* rdp, STREAM* s); diff --git a/libfreerdp-core/capabilities.c b/libfreerdp-core/capabilities.c index 02a6cd3..e78bc71 100644 --- a/libfreerdp-core/capabilities.c +++ b/libfreerdp-core/capabilities.c @@ -1576,15 +1576,29 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number return True; } -void rdp_read_demand_active(STREAM* s, rdpSettings* settings) +boolean rdp_read_demand_active(rdpRdp* rdp, STREAM* s) { + uint16 length; + uint16 channelId; + uint16 pduType; + uint16 pduLength; uint16 numberCapabilities; uint16 lengthSourceDescriptor; uint16 lengthCombinedCapabilities; + if (!rdp_read_header(rdp, s, &length, &channelId)) + return False; + if (channelId != MCS_GLOBAL_CHANNEL_ID) + return False; + + if (!rdp_read_share_control_header(s, &pduLength, &pduType, &rdp->settings->pdu_source)) + return False; + if (pduType != PDU_TYPE_DEMAND_ACTIVE) + return False; + //printf("Demand Active PDU\n"); - stream_read_uint32(s, settings->share_id); /* shareId (4 bytes) */ + stream_read_uint32(s, rdp->settings->share_id); /* shareId (4 bytes) */ stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */ stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */ stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */ @@ -1592,18 +1606,12 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings) stream_seek(s, 2); /* pad2Octets (2 bytes) */ /* capabilitySets */ - rdp_read_capability_sets(s, settings, numberCapabilities); -} - -void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings) -{ - rdp_read_demand_active(s, settings); - - rdp->update->glyph_v2 = (settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False; + if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities)) + return False; - rdp_send_confirm_active(rdp); + rdp->update->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False; - rdp_send_client_synchronize_pdu(rdp); + return True; } void rdp_write_demand_active(STREAM* s, rdpSettings* settings) @@ -1803,7 +1811,7 @@ void rdp_write_confirm_active(STREAM* s, rdpSettings* settings) stream_set_mark(s, em); } -void rdp_send_confirm_active(rdpRdp* rdp) +boolean rdp_send_confirm_active(rdpRdp* rdp) { STREAM* s; @@ -1811,6 +1819,6 @@ void rdp_send_confirm_active(rdpRdp* rdp) rdp_write_confirm_active(s, rdp->settings); - rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); + return rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->user_id); } diff --git a/libfreerdp-core/capabilities.h b/libfreerdp-core/capabilities.h index cc7473c..677bed9 100644 --- a/libfreerdp-core/capabilities.h +++ b/libfreerdp-core/capabilities.h @@ -163,12 +163,11 @@ #define CLW_ENTROPY_RLGR1 0x01 #define CLW_ENTROPY_RLGR3 0x04 -void rdp_read_demand_active(STREAM* s, rdpSettings* settings); -void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings); +boolean rdp_read_demand_active(rdpRdp* rdp, STREAM* s); void rdp_write_demand_active(STREAM* s, rdpSettings* settings); boolean rdp_send_demand_active(rdpRdp* rdp); boolean rdp_read_confirm_active(rdpRdp* rdp, STREAM* s); void rdp_write_confirm_active(STREAM* s, rdpSettings* settings); -void rdp_send_confirm_active(rdpRdp* rdp); +boolean rdp_send_confirm_active(rdpRdp* rdp); #endif /* __CAPABILITIES_H */ diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index b330a0d..a864180 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -86,24 +86,168 @@ boolean rdp_client_connect(rdpRdp* rdp) if (!ret) return False; - if (mcs_connect(rdp->mcs) != True) + rdp_set_blocking_mode(rdp, False); + rdp->state = CONNECTION_STATE_NEGO; + + if (!mcs_send_connect_initial(rdp->mcs)) { - printf("Error: Multipoint Connection Service (MCS) connection failure\n"); + printf("Error: unable to send MCS Connect Initial\n"); return False; } - rdp_send_client_info(rdp); + while (rdp->state != CONNECTION_STATE_ACTIVE) + { + if (rdp_check_fds(rdp) < 0) + return False; + } + + return True; +} + +boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_read_connect_response(rdp->mcs, s)) + return False; + + if (!mcs_send_erect_domain_request(rdp->mcs)) + return False; + if (!mcs_send_attach_user_request(rdp->mcs)) + return False; + + rdp->state = CONNECTION_STATE_MCS_ATTACH_USER; + + return True; +} + +boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s) +{ + if (!mcs_read_attach_user_confirm(rdp->mcs, s)) + return False; + + if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->user_id)) + return False; + + rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN; + + return True; +} + +boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s) +{ + int i; + uint16 channel_id; + boolean all_joined = True; + + if (!mcs_read_channel_join_confirm(rdp->mcs, s, &channel_id)) + return False; + + if (!rdp->mcs->user_channel_joined) + { + if (channel_id != rdp->mcs->user_id) + return False; + rdp->mcs->user_channel_joined = True; + + if (!mcs_send_channel_join_request(rdp->mcs, MCS_GLOBAL_CHANNEL_ID)) + return False; + } + else if (!rdp->mcs->global_channel_joined) + { + if (channel_id != MCS_GLOBAL_CHANNEL_ID) + return False; + rdp->mcs->global_channel_joined = True; + + if (rdp->settings->num_channels > 0) + { + if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[0].chan_id)) + return False; + + all_joined = False; + } + } + else + { + for (i = 0; i < rdp->settings->num_channels; i++) + { + if (rdp->settings->channels[i].joined) + continue; + + if (rdp->settings->channels[i].chan_id != channel_id) + return False; - if (license_connect(rdp->license) != True) + rdp->settings->channels[i].joined = True; + break; + } + if (i + 1 < rdp->settings->num_channels) + { + if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[i + 1].chan_id)) + return False; + + all_joined = False; + } + } + + if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined) { - printf("Error: license connection sequence failure\n"); + if (!rdp_send_client_info(rdp)) + return False; + rdp->state = CONNECTION_STATE_LICENSE; + } + + return True; +} + +boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s) +{ + if (!license_read(rdp->license, s)) + return False; + + if (rdp->license->state == LICENSE_STATE_ABORTED) + { + printf("license connection sequence aborted.\n"); return False; } - rdp->licensed = True; + if (rdp->license->state == LICENSE_STATE_COMPLETED) + { + printf("license connection sequence completed.\n"); - rdp_client_activate(rdp); - rdp_set_blocking_mode(rdp, False); + rdp->state = CONNECTION_STATE_CAPABILITY; + } + + return True; +} + +boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s) +{ + if (!rdp_read_demand_active(rdp, s)) + return False; + + if (!rdp_send_confirm_active(rdp)) + return False; + + /** + * [MS-RDPBCGR] 1.3.1.1 - 8. + * The client-to-server PDUs sent during this phase have no dependencies on any of the server-to- + * client PDUs; they may be sent as a single batch, provided that sequencing is maintained. + */ + if (!rdp_send_client_synchronize_pdu(rdp)) + return False; + if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE)) + return False; + if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL)) + return False; + if (!rdp_send_client_persistent_key_list_pdu(rdp)) + return False; + if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST)) + return False; + + rdp->state = CONNECTION_STATE_ACTIVE; + + update_reset_state(rdp->update); + rdp->update->switch_surface.bitmapId = SCREEN_BITMAP_SURFACE; + IFCALL(rdp->update->SwitchSurface, rdp->update, &(rdp->update->switch_surface)); + + printf("client is activated\n"); return True; } @@ -114,7 +258,7 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) transport_set_blocking_mode(rdp->transport, True); - if (!nego_recv_request(rdp->nego, s)) + if (!nego_read_request(rdp->nego, s)) return False; if (rdp->nego->requested_protocols == PROTOCOL_RDP) { @@ -240,7 +384,7 @@ boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s) } if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined) - rdp->state = CONNECTION_STATE_CHANNEL_JOIN; + rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN; return True; } diff --git a/libfreerdp-core/connection.h b/libfreerdp-core/connection.h index a69f7c6..c761da6 100644 --- a/libfreerdp-core/connection.h +++ b/libfreerdp-core/connection.h @@ -38,12 +38,18 @@ enum CONNECTION_STATE CONNECTION_STATE_MCS_CONNECT, CONNECTION_STATE_MCS_ERECT_DOMAIN, CONNECTION_STATE_MCS_ATTACH_USER, - CONNECTION_STATE_CHANNEL_JOIN, + CONNECTION_STATE_MCS_CHANNEL_JOIN, CONNECTION_STATE_LICENSE, + CONNECTION_STATE_CAPABILITY, CONNECTION_STATE_ACTIVE }; boolean rdp_client_connect(rdpRdp* rdp); +boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s); +boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s); boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s); boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s); diff --git a/libfreerdp-core/gcc.c b/libfreerdp-core/gcc.c index 094e5e5..289afba 100644 --- a/libfreerdp-core/gcc.c +++ b/libfreerdp-core/gcc.c @@ -215,7 +215,7 @@ void gcc_write_conference_create_request(STREAM* s, STREAM* user_data) 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, rdpSettings* settings) +boolean gcc_read_conference_create_response(STREAM* s, rdpSettings* settings) { uint16 length; uint32 tag; @@ -254,7 +254,10 @@ void gcc_read_conference_create_response(STREAM* s, rdpSettings* settings) /* userData (OCTET_STRING) */ per_read_length(s, &length); - gcc_read_server_data_blocks(s, settings, length); + if (!gcc_read_server_data_blocks(s, settings, length)) + return False; + + return True; } void gcc_write_conference_create_response(STREAM* s, STREAM* user_data) @@ -349,7 +352,7 @@ void gcc_write_client_data_blocks(STREAM* s, rdpSettings *settings) gcc_write_client_monitor_data(s, settings); } -void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length) +boolean gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length) { uint16 type; uint16 offset = 0; @@ -357,20 +360,24 @@ void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length) while (offset < length) { - gcc_read_user_data_header(s, &type, &blockLength); + if (!gcc_read_user_data_header(s, &type, &blockLength)) + return False; switch (type) { case SC_CORE: - gcc_read_server_core_data(s, settings); + if (!gcc_read_server_core_data(s, settings)) + return False; break; case SC_SECURITY: - gcc_read_server_security_data(s, settings); + if (!gcc_read_server_security_data(s, settings)) + return False; break; case SC_NET: - gcc_read_server_network_data(s, settings); + if (!gcc_read_server_network_data(s, settings)) + return False; break; default: @@ -379,6 +386,8 @@ void gcc_read_server_data_blocks(STREAM* s, rdpSettings *settings, int length) offset += blockLength; } + + return True; } void gcc_write_server_data_blocks(STREAM* s, rdpSettings *settings) @@ -388,10 +397,15 @@ void gcc_write_server_data_blocks(STREAM* s, rdpSettings *settings) gcc_write_server_security_data(s, settings); } -void gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length) +boolean gcc_read_user_data_header(STREAM* s, uint16* type, uint16* length) { stream_read_uint16(s, *type); /* type */ stream_read_uint16(s, *length); /* length */ + + if (stream_get_left(s) < *length - 4) + return False; + + return True; } /** @@ -661,7 +675,7 @@ void gcc_write_client_core_data(STREAM* s, rdpSettings *settings) stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */ } -void gcc_read_server_core_data(STREAM* s, rdpSettings *settings) +boolean gcc_read_server_core_data(STREAM* s, rdpSettings *settings) { uint32 version; uint32 clientRequestedProtocols; @@ -673,6 +687,8 @@ void gcc_read_server_core_data(STREAM* s, rdpSettings *settings) settings->rdp_version = 4; else if (version == RDP_VERSION_5_PLUS && settings->rdp_version < 5) settings->rdp_version = 7; + + return True; } void gcc_write_server_core_data(STREAM* s, rdpSettings *settings) @@ -726,7 +742,7 @@ void gcc_write_client_security_data(STREAM* s, rdpSettings *settings) } } -void gcc_read_server_security_data(STREAM* s, rdpSettings *settings) +boolean gcc_read_server_security_data(STREAM* s, rdpSettings *settings) { uint32 encryptionMethod; uint32 encryptionLevel; @@ -735,15 +751,16 @@ void gcc_read_server_security_data(STREAM* s, rdpSettings *settings) stream_read_uint32(s, encryptionMethod); /* encryptionMethod */ stream_read_uint32(s, encryptionLevel); /* encryptionLevel */ - stream_read_uint32(s, serverRandomLen); /* serverRandomLen */ - stream_read_uint32(s, serverCertLen); /* serverCertLen */ if (encryptionMethod == 0 && encryptionLevel == 0) { /* serverRandom and serverRandom must not be present */ - return; + return True; } + stream_read_uint32(s, serverRandomLen); /* serverRandomLen */ + stream_read_uint32(s, serverCertLen); /* serverCertLen */ + if (serverRandomLen > 0) { /* serverRandom */ @@ -759,6 +776,8 @@ void gcc_read_server_security_data(STREAM* s, rdpSettings *settings) memcpy(settings->server_certificate.data, s->p, serverCertLen); stream_seek(s, serverCertLen); } + + return True; } void gcc_write_server_security_data(STREAM* s, rdpSettings *settings) @@ -834,7 +853,7 @@ void gcc_write_client_network_data(STREAM* s, rdpSettings *settings) } } -void gcc_read_server_network_data(STREAM* s, rdpSettings *settings) +boolean gcc_read_server_network_data(STREAM* s, rdpSettings *settings) { int i; uint16 MCSChannelId; @@ -858,6 +877,8 @@ void gcc_read_server_network_data(STREAM* s, rdpSettings *settings) if (channelCount % 2 == 1) stream_seek(s, 2); /* padding */ + + return True; } void gcc_write_server_network_data(STREAM* s, rdpSettings *settings) diff --git a/libfreerdp-core/gcc.h b/libfreerdp-core/gcc.h index 9ee45f6..8d6d598 100644 --- a/libfreerdp-core/gcc.h +++ b/libfreerdp-core/gcc.h @@ -102,25 +102,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); +boolean 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); +boolean 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); +boolean 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); +boolean 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); +boolean 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); +boolean 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); diff --git a/libfreerdp-core/info.c b/libfreerdp-core/info.c index 5da1daf..ea7737c 100644 --- a/libfreerdp-core/info.c +++ b/libfreerdp-core/info.c @@ -578,7 +578,7 @@ boolean rdp_read_client_info(rdpRdp* rdp, STREAM* s) * @param rdp RDP module */ -void rdp_send_client_info(rdpRdp* rdp) +boolean rdp_send_client_info(rdpRdp* rdp) { STREAM* s; @@ -587,7 +587,7 @@ void rdp_send_client_info(rdpRdp* rdp) rdp_write_security_header(s, SEC_INFO_PKT); rdp_write_info_packet(s, rdp->settings); - rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); + return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID); } void rdp_recv_logon_info_v1(rdpRdp* rdp, STREAM* s) diff --git a/libfreerdp-core/info.h b/libfreerdp-core/info.h index f7e890c..e563287 100644 --- a/libfreerdp-core/info.h +++ b/libfreerdp-core/info.h @@ -84,7 +84,7 @@ void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings); boolean rdp_read_info_packet(STREAM* s, rdpSettings* settings); void rdp_write_info_packet(STREAM* s, rdpSettings* settings); boolean rdp_read_client_info(rdpRdp* rdp, STREAM* s); -void rdp_send_client_info(rdpRdp* rdp); +boolean rdp_send_client_info(rdpRdp* rdp); void rdp_recv_save_session_info(rdpRdp* rdp, STREAM* s); #endif /* __INFO_H */ diff --git a/libfreerdp-core/license.c b/libfreerdp-core/license.c index 8d6d714..96f0703 100644 --- a/libfreerdp-core/license.c +++ b/libfreerdp-core/license.c @@ -64,33 +64,6 @@ uint8 state_transitions[][32] = }; /** - * Perform licensing phase of connection sequence.\n - * @param license license module - * @return - */ - -boolean license_connect(rdpLicense* license) -{ - while (1) - { - rdp_recv(license->rdp); - - if (license->state == LICENSE_STATE_COMPLETED) - { - printf("license connection sequence completed.\n"); - return True; - } - else if (license->state == LICENSE_STATE_ABORTED) - { - printf("license connection sequence aborted.\n"); - return False; - } - } - - return False; -} - -/** * Read a licensing preamble.\n * @msdn{cc240480} * @param s stream @@ -145,7 +118,7 @@ STREAM* license_send_stream_init(rdpLicense* license) * @param s stream */ -void license_send(rdpLicense* license, STREAM* s, uint8 type) +boolean license_send(rdpLicense* license, STREAM* s, uint8 type) { int length; uint8 flags; @@ -175,7 +148,10 @@ void license_send(rdpLicense* license, STREAM* s, uint8 type) #endif stream_set_pos(s, length); - transport_write(license->rdp->transport, s); + if (transport_write(license->rdp->transport, s) < 0) + return False; + + return True; } /** @@ -185,12 +161,28 @@ void license_send(rdpLicense* license, STREAM* s, uint8 type) * @param s stream */ -void license_recv(rdpLicense* license, STREAM* s) +boolean license_read(rdpLicense* license, STREAM* s) { + uint16 length; + uint16 channelId; + uint16 sec_flags; uint8 flags; uint8 bMsgType; uint16 wMsgSize; + if (!rdp_read_header(license->rdp, s, &length, &channelId)) + { + printf("Incorrect RDP header.\n"); + return False; + } + + rdp_read_security_header(s, &sec_flags); + if (!(sec_flags & SEC_LICENSE_PKT)) + { + printf("Unexpected license packet.\n"); + return False; + } + license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */ DEBUG_LICENSE("Receiving %s Packet", LICENSE_MESSAGE_STRINGS[bMsgType & 0x1F]); @@ -221,8 +213,10 @@ void license_recv(rdpLicense* license, STREAM* s) default: printf("invalid bMsgType:%d\n", bMsgType); - break; + return False; } + + return True; } void license_generate_randoms(rdpLicense* license) diff --git a/libfreerdp-core/license.h b/libfreerdp-core/license.h index a1b3993..54e3105 100644 --- a/libfreerdp-core/license.h +++ b/libfreerdp-core/license.h @@ -156,10 +156,8 @@ struct rdp_license SCOPE_LIST* scope_list; }; -boolean license_connect(rdpLicense* license); - -void license_send(rdpLicense* license, STREAM* s, uint8 type); -void license_recv(rdpLicense* license, STREAM* s); +boolean license_read(rdpLicense* license, STREAM* s); +boolean license_send(rdpLicense* license, STREAM* s, uint8 type); STREAM* license_send_stream_init(rdpLicense* license); void license_generate_randoms(rdpLicense* license); diff --git a/libfreerdp-core/mcs.c b/libfreerdp-core/mcs.c index 28956a9..33315f9 100644 --- a/libfreerdp-core/mcs.c +++ b/libfreerdp-core/mcs.c @@ -176,43 +176,6 @@ uint8 mcs_result_enumerated[16][32] = }; /** - * MCS Connection Sequence. - * @param mcs mcs module - * @return - */ - -boolean mcs_connect(rdpMcs* mcs) -{ - int i; - uint16 channelId; - rdpSettings* settings; - - settings = mcs->transport->settings; - - mcs_send_connect_initial(mcs); - mcs_recv_connect_response(mcs); - - mcs_send_erect_domain_request(mcs); - mcs_send_attach_user_request(mcs); - mcs_recv_attach_user_confirm(mcs); - - mcs_send_channel_join_request(mcs, mcs->user_id); - mcs_recv_channel_join_confirm(mcs); - - mcs_send_channel_join_request(mcs, MCS_GLOBAL_CHANNEL_ID); - mcs_recv_channel_join_confirm(mcs); - - for (i = 0; i < settings->num_channels; i++) - { - channelId = settings->channels[i].chan_id; - mcs_send_channel_join_request(mcs, channelId); - mcs_recv_channel_join_confirm(mcs); - } - - return True; -} - -/** * Read a DomainMCSPDU header. * @param s stream * @param domainMCSPDU DomainMCSPDU type @@ -283,7 +246,7 @@ static void mcs_init_domain_parameters(DomainParameters* domainParameters, * @param domainParameters domain parameters */ -void mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters) +boolean mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters) { int length; ber_read_sequence_tag(s, &length); @@ -295,6 +258,8 @@ void mcs_read_domain_parameters(STREAM* s, DomainParameters* domainParameters) ber_read_integer(s, &(domainParameters->maxHeight)); ber_read_integer(s, &(domainParameters->maxMCSPDUsize)); ber_read_integer(s, &(domainParameters->protocolVersion)); + + return True; } /** @@ -488,13 +453,14 @@ void mcs_write_connect_response(STREAM* s, rdpMcs* mcs, STREAM* user_data) * @param mcs mcs module */ -void mcs_send_connect_initial(rdpMcs* mcs) +boolean mcs_send_connect_initial(rdpMcs* mcs) { STREAM* s; int length; uint8 *bm, *em; STREAM* gcc_CCrq; STREAM* client_data; + int status; client_data = stream_new(512); gcc_write_client_data_blocks(client_data, mcs->transport->settings); @@ -516,42 +482,44 @@ void mcs_send_connect_initial(rdpMcs* mcs) tpdu_write_data(s); stream_set_mark(s, em); - transport_write(mcs->transport, s); + status = transport_write(mcs->transport, s); stream_free(gcc_CCrq); stream_free(client_data); + + return (status < 0 ? False : True); } /** - * Receive MCS Connect Response.\n + * Read MCS Connect Response.\n * @msdn{cc240501} * @param mcs mcs module */ -void mcs_recv_connect_response(rdpMcs* mcs) +boolean mcs_read_connect_response(rdpMcs* mcs, STREAM* s) { - STREAM* s; int length; uint8 result; uint32 calledConnectId; - s = transport_recv_stream_init(mcs->transport, 1024); - transport_read(mcs->transport, s); - tpkt_read_header(s); if (tpdu_read_data(s) == 0) - return; + return False; ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length); ber_read_enumerated(s, &result, MCS_Result_enum_length); ber_read_integer(s, &calledConnectId); - mcs_read_domain_parameters(s, &(mcs->domainParameters)); + if (!mcs_read_domain_parameters(s, &(mcs->domainParameters))) + return False; ber_read_octet_string(s, &length); - gcc_read_conference_create_response(s, mcs->transport->settings); + if (!gcc_read_conference_create_response(s, mcs->transport->settings)) + return False; + + return True; } /** @@ -621,7 +589,7 @@ boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s) * @param mcs */ -void mcs_send_erect_domain_request(rdpMcs* mcs) +boolean mcs_send_erect_domain_request(rdpMcs* mcs) { STREAM* s; uint16 length = 12; @@ -632,7 +600,10 @@ void mcs_send_erect_domain_request(rdpMcs* mcs) per_write_integer(s, 0); /* subHeight (INTEGER) */ per_write_integer(s, 0); /* subInterval (INTEGER) */ - transport_write(mcs->transport, s); + if (transport_write(mcs->transport, s) < 0) + return False; + + return True; } /** @@ -660,7 +631,7 @@ boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s) * @param mcs mcs module */ -void mcs_send_attach_user_request(rdpMcs* mcs) +boolean mcs_send_attach_user_request(rdpMcs* mcs) { STREAM* s; uint16 length = 8; @@ -668,30 +639,32 @@ void mcs_send_attach_user_request(rdpMcs* mcs) mcs_write_domain_mcspdu_header(s, DomainMCSPDU_AttachUserRequest, length, 0); - transport_write(mcs->transport, s); + if (transport_write(mcs->transport, s) < 0) + return False; + + return True; } /** - * Receive MCS Attach User Confirm.\n + * Read MCS Attach User Confirm.\n * @msdn{cc240525} * @param mcs mcs module */ -void mcs_recv_attach_user_confirm(rdpMcs* mcs) +boolean mcs_read_attach_user_confirm(rdpMcs* mcs, STREAM* s) { - STREAM* s; uint16 length; uint8 result; enum DomainMCSPDU MCSPDU; - s = transport_recv_stream_init(mcs->transport, 32); - transport_read(mcs->transport, s); - MCSPDU = DomainMCSPDU_AttachUserConfirm; - mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return False; per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ per_read_integer16(s, &(mcs->user_id), MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ + + return True; } /** @@ -752,7 +725,7 @@ boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id * @param channel_id channel id */ -void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id) +boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id) { STREAM* s; uint16 length = 12; @@ -763,35 +736,36 @@ void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id) per_write_integer16(s, mcs->user_id, MCS_BASE_CHANNEL_ID); per_write_integer16(s, channel_id, 0); - transport_write(mcs->transport, s); + if (transport_write(mcs->transport, s) < 0) + return False; + + return True; } /** - * Receive MCS Channel Join Confirm.\n + * Read MCS Channel Join Confirm.\n * @msdn{cc240527} * @param mcs mcs module */ -void mcs_recv_channel_join_confirm(rdpMcs* mcs) +boolean mcs_read_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id) { - STREAM* s; uint16 length; uint8 result; uint16 initiator; uint16 requested; - uint16 channelId; enum DomainMCSPDU MCSPDU; - s = transport_recv_stream_init(mcs->transport, 32); - transport_read(mcs->transport, s); - MCSPDU = DomainMCSPDU_ChannelJoinConfirm; - mcs_read_domain_mcspdu_header(s, &MCSPDU, &length); + if (!mcs_read_domain_mcspdu_header(s, &MCSPDU, &length)) + return False; per_read_enumerated(s, &result, MCS_Result_enum_length); /* result */ per_read_integer16(s, &initiator, MCS_BASE_CHANNEL_ID); /* initiator (UserId) */ per_read_integer16(s, &requested, 0); /* requested (ChannelId) */ - per_read_integer16(s, &channelId, 0); /* channelId */ + per_read_integer16(s, channel_id, 0); /* channelId */ + + return True; } /** diff --git a/libfreerdp-core/mcs.h b/libfreerdp-core/mcs.h index 744d0b6..66e8b51 100644 --- a/libfreerdp-core/mcs.h +++ b/libfreerdp-core/mcs.h @@ -129,24 +129,22 @@ typedef struct rdp_mcs rdpMcs; #define MCS_TYPE_CONNECT_INITIAL 0x65 #define MCS_TYPE_CONNECT_RESPONSE 0x66 -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); -void mcs_recv_connect_response(rdpMcs* mcs); +boolean mcs_send_connect_initial(rdpMcs* mcs); +boolean mcs_read_connect_response(rdpMcs* mcs, STREAM* s); boolean mcs_send_connect_response(rdpMcs* mcs); boolean mcs_read_erect_domain_request(rdpMcs* mcs, STREAM* s); -void mcs_send_erect_domain_request(rdpMcs* mcs); +boolean mcs_send_erect_domain_request(rdpMcs* mcs); boolean mcs_read_attach_user_request(rdpMcs* mcs, STREAM* s); -void mcs_send_attach_user_request(rdpMcs* mcs); -void mcs_recv_attach_user_confirm(rdpMcs* mcs); +boolean mcs_send_attach_user_request(rdpMcs* mcs); +boolean mcs_read_attach_user_confirm(rdpMcs* mcs, STREAM* s); boolean mcs_send_attach_user_confirm(rdpMcs* mcs); boolean mcs_read_channel_join_request(rdpMcs* mcs, STREAM* s, uint16* channel_id); -void mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id); -void mcs_recv_channel_join_confirm(rdpMcs* mcs); +boolean mcs_send_channel_join_request(rdpMcs* mcs, uint16 channel_id); +boolean mcs_read_channel_join_confirm(rdpMcs* mcs, STREAM* s, uint16* channel_id); boolean mcs_send_channel_join_confirm(rdpMcs* mcs, uint16 channel_id); boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU, uint16* length); void mcs_write_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU domainMCSPDU, uint16 length, uint8 options); diff --git a/libfreerdp-core/nego.c b/libfreerdp-core/nego.c index 1fff545..2b92e0f 100644 --- a/libfreerdp-core/nego.c +++ b/libfreerdp-core/nego.c @@ -271,12 +271,12 @@ int nego_recv(rdpTransport* transport, STREAM* s, void* extra) } /** - * Receive protocol security negotiation request message.\n + * Read protocol security negotiation request message.\n * @param nego * @param s stream */ -boolean nego_recv_request(rdpNego* nego, STREAM* s) +boolean nego_read_request(rdpNego* nego, STREAM* s) { uint8 li; uint8 c; diff --git a/libfreerdp-core/nego.h b/libfreerdp-core/nego.h index 9db30dd..916e7f6 100644 --- a/libfreerdp-core/nego.h +++ b/libfreerdp-core/nego.h @@ -94,7 +94,7 @@ void nego_attempt_rdp(rdpNego* nego); void nego_send(rdpNego* nego); int nego_recv(rdpTransport* transport, STREAM* s, void* extra); void nego_recv_response(rdpNego* nego); -boolean nego_recv_request(rdpNego* nego, STREAM* s); +boolean nego_read_request(rdpNego* nego, STREAM* s); void nego_send_negotiation_request(rdpNego* nego); void nego_process_negotiation_request(rdpNego* nego, STREAM* s); diff --git a/libfreerdp-core/peer.c b/libfreerdp-core/peer.c index 3d4168e..36f3952 100644 --- a/libfreerdp-core/peer.c +++ b/libfreerdp-core/peer.c @@ -175,7 +175,7 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra) return -1; break; - case CONNECTION_STATE_CHANNEL_JOIN: + case CONNECTION_STATE_MCS_CHANNEL_JOIN: if (!rdp_server_accept_client_info(peer->rdp, s)) return -1; break; diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index d0acadc..8853bec 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -235,7 +235,7 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id) * @param channel_id channel id */ -void rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id) +boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id) { uint16 length; @@ -245,10 +245,13 @@ void rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id) rdp_write_header(rdp, s, length, channel_id); stream_set_pos(s, length); - transport_write(rdp->transport, s); + if (transport_write(rdp->transport, s) < 0) + return False; + + return True; } -void rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) +boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) { uint16 length; @@ -259,10 +262,13 @@ void rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id) rdp_write_share_control_header(s, length, type, channel_id); stream_set_pos(s, length); - transport_write(rdp->transport, s); + if (transport_write(rdp->transport, s) < 0) + return False; + + return True; } -void rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id) +boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id) { uint16 length; @@ -276,7 +282,10 @@ void rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id) //printf("send %s Data PDU (0x%02X), length:%d\n", DATA_PDU_TYPE_STRINGS[type], type, length); stream_set_pos(s, length); - transport_write(rdp->transport, s); + if (transport_write(rdp->transport, s) < 0) + return False; + + return True; } void rdp_read_set_error_info_data_pdu(STREAM* s) @@ -307,7 +316,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_CONTROL: - rdp_recv_server_control_pdu(rdp, s, rdp->settings); + rdp_read_server_control_pdu(rdp, s); break; case DATA_PDU_TYPE_POINTER: @@ -317,7 +326,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_SYNCHRONIZE: - rdp_recv_server_synchronize_pdu(rdp, s, rdp->settings); + rdp_read_server_synchronize_pdu(rdp, s); break; case DATA_PDU_TYPE_REFRESH_RECT: @@ -343,7 +352,7 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) break; case DATA_PDU_TYPE_FONT_MAP: - rdp_recv_server_font_map_pdu(rdp, s, rdp->settings); + rdp_read_server_font_map_pdu(rdp, s); break; case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS: @@ -391,49 +400,17 @@ void rdp_read_data_pdu(rdpRdp* rdp, STREAM* s) * @param s stream */ -static void rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s) +static boolean rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s) { uint16 length; uint16 pduType; uint16 pduLength; uint16 channelId; - uint16 sec_flags; - boolean processed; if (!rdp_read_header(rdp, s, &length, &channelId)) { printf("Incorrect RDP header.\n"); - return; - } - - if (rdp->licensed != True) - { - processed = False; - rdp_read_security_header(s, &sec_flags); - - if (sec_flags & SEC_PKT_MASK) - { - switch (sec_flags & SEC_PKT_MASK) - { - case SEC_LICENSE_PKT: - processed = True; - license_recv(rdp->license, s); - break; - - case SEC_REDIRECTION_PKT: - processed = True; - rdp_read_redirection_packet(rdp, s); - break; - - default: - break; - } - } - - if (processed) - return; - else - stream_rewind(s, 4); + return False; } if (channelId != MCS_GLOBAL_CHANNEL_ID) @@ -450,12 +427,9 @@ static void rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s) rdp_read_data_pdu(rdp, s); break; - case PDU_TYPE_DEMAND_ACTIVE: - rdp_recv_demand_active(rdp, s, rdp->settings); - break; - case PDU_TYPE_DEACTIVATE_ALL: - rdp_recv_deactivate_all(rdp, s); + if (!rdp_read_deactivate_all(rdp, s)) + return False; break; case PDU_TYPE_SERVER_REDIRECTION: @@ -467,9 +441,11 @@ static void rdp_read_tpkt_pdu(rdpRdp* rdp, STREAM* s) break; } } + + return True; } -static void rdp_read_fastpath_pdu(rdpRdp* rdp, STREAM* s) +static boolean rdp_read_fastpath_pdu(rdpRdp* rdp, STREAM* s) { uint16 length; @@ -477,7 +453,7 @@ static void rdp_read_fastpath_pdu(rdpRdp* rdp, STREAM* s) if (length > stream_get_size(s)) { printf("incorrect FastPath PDU header length %d\n", length); - return; + return False; } /* TODO: fipsInformation */ @@ -488,14 +464,16 @@ static void rdp_read_fastpath_pdu(rdpRdp* rdp, STREAM* s) } fastpath_recv_updates(rdp->fastpath, s); + + return True; } -static void rdp_read_pdu(rdpRdp* rdp, STREAM* s) +static boolean rdp_read_pdu(rdpRdp* rdp, STREAM* s) { if (tpkt_verify_header(s)) - rdp_read_tpkt_pdu(rdp, s); + return rdp_read_tpkt_pdu(rdp, s); else - rdp_read_fastpath_pdu(rdp, s); + return rdp_read_fastpath_pdu(rdp, s); } /** @@ -517,7 +495,42 @@ static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra) { rdpRdp* rdp = (rdpRdp*) extra; - rdp_read_pdu(rdp, s); + switch (rdp->state) + { + case CONNECTION_STATE_NEGO: + if (!rdp_client_connect_mcs_connect_response(rdp, s)) + return -1; + break; + + case CONNECTION_STATE_MCS_ATTACH_USER: + if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s)) + return -1; + break; + + case CONNECTION_STATE_MCS_CHANNEL_JOIN: + if (!rdp_client_connect_mcs_channel_join_confirm(rdp, s)) + return -1; + break; + + case CONNECTION_STATE_LICENSE: + if (!rdp_client_connect_license(rdp, s)) + return -1; + break; + + case CONNECTION_STATE_CAPABILITY: + if (!rdp_client_connect_demand_active(rdp, s)) + return -1; + break; + + case CONNECTION_STATE_ACTIVE: + if (!rdp_read_pdu(rdp, s)) + return -1; + break; + + default: + printf("Invalid state %d\n", rdp->state); + return -1; + } return 1; } @@ -557,7 +570,6 @@ rdpRdp* rdp_new(freerdp* instance) if (rdp != NULL) { - rdp->licensed = False; rdp->settings = settings_new(); rdp->transport = transport_new(rdp->settings); rdp->license = license_new(rdp); diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h index 8f49944..e362367 100644 --- a/libfreerdp-core/rdp.h +++ b/libfreerdp-core/rdp.h @@ -113,8 +113,6 @@ typedef struct rdp_rdp rdpRdp; struct rdp_rdp { - boolean licensed; - boolean activated; int state; struct rdp_mcs* mcs; struct rdp_nego* nego; @@ -142,12 +140,12 @@ boolean rdp_read_header(rdpRdp* rdp, STREAM* s, uint16* length, uint16* channel_ void rdp_write_header(rdpRdp* rdp, STREAM* s, uint16 length, uint16 channel_id); STREAM* rdp_pdu_init(rdpRdp* rdp); -void rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id); +boolean rdp_send_pdu(rdpRdp* rdp, STREAM* s, uint16 type, uint16 channel_id); STREAM* rdp_data_pdu_init(rdpRdp* rdp); -void rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id); +boolean rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, uint8 type, uint16 channel_id); -void rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id); +boolean rdp_send(rdpRdp* rdp, STREAM* s, uint16 channel_id); void rdp_recv(rdpRdp* rdp); int rdp_send_channel_data(rdpRdp* rdp, int channel_id, uint8* data, int size); -- 2.7.4