mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: fix transport failure case with session redirection
This commit is contained in:
@@ -170,6 +170,14 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
{
|
||||
rdpSettings* settings = rdp->settings;
|
||||
|
||||
if (rdp->settingsCopy)
|
||||
{
|
||||
freerdp_settings_free(rdp->settingsCopy);
|
||||
rdp->settingsCopy = NULL;
|
||||
}
|
||||
|
||||
rdp->settingsCopy = freerdp_settings_clone(settings);
|
||||
|
||||
nego_init(rdp->nego);
|
||||
nego_set_target(rdp->nego, settings->ServerHostname, settings->ServerPort);
|
||||
|
||||
@@ -278,6 +286,7 @@ BOOL rdp_client_disconnect(rdpRdp* rdp)
|
||||
|
||||
BOOL rdp_client_redirect(rdpRdp* rdp)
|
||||
{
|
||||
BOOL status;
|
||||
rdpSettings* settings = rdp->settings;
|
||||
rdpRedirection* redirection = rdp->redirection;
|
||||
|
||||
@@ -297,7 +306,7 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
|
||||
rdp->fips_hmac = NULL;
|
||||
|
||||
free(settings->ServerRandom);
|
||||
settings->ServerRandom = NULL ;
|
||||
settings->ServerRandom = NULL;
|
||||
free(settings->ServerCertificate);
|
||||
settings->ServerCertificate = NULL;
|
||||
free(settings->ClientAddress);
|
||||
@@ -361,7 +370,9 @@ BOOL rdp_client_redirect(rdpRdp* rdp)
|
||||
settings->RedirectionPasswordLength = redirection->PasswordCookieLength;
|
||||
}
|
||||
|
||||
return rdp_client_connect(rdp);
|
||||
status = rdp_client_connect(rdp);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
#ifndef __FASTPATH_H
|
||||
#define __FASTPATH_H
|
||||
|
||||
typedef struct rdp_fastpath rdpFastPath;
|
||||
|
||||
#include "rdp.h"
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
typedef struct rdp_fastpath rdpFastPath;
|
||||
|
||||
enum FASTPATH_INPUT_ACTION_TYPE
|
||||
{
|
||||
FASTPATH_INPUT_ACTION_FASTPATH = 0x0,
|
||||
|
||||
@@ -964,7 +964,7 @@ void nego_init(rdpNego* nego)
|
||||
* @return
|
||||
*/
|
||||
|
||||
rdpNego* nego_new(struct rdp_transport * transport)
|
||||
rdpNego* nego_new(rdpTransport* transport)
|
||||
{
|
||||
rdpNego* nego = (rdpNego*) malloc(sizeof(rdpNego));
|
||||
|
||||
|
||||
@@ -816,7 +816,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
*/
|
||||
Stream_Rewind(s, 2);
|
||||
rdp_recv_enhanced_security_redirection_packet(rdp, s);
|
||||
return -1;
|
||||
return 1; /* 1 = redirection */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -976,7 +976,9 @@ void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
|
||||
|
||||
int rdp_check_fds(rdpRdp* rdp)
|
||||
{
|
||||
return transport_check_fds(&(rdp->transport));
|
||||
int status;
|
||||
status = transport_check_fds(&(rdp->transport));
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1035,7 +1037,7 @@ rdpRdp* rdp_new(rdpContext* context)
|
||||
|
||||
void rdp_free(rdpRdp* rdp)
|
||||
{
|
||||
if (rdp != NULL)
|
||||
if (rdp)
|
||||
{
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
@@ -1043,6 +1045,7 @@ void rdp_free(rdpRdp* rdp)
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
crypto_hmac_free(rdp->fips_hmac);
|
||||
freerdp_settings_free(rdp->settings);
|
||||
freerdp_settings_free(rdp->settingsCopy);
|
||||
extension_free(rdp->extension);
|
||||
transport_free(rdp->transport);
|
||||
license_free(rdp->license);
|
||||
|
||||
@@ -121,16 +121,16 @@ struct rdp_rdp
|
||||
int state;
|
||||
freerdp* instance;
|
||||
rdpContext* context;
|
||||
struct rdp_mcs* mcs;
|
||||
struct rdp_nego* nego;
|
||||
struct rdp_input* input;
|
||||
struct rdp_update* update;
|
||||
struct rdp_fastpath* fastpath;
|
||||
struct rdp_license* license;
|
||||
struct rdp_redirection* redirection;
|
||||
struct rdp_settings* settings;
|
||||
struct rdp_transport* transport;
|
||||
struct rdp_extension* extension;
|
||||
rdpMcs* mcs;
|
||||
rdpNego* nego;
|
||||
rdpInput* input;
|
||||
rdpUpdate* update;
|
||||
rdpFastPath* fastpath;
|
||||
rdpLicense* license;
|
||||
rdpRedirection* redirection;
|
||||
rdpSettings* settings;
|
||||
rdpTransport* transport;
|
||||
rdpExtension* extension;
|
||||
struct rdp_mppc_dec* mppc_dec;
|
||||
struct rdp_mppc_enc* mppc_enc;
|
||||
struct crypto_rc4_struct* rc4_decrypt_key;
|
||||
@@ -160,6 +160,7 @@ struct rdp_rdp
|
||||
BOOL resendFocus;
|
||||
BOOL deactivation_reactivation;
|
||||
BOOL AwaitCapabilities;
|
||||
rdpSettings* settingsCopy;
|
||||
};
|
||||
|
||||
BOOL rdp_read_security_header(wStream* s, UINT16* flags);
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef __REDIRECTION_H
|
||||
#define __REDIRECTION_H
|
||||
|
||||
typedef struct rdp_redirection rdpRedirection;
|
||||
|
||||
#include "rdp.h"
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
@@ -46,7 +48,6 @@ struct rdp_redirection
|
||||
UINT32 TargetNetAddressesCount;
|
||||
char** TargetNetAddresses;
|
||||
};
|
||||
typedef struct rdp_redirection rdpRedirection;
|
||||
|
||||
BOOL rdp_recv_redirection_packet(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, wStream* s);
|
||||
|
||||
@@ -301,6 +301,9 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
ZeroMemory(settings->ClientHostname, 32);
|
||||
ZeroMemory(settings->ClientProductId, 32);
|
||||
|
||||
gethostname(settings->ClientHostname, 31);
|
||||
settings->ClientHostname[31] = 0;
|
||||
|
||||
settings->ColorPointerFlag = TRUE;
|
||||
settings->LargePointerFlag = TRUE;
|
||||
settings->PointerCacheSize = 20;
|
||||
@@ -381,9 +384,6 @@ rdpSettings* freerdp_settings_new(DWORD flags)
|
||||
settings->FastPathOutput = TRUE;
|
||||
|
||||
settings->FrameAcknowledge = 2;
|
||||
|
||||
gethostname(settings->ClientHostname, 31);
|
||||
settings->ClientHostname[31] = 0;
|
||||
settings->MouseMotion = TRUE;
|
||||
|
||||
settings->AutoReconnectionEnabled = TRUE;
|
||||
|
||||
@@ -94,6 +94,7 @@ BOOL transport_disconnect(rdpTransport* transport)
|
||||
CloseHandle(transport->thread);
|
||||
CloseHandle(transport->stopEvent);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -889,23 +890,32 @@ int transport_check_fds(rdpTransport** ptransport)
|
||||
Stream_SealLength(received);
|
||||
Stream_SetPosition(received, 0);
|
||||
|
||||
/**
|
||||
* status:
|
||||
* -1: error
|
||||
* 0: success
|
||||
* 1: redirection
|
||||
*/
|
||||
|
||||
recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
|
||||
|
||||
if (transport == *ptransport)
|
||||
if (recv_status == 1)
|
||||
{
|
||||
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
|
||||
/* so only release if still valid */
|
||||
Stream_Release(received);
|
||||
/**
|
||||
* Last call to ReceiveCallback resulted in a session redirection,
|
||||
* which means the current rdpTransport* transport pointer has been freed.
|
||||
* Return 0 for success, the rest of this function is meant for non-redirected cases.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
Stream_Release(received);
|
||||
|
||||
if (recv_status < 0)
|
||||
status = -1;
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
|
||||
transport = *ptransport;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user