int guac_client_init(guac_client* client, int argc, char** argv) { rdp_guac_client_data* guac_client_data; guac_rdp_settings* settings; freerdp* rdp_inst; /* Validate number of arguments received */ if (argc != RDP_ARGS_COUNT) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Wrong argument count received."); return 1; } /* Allocate client data */ guac_client_data = malloc(sizeof(rdp_guac_client_data)); /* Init random number generator */ srandom(time(NULL)); /* Init client */ #ifdef HAVE_FREERDP_CHANNELS_GLOBAL_INIT freerdp_channels_global_init(); #endif rdp_inst = freerdp_new(); rdp_inst->PreConnect = rdp_freerdp_pre_connect; rdp_inst->PostConnect = rdp_freerdp_post_connect; rdp_inst->Authenticate = rdp_freerdp_authenticate; rdp_inst->VerifyCertificate = rdp_freerdp_verify_certificate; rdp_inst->ReceiveChannelData = __guac_receive_channel_data; /* Allocate FreeRDP context */ #ifdef LEGACY_FREERDP rdp_inst->context_size = sizeof(rdp_freerdp_context); #else rdp_inst->ContextSize = sizeof(rdp_freerdp_context); #endif rdp_inst->ContextNew = (pContextNew) rdp_freerdp_context_new; rdp_inst->ContextFree = (pContextFree) rdp_freerdp_context_free; freerdp_context_new(rdp_inst); /* Set settings */ settings = &(guac_client_data->settings); /* Console */ settings->console = (strcmp(argv[IDX_CONSOLE], "true") == 0); settings->console_audio = (strcmp(argv[IDX_CONSOLE_AUDIO], "true") == 0); /* Certificate and auth */ settings->ignore_certificate = (strcmp(argv[IDX_IGNORE_CERT], "true") == 0); settings->disable_authentication = (strcmp(argv[IDX_DISABLE_AUTH], "true") == 0); /* NLA security */ if (strcmp(argv[IDX_SECURITY], "nla") == 0) { guac_client_log(client, GUAC_LOG_INFO, "Security mode: NLA"); settings->security_mode = GUAC_SECURITY_NLA; } /* TLS security */ else if (strcmp(argv[IDX_SECURITY], "tls") == 0) { guac_client_log(client, GUAC_LOG_INFO, "Security mode: TLS"); settings->security_mode = GUAC_SECURITY_TLS; } /* RDP security */ else if (strcmp(argv[IDX_SECURITY], "rdp") == 0) { guac_client_log(client, GUAC_LOG_INFO, "Security mode: RDP"); settings->security_mode = GUAC_SECURITY_RDP; } /* ANY security (allow server to choose) */ else if (strcmp(argv[IDX_SECURITY], "any") == 0) { guac_client_log(client, GUAC_LOG_INFO, "Security mode: ANY"); settings->security_mode = GUAC_SECURITY_ANY; } /* If nothing given, default to RDP */ else { guac_client_log(client, GUAC_LOG_INFO, "No security mode specified. Defaulting to RDP."); settings->security_mode = GUAC_SECURITY_RDP; } /* Set hostname */ settings->hostname = strdup(argv[IDX_HOSTNAME]); /* If port specified, use it */ settings->port = RDP_DEFAULT_PORT; if (argv[IDX_PORT][0] != '\0') settings->port = atoi(argv[IDX_PORT]); guac_client_log(client, GUAC_LOG_DEBUG, "Client resolution is %ix%i at %i DPI", client->info.optimal_width, client->info.optimal_height, client->info.optimal_resolution); /* Use suggested resolution unless overridden */ settings->resolution = guac_rdp_suggest_resolution(client); if (argv[IDX_DPI][0] != '\0') settings->resolution = atoi(argv[IDX_DPI]); /* Use optimal width unless overridden */ settings->width = client->info.optimal_width * settings->resolution / client->info.optimal_resolution; if (argv[IDX_WIDTH][0] != '\0') settings->width = atoi(argv[IDX_WIDTH]); /* Use default width if given width is invalid. */ if (settings->width <= 0) { settings->width = RDP_DEFAULT_WIDTH; guac_client_log(client, GUAC_LOG_ERROR, "Invalid width: \"%s\". Using default of %i.", argv[IDX_WIDTH], settings->width); } /* Round width down to nearest multiple of 4 */ settings->width = settings->width & ~0x3; /* Use optimal height unless overridden */ settings->height = client->info.optimal_height * settings->resolution / client->info.optimal_resolution; if (argv[IDX_HEIGHT][0] != '\0') settings->height = atoi(argv[IDX_HEIGHT]); /* Use default height if given height is invalid. */ if (settings->height <= 0) { settings->height = RDP_DEFAULT_HEIGHT; guac_client_log(client, GUAC_LOG_ERROR, "Invalid height: \"%s\". Using default of %i.", argv[IDX_WIDTH], settings->height); } guac_client_log(client, GUAC_LOG_DEBUG, "Using resolution of %ix%i at %i DPI", settings->width, settings->height, settings->resolution); /* Domain */ settings->domain = NULL; if (argv[IDX_DOMAIN][0] != '\0') settings->domain = strdup(argv[IDX_DOMAIN]); /* Username */ settings->username = NULL; if (argv[IDX_USERNAME][0] != '\0') settings->username = strdup(argv[IDX_USERNAME]); /* Password */ settings->password = NULL; if (argv[IDX_PASSWORD][0] != '\0') settings->password = strdup(argv[IDX_PASSWORD]); /* Client name */ settings->client_name = NULL; if (argv[IDX_CLIENT_NAME][0] != '\0') settings->client_name = strdup(argv[IDX_CLIENT_NAME]); /* Initial program */ settings->initial_program = NULL; if (argv[IDX_INITIAL_PROGRAM][0] != '\0') settings->initial_program = strdup(argv[IDX_INITIAL_PROGRAM]); /* RemoteApp program */ settings->remote_app = NULL; if (argv[IDX_REMOTE_APP][0] != '\0') settings->remote_app = strdup(argv[IDX_REMOTE_APP]); /* RemoteApp working directory */ settings->remote_app_dir = NULL; if (argv[IDX_REMOTE_APP_DIR][0] != '\0') settings->remote_app_dir = strdup(argv[IDX_REMOTE_APP_DIR]); /* RemoteApp arguments */ settings->remote_app_args = NULL; if (argv[IDX_REMOTE_APP_ARGS][0] != '\0') settings->remote_app_args = strdup(argv[IDX_REMOTE_APP_ARGS]); /* Static virtual channels */ settings->svc_names = NULL; if (argv[IDX_STATIC_CHANNELS][0] != '\0') settings->svc_names = guac_split(argv[IDX_STATIC_CHANNELS], ','); /* Performance flags */ settings->wallpaper_enabled = (strcmp(argv[IDX_ENABLE_WALLPAPER], "true") == 0); settings->theming_enabled = (strcmp(argv[IDX_ENABLE_THEMING], "true") == 0); settings->font_smoothing_enabled = (strcmp(argv[IDX_ENABLE_FONT_SMOOTHING], "true") == 0); settings->full_window_drag_enabled = (strcmp(argv[IDX_ENABLE_FULL_WINDOW_DRAG], "true") == 0); settings->desktop_composition_enabled = (strcmp(argv[IDX_ENABLE_DESKTOP_COMPOSITION], "true") == 0); settings->menu_animations_enabled = (strcmp(argv[IDX_ENABLE_MENU_ANIMATIONS], "true") == 0); /* Session color depth */ settings->color_depth = RDP_DEFAULT_DEPTH; if (argv[IDX_COLOR_DEPTH][0] != '\0') settings->color_depth = atoi(argv[IDX_COLOR_DEPTH]); /* Use default depth if given depth is invalid. */ if (settings->color_depth == 0) { settings->color_depth = RDP_DEFAULT_DEPTH; guac_client_log(client, GUAC_LOG_ERROR, "Invalid color-depth: \"%s\". Using default of %i.", argv[IDX_WIDTH], settings->color_depth); } /* Audio enable/disable */ guac_client_data->settings.audio_enabled = (strcmp(argv[IDX_DISABLE_AUDIO], "true") != 0); /* Printing enable/disable */ guac_client_data->settings.printing_enabled = (strcmp(argv[IDX_ENABLE_PRINTING], "true") == 0); /* Drive enable/disable */ guac_client_data->settings.drive_enabled = (strcmp(argv[IDX_ENABLE_DRIVE], "true") == 0); guac_client_data->settings.drive_path = strdup(argv[IDX_DRIVE_PATH]); guac_client_data->settings.create_drive_path = (strcmp(argv[IDX_CREATE_DRIVE_PATH], "true") == 0); /* Store client data */ guac_client_data->rdp_inst = rdp_inst; guac_client_data->mouse_button_mask = 0; guac_client_data->clipboard = guac_common_clipboard_alloc(GUAC_RDP_CLIPBOARD_MAX_LENGTH); guac_client_data->requested_clipboard_format = CB_FORMAT_TEXT; guac_client_data->audio = NULL; guac_client_data->filesystem = NULL; guac_client_data->available_svc = guac_common_list_alloc(); /* Main socket needs to be threadsafe */ guac_socket_require_threadsafe(client->socket); /* Recursive attribute for locks */ pthread_mutexattr_init(&(guac_client_data->attributes)); pthread_mutexattr_settype(&(guac_client_data->attributes), PTHREAD_MUTEX_RECURSIVE); /* Init RDP lock */ pthread_mutex_init(&(guac_client_data->rdp_lock), &(guac_client_data->attributes)); /* Clear keysym state mapping and keymap */ memset(guac_client_data->keysym_state, 0, sizeof(guac_rdp_keysym_state_map)); memset(guac_client_data->keymap, 0, sizeof(guac_rdp_static_keymap)); client->data = guac_client_data; ((rdp_freerdp_context*) rdp_inst->context)->client = client; /* Pick keymap based on argument */ settings->server_layout = NULL; if (argv[IDX_SERVER_LAYOUT][0] != '\0') settings->server_layout = guac_rdp_keymap_find(argv[IDX_SERVER_LAYOUT]); /* If no keymap requested, use default */ if (settings->server_layout == NULL) settings->server_layout = guac_rdp_keymap_find(GUAC_DEFAULT_KEYMAP); /* Load keymap into client */ __guac_rdp_client_load_keymap(client, settings->server_layout); #ifdef ENABLE_COMMON_SSH guac_common_ssh_init(client); /* Connect via SSH if SFTP is enabled */ if (strcmp(argv[IDX_ENABLE_SFTP], "true") == 0) { guac_client_log(client, GUAC_LOG_DEBUG, "Connecting via SSH for SFTP filesystem access."); /* Parse username - use RDP username by default */ const char* sftp_username = argv[IDX_SFTP_USERNAME]; if (sftp_username[0] == '\0' && settings->username != NULL) sftp_username = settings->username; guac_client_data->sftp_user = guac_common_ssh_create_user(sftp_username); /* Import private key, if given */ if (argv[IDX_SFTP_PRIVATE_KEY][0] != '\0') { guac_client_log(client, GUAC_LOG_DEBUG, "Authenticating with private key."); /* Abort if private key cannot be read */ if (guac_common_ssh_user_import_key(guac_client_data->sftp_user, argv[IDX_SFTP_PRIVATE_KEY], argv[IDX_SFTP_PASSPHRASE])) { guac_common_ssh_destroy_user(guac_client_data->sftp_user); return 1; } } /* Otherwise, use specified password */ else { guac_client_log(client, GUAC_LOG_DEBUG, "Authenticating with password."); /* Parse password - use RDP password by default */ const char* sftp_password = argv[IDX_SFTP_PASSWORD]; if (sftp_password[0] == '\0' && settings->password != NULL) sftp_password = settings->password; guac_common_ssh_user_set_password(guac_client_data->sftp_user, sftp_password); } /* Parse hostname - use RDP hostname by default */ const char* sftp_hostname = argv[IDX_SFTP_HOSTNAME]; if (sftp_hostname[0] == '\0') sftp_hostname = settings->hostname; /* Parse port, defaulting to standard SSH port */ const char* sftp_port = argv[IDX_SFTP_PORT]; if (sftp_port[0] == '\0') sftp_port = "22"; /* Attempt SSH connection */ guac_client_data->sftp_session = guac_common_ssh_create_session(client, sftp_hostname, sftp_port, guac_client_data->sftp_user); /* Fail if SSH connection does not succeed */ if (guac_client_data->sftp_session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ guac_common_ssh_destroy_user(guac_client_data->sftp_user); return 1; } /* Load and expose filesystem */ guac_client_data->sftp_filesystem = guac_common_ssh_create_sftp_filesystem( guac_client_data->sftp_session, "/"); /* Abort if SFTP connection fails */ if (guac_client_data->sftp_filesystem == NULL) { guac_common_ssh_destroy_session(guac_client_data->sftp_session); guac_common_ssh_destroy_user(guac_client_data->sftp_user); return 1; } /* Configure destination for basic uploads, if specified */ if (argv[IDX_SFTP_DIRECTORY][0] != '\0') { client->file_handler = guac_rdp_sftp_file_handler; guac_common_ssh_sftp_set_upload_path( guac_client_data->sftp_filesystem, argv[IDX_SFTP_DIRECTORY]); } /* Otherwise, use SFTP for basic uploads only if drive not enabled */ else if (!settings->drive_enabled) client->file_handler = guac_rdp_sftp_file_handler; guac_client_log(client, GUAC_LOG_DEBUG, "SFTP connection succeeded."); } #endif /* Create default surface */ guac_client_data->default_surface = guac_common_surface_alloc(client->socket, GUAC_DEFAULT_LAYER, settings->width, settings->height); guac_client_data->current_surface = guac_client_data->default_surface; /* Send connection name */ guac_protocol_send_name(client->socket, settings->hostname); /* Set default pointer */ guac_common_set_pointer_cursor(client); /* Push desired settings to FreeRDP */ guac_rdp_push_settings(settings, rdp_inst); /* Connect to RDP server */ if (!freerdp_connect(rdp_inst)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Error connecting to RDP server"); return 1; } /* Success */ return 0; }
guac_rdp_settings* guac_rdp_parse_args(guac_user* user, int argc, const char** argv) { /* Validate arg count */ if (argc != RDP_ARGS_COUNT) { guac_user_log(user, GUAC_LOG_WARNING, "Incorrect number of connection " "parameters provided: expected %i, got %i.", RDP_ARGS_COUNT, argc); return NULL; } guac_rdp_settings* settings = calloc(1, sizeof(guac_rdp_settings)); /* Use console */ settings->console = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_CONSOLE, 0); /* Enable/disable console audio */ settings->console_audio = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_CONSOLE_AUDIO, 0); /* Ignore SSL/TLS certificate */ settings->ignore_certificate = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_IGNORE_CERT, 0); /* Disable authentication */ settings->disable_authentication = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_DISABLE_AUTH, 0); /* NLA security */ if (strcmp(argv[IDX_SECURITY], "nla") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Security mode: NLA"); settings->security_mode = GUAC_SECURITY_NLA; } /* TLS security */ else if (strcmp(argv[IDX_SECURITY], "tls") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Security mode: TLS"); settings->security_mode = GUAC_SECURITY_TLS; } /* RDP security */ else if (strcmp(argv[IDX_SECURITY], "rdp") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Security mode: RDP"); settings->security_mode = GUAC_SECURITY_RDP; } /* ANY security (allow server to choose) */ else if (strcmp(argv[IDX_SECURITY], "any") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Security mode: ANY"); settings->security_mode = GUAC_SECURITY_ANY; } /* If nothing given, default to RDP */ else { guac_user_log(user, GUAC_LOG_INFO, "No security mode specified. Defaulting to RDP."); settings->security_mode = GUAC_SECURITY_RDP; } /* Set hostname */ settings->hostname = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_HOSTNAME, ""); /* If port specified, use it */ settings->port = guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_PORT, RDP_DEFAULT_PORT); guac_user_log(user, GUAC_LOG_DEBUG, "User resolution is %ix%i at %i DPI", user->info.optimal_width, user->info.optimal_height, user->info.optimal_resolution); /* Use suggested resolution unless overridden */ settings->resolution = guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_DPI, guac_rdp_suggest_resolution(user)); /* Use optimal width unless overridden */ settings->width = user->info.optimal_width * settings->resolution / user->info.optimal_resolution; if (argv[IDX_WIDTH][0] != '\0') settings->width = atoi(argv[IDX_WIDTH]); /* Use default width if given width is invalid. */ if (settings->width <= 0) { settings->width = RDP_DEFAULT_WIDTH; guac_user_log(user, GUAC_LOG_ERROR, "Invalid width: \"%s\". Using default of %i.", argv[IDX_WIDTH], settings->width); } /* Round width down to nearest multiple of 4 */ settings->width = settings->width & ~0x3; /* Use optimal height unless overridden */ settings->height = user->info.optimal_height * settings->resolution / user->info.optimal_resolution; if (argv[IDX_HEIGHT][0] != '\0') settings->height = atoi(argv[IDX_HEIGHT]); /* Use default height if given height is invalid. */ if (settings->height <= 0) { settings->height = RDP_DEFAULT_HEIGHT; guac_user_log(user, GUAC_LOG_ERROR, "Invalid height: \"%s\". Using default of %i.", argv[IDX_WIDTH], settings->height); } guac_user_log(user, GUAC_LOG_DEBUG, "Using resolution of %ix%i at %i DPI", settings->width, settings->height, settings->resolution); /* Domain */ settings->domain = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_DOMAIN, NULL); /* Username */ settings->username = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_USERNAME, NULL); /* Password */ settings->password = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_PASSWORD, NULL); /* Read-only mode */ settings->read_only = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_READ_ONLY, 0); /* Client name */ settings->client_name = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_CLIENT_NAME, NULL); /* Initial program */ settings->initial_program = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_INITIAL_PROGRAM, NULL); /* RemoteApp program */ settings->remote_app = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_REMOTE_APP, NULL); /* RemoteApp working directory */ settings->remote_app_dir = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_REMOTE_APP_DIR, NULL); /* RemoteApp arguments */ settings->remote_app_args = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_REMOTE_APP_ARGS, NULL); /* Static virtual channels */ settings->svc_names = NULL; if (argv[IDX_STATIC_CHANNELS][0] != '\0') settings->svc_names = guac_split(argv[IDX_STATIC_CHANNELS], ','); /* * Performance flags */ settings->wallpaper_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_WALLPAPER, 0); settings->theming_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_THEMING, 0); settings->font_smoothing_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_FONT_SMOOTHING, 0); settings->full_window_drag_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_FULL_WINDOW_DRAG, 0); settings->desktop_composition_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_DESKTOP_COMPOSITION, 0); settings->menu_animations_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_MENU_ANIMATIONS, 0); /* Session color depth */ settings->color_depth = guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_COLOR_DEPTH, RDP_DEFAULT_DEPTH); /* Preconnection ID */ settings->preconnection_id = -1; if (argv[IDX_PRECONNECTION_ID][0] != '\0') { /* Parse preconnection ID, warn if invalid */ int preconnection_id = atoi(argv[IDX_PRECONNECTION_ID]); if (preconnection_id < 0) guac_user_log(user, GUAC_LOG_WARNING, "Ignoring invalid preconnection ID: %i", preconnection_id); /* Otherwise, assign specified ID */ else { settings->preconnection_id = preconnection_id; guac_user_log(user, 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_user_log(user, 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_user_log(user, 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 */ settings->audio_enabled = !guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_DISABLE_AUDIO, 0); /* Printing enable/disable */ settings->printing_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_PRINTING, 0); /* Drive enable/disable */ settings->drive_enabled = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_DRIVE, 0); settings->drive_path = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_DRIVE_PATH, ""); settings->create_drive_path = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_CREATE_DRIVE_PATH, 0); /* Pick keymap based on argument */ settings->server_layout = NULL; if (argv[IDX_SERVER_LAYOUT][0] != '\0') settings->server_layout = guac_rdp_keymap_find(argv[IDX_SERVER_LAYOUT]); /* If no keymap requested, use default */ if (settings->server_layout == NULL) settings->server_layout = guac_rdp_keymap_find(GUAC_DEFAULT_KEYMAP); #ifdef ENABLE_COMMON_SSH /* SFTP enable/disable */ settings->enable_sftp = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_ENABLE_SFTP, 0); /* Hostname for SFTP connection */ settings->sftp_hostname = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_HOSTNAME, settings->hostname); /* Port for SFTP connection */ settings->sftp_port = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PORT, "22"); /* Username for SSH/SFTP authentication */ settings->sftp_username = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_USERNAME, settings->username != NULL ? settings->username : ""); /* Password for SFTP (if not using private key) */ settings->sftp_password = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PASSWORD, ""); /* Private key for SFTP (if not using password) */ settings->sftp_private_key = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PRIVATE_KEY, NULL); /* Passphrase for decrypting the SFTP private key (if applicable */ settings->sftp_passphrase = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_PASSPHRASE, ""); /* Default upload directory */ settings->sftp_directory = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_DIRECTORY, NULL); /* SFTP root directory */ settings->sftp_root_directory = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_ROOT_DIRECTORY, "/"); /* Default keepalive value */ settings->sftp_server_alive_interval = guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_SFTP_SERVER_ALIVE_INTERVAL, 0); #endif /* Read recording path */ settings->recording_path = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_RECORDING_PATH, NULL); /* Read recording name */ settings->recording_name = guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_RECORDING_NAME, GUAC_RDP_DEFAULT_RECORDING_NAME); /* Parse path creation flag */ settings->create_recording_path = guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_CREATE_RECORDING_PATH, 0); /* No resize method */ if (strcmp(argv[IDX_RESIZE_METHOD], "") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Resize method: none"); settings->resize_method = GUAC_RESIZE_NONE; } /* Resize method: "reconnect" */ else if (strcmp(argv[IDX_RESIZE_METHOD], "reconnect") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Resize method: reconnect"); settings->resize_method = GUAC_RESIZE_RECONNECT; } /* Resize method: "display-update" */ else if (strcmp(argv[IDX_RESIZE_METHOD], "display-update") == 0) { guac_user_log(user, GUAC_LOG_INFO, "Resize method: display-update"); settings->resize_method = GUAC_RESIZE_DISPLAY_UPDATE; } /* Default to no resize method if invalid */ else { guac_user_log(user, GUAC_LOG_INFO, "Resize method \"%s\" invalid. ", "Defaulting to no resize method.", argv[IDX_RESIZE_METHOD]); settings->resize_method = GUAC_RESIZE_NONE; } /* Audio input enable/disable */ settings->enable_audio_input = 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; }