libfreerdp-core: change client connection sequence using nonblocking.
This commit is contained in:
parent
00733ab128
commit
c08fef7d33
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
|
||||
return False;
|
||||
|
||||
void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings)
|
||||
{
|
||||
rdp_read_demand_active(s, settings);
|
||||
rdp->update->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False;
|
||||
|
||||
rdp->update->glyph_v2 = (settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False;
|
||||
|
||||
rdp_send_confirm_active(rdp);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -86,24 +86,168 @@ boolean rdp_client_connect(rdpRdp* rdp)
|
||||
if (!ret)
|
||||
return False;
|
||||
|
||||
if (mcs_connect(rdp->mcs) != True)
|
||||
{
|
||||
printf("Error: Multipoint Connection Service (MCS) connection failure\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
rdp_send_client_info(rdp);
|
||||
|
||||
if (license_connect(rdp->license) != True)
|
||||
{
|
||||
printf("Error: license connection sequence failure\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
rdp->licensed = True;
|
||||
|
||||
rdp_client_activate(rdp);
|
||||
rdp_set_blocking_mode(rdp, False);
|
||||
rdp->state = CONNECTION_STATE_NEGO;
|
||||
|
||||
if (!mcs_send_connect_initial(rdp->mcs))
|
||||
{
|
||||
printf("Error: unable to send MCS Connect Initial\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (rdp->license->state == LICENSE_STATE_COMPLETED)
|
||||
{
|
||||
printf("license connection sequence completed.\n");
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -63,33 +63,6 @@ uint8 state_transitions[][32] =
|
||||
"ST_RESEND_LAST_MESSAGE"
|
||||
};
|
||||
|
||||
/**
|
||||
* 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}
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -175,43 +175,6 @@ uint8 mcs_result_enumerated[16][32] =
|
||||
"rt-user-rejected"
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user