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) {
/* 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,
"Support for the CLIPRDR channel (clipboard redirection) "
"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\".",
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 */
int result = guac_freerdp_channels_load_plugin(context, "guac-common-svc", svc);
if (result) {
guac_client_log(client, GUAC_LOG_WARNING, "Cannot create static "
"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;
/* 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,
"Support for the RAIL channel (RemoteApp) could not be "
"loaded. This support normally takes the form of a plugin "

View File

@ -18,6 +18,7 @@
*/
#include "plugins/channels.h"
#include "rdp.h"
#include <freerdp/channels/channels.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 };
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
* 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;
}
/* Generate wrapped version of provided entry point */
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
* 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;
}
/* Generate wrapped version of provided entry point */
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,
rdpSettings* settings, const char* name, void* data) {
int guac_freerdp_channels_load_plugin(rdpContext* context,
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 */
PVIRTUALCHANNELENTRYEX entry_ex = (PVIRTUALCHANNELENTRYEX) (void*) freerdp_load_channel_addin_entry(name,
NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC | FREERDP_ADDIN_CHANNEL_ENTRYEX);
if (entry_ex != NULL) {
entry_ex = guac_rdp_plugin_wrap_entry_ex(entry_ex);
return freerdp_channels_client_load_ex(channels, settings, entry_ex, data);
entry_ex = guac_rdp_plugin_wrap_entry_ex(client, entry_ex);
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 */
@ -85,8 +98,8 @@ int guac_freerdp_channels_load_plugin(rdpChannels* channels,
NULL, NULL, FREERDP_ADDIN_CHANNEL_STATIC);
if (entry != NULL) {
entry = guac_rdp_plugin_wrap_entry(entry);
return freerdp_channels_client_load(channels, settings, entry, data);
entry = guac_rdp_plugin_wrap_entry(client, entry);
return freerdp_channels_client_load(context->channels, context->settings, entry, data);
}
/* The plugin does not exist / cannot be loaded */

View File

@ -23,6 +23,7 @@
#include <freerdp/channels/channels.h>
#include <freerdp/freerdp.h>
#include <freerdp/settings.h>
#include <guacamole/client.h>
#include <winpr/wtsapi.h>
/**
@ -41,25 +42,20 @@
#error "GUAC_RDP_MAX_CHANNELS must not be less than CHANNEL_MAX_COUNT"
#endif
/**
* Loads the FreeRDP plugin having the given name. This function is a drop-in
* replacement for freerdp_channels_load_plugin() which additionally loads
* plugins implementing the PVIRTUALCHANNELENTRYEX version of the channel
* plugin entry point. The freerdp_channels_load_plugin() function which is
* part of FreeRDP can load only plugins which implement the
* PVIRTUALCHANNELENTRY version of the entry point.
/** Loads the FreeRDP plugin having the given name. With the exception that
* this function requires the rdpContext rather than rdpChannels and
* rdpSettings, this function is essentially a drop-in replacement for
* freerdp_channels_load_plugin() which additionally loads plugins implementing
* the PVIRTUALCHANNELENTRYEX version of the channel plugin entry point. The
* freerdp_channels_load_plugin() function which is part of FreeRDP can load
* only plugins which implement the PVIRTUALCHANNELENTRY version of the entry
* point.
*
* This MUST be called within the PreConnect callback of the freerdp instance
* for the referenced plugin to be loaded correctly.
*
* @param channels
* The rdpChannels structure with which the plugin should be registered
* 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 context
* The rdpContext associated with the active RDP session.
*
* @param name
* 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
* not be loaded.
*/
int guac_freerdp_channels_load_plugin(rdpChannels* channels,
rdpSettings* settings, const char* name, void* data);
int guac_freerdp_channels_load_plugin(rdpContext* context,
const char* name, void* data);
/**
* 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
* FreeRDP plugin to be loaded multiple times.
*
* @param client
* The guac_client associated with the relevant RDP session.
*
* @param entry_ex
* 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
* 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
@ -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
* FreeRDP plugin to be loaded multiple times.
*
* @param client
* The guac_client associated with the relevant RDP session.
*
* @param entry
* 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
* 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

View File

@ -77,7 +77,6 @@
BOOL rdp_freerdp_pre_connect(freerdp* instance) {
rdpContext* context = instance->context;
rdpChannels* channels = context->channels;
rdpGraphics* graphics = context->graphics;
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 */
if (instance->settings->SupportDynamicChannels &&
guac_freerdp_channels_load_plugin(channels, instance->settings,
"drdynvc", instance->settings)) {
guac_freerdp_channels_load_plugin(context, "drdynvc",
instance->settings)) {
guac_client_log(client, GUAC_LOG_WARNING,
"Failed to load drdynvc plugin. Display update and audio "
"input support will be disabled.");