From 4ea803134e69cfd596c2cd90b2dd8f811de11f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Tue, 27 Jan 2026 14:03:53 +0100 Subject: [PATCH] peer: Disconnect if Logon() returned FALSE Returning FALSE implies the client was not authorized, but it does not have any real impact on the connection, other than setting the authorized field. Change this by disconnecting the client if a Logon() callback returned that a client was not authorized. --- include/freerdp/peer.h | 13 +++++++++++++ libfreerdp/core/peer.c | 32 +++++++++++++++++++------------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/include/freerdp/peer.h b/include/freerdp/peer.h index 369b6ad95..d59bef528 100644 --- a/include/freerdp/peer.h +++ b/include/freerdp/peer.h @@ -71,8 +71,21 @@ extern "C" typedef BOOL (*psPeerCapabilities)(freerdp_peer* peer); typedef BOOL (*psPeerPostConnect)(freerdp_peer* peer); typedef BOOL (*psPeerActivate)(freerdp_peer* peer); + + /** @brief Callback after the initial RDP authentication (NLA) succeeded or anonymous tunnel was + * established (RDP, TLS, ...) + * + * @param peer A pointer to a peer context to work on + * @param identity A pointer to the identity of the peer + * @param automatic \b TRUE in case the connection is already authenticated, \b FALSE in case + * of \b RDP, \b TLS or similar anonymous tunnels + * + * @return \b TRUE if the connection is allowed, \b FALSE if denied. Defaults to \b TRUE if the + * callback is unused. + */ typedef BOOL (*psPeerLogon)(freerdp_peer* peer, const SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic); + typedef BOOL (*psPeerSendServerRedirection)(freerdp_peer* peer, const rdpRedirection* redirection); typedef BOOL (*psPeerAdjustMonitorsLayout)(freerdp_peer* peer); diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index cedf38149..bf26aab6d 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -789,20 +789,17 @@ static state_run_t rdp_peer_handle_state_active(freerdp_peer* client) static state_run_t peer_recv_callback_internal(WINPR_ATTR_UNUSED rdpTransport* transport, wStream* s, void* extra) { - UINT32 SelectedProtocol = 0; freerdp_peer* client = (freerdp_peer*)extra; - rdpRdp* rdp = NULL; state_run_t ret = STATE_RUN_FAILED; - rdpSettings* settings = NULL; WINPR_ASSERT(transport); WINPR_ASSERT(client); WINPR_ASSERT(client->context); - rdp = client->context->rdp; + rdpRdp* rdp = client->context->rdp; WINPR_ASSERT(rdp); - settings = client->context->settings; + rdpSettings* settings = client->context->settings; WINPR_ASSERT(settings); IFCALL(client->ReachedState, client, rdp_get_state(rdp)); @@ -822,28 +819,37 @@ static state_run_t peer_recv_callback_internal(WINPR_ATTR_UNUSED rdpTransport* t } else { - SelectedProtocol = nego_get_selected_protocol(rdp->nego); + const UINT32 SelectedProtocol = nego_get_selected_protocol(rdp->nego); + settings->RdstlsSecurity = (SelectedProtocol & PROTOCOL_RDSTLS) ? TRUE : FALSE; settings->NlaSecurity = (SelectedProtocol & PROTOCOL_HYBRID) ? TRUE : FALSE; settings->TlsSecurity = (SelectedProtocol & PROTOCOL_SSL) ? TRUE : FALSE; settings->RdpSecurity = (SelectedProtocol == PROTOCOL_RDP) ? TRUE : FALSE; + client->authenticated = FALSE; if (SelectedProtocol & PROTOCOL_HYBRID) { SEC_WINNT_AUTH_IDENTITY_INFO* identity = (SEC_WINNT_AUTH_IDENTITY_INFO*)nego_get_identity(rdp->nego); - sspi_CopyAuthIdentity(&client->identity, identity); - IFCALLRET(client->Logon, client->authenticated, client, &client->identity, - TRUE); + if (sspi_CopyAuthIdentity(&client->identity, identity) >= 0) + { + client->authenticated = + IFCALLRESULT(TRUE, client->Logon, client, &client->identity, TRUE); + } nego_free_nla(rdp->nego); } else { - IFCALLRET(client->Logon, client->authenticated, client, &client->identity, - FALSE); + client->authenticated = + IFCALLRESULT(TRUE, client->Logon, client, &client->identity, FALSE); + } + if (!client->authenticated) + ret = STATE_RUN_FAILED; + else + { + if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST)) + ret = STATE_RUN_SUCCESS; } - if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST)) - ret = STATE_RUN_SUCCESS; } break;