libfreerdp-core: fix transport failure case with session redirection

This commit is contained in:
Marc-André Moreau
2013-11-01 14:13:09 -04:00
parent 16f287015f
commit 76414588b1
8 changed files with 55 additions and 29 deletions

View File

@@ -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 };

View File

@@ -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,

View File

@@ -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));

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;