libfreerdp-core: fix race condition in connection finalization

This commit is contained in:
Marc-André Moreau 2011-12-18 15:15:48 -05:00
parent b913b1d1b8
commit 135503612d
5 changed files with 40 additions and 7 deletions

View File

@ -38,6 +38,7 @@ void rdp_write_synchronize_pdu(STREAM* s, rdpSettings* settings)
boolean rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s)
{
rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
return true;
}
@ -48,7 +49,6 @@ boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp)
s = rdp_data_pdu_init(rdp);
rdp_write_synchronize_pdu(s, rdp->settings);
rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->user_id);
return true;
@ -105,6 +105,17 @@ boolean rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s)
rdp_recv_control_pdu(s, &action);
switch (action)
{
case CTRLACTION_COOPERATE:
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_COOPERATE_PDU;
break;
case CTRLACTION_GRANTED_CONTROL:
rdp->finalize_sc_pdus |= FINALIZE_SC_CONTROL_GRANTED_PDU;
break;
}
return true;
}
@ -143,7 +154,6 @@ boolean rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action)
STREAM* s;
s = rdp_data_pdu_init(rdp);
rdp_write_client_control_pdu(s, action);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->user_id);
@ -179,7 +189,6 @@ boolean rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
STREAM* s;
s = rdp_data_pdu_init(rdp);
rdp_write_client_persistent_key_list_pdu(s, rdp->settings);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->user_id);
@ -206,7 +215,6 @@ boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags)
STREAM* s;
s = rdp_data_pdu_init(rdp);
rdp_write_client_font_list_pdu(s, flags);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->user_id);
@ -214,6 +222,7 @@ boolean rdp_send_client_font_list_pdu(rdpRdp* rdp, uint16 flags)
boolean rdp_recv_server_font_map_pdu(rdpRdp* rdp, STREAM* s)
{
rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
return true;
}

View File

@ -97,6 +97,7 @@ boolean rdp_client_connect(rdpRdp* rdp)
rdp_set_blocking_mode(rdp, false);
rdp->state = CONNECTION_STATE_NEGO;
rdp->finalize_sc_pdus = 0;
if (mcs_send_connect_initial(rdp->mcs) != true)
{
@ -390,6 +391,16 @@ boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
IFCALL(rdp->update->DesktopResize, rdp->update->context);
}
rdp->state = CONNECTION_STATE_FINALIZATION;
update_reset_state(rdp->update);
rdp_client_connect_finalize(rdp);
return true;
}
boolean rdp_client_connect_finalize(rdpRdp* rdp)
{
/**
* [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-
@ -407,9 +418,6 @@ boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
return false;
rdp->state = CONNECTION_STATE_ACTIVE;
update_reset_state(rdp->update);
return true;
}

View File

@ -41,6 +41,7 @@ enum CONNECTION_STATE
CONNECTION_STATE_MCS_CHANNEL_JOIN,
CONNECTION_STATE_LICENSE,
CONNECTION_STATE_CAPABILITY,
CONNECTION_STATE_FINALIZATION,
CONNECTION_STATE_ACTIVE
};
@ -51,6 +52,7 @@ 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_client_connect_finalize(rdpRdp* rdp);
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s);

View File

@ -760,6 +760,13 @@ static boolean rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra
}
break;
case CONNECTION_STATE_FINALIZATION:
if (!rdp_recv_pdu(rdp, s))
return false;
if (rdp->finalize_sc_pdus == FINALIZE_SC_COMPLETE)
rdp->state = CONNECTION_STATE_ACTIVE;
break;
case CONNECTION_STATE_ACTIVE:
if (!rdp_recv_pdu(rdp, s))
return false;

View File

@ -71,6 +71,12 @@
#define PDU_TYPE_DATA 0x7
#define PDU_TYPE_SERVER_REDIRECTION 0xA
#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01
#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02
#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04
#define FINALIZE_SC_FONT_MAP_PDU 0x08
#define FINALIZE_SC_COMPLETE 0x0F
/* Data PDU Types */
#define DATA_PDU_TYPE_UPDATE 0x02
#define DATA_PDU_TYPE_CONTROL 0x14
@ -147,6 +153,7 @@ struct rdp_rdp
uint8 fips_encrypt_key[24];
uint8 fips_decrypt_key[24];
uint32 errorInfo;
uint32 finalize_sc_pdus;
};
void rdp_read_security_header(STREAM* s, uint16* flags);