Fixed #7696: Abort freerdp_connect if manually canceled (#7700)

If freerdp_abort_connect is called, set FREERDP_ERROR_CONNECT_CANCELLED
This way freerdp_reconnect can distinguish between network issues and
user interaction and abort a retry attempt.
This commit is contained in:
akallabeth
2022-03-07 13:47:43 +01:00
committed by GitHub
parent c539a173fa
commit fa3cf9417f
8 changed files with 41 additions and 20 deletions

View File

@@ -37,6 +37,8 @@
#include <freerdp/listener.h>
#include <freerdp/cache/pointer.h>
#include "utils.h"
#define TAG FREERDP_TAG("core.connection")
/**
@@ -434,10 +436,12 @@ BOOL rdp_client_disconnect_and_clear(rdpRdp* rdp)
context = rdp->context;
WINPR_ASSERT(context);
if (freerdp_get_last_error(context) == FREERDP_ERROR_CONNECT_CANCELLED)
return FALSE;
context->LastError = FREERDP_ERROR_SUCCESS;
clearChannelError(context);
ResetEvent(context->abortEvent);
return TRUE;
return utils_reset_abort(context);
}
static BOOL rdp_client_reconnect_channels(rdpRdp* rdp, BOOL redirect)

View File

@@ -53,6 +53,7 @@
#include <freerdp/cache/pointer.h>
#include "settings.h"
#include "utils.h"
#define TAG FREERDP_TAG("core")
@@ -84,7 +85,8 @@ BOOL freerdp_connect(freerdp* instance)
instance->ConnectionCallbackState = CLIENT_STATE_INITIAL;
freerdp_set_last_error_log(instance->context, FREERDP_ERROR_SUCCESS);
clearChannelError(instance->context);
ResetEvent(instance->context->abortEvent);
if (!utils_reset_abort(instance->context))
return FALSE;
rdp = instance->context->rdp;
WINPR_ASSERT(rdp);
@@ -239,7 +241,8 @@ BOOL freerdp_abort_connect(freerdp* instance)
if (!instance || !instance->context)
return FALSE;
return SetEvent(instance->context->abortEvent);
freerdp_set_last_error_if_not(instance->context, FREERDP_ERROR_CONNECT_CANCELLED);
return utils_abort_connect(instance->context);
}
#if defined(WITH_FREERDP_DEPRECATED)
@@ -480,7 +483,7 @@ BOOL freerdp_disconnect(freerdp* instance)
if (!instance || !instance->context)
return FALSE;
freerdp_abort_connect(instance);
utils_abort_connect(instance->context);
rdp = instance->context->rdp;
if (!rdp_client_disconnect(rdp))
@@ -528,10 +531,13 @@ BOOL freerdp_reconnect(freerdp* instance)
WINPR_ASSERT(instance);
WINPR_ASSERT(instance->context);
if (freerdp_get_last_error(instance->context) == FREERDP_ERROR_CONNECT_CANCELLED)
return FALSE;
rdp = instance->context->rdp;
WINPR_ASSERT(instance->context->abortEvent);
ResetEvent(instance->context->abortEvent);
if (!utils_reset_abort(instance->context))
return FALSE;
return rdp_client_reconnect(rdp);
}

View File

@@ -36,6 +36,7 @@
#include "rpc_client.h"
#include "rts_signature.h"
#include "../utils.h"
#include "../rdp.h"
#include "../proxy.h"
@@ -360,7 +361,7 @@ static int rpc_client_recv_fragment(rdpRpc* rpc, wStream* fragment)
Stream_SetPosition(fragment, StubOffset);
Stream_Read_UINT32(fragment, rpc->result);
freerdp_abort_connect(context->instance);
utils_abort_connect(context);
tsg_set_state(tsg, TSG_STATE_TUNNEL_CLOSE_PENDING);
EventArgsInit(&e, "freerdp");
e.code = 0;

View File

@@ -25,6 +25,7 @@
#include "rdp.h"
#include "info.h"
#include "utils.h"
#include "redirection.h"
#include <freerdp/crypto/per.h>
@@ -360,7 +361,7 @@ BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo)
WLog_ERR(TAG, "%s missing context=%p", __FUNCTION__, context);
/* Ensure the connection is terminated */
freerdp_abort_connect(context->instance);
utils_abort_connect(context);
}
else
{
@@ -420,7 +421,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
{
if (code == X224_TPDU_DISCONNECT_REQUEST)
{
freerdp_abort_connect(rdp->instance);
utils_abort_connect(rdp->instance->context);
return TRUE;
}
@@ -477,7 +478,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
}
WLog_DBG(TAG, "DisconnectProviderUltimatum: reason: %d", reason);
freerdp_abort_connect(rdp->instance);
utils_abort_connect(context);
EventArgsInit(&e, "freerdp");
e.code = 0;
PubSub_OnTerminate(context->pubSub, context, &e);

View File

@@ -838,12 +838,7 @@ static BOOL freerdp_tcp_connect_timeout(rdpContext* context, int sockfd, struct
status = WaitForMultipleObjects(count, handles, FALSE, tout);
if (WAIT_OBJECT_0 != status)
{
if (status == WAIT_OBJECT_0 + 1)
freerdp_set_last_error_log(context, FREERDP_ERROR_CONNECT_CANCELLED);
goto fail;
}
status = recv(sockfd, NULL, 0, 0);
@@ -1240,9 +1235,6 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
if (WaitForSingleObject(context->abortEvent, 0) == WAIT_OBJECT_0)
{
close(sockfd);
freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
return -1;
}

View File

@@ -161,3 +161,16 @@ BOOL utils_str_is_empty(const char* str)
return TRUE;
return FALSE;
}
BOOL utils_abort_connect(rdpContext* context)
{
WINPR_ASSERT(context);
return SetEvent(context->abortEvent);
}
BOOL utils_reset_abort(rdpContext* context)
{
WINPR_ASSERT(context);
return ResetEvent(context->abortEvent);
}

View File

@@ -31,8 +31,12 @@ typedef enum
AUTH_NO_CREDENTIALS,
AUTH_FAILED
} auth_status;
auth_status utils_authenticate_gateway(freerdp* instance, rdp_auth_reason reason);
auth_status utils_authenticate(freerdp* instance, rdp_auth_reason reason, BOOL override);
BOOL utils_reset_abort(rdpContext* context);
BOOL utils_abort_connect(rdpContext* context);
BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway);
BOOL utils_str_is_empty(const char* str);

View File

@@ -863,7 +863,7 @@ int tls_connect(rdpTls* tls, BIO* underlying)
#else
if (!tls_prepare(tls, underlying, TLS_client_method(), options, TRUE))
#endif
return FALSE;
return 0;
#if !defined(OPENSSL_NO_TLSEXT) && !defined(LIBRESSL_VERSION_NUMBER)
SSL_set_tlsext_host_name(tls->ssl, tls->hostname);