[core,gateway] automatically accept ARM redirection

When using ARM gateway transport auto accept the certificate provided
by server response.
This commit is contained in:
Armin Novak
2025-09-17 14:32:12 +02:00
parent ef6db048ef
commit 7e6de56338
4 changed files with 54 additions and 34 deletions

View File

@@ -796,12 +796,12 @@ out:
return ret;
}
static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const WINPR_JSON* json)
static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const WINPR_JSON* json,
const rdpCertificate* redirectedServerCert)
{
BOOL ret = TRUE;
BYTE* cert = NULL;
BYTE* authBlob = NULL;
rdpCertificate* redirectedServerCert = NULL;
do
{
@@ -837,14 +837,6 @@ static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const WINPR_JSON
goto endOfFunction;
}
/* redirectedServerCert */
size_t certLen = 0;
if (!arm_pick_base64Utf16Field(arm->log, json, "redirectedServerCert", &cert, &certLen))
break;
if (!rdp_redirection_read_target_cert(&redirectedServerCert, cert, certLen))
break;
/* redirectedAuthBlob */
size_t authBlobLen = 0;
if (!arm_pick_base64Utf16Field(arm->log, json, "redirectedAuthBlob", &authBlob,
@@ -865,7 +857,6 @@ static BOOL arm_fill_rdstls(rdpArm* arm, rdpSettings* settings, const WINPR_JSON
} while (FALSE);
free(cert);
freerdp_certificate_free(redirectedServerCert);
free(authBlob);
endOfFunction:
@@ -878,6 +869,7 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
WINPR_ASSERT(arm->context);
WINPR_ASSERT(message);
rdpCertificate* redirectedServerCert = NULL;
WINPR_JSON* json = WINPR_JSON_ParseWithLength(message, len);
BOOL status = FALSE;
if (!json)
@@ -890,9 +882,7 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
{
WLog_Print(arm->log, WLOG_DEBUG, "extracted target url %s", gwurlstr);
if (!freerdp_settings_set_string(settings, FreeRDP_GatewayUrl, gwurlstr))
status = FALSE;
else
status = TRUE;
goto fail;
}
WINPR_JSON* serverNameNode = WINPR_JSON_GetObjectItem(json, "redirectedServerName");
@@ -900,7 +890,10 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
{
const char* serverName = WINPR_JSON_GetStringValue(serverNameNode);
if (serverName)
status = freerdp_settings_set_string(settings, FreeRDP_ServerHostname, serverName);
{
if (!freerdp_settings_set_string(settings, FreeRDP_ServerHostname, serverName))
goto fail;
}
}
WINPR_JSON* azureMeta = WINPR_JSON_GetObjectItem(json, "azureInstanceNetworkMetadata");
@@ -910,18 +903,35 @@ static BOOL arm_fill_gateway_parameters(rdpArm* arm, const char* message, size_t
settings))
{
WLog_Print(arm->log, WLOG_ERROR, "error when treating azureInstanceNetworkMetadata");
goto fail;
}
}
/* redirectedServerCert */
size_t certLen = 0;
BYTE* cert = NULL;
if (arm_pick_base64Utf16Field(arm->log, json, "redirectedServerCert", &cert, &certLen))
{
const BOOL rc = rdp_redirection_read_target_cert(&redirectedServerCert, cert, certLen);
free(cert);
if (!rc)
goto fail;
else if (!rdp_set_target_certificate(settings, redirectedServerCert))
goto fail;
}
if (freerdp_settings_get_string(settings, FreeRDP_Password))
{
/* note: we retrieve some more fields for RDSTLS only if we have a password provided by the
* user, otherwise these are useless: we will not be able to do RDSTLS
*/
status = arm_fill_rdstls(arm, settings, json);
status = arm_fill_rdstls(arm, settings, json, redirectedServerCert);
}
else
status = TRUE;
fail:
WINPR_JSON_Delete(json);
freerdp_certificate_free(redirectedServerCert);
return status;
}

View File

@@ -453,6 +453,27 @@ static BOOL rdp_redirection_read_target_cert_stream(wStream* s, rdpRedirection*
return rc;
}
BOOL rdp_set_target_certificate(rdpSettings* settings, const rdpCertificate* tcert)
{
rdpCertificate* cert = freerdp_certificate_clone(tcert);
if (!freerdp_settings_set_pointer(settings, FreeRDP_RedirectionTargetCertificate, cert))
return FALSE;
BOOL pres = FALSE;
size_t length = 0;
char* pem = freerdp_certificate_get_pem(cert, &length);
if (pem && (length <= UINT32_MAX))
{
pres =
freerdp_settings_set_string_len(settings, FreeRDP_RedirectionAcceptedCert, pem, length);
if (pres)
pres = freerdp_settings_set_uint32(settings, FreeRDP_RedirectionAcceptedCertLength,
(UINT32)length);
}
free(pem);
return pres;
}
int rdp_redirection_apply_settings(rdpRdp* rdp)
{
rdpSettings* settings = NULL;
@@ -610,23 +631,7 @@ int rdp_redirection_apply_settings(rdpRdp* rdp)
if (settings->RedirectionFlags & LB_TARGET_CERTIFICATE)
{
rdpCertificate* cert = freerdp_certificate_clone(redirection->TargetCertificate);
if (!freerdp_settings_set_pointer(settings, FreeRDP_RedirectionTargetCertificate, cert))
return -1;
BOOL pres = FALSE;
size_t length = 0;
char* pem = freerdp_certificate_get_pem(cert, &length);
if (pem && (length <= UINT32_MAX))
{
pres = freerdp_settings_set_string_len(settings, FreeRDP_RedirectionAcceptedCert, pem,
length);
if (pres)
pres = freerdp_settings_set_uint32(settings, FreeRDP_RedirectionAcceptedCertLength,
(UINT32)length);
}
free(pem);
if (!pres)
if (!rdp_set_target_certificate(settings, redirection->TargetCertificate))
return -1;
}

View File

@@ -45,6 +45,8 @@ rdp_write_enhanced_security_redirection_packet(wStream* s, const rdpRedirection*
FREERDP_LOCAL BOOL rdp_redirection_read_target_cert(rdpCertificate** ptargetCertificate,
const BYTE* data, size_t length);
FREERDP_LOCAL BOOL rdp_set_target_certificate(rdpSettings* settings, const rdpCertificate* tcert);
#define REDIR_TAG FREERDP_TAG("core.redirection")
#ifdef WITH_DEBUG_REDIR
#define DEBUG_REDIR(...) WLog_DBG(REDIR_TAG, __VA_ARGS__)

View File

@@ -1343,6 +1343,9 @@ static BOOL is_redirected(rdpTls* tls)
{
rdpSettings* settings = tls->context->settings;
if (settings->GatewayArmTransport)
return TRUE;
if (LB_NOREDIRECT & settings->RedirectionFlags)
return FALSE;