diff --git a/configure.ac b/configure.ac index 5018d5cc..a38ad431 100644 --- a/configure.ac +++ b/configure.ac @@ -609,6 +609,7 @@ then rdpSettings.Height, rdpSettings.FastPathInput, rdpSettings.FastPathOutput, + rdpSettings.SendPreconnectionPdu, rdpSettings.OrderSupport], [rdpsettings_interface=stable],, [[#include ]]) diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index a669a101..8d34a6d2 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -129,6 +129,8 @@ const char* GUAC_CLIENT_ARGS[] = { "enable-full-window-drag", "enable-desktop-composition", "enable-menu-animations", + "preconnection-id", + "preconnection-blob", #ifdef ENABLE_COMMON_SSH "enable-sftp", @@ -178,6 +180,8 @@ enum RDP_ARGS_IDX { IDX_ENABLE_FULL_WINDOW_DRAG, IDX_ENABLE_DESKTOP_COMPOSITION, IDX_ENABLE_MENU_ANIMATIONS, + IDX_PRECONNECTION_ID, + IDX_PRECONNECTION_BLOB, #ifdef ENABLE_COMMON_SSH IDX_ENABLE_SFTP, @@ -773,6 +777,33 @@ int guac_client_init(guac_client* client, int argc, char** argv) { argv[IDX_WIDTH], settings->color_depth); } + /* Preconnection ID */ + settings->preconnection_id = -1; + if (argv[IDX_PRECONNECTION_ID][0] != '\0') { + settings->preconnection_id = atoi(argv[IDX_PRECONNECTION_ID]); + guac_client_log(client, GUAC_LOG_DEBUG, + "Preconnection ID: %i", settings->preconnection_id); + } + + /* Preconnection BLOB */ + settings->preconnection_blob = NULL; + if (argv[IDX_PRECONNECTION_BLOB][0] != '\0') { + settings->preconnection_blob = strdup(argv[IDX_PRECONNECTION_BLOB]); + guac_client_log(client, GUAC_LOG_DEBUG, + "Preconnection BLOB: \"%s\"", settings->preconnection_blob); + } + +#ifndef HAVE_RDPSETTINGS_SENDPRECONNECTIONPDU + /* Warn if support for the preconnection BLOB / ID is absent */ + if (settings->preconnection_blob != NULL + || settings->preconnection_id != -1) { + guac_client_log(client, GUAC_LOG_WARNING, + "Installed version of FreeRDP lacks support for the " + "preconnection PDU. The specified preconnection BLOB and/or " + "ID will be ignored."); + } +#endif + /* Audio enable/disable */ guac_client_data->settings.audio_enabled = (strcmp(argv[IDX_DISABLE_AUDIO], "true") != 0); diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c index 52471b9f..ef12e15e 100644 --- a/src/protocols/rdp/rdp_settings.c +++ b/src/protocols/rdp/rdp_settings.c @@ -292,6 +292,22 @@ void guac_rdp_push_settings(guac_rdp_settings* guac_settings, freerdp* rdp) { #endif } +#ifdef HAVE_RDPSETTINGS_SENDPRECONNECTIONPDU + /* Preconnection ID */ + if (guac_settings->preconnection_id != -1) { + rdp_settings->NegotiateSecurityLayer = FALSE; + rdp_settings->SendPreconnectionPdu = TRUE; + rdp_settings->PreconnectionId = guac_settings->preconnection_id; + } + + /* Preconnection BLOB */ + if (guac_settings->preconnection_blob != NULL) { + rdp_settings->NegotiateSecurityLayer = FALSE; + rdp_settings->SendPreconnectionPdu = TRUE; + rdp_settings->PreconnectionBlob = guac_settings->preconnection_blob; + } +#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 e93ab9a1..aa60b568 100644 --- a/src/protocols/rdp/rdp_settings.h +++ b/src/protocols/rdp/rdp_settings.h @@ -266,6 +266,20 @@ typedef struct guac_rdp_settings { */ int menu_animations_enabled; + /** + * The preconnection ID to send within the preconnection PDU when + * initiating an RDP connection, if any. If no preconnection ID is + * specified, this will be -1. + */ + int preconnection_id; + + /** + * The preconnection BLOB (PCB) to send to the RDP server prior to full RDP + * connection negotiation. This value is used by Hyper-V to select the + * destination VM. + */ + char* preconnection_blob; + } guac_rdp_settings; /**