diff --git a/configure.ac b/configure.ac index c9391ede..a61534a4 100644 --- a/configure.ac +++ b/configure.ac @@ -609,6 +609,24 @@ then #include ]) fi +# Support for RDP gateways +if test "x${have_freerdp}" = "xyes" +then + AC_CHECK_MEMBERS([rdpSettings.GatewayEnabled], + [AC_DEFINE([HAVE_FREERDP_GATEWAY_SUPPORT],, + [Whether FreeRDP supports RDP gateways])],, + [[#include ]]) +fi + +# Support for load balancing via connection brokers +if test "x${have_freerdp}" = "xyes" +then + AC_CHECK_MEMBERS([rdpSettings.LoadBalanceInfo], + [AC_DEFINE([HAVE_FREERDP_LOAD_BALANCER_SUPPORT],, + [Whether FreeRDP supports load balancers])],, + [[#include ]]) +fi + # Support for "PubSub" event system if test "x${have_freerdp}" = "xyes" then diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c index e8161b13..998f0a21 100644 --- a/src/protocols/rdp/rdp_settings.c +++ b/src/protocols/rdp/rdp_settings.c @@ -93,6 +93,18 @@ const char* GUAC_RDP_CLIENT_ARGS[] = { "enable-audio-input", "read-only", +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + "gateway-hostname", + "gateway-port", + "gateway-domain", + "gateway-username", + "gateway-password", +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + "load-balance-info", +#endif + NULL }; @@ -392,6 +404,53 @@ enum RDP_ARGS_IDX { */ IDX_READ_ONLY, +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + /** + * The hostname of the remote desktop gateway that should be used as an + * intermediary for the remote desktop connection. If omitted, a gateway + * will not be used. + */ + IDX_GATEWAY_HOSTNAME, + + /** + * The port of the remote desktop gateway that should be used as an + * intermediary for the remote desktop connection. By default, this will be + * 443. + * + * NOTE: If using a version of FreeRDP prior to 1.2, this setting has no + * effect. FreeRDP instead uses a hard-coded value of 443. + */ + IDX_GATEWAY_PORT, + + /** + * The domain of the user authenticating with the remote desktop gateway, + * if a gateway is being used. This is not necessarily the same as the + * user actually using the remote desktop connection. + */ + IDX_GATEWAY_DOMAIN, + + /** + * The username of the user authenticating with the remote desktop gateway, + * if a gateway is being used. This is not necessarily the same as the + * user actually using the remote desktop connection. + */ + IDX_GATEWAY_USERNAME, + + /** + * The password to provide when authenticating with the remote desktop + * gateway, if a gateway is being used. + */ + IDX_GATEWAY_PASSWORD, +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + /** + * The load balancing information/cookie which should be provided to + * the connection broker, if a connection broker is being used. + */ + IDX_LOAD_BALANCE_INFO, +#endif + RDP_ARGS_COUNT }; @@ -763,6 +822,40 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user, guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_AUDIO_INPUT, 0); +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + /* Set gateway hostname */ + settings->gateway_hostname = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_GATEWAY_HOSTNAME, NULL); + + /* If gateway port specified, use it */ + settings->gateway_port = + guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_GATEWAY_PORT, 443); + + /* Set gateway domain */ + settings->gateway_domain = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_GATEWAY_DOMAIN, NULL); + + /* Set gateway username */ + settings->gateway_username = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_GATEWAY_USERNAME, NULL); + + /* Set gateway password */ + settings->gateway_password = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_GATEWAY_PASSWORD, NULL); +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + /* Set load balance info */ + settings->load_balance_info = + guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, + IDX_LOAD_BALANCE_INFO, NULL); +#endif + /* Success */ return settings; @@ -811,6 +904,19 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) { free(settings->sftp_username); #endif +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + /* Free RD gateway information */ + free(settings->gateway_hostname); + free(settings->gateway_domain); + free(settings->gateway_username); + free(settings->gateway_password); +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + /* Free load balancer information string */ + free(settings->load_balance_info); +#endif + /* Free settings structure */ free(settings); @@ -1143,6 +1249,34 @@ void guac_rdp_push_settings(guac_rdp_settings* guac_settings, freerdp* rdp) { } #endif +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + /* Enable use of RD gateway if a gateway hostname is provided */ + if (guac_settings->gateway_hostname != NULL) { + + /* Enable RD gateway */ + rdp_settings->GatewayEnabled = TRUE; + + /* RD gateway connection details */ + rdp_settings->GatewayHostname = guac_rdp_strdup(guac_settings->gateway_hostname); + rdp_settings->GatewayPort = guac_settings->gateway_port; + + /* RD gateway credentials */ + rdp_settings->GatewayUseSameCredentials = FALSE; + rdp_settings->GatewayDomain = guac_rdp_strdup(guac_settings->gateway_domain); + rdp_settings->GatewayUsername = guac_rdp_strdup(guac_settings->gateway_username); + rdp_settings->GatewayPassword = guac_rdp_strdup(guac_settings->gateway_password); + + } +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + /* Store load balance info (and calculate length) if provided */ + if (guac_settings->load_balance_info != NULL) { + rdp_settings->LoadBalanceInfo = (BYTE*) guac_rdp_strdup(guac_settings->load_balance_info); + rdp_settings->LoadBalanceInfoLength = strlen(guac_settings->load_balance_info); + } +#endif + /* Order support */ #ifdef LEGACY_RDPSETTINGS bitmap_cache = rdp_settings->bitmap_cache; diff --git a/src/protocols/rdp/rdp_settings.h b/src/protocols/rdp/rdp_settings.h index bcbe9b66..3ff634ad 100644 --- a/src/protocols/rdp/rdp_settings.h +++ b/src/protocols/rdp/rdp_settings.h @@ -388,6 +388,51 @@ typedef struct guac_rdp_settings { */ int enable_audio_input; +#ifdef HAVE_FREERDP_GATEWAY_SUPPORT + /** + * The hostname of the remote desktop gateway that should be used as an + * intermediary for the remote desktop connection. If no gateway should + * be used, this will be NULL. + */ + char* gateway_hostname; + + /** + * The port of the remote desktop gateway that should be used as an + * intermediary for the remote desktop connection. NOTE: versions of + * FreeRDP prior to 1.2 which have gateway support ignore this value, and + * instead use a hard-coded value of 443. + */ + int gateway_port; + + /** + * The domain of the user authenticating with the remote desktop gateway, + * if a gateway is being used. This is not necessarily the same as the + * user actually using the remote desktop connection. + */ + char* gateway_domain; + + /** + * The username of the user authenticating with the remote desktop gateway, + * if a gateway is being used. This is not necessarily the same as the + * user actually using the remote desktop connection. + */ + char* gateway_username; + + /** + * The password to provide when authenticating with the remote desktop + * gateway, if a gateway is being used. + */ + char* gateway_password; +#endif + +#ifdef HAVE_FREERDP_LOAD_BALANCER_SUPPORT + /** + * The load balancing information/cookie which should be provided to + * the connection broker, if a connection broker is being used. + */ + char* load_balance_info; +#endif + } guac_rdp_settings; /**