GUACAMOLE-249: Refactor guac_freerdp_channels_load_plugin() to log a warning if plugin limits are reached.

This commit is contained in:
Michael Jumper 2020-01-09 14:12:08 -08:00
parent b3a713bf7a
commit 62ee36142d
6 changed files with 51 additions and 37 deletions

View File

@ -496,7 +496,7 @@ void guac_rdp_clipboard_load_plugin(guac_rdp_clipboard* clipboard,
rdpContext* context) { rdpContext* context) {
/* Attempt to load FreeRDP support for the CLIPRDR channel */ /* Attempt to load FreeRDP support for the CLIPRDR channel */
if (guac_freerdp_channels_load_plugin(context->channels, context->settings, "cliprdr", NULL)) { if (guac_freerdp_channels_load_plugin(context, "cliprdr", NULL)) {
guac_client_log(clipboard->client, GUAC_LOG_WARNING, guac_client_log(clipboard->client, GUAC_LOG_WARNING,
"Support for the CLIPRDR channel (clipboard redirection) " "Support for the CLIPRDR channel (clipboard redirection) "
"could not be loaded. This support normally takes the form of " "could not be loaded. This support normally takes the form of "

View File

@ -59,10 +59,8 @@ int guac_rdp_common_svc_load_plugin(rdpContext* context,
"characters and will be truncated to \"%s\".", "characters and will be truncated to \"%s\".",
name, GUAC_RDP_SVC_MAX_LENGTH - 1, svc->name); name, GUAC_RDP_SVC_MAX_LENGTH - 1, svc->name);
int result = guac_freerdp_channels_load_plugin(context->channels,
context->settings, "guac-common-svc", svc);
/* Attempt to load the common SVC plugin for new static channel */ /* Attempt to load the common SVC plugin for new static channel */
int result = guac_freerdp_channels_load_plugin(context, "guac-common-svc", svc);
if (result) { if (result) {
guac_client_log(client, GUAC_LOG_WARNING, "Cannot create static " guac_client_log(client, GUAC_LOG_WARNING, "Cannot create static "
"channel \"%s\": failed to load \"guac-common-svc\" plugin " "channel \"%s\": failed to load \"guac-common-svc\" plugin "

View File

@ -177,7 +177,7 @@ void guac_rdp_rail_load_plugin(rdpContext* context) {
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
/* Attempt to load FreeRDP support for the RAIL channel */ /* Attempt to load FreeRDP support for the RAIL channel */
if (guac_freerdp_channels_load_plugin(context->channels, context->settings, "rail", context->settings)) { if (guac_freerdp_channels_load_plugin(context, "rail", context->settings)) {
guac_client_log(client, GUAC_LOG_WARNING, guac_client_log(client, GUAC_LOG_WARNING,
"Support for the RAIL channel (RemoteApp) could not be " "Support for the RAIL channel (RemoteApp) could not be "
"loaded. This support normally takes the form of a plugin " "loaded. This support normally takes the form of a plugin "

View File

@ -18,6 +18,7 @@
*/ */
#include "plugins/channels.h" #include "plugins/channels.h"
#include "rdp.h"
#include <freerdp/channels/channels.h> #include <freerdp/channels/channels.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
@ -36,12 +37,17 @@ PVIRTUALCHANNELENTRYEX guac_rdp_wrapped_entry_ex[GUAC_RDP_MAX_CHANNELS] = { NULL
PVIRTUALCHANNELENTRY guac_rdp_wrapped_entry[GUAC_RDP_MAX_CHANNELS] = { NULL }; PVIRTUALCHANNELENTRY guac_rdp_wrapped_entry[GUAC_RDP_MAX_CHANNELS] = { NULL };
PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX entry_ex) { PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(guac_client* client,
PVIRTUALCHANNELENTRYEX entry_ex) {
/* Do not wrap if there is insufficient space to store the wrapped /* Do not wrap if there is insufficient space to store the wrapped
* function */ * function */
if (guac_rdp_wrapped_entry_ex_count == GUAC_RDP_MAX_CHANNELS) if (guac_rdp_wrapped_entry_ex_count == GUAC_RDP_MAX_CHANNELS) {
guac_client_log(client, GUAC_LOG_WARNING, "Maximum number of static "
"channels has been reached. Further FreeRDP plugins and "
"channel support may fail to load.");
return entry_ex; return entry_ex;
}
/* Generate wrapped version of provided entry point */ /* Generate wrapped version of provided entry point */
PVIRTUALCHANNELENTRYEX wrapper = guac_rdp_entry_ex_wrappers[guac_rdp_wrapped_entry_ex_count]; PVIRTUALCHANNELENTRYEX wrapper = guac_rdp_entry_ex_wrappers[guac_rdp_wrapped_entry_ex_count];
@ -52,12 +58,17 @@ PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX entr
} }
PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry) { PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(guac_client* client,
PVIRTUALCHANNELENTRY entry) {
/* Do not wrap if there is insufficient space to store the wrapped /* Do not wrap if there is insufficient space to store the wrapped
* function */ * function */
if (guac_rdp_wrapped_entry_count == GUAC_RDP_MAX_CHANNELS) if (guac_rdp_wrapped_entry_count == GUAC_RDP_MAX_CHANNELS) {
guac_client_log(client, GUAC_LOG_WARNING, "Maximum number of static "
"channels has been reached. Further FreeRDP plugins and "
"channel support may fail to load.");
return entry; return entry;
}
/* Generate wrapped version of provided entry point */ /* Generate wrapped version of provided entry point */
PVIRTUALCHANNELENTRY wrapper = guac_rdp_entry_wrappers[guac_rdp_wrapped_entry_count]; PVIRTUALCHANNELENTRY wrapper = guac_rdp_entry_wrappers[guac_rdp_wrapped_entry_count];
@ -68,16 +79,18 @@ PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry) {
} }
int guac_freerdp_channels_load_plugin(rdpChannels* channels, int guac_freerdp_channels_load_plugin(rdpContext* context,
rdpSettings* settings, const char* name, void* data) { const char* name, void* data) {
guac_client* client = ((rdp_freerdp_context*) context)->client;
/* Load plugin using "ex" version of the channel plugin entry point, if it exists */ /* Load plugin using "ex" version of the channel plugin entry point, if it exists */
PVIRTUALCHANNELENTRYEX entry_ex = (PVIRTUALCHANNELENTRYEX) (void*) freerdp_load_channel_addin_entry(name, PVIRTUALCHANNELENTRYEX entry_ex = (PVIRTUALCHANNELENTRYEX) (void*) freerdp_load_channel_addin_entry(name,
NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC | FREERDP_ADDIN_CHANNEL_ENTRYEX); NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC | FREERDP_ADDIN_CHANNEL_ENTRYEX);
if (entry_ex != NULL) { if (entry_ex != NULL) {
entry_ex = guac_rdp_plugin_wrap_entry_ex(entry_ex); entry_ex = guac_rdp_plugin_wrap_entry_ex(client, entry_ex);
return freerdp_channels_client_load_ex(channels, settings, entry_ex, data); return freerdp_channels_client_load_ex(context->channels, context->settings, entry_ex, data);
} }
/* Lacking the "ex" entry point, attempt to load using the non-ex version */ /* Lacking the "ex" entry point, attempt to load using the non-ex version */
@ -85,8 +98,8 @@ int guac_freerdp_channels_load_plugin(rdpChannels* channels,
NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC); NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
if (entry != NULL) { if (entry != NULL) {
entry = guac_rdp_plugin_wrap_entry(entry); entry = guac_rdp_plugin_wrap_entry(client, entry);
return freerdp_channels_client_load(channels, settings, entry, data); return freerdp_channels_client_load(context->channels, context->settings, entry, data);
} }
/* The plugin does not exist / cannot be loaded */ /* The plugin does not exist / cannot be loaded */

View File

@ -23,6 +23,7 @@
#include <freerdp/channels/channels.h> #include <freerdp/channels/channels.h>
#include <freerdp/freerdp.h> #include <freerdp/freerdp.h>
#include <freerdp/settings.h> #include <freerdp/settings.h>
#include <guacamole/client.h>
#include <winpr/wtsapi.h> #include <winpr/wtsapi.h>
/** /**
@ -41,25 +42,20 @@
#error "GUAC_RDP_MAX_CHANNELS must not be less than CHANNEL_MAX_COUNT" #error "GUAC_RDP_MAX_CHANNELS must not be less than CHANNEL_MAX_COUNT"
#endif #endif
/** /** Loads the FreeRDP plugin having the given name. With the exception that
* Loads the FreeRDP plugin having the given name. This function is a drop-in * this function requires the rdpContext rather than rdpChannels and
* replacement for freerdp_channels_load_plugin() which additionally loads * rdpSettings, this function is essentially a drop-in replacement for
* plugins implementing the PVIRTUALCHANNELENTRYEX version of the channel * freerdp_channels_load_plugin() which additionally loads plugins implementing
* plugin entry point. The freerdp_channels_load_plugin() function which is * the PVIRTUALCHANNELENTRYEX version of the channel plugin entry point. The
* part of FreeRDP can load only plugins which implement the * freerdp_channels_load_plugin() function which is part of FreeRDP can load
* PVIRTUALCHANNELENTRY version of the entry point. * only plugins which implement the PVIRTUALCHANNELENTRY version of the entry
* point.
* *
* This MUST be called within the PreConnect callback of the freerdp instance * This MUST be called within the PreConnect callback of the freerdp instance
* for the referenced plugin to be loaded correctly. * for the referenced plugin to be loaded correctly.
* *
* @param channels * @param context
* The rdpChannels structure with which the plugin should be registered * The rdpContext associated with the active RDP session.
* once loaded. This structure should be retrieved directly from the
* relevant FreeRDP instance.
*
* @param settings
* The rdpSettings structure associated with the FreeRDP instance, already
* populated with any settings applicable to the plugin being loaded.
* *
* @param name * @param name
* The name of the plugin to load. If the plugin is not statically built * The name of the plugin to load. If the plugin is not statically built
@ -78,8 +74,8 @@
* Zero if the plugin was loaded successfully, non-zero if the plugin could * Zero if the plugin was loaded successfully, non-zero if the plugin could
* not be loaded. * not be loaded.
*/ */
int guac_freerdp_channels_load_plugin(rdpChannels* channels, int guac_freerdp_channels_load_plugin(rdpContext* context,
rdpSettings* settings, const char* name, void* data); const char* name, void* data);
/** /**
* Schedules loading of the FreeRDP dynamic virtual channel plugin having the * Schedules loading of the FreeRDP dynamic virtual channel plugin having the
@ -150,6 +146,9 @@ extern PVIRTUALCHANNELENTRYEX guac_rdp_entry_ex_wrappers[GUAC_RDP_MAX_CHANNELS];
* load a plugin if its entry point is already loaded, this allows a single * load a plugin if its entry point is already loaded, this allows a single
* FreeRDP plugin to be loaded multiple times. * FreeRDP plugin to be loaded multiple times.
* *
* @param client
* The guac_client associated with the relevant RDP session.
*
* @param entry_ex * @param entry_ex
* The entry point function to wrap. * The entry point function to wrap.
* *
@ -158,7 +157,8 @@ extern PVIRTUALCHANNELENTRYEX guac_rdp_entry_ex_wrappers[GUAC_RDP_MAX_CHANNELS];
* point if there is insufficient space remaining within * point if there is insufficient space remaining within
* guac_rdp_entry_ex_wrappers to wrap the entry point. * guac_rdp_entry_ex_wrappers to wrap the entry point.
*/ */
PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(PVIRTUALCHANNELENTRYEX entry_ex); PVIRTUALCHANNELENTRYEX guac_rdp_plugin_wrap_entry_ex(guac_client* client,
PVIRTUALCHANNELENTRYEX entry_ex);
/** /**
* The number of wrapped channel entry points currently stored within * The number of wrapped channel entry points currently stored within
@ -189,6 +189,9 @@ extern PVIRTUALCHANNELENTRY guac_rdp_entry_wrappers[GUAC_RDP_MAX_CHANNELS];
* load a plugin if its entry point is already loaded, this allows a single * load a plugin if its entry point is already loaded, this allows a single
* FreeRDP plugin to be loaded multiple times. * FreeRDP plugin to be loaded multiple times.
* *
* @param client
* The guac_client associated with the relevant RDP session.
*
* @param entry * @param entry
* The entry point function to wrap. * The entry point function to wrap.
* *
@ -197,7 +200,8 @@ extern PVIRTUALCHANNELENTRY guac_rdp_entry_wrappers[GUAC_RDP_MAX_CHANNELS];
* point if there is insufficient space remaining within * point if there is insufficient space remaining within
* guac_rdp_entry_wrappers to wrap the entry point. * guac_rdp_entry_wrappers to wrap the entry point.
*/ */
PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(PVIRTUALCHANNELENTRY entry); PVIRTUALCHANNELENTRY guac_rdp_plugin_wrap_entry(guac_client* client,
PVIRTUALCHANNELENTRY entry);
#endif #endif

View File

@ -77,7 +77,6 @@
BOOL rdp_freerdp_pre_connect(freerdp* instance) { BOOL rdp_freerdp_pre_connect(freerdp* instance) {
rdpContext* context = instance->context; rdpContext* context = instance->context;
rdpChannels* channels = context->channels;
rdpGraphics* graphics = context->graphics; rdpGraphics* graphics = context->graphics;
guac_client* client = ((rdp_freerdp_context*) context)->client; guac_client* client = ((rdp_freerdp_context*) context)->client;
@ -127,8 +126,8 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
/* Load plugin providing Dynamic Virtual Channel support, if required */ /* Load plugin providing Dynamic Virtual Channel support, if required */
if (instance->settings->SupportDynamicChannels && if (instance->settings->SupportDynamicChannels &&
guac_freerdp_channels_load_plugin(channels, instance->settings, guac_freerdp_channels_load_plugin(context, "drdynvc",
"drdynvc", instance->settings)) { instance->settings)) {
guac_client_log(client, GUAC_LOG_WARNING, guac_client_log(client, GUAC_LOG_WARNING,
"Failed to load drdynvc plugin. Display update and audio " "Failed to load drdynvc plugin. Display update and audio "
"input support will be disabled."); "input support will be disabled.");