summaryrefslogtreecommitdiffstats
path: root/libfreerdp/core/utils.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 01:25:12 +0000
commit827a4c3faa27e0c186452585b15094eee1119085 (patch)
treee6a08b0c767863d66f7d4a9de80db5edc7db29be /libfreerdp/core/utils.c
parentReleasing progress-linux version 3.3.0+dfsg1-1~progress7.99u1. (diff)
downloadfreerdp3-827a4c3faa27e0c186452585b15094eee1119085.tar.xz
freerdp3-827a4c3faa27e0c186452585b15094eee1119085.zip
Merging upstream version 3.5.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libfreerdp/core/utils.c')
-rw-r--r--libfreerdp/core/utils.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/libfreerdp/core/utils.c b/libfreerdp/core/utils.c
index 1bcb090..f414611 100644
--- a/libfreerdp/core/utils.c
+++ b/libfreerdp/core/utils.c
@@ -25,6 +25,8 @@
#include <winpr/assert.h>
#include <freerdp/freerdp.h>
+#include <freerdp/channels/cliprdr.h>
+#include <freerdp/channels/rdpdr.h>
#include <freerdp/log.h>
#define TAG FREERDP_TAG("core.gateway.utils")
@@ -299,3 +301,182 @@ const char* utils_is_vsock(const char* hostname)
return &hostname[sizeof(vsock)];
return NULL;
}
+
+static BOOL remove_rdpdr_type(rdpSettings* settings, UINT32 type)
+{
+ RDPDR_DEVICE* printer = NULL;
+ do
+ {
+ printer = freerdp_device_collection_find_type(settings, type);
+ freerdp_device_collection_del(settings, printer);
+ freerdp_device_free(printer);
+ } while (printer);
+ return TRUE;
+}
+
+static BOOL disable_clipboard(rdpSettings* settings)
+{
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, FALSE))
+ return FALSE;
+ freerdp_static_channel_collection_del(settings, CLIPRDR_SVC_CHANNEL_NAME);
+ return TRUE;
+}
+
+static BOOL disable_drive(rdpSettings* settings)
+{
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectDrives, FALSE))
+ return FALSE;
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectHomeDrive, FALSE))
+ return FALSE;
+
+ return remove_rdpdr_type(settings, RDPDR_DTYP_FILESYSTEM);
+}
+
+static BOOL disable_printers(rdpSettings* settings)
+{
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectPrinters, FALSE))
+ return FALSE;
+
+ return remove_rdpdr_type(settings, RDPDR_DTYP_PRINT);
+}
+
+static BOOL disable_port(rdpSettings* settings)
+{
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectParallelPorts, FALSE))
+ return FALSE;
+ if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSerialPorts, FALSE))
+ return FALSE;
+ if (!remove_rdpdr_type(settings, RDPDR_DTYP_SERIAL))
+ return FALSE;
+ return remove_rdpdr_type(settings, RDPDR_DTYP_PARALLEL);
+}
+
+static BOOL disable_pnp(rdpSettings* settings)
+{
+ // TODO(akallabeth): [MS-RDPEPNP] related stuff is disabled.
+ return TRUE;
+}
+
+static BOOL apply_gw_policy(rdpContext* context)
+{
+ WINPR_ASSERT(context);
+ return utils_reload_channels(context);
+}
+
+BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags, const char* module)
+{
+ WINPR_ASSERT(log);
+ WINPR_ASSERT(context);
+
+ rdpSettings* settings = context->settings;
+ WINPR_ASSERT(settings);
+
+ if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
+ {
+ WLog_Print(log, WLOG_DEBUG, "[%s] policy allows all redirections", module);
+ }
+ else if (freerdp_settings_get_bool(settings, FreeRDP_GatewayIgnoreRedirectionPolicy))
+ {
+ char buffer[128] = { 0 };
+ WLog_Print(log, WLOG_INFO, "[%s] policy ignored on user request %s", module,
+ utils_redir_flags_to_string(flags, buffer, sizeof(buffer)));
+ }
+ else if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies all redirections", module);
+ if (!disable_drive(settings))
+ return FALSE;
+ if (!disable_printers(settings))
+ return FALSE;
+ if (!disable_clipboard(settings))
+ return FALSE;
+ if (!disable_port(settings))
+ return FALSE;
+ if (!disable_pnp(settings))
+ return FALSE;
+ if (!apply_gw_policy(context))
+ return FALSE;
+ }
+ else
+ {
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies drive redirections", module);
+ if (!disable_drive(settings))
+ return FALSE;
+ }
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies printer redirections", module);
+ if (!disable_printers(settings))
+ return FALSE;
+ }
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies port redirections", module);
+ if (!disable_port(settings))
+ return FALSE;
+ }
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies clipboard redirections", module);
+ if (!disable_clipboard(settings))
+ return FALSE;
+ }
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
+ {
+ WLog_Print(log, WLOG_INFO, "[%s] policy denies PNP redirections", module);
+ if (!disable_pnp(settings))
+ return FALSE;
+ }
+ if (flags != 0)
+ {
+ if (!apply_gw_policy(context))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+char* utils_redir_flags_to_string(UINT32 flags, char* buffer, size_t size)
+{
+ winpr_str_append("{", buffer, size, "");
+ if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
+ winpr_str_append("ENABLE_ALL", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
+ winpr_str_append("DISABLE_ALL", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
+ winpr_str_append("DISABLE_DRIVE", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
+ winpr_str_append("DISABLE_PRINTER", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
+ winpr_str_append("DISABLE_PORT", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
+ winpr_str_append("DISABLE_CLIPBOARD", buffer, size, "|");
+ if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
+ winpr_str_append("DISABLE_PNP", buffer, size, "|");
+
+ char fbuffer[16] = { 0 };
+ _snprintf(fbuffer, sizeof(fbuffer), "[0x%08" PRIx32 "]", flags);
+
+ winpr_str_append(fbuffer, buffer, size, " ");
+ winpr_str_append("{", buffer, size, "}");
+ return buffer;
+}
+
+BOOL utils_reload_channels(rdpContext* context)
+{
+ WINPR_ASSERT(context);
+
+ freerdp_channels_disconnect(context->channels, context->instance);
+ freerdp_channels_close(context->channels, context->instance);
+ freerdp_channels_free(context->channels);
+ context->channels = freerdp_channels_new(context->instance);
+ WINPR_ASSERT(context->channels);
+
+ BOOL rc = TRUE;
+ IFCALLRET(context->instance->LoadChannels, rc, context->instance);
+ if (rc)
+ return freerdp_channels_pre_connect(context->channels, context->instance) == CHANNEL_RC_OK;
+ return rc;
+}