Merge pull request #11202 from akallabeth/rdp-teardown

[core,freerdp] send MCS Disconnect Provider Ultimatum PDU
This commit is contained in:
Martin Fleisz
2025-02-17 11:05:17 +01:00
committed by GitHub
5 changed files with 46 additions and 5 deletions

View File

@@ -347,6 +347,8 @@ extern "C"
/**
* Defines the possible disconnect reasons in the MCS Disconnect Provider
* Ultimatum PDU
*
* [T.125] 7 Structure of Version 2 MCSPDUs Reason ::= ENUMERATED
*/
enum Disconnect_Ultimatum
@@ -579,6 +581,16 @@ owned by rdpRdp */
FREERDP_API BOOL freerdp_shall_disconnect_context(const rdpContext* context);
FREERDP_API BOOL freerdp_disconnect(freerdp* instance);
/** @brief stringify disconnect reason of type Disconnect_Ultimatum
*
* @param reason the reason of type \b Disconnect_Ultimatum
*
* @return a string representation of \b reason or rn-unknown
*
* @since version 3.12.1
*/
FREERDP_API const char* freerdp_disconnect_reason_string(int reason);
WINPR_DEPRECATED_VAR("use freerdp_disconnect_before_reconnect_context instead",
FREERDP_API BOOL freerdp_disconnect_before_reconnect(freerdp* instance));
FREERDP_API BOOL freerdp_disconnect_before_reconnect_context(rdpContext* context);

View File

@@ -314,6 +314,11 @@ BOOL freerdp_abort_connect_context(rdpContext* context)
freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
/* Try to send a [MS-RDPBCGR] 1.3.1.4.1 User-Initiated on Client PDU, we don't care about
* success */
if (context->rdp && context->rdp->mcs)
(void)mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
Disconnect_Ultimatum_user_requested);
return utils_abort_connect(context->rdp);
}
@@ -1468,3 +1473,22 @@ BOOL freerdp_persist_credentials(rdpContext* context)
WINPR_ASSERT(context->rdp);
return utils_persist_credentials(context->rdp->originalSettings, context->rdp->settings);
}
const char* freerdp_disconnect_reason_string(int reason)
{
switch (reason)
{
case Disconnect_Ultimatum_domain_disconnected:
return "rn-domain-disconnected";
case Disconnect_Ultimatum_provider_initiated:
return "rn-provider-initiated";
case Disconnect_Ultimatum_token_purged:
return "rn-token-purged";
case Disconnect_Ultimatum_user_requested:
return "rn-user-requested";
case Disconnect_Ultimatum_channel_purged:
return "rn-channel-purged";
default:
return "rn-unknown";
}
}

View File

@@ -1363,7 +1363,7 @@ BOOL mcs_recv_disconnect_provider_ultimatum(WINPR_ATTR_UNUSED rdpMcs* mcs, wStre
* @param mcs mcs module
*/
BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs)
BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs, enum Disconnect_Ultimatum reason)
{
wStream* s = NULL;
int status = -1;
@@ -1379,10 +1379,12 @@ BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs)
if (!mcs_write_domain_mcspdu_header(s, DomainMCSPDU_DisconnectProviderUltimatum, length, 1))
goto fail;
if (!per_write_enumerated(s, 0x80, 0))
if (!per_write_enumerated(s, 0x80, reason))
goto fail;
status = transport_write(mcs->transport, s);
fail:
WLog_DBG(TAG, "sending DisconnectProviderUltimatum(%s)",
freerdp_disconnect_reason_string(reason));
Stream_Free(s, TRUE);
return (status < 0) ? FALSE : TRUE;
}

View File

@@ -172,7 +172,8 @@ FREERDP_LOCAL BOOL mcs_send_channel_join_request(rdpMcs* mcs, UINT16 channelId);
FREERDP_LOCAL BOOL mcs_recv_channel_join_confirm(rdpMcs* mcs, wStream* s, UINT16* channelId);
FREERDP_LOCAL BOOL mcs_send_channel_join_confirm(rdpMcs* mcs, UINT16 channelId);
FREERDP_LOCAL BOOL mcs_recv_disconnect_provider_ultimatum(rdpMcs* mcs, wStream* s, int* reason);
FREERDP_LOCAL BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs);
FREERDP_LOCAL BOOL mcs_send_disconnect_provider_ultimatum(rdpMcs* mcs,
enum Disconnect_Ultimatum reason);
FREERDP_LOCAL BOOL mcs_write_domain_mcspdu_header(wStream* s, DomainMCSPDU domainMCSPDU,
UINT16 length, BYTE options);

View File

@@ -394,7 +394,8 @@ static state_run_t peer_recv_data_pdu(freerdp_peer* client, wStream* s,
return STATE_RUN_CONTINUE; // State changed, trigger rerun
case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
mcs_send_disconnect_provider_ultimatum(rdp->mcs);
mcs_send_disconnect_provider_ultimatum(rdp->mcs,
Disconnect_Ultimatum_provider_initiated);
WLog_WARN(TAG, "disconnect provider ultimatum sent to peer, closing connection");
return STATE_RUN_QUIT_SESSION;
@@ -1219,7 +1220,8 @@ static BOOL freerdp_peer_close(freerdp_peer* client)
rdp_send_error_info(context->rdp);
}
return mcs_send_disconnect_provider_ultimatum(context->rdp->mcs);
return mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
Disconnect_Ultimatum_provider_initiated);
}
static void freerdp_peer_disconnect(freerdp_peer* client)