settings.c (55148B)
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20#include "argv.h" 21#include "common/defaults.h" 22#include "common/string.h" 23#include "config.h" 24#include "resolution.h" 25#include "settings.h" 26 27#include <freerdp/constants.h> 28#include <freerdp/settings.h> 29#include <freerdp/freerdp.h> 30#include <guacamole/client.h> 31#include <guacamole/mem.h> 32#include <guacamole/fips.h> 33#include <guacamole/string.h> 34#include <guacamole/user.h> 35#include <guacamole/wol-constants.h> 36#include <winpr/crt.h> 37#include <winpr/wtypes.h> 38 39#include <errno.h> 40#include <stddef.h> 41#include <stdlib.h> 42#include <string.h> 43 44/** 45 * A warning to log when NLA mode is selected while FIPS mode is active on the 46 * guacd server. 47 */ 48const char fips_nla_mode_warning[] = ( 49 "NLA security mode was selected, but is known to be currently incompatible " 50 "with FIPS mode (see FreeRDP/FreeRDP#3412). Security negotiation with the " 51 "RDP server may fail unless TLS security mode is selected instead." 52); 53 54/* Client plugin arguments */ 55const char* GUAC_RDP_CLIENT_ARGS[] = { 56 "hostname", 57 "port", 58 GUAC_RDP_ARGV_DOMAIN, 59 GUAC_RDP_ARGV_USERNAME, 60 GUAC_RDP_ARGV_PASSWORD, 61 "width", 62 "height", 63 "dpi", 64 "initial-program", 65 "color-depth", 66 "disable-audio", 67 "enable-printing", 68 "printer-name", 69 "enable-drive", 70 "drive-name", 71 "drive-path", 72 "create-drive-path", 73 "disable-download", 74 "disable-upload", 75 "console", 76 "console-audio", 77 "server-layout", 78 "security", 79 "ignore-cert", 80 "disable-auth", 81 "remote-app", 82 "remote-app-dir", 83 "remote-app-args", 84 "static-channels", 85 "client-name", 86 "enable-wallpaper", 87 "enable-theming", 88 "enable-font-smoothing", 89 "enable-full-window-drag", 90 "enable-desktop-composition", 91 "enable-menu-animations", 92 "disable-bitmap-caching", 93 "disable-offscreen-caching", 94 "disable-glyph-caching", 95 "preconnection-id", 96 "preconnection-blob", 97 "timezone", 98 99#ifdef ENABLE_COMMON_SSH 100 "enable-sftp", 101 "sftp-hostname", 102 "sftp-host-key", 103 "sftp-port", 104 "sftp-username", 105 "sftp-password", 106 "sftp-private-key", 107 "sftp-passphrase", 108 "sftp-directory", 109 "sftp-root-directory", 110 "sftp-server-alive-interval", 111 "sftp-disable-download", 112 "sftp-disable-upload", 113#endif 114 115 "recording-path", 116 "recording-name", 117 "recording-exclude-output", 118 "recording-exclude-mouse", 119 "recording-exclude-touch", 120 "recording-include-keys", 121 "create-recording-path", 122 "resize-method", 123 "enable-audio-input", 124 "enable-touch", 125 "read-only", 126 127 "gateway-hostname", 128 "gateway-port", 129 "gateway-domain", 130 "gateway-username", 131 "gateway-password", 132 133 "load-balance-info", 134 135 "disable-copy", 136 "disable-paste", 137 138 "wol-send-packet", 139 "wol-mac-addr", 140 "wol-broadcast-addr", 141 "wol-udp-port", 142 "wol-wait-time", 143 144 "force-lossless", 145 "normalize-clipboard", 146 NULL 147}; 148 149enum RDP_ARGS_IDX { 150 151 /** 152 * The hostname to connect to. 153 */ 154 IDX_HOSTNAME, 155 156 /** 157 * The port to connect to. If omitted, the default RDP port of 3389 will be 158 * used. 159 */ 160 IDX_PORT, 161 162 /** 163 * The domain of the user logging in. 164 */ 165 IDX_DOMAIN, 166 167 /** 168 * The username of the user logging in. 169 */ 170 IDX_USERNAME, 171 172 /** 173 * The password of the user logging in. 174 */ 175 IDX_PASSWORD, 176 177 /** 178 * The width of the display to request, in pixels. If omitted, a reasonable 179 * value will be calculated based on the user's own display size and 180 * resolution. 181 */ 182 IDX_WIDTH, 183 184 /** 185 * The height of the display to request, in pixels. If omitted, a 186 * reasonable value will be calculated based on the user's own display 187 * size and resolution. 188 */ 189 IDX_HEIGHT, 190 191 /** 192 * The resolution of the display to request, in DPI. If omitted, a 193 * reasonable value will be calculated based on the user's own display 194 * size and resolution. 195 */ 196 IDX_DPI, 197 198 /** 199 * The initial program to run, if any. 200 */ 201 IDX_INITIAL_PROGRAM, 202 203 /** 204 * The color depth of the display to request, in bits. 205 */ 206 IDX_COLOR_DEPTH, 207 208 /** 209 * "true" if audio should be disabled, "false" or blank to leave audio 210 * enabled. 211 */ 212 IDX_DISABLE_AUDIO, 213 214 /** 215 * "true" if printing should be enabled, "false" or blank otherwise. 216 */ 217 IDX_ENABLE_PRINTING, 218 219 /** 220 * The name of the printer that will be passed through to the RDP server. 221 */ 222 IDX_PRINTER_NAME, 223 224 /** 225 * "true" if the virtual drive should be enabled, "false" or blank 226 * otherwise. 227 */ 228 IDX_ENABLE_DRIVE, 229 230 /** 231 * The name of the virtual driver that will be passed through to the 232 * RDP connection. 233 */ 234 IDX_DRIVE_NAME, 235 236 /** 237 * The local system path which will be used to persist the 238 * virtual drive. This must be specified if the virtual drive is enabled. 239 */ 240 IDX_DRIVE_PATH, 241 242 /** 243 * "true" to automatically create the local system path used by the virtual 244 * drive if it does not yet exist, "false" or blank otherwise. 245 */ 246 IDX_CREATE_DRIVE_PATH, 247 248 /** 249 * "true" to disable the ability to download files from a remote server to 250 * the local client over RDP, "false" or blank otherwise. 251 */ 252 IDX_DISABLE_DOWNLOAD, 253 254 /** 255 * "true" to disable the ability to upload files from the local client to 256 * the remote server over RDP, "false" or blank otherwise. 257 */ 258 IDX_DISABLE_UPLOAD, 259 260 /** 261 * "true" if this session is a console session, "false" or blank otherwise. 262 */ 263 IDX_CONSOLE, 264 265 /** 266 * "true" if audio should be allowed in console sessions, "false" or blank 267 * otherwise. 268 */ 269 IDX_CONSOLE_AUDIO, 270 271 /** 272 * The name of the keymap chosen as the layout of the server. Legal names 273 * are defined within the *.keymap files in the "keymaps" directory of the 274 * source for Guacamole's RDP support. 275 */ 276 IDX_SERVER_LAYOUT, 277 278 /** 279 * The type of security to use for the connection. Valid values are "rdp", 280 * "tls", "nla", "nla-ext", "vmconnect", or "any". By default, the security 281 * mode is negotiated ("any"). 282 */ 283 IDX_SECURITY, 284 285 /** 286 * "true" if validity of the RDP server's certificate should be ignored, 287 * "false" or blank if invalid certificates should result in a failure to 288 * connect. 289 */ 290 IDX_IGNORE_CERT, 291 292 /** 293 * "true" if authentication should be disabled, "false" or blank otherwise. 294 * This is different from the authentication that takes place when a user 295 * provides their username and password. Authentication is required by 296 * definition for NLA. 297 */ 298 IDX_DISABLE_AUTH, 299 300 /** 301 * The application to launch, if RemoteApp is in use. 302 */ 303 IDX_REMOTE_APP, 304 305 /** 306 * The working directory of the remote application, if RemoteApp is in use. 307 */ 308 IDX_REMOTE_APP_DIR, 309 310 /** 311 * The arguments to pass to the remote application, if RemoteApp is in use. 312 */ 313 IDX_REMOTE_APP_ARGS, 314 315 /** 316 * Comma-separated list of the names of all static virtual channels that 317 * should be connected to and exposed as Guacamole pipe streams, or blank 318 * if no static virtual channels should be used. 319 */ 320 IDX_STATIC_CHANNELS, 321 322 /** 323 * The name of the client to submit to the RDP server upon connection. 324 */ 325 IDX_CLIENT_NAME, 326 327 /** 328 * "true" if the desktop wallpaper should be visible, "false" or blank if 329 * the desktop wallpaper should be hidden. 330 */ 331 IDX_ENABLE_WALLPAPER, 332 333 /** 334 * "true" if desktop and window theming should be allowed, "false" or blank 335 * if theming should be temporarily disabled on the desktop of the RDP 336 * server for the sake of performance. 337 */ 338 IDX_ENABLE_THEMING, 339 340 /** 341 * "true" if glyphs should be smoothed with antialiasing (ClearType), 342 * "false" or blank if glyphs should be rendered with sharp edges and using 343 * single colors, effectively 1-bit images. 344 */ 345 IDX_ENABLE_FONT_SMOOTHING, 346 347 /** 348 * "true" if windows' contents should be shown as they are moved, "false" 349 * or blank if only a window border should be shown during window move 350 * operations. 351 */ 352 IDX_ENABLE_FULL_WINDOW_DRAG, 353 354 /** 355 * "true" if desktop composition (Aero) should be enabled during the 356 * session, "false" or blank otherwise. As desktop composition provides 357 * alpha blending and other special effects, this increases the amount of 358 * bandwidth used. 359 */ 360 IDX_ENABLE_DESKTOP_COMPOSITION, 361 362 /** 363 * "true" if menu animations should be shown, "false" or blank menus should 364 * not be animated. 365 */ 366 IDX_ENABLE_MENU_ANIMATIONS, 367 368 /** 369 * "true" if bitmap caching should be disabled, "false" if bitmap caching 370 * should remain enabled. 371 */ 372 IDX_DISABLE_BITMAP_CACHING, 373 374 /** 375 * "true" if the offscreen caching should be disabled, false if offscreen 376 * caching should remain enabled. 377 */ 378 IDX_DISABLE_OFFSCREEN_CACHING, 379 380 /** 381 * "true" if glyph caching should be disabled, false if glyph caching should 382 * remain enabled. 383 */ 384 IDX_DISABLE_GLYPH_CACHING, 385 386 /** 387 * The preconnection ID to send within the preconnection PDU when 388 * initiating an RDP connection, if any. 389 */ 390 IDX_PRECONNECTION_ID, 391 392 /** 393 * The preconnection BLOB (PCB) to send to the RDP server prior to full RDP 394 * connection negotiation. This value is used by Hyper-V to select the 395 * destination VM. 396 */ 397 IDX_PRECONNECTION_BLOB, 398 399 /** 400 * The timezone to pass through to the RDP connection, in IANA format, which 401 * will be translated into Windows formats. See the following page for 402 * information and list of valid values: 403 * https://en.wikipedia.org/wiki/List_of_tz_database_time_zones 404 */ 405 IDX_TIMEZONE, 406 407#ifdef ENABLE_COMMON_SSH 408 /** 409 * "true" if SFTP should be enabled for the RDP connection, "false" or 410 * blank otherwise. 411 */ 412 IDX_ENABLE_SFTP, 413 414 /** 415 * The hostname of the SSH server to connect to for SFTP. If blank, the 416 * hostname of the RDP server will be used. 417 */ 418 IDX_SFTP_HOSTNAME, 419 420 /** 421 * The public SSH host key of the SFTP server. Optional. 422 */ 423 IDX_SFTP_HOST_KEY, 424 425 /** 426 * The port of the SSH server to connect to for SFTP. If blank, the default 427 * SSH port of "22" will be used. 428 */ 429 IDX_SFTP_PORT, 430 431 /** 432 * The username to provide when authenticating with the SSH server for 433 * SFTP. If blank, the username provided for the RDP user will be used. 434 */ 435 IDX_SFTP_USERNAME, 436 437 /** 438 * The password to provide when authenticating with the SSH server for 439 * SFTP (if not using a private key). 440 */ 441 IDX_SFTP_PASSWORD, 442 443 /** 444 * The base64-encoded private key to use when authenticating with the SSH 445 * server for SFTP (if not using a password). 446 */ 447 IDX_SFTP_PRIVATE_KEY, 448 449 /** 450 * The passphrase to use to decrypt the provided base64-encoded private 451 * key. 452 */ 453 IDX_SFTP_PASSPHRASE, 454 455 /** 456 * The default location for file uploads within the SSH server. This will 457 * apply only to uploads which do not use the filesystem guac_object (where 458 * the destination directory is otherwise ambiguous). 459 */ 460 IDX_SFTP_DIRECTORY, 461 462 /** 463 * The path of the directory within the SSH server to expose as a 464 * filesystem guac_object. If omitted, "/" will be used by default. 465 */ 466 IDX_SFTP_ROOT_DIRECTORY, 467 468 /** 469 * The interval at which SSH keepalive messages are sent to the server for 470 * SFTP connections. The default is 0 (disabling keepalives), and a value 471 * of 1 is automatically increased to 2 by libssh2 to avoid busy loop corner 472 * cases. 473 */ 474 IDX_SFTP_SERVER_ALIVE_INTERVAL, 475 476 /** 477 * "true" to disable file download from the SFTP server to the local client 478 * over the SFTP connection, if SFTP is configured and enabled. "false" or 479 * blank otherwise. 480 */ 481 IDX_SFTP_DISABLE_DOWNLOAD, 482 483 /** 484 * "true" to disable file upload from the SFTP server to the local client 485 * over the SFTP connection, if SFTP is configured and enabled. "false" or 486 * blank otherwise. 487 */ 488 IDX_SFTP_DISABLE_UPLOAD, 489#endif 490 491 /** 492 * The full absolute path to the directory in which screen recordings 493 * should be written. 494 */ 495 IDX_RECORDING_PATH, 496 497 /** 498 * The name that should be given to screen recordings which are written in 499 * the given path. 500 */ 501 IDX_RECORDING_NAME, 502 503 /** 504 * Whether output which is broadcast to each connected client (graphics, 505 * streams, etc.) should NOT be included in the session recording. Output 506 * is included by default, as it is necessary for any recording which must 507 * later be viewable as video. 508 */ 509 IDX_RECORDING_EXCLUDE_OUTPUT, 510 511 /** 512 * Whether changes to mouse state, such as position and buttons pressed or 513 * released, should NOT be included in the session recording. Mouse state 514 * is included by default, as it is necessary for the mouse cursor to be 515 * rendered in any resulting video. 516 */ 517 IDX_RECORDING_EXCLUDE_MOUSE, 518 519 /** 520 * Whether changes to touch contact state should NOT be included in the 521 * session recording. Touch state is included by default, as it may be 522 * necessary for touch interactions to be rendered in any resulting video. 523 */ 524 IDX_RECORDING_EXCLUDE_TOUCH, 525 526 /** 527 * Whether keys pressed and released should be included in the session 528 * recording. Key events are NOT included by default within the recording, 529 * as doing so has privacy and security implications. Including key events 530 * may be necessary in certain auditing contexts, but should only be done 531 * with caution. Key events can easily contain sensitive information, such 532 * as passwords, credit card numbers, etc. 533 */ 534 IDX_RECORDING_INCLUDE_KEYS, 535 536 /** 537 * Whether the specified screen recording path should automatically be 538 * created if it does not yet exist. 539 */ 540 IDX_CREATE_RECORDING_PATH, 541 542 /** 543 * The method to use to apply screen size changes requested by the user. 544 * Valid values are blank, "display-update", and "reconnect". 545 */ 546 IDX_RESIZE_METHOD, 547 548 /** 549 * "true" if audio input (microphone) should be enabled for the RDP 550 * connection, "false" or blank otherwise. 551 */ 552 IDX_ENABLE_AUDIO_INPUT, 553 554 /** 555 * "true" if multi-touch support should be enabled for the RDP connection, 556 * "false" or blank otherwise. 557 */ 558 IDX_ENABLE_TOUCH, 559 560 /** 561 * "true" if this connection should be read-only (user input should be 562 * dropped), "false" or blank otherwise. 563 */ 564 IDX_READ_ONLY, 565 566 /** 567 * The hostname of the remote desktop gateway that should be used as an 568 * intermediary for the remote desktop connection. If omitted, a gateway 569 * will not be used. 570 */ 571 IDX_GATEWAY_HOSTNAME, 572 573 /** 574 * The port of the remote desktop gateway that should be used as an 575 * intermediary for the remote desktop connection. By default, this will be 576 * 443. 577 * 578 * NOTE: If using a version of FreeRDP prior to 1.2, this setting has no 579 * effect. FreeRDP instead uses a hard-coded value of 443. 580 */ 581 IDX_GATEWAY_PORT, 582 583 /** 584 * The domain of the user authenticating with the remote desktop gateway, 585 * if a gateway is being used. This is not necessarily the same as the 586 * user actually using the remote desktop connection. 587 */ 588 IDX_GATEWAY_DOMAIN, 589 590 /** 591 * The username of the user authenticating with the remote desktop gateway, 592 * if a gateway is being used. This is not necessarily the same as the 593 * user actually using the remote desktop connection. 594 */ 595 IDX_GATEWAY_USERNAME, 596 597 /** 598 * The password to provide when authenticating with the remote desktop 599 * gateway, if a gateway is being used. 600 */ 601 IDX_GATEWAY_PASSWORD, 602 603 /** 604 * The load balancing information/cookie which should be provided to 605 * the connection broker, if a connection broker is being used. 606 */ 607 IDX_LOAD_BALANCE_INFO, 608 609 /** 610 * Whether outbound clipboard access should be blocked. If set to "true", 611 * it will not be possible to copy data from the remote desktop to the 612 * client using the clipboard. By default, clipboard access is not blocked. 613 */ 614 IDX_DISABLE_COPY, 615 616 /** 617 * Whether inbound clipboard access should be blocked. If set to "true", it 618 * will not be possible to paste data from the client to the remote desktop 619 * using the clipboard. By default, clipboard access is not blocked. 620 */ 621 IDX_DISABLE_PASTE, 622 623 /** 624 * Whether or not to send the magic Wake-on-LAN (WoL) packet to the host 625 * prior to attempting to connect. Non-zero values will enable sending 626 * the WoL packet, while zero will disable this functionality. By default 627 * the WoL packet is not sent. 628 */ 629 IDX_WOL_SEND_PACKET, 630 631 /** 632 * The MAC address to put in the magic WoL packet for the host that should 633 * be woken up. 634 */ 635 IDX_WOL_MAC_ADDR, 636 637 /** 638 * The broadcast address to which to send the magic WoL packet to wake up 639 * the remote host. 640 */ 641 IDX_WOL_BROADCAST_ADDR, 642 643 /** 644 * The UDP port to use in the magic WoL packet. 645 */ 646 IDX_WOL_UDP_PORT, 647 648 /** 649 * The amount of time, in seconds, to wait after sending the WoL packet 650 * before attempting to connect to the host. This should be a reasonable 651 * amount of time to allow the remote host to fully boot and respond to 652 * network connection requests. The default is not to wait at all 653 * (0 seconds). 654 */ 655 IDX_WOL_WAIT_TIME, 656 657 /** 658 * "true" if all graphical updates for this connection should use lossless 659 * compresion only, "false" or blank otherwise. 660 */ 661 IDX_FORCE_LOSSLESS, 662 663 /** 664 * Controls whether the text content of the clipboard should be 665 * automatically normalized to use a particular line ending format. Valid 666 * values are "preserve", to preserve line endings verbatim, "windows" to 667 * transform all line endings to Windows-style CRLF sequences, or "unix" to 668 * transform all line endings to Unix-style newline characters ('\n'). By 669 * default, line endings within the clipboard are preserved. 670 */ 671 IDX_NORMALIZE_CLIPBOARD, 672 673 RDP_ARGS_COUNT 674}; 675 676guac_rdp_settings* guac_rdp_parse_args(guac_user* user, 677 int argc, const char** argv) { 678 679 /* Validate arg count */ 680 if (argc != RDP_ARGS_COUNT) { 681 guac_user_log(user, GUAC_LOG_WARNING, "Incorrect number of connection " 682 "parameters provided: expected %i, got %i.", 683 RDP_ARGS_COUNT, argc); 684 return NULL; 685 } 686 687 guac_rdp_settings* settings = guac_mem_zalloc(sizeof(guac_rdp_settings)); 688 689 /* Use console */ 690 settings->console = 691 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 692 IDX_CONSOLE, 0); 693 694 /* Enable/disable console audio */ 695 settings->console_audio = 696 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 697 IDX_CONSOLE_AUDIO, 0); 698 699 /* Ignore SSL/TLS certificate */ 700 settings->ignore_certificate = 701 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 702 IDX_IGNORE_CERT, 0); 703 704 /* Disable authentication */ 705 settings->disable_authentication = 706 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 707 IDX_DISABLE_AUTH, 0); 708 709 /* NLA security */ 710 if (strcmp(argv[IDX_SECURITY], "nla") == 0) { 711 guac_user_log(user, GUAC_LOG_INFO, "Security mode: NLA"); 712 settings->security_mode = GUAC_SECURITY_NLA; 713 714 /* 715 * NLA is known not to work with FIPS; allow the mode selection but 716 * warn that it will not work. 717 */ 718 if (guac_fips_enabled()) 719 guac_user_log(user, GUAC_LOG_WARNING, fips_nla_mode_warning); 720 721 } 722 723 /* Extended NLA security */ 724 else if (strcmp(argv[IDX_SECURITY], "nla-ext") == 0) { 725 guac_user_log(user, GUAC_LOG_INFO, "Security mode: Extended NLA"); 726 settings->security_mode = GUAC_SECURITY_EXTENDED_NLA; 727 728 /* 729 * NLA is known not to work with FIPS; allow the mode selection but 730 * warn that it will not work. 731 */ 732 if (guac_fips_enabled()) 733 guac_user_log(user, GUAC_LOG_WARNING, fips_nla_mode_warning); 734 } 735 736 /* TLS security */ 737 else if (strcmp(argv[IDX_SECURITY], "tls") == 0) { 738 guac_user_log(user, GUAC_LOG_INFO, "Security mode: TLS"); 739 settings->security_mode = GUAC_SECURITY_TLS; 740 } 741 742 /* RDP security */ 743 else if (strcmp(argv[IDX_SECURITY], "rdp") == 0) { 744 guac_user_log(user, GUAC_LOG_INFO, "Security mode: RDP"); 745 settings->security_mode = GUAC_SECURITY_RDP; 746 } 747 748 /* Negotiate security supported by VMConnect */ 749 else if (strcmp(argv[IDX_SECURITY], "vmconnect") == 0) { 750 guac_user_log(user, GUAC_LOG_INFO, "Security mode: Hyper-V / VMConnect"); 751 settings->security_mode = GUAC_SECURITY_VMCONNECT; 752 } 753 754 /* Negotiate security (allow server to choose) */ 755 else if (strcmp(argv[IDX_SECURITY], "any") == 0) { 756 guac_user_log(user, GUAC_LOG_INFO, "Security mode: Negotiate (ANY)"); 757 settings->security_mode = GUAC_SECURITY_ANY; 758 } 759 760 /* If nothing given, default to RDP */ 761 else { 762 guac_user_log(user, GUAC_LOG_INFO, "No security mode specified. Defaulting to security mode negotiation with server."); 763 settings->security_mode = GUAC_SECURITY_ANY; 764 } 765 766 /* Set hostname */ 767 settings->hostname = 768 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 769 IDX_HOSTNAME, ""); 770 771 /* If port specified, use it, otherwise use an appropriate default */ 772 settings->port = 773 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, IDX_PORT, 774 settings->security_mode == GUAC_SECURITY_VMCONNECT ? RDP_DEFAULT_VMCONNECT_PORT : RDP_DEFAULT_PORT); 775 776 guac_user_log(user, GUAC_LOG_DEBUG, 777 "User resolution is %ix%i at %i DPI", 778 user->info.optimal_width, 779 user->info.optimal_height, 780 user->info.optimal_resolution); 781 782 /* Use suggested resolution unless overridden */ 783 settings->resolution = 784 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 785 IDX_DPI, guac_rdp_suggest_resolution(user)); 786 787 /* Use optimal width unless overridden */ 788 settings->width = user->info.optimal_width 789 * settings->resolution 790 / user->info.optimal_resolution; 791 792 if (argv[IDX_WIDTH][0] != '\0') 793 settings->width = atoi(argv[IDX_WIDTH]); 794 795 /* Use default width if given width is invalid. */ 796 if (settings->width <= 0) { 797 settings->width = RDP_DEFAULT_WIDTH; 798 guac_user_log(user, GUAC_LOG_ERROR, 799 "Invalid width: \"%s\". Using default of %i.", 800 argv[IDX_WIDTH], settings->width); 801 } 802 803 /* Round width down to nearest multiple of 4 */ 804 settings->width = settings->width & ~0x3; 805 806 /* Use optimal height unless overridden */ 807 settings->height = user->info.optimal_height 808 * settings->resolution 809 / user->info.optimal_resolution; 810 811 if (argv[IDX_HEIGHT][0] != '\0') 812 settings->height = atoi(argv[IDX_HEIGHT]); 813 814 /* Use default height if given height is invalid. */ 815 if (settings->height <= 0) { 816 settings->height = RDP_DEFAULT_HEIGHT; 817 guac_user_log(user, GUAC_LOG_ERROR, 818 "Invalid height: \"%s\". Using default of %i.", 819 argv[IDX_WIDTH], settings->height); 820 } 821 822 guac_user_log(user, GUAC_LOG_DEBUG, 823 "Using resolution of %ix%i at %i DPI", 824 settings->width, 825 settings->height, 826 settings->resolution); 827 828 /* Lossless compression */ 829 settings->lossless = 830 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 831 IDX_FORCE_LOSSLESS, 0); 832 833 /* Domain */ 834 settings->domain = 835 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 836 IDX_DOMAIN, NULL); 837 838 /* Username */ 839 settings->username = 840 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 841 IDX_USERNAME, NULL); 842 843 /* Password */ 844 settings->password = 845 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 846 IDX_PASSWORD, NULL); 847 848 /* Read-only mode */ 849 settings->read_only = 850 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 851 IDX_READ_ONLY, 0); 852 853 /* Client name */ 854 settings->client_name = 855 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 856 IDX_CLIENT_NAME, "Guacamole RDP"); 857 858 /* Initial program */ 859 settings->initial_program = 860 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 861 IDX_INITIAL_PROGRAM, NULL); 862 863 /* RemoteApp program */ 864 settings->remote_app = 865 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 866 IDX_REMOTE_APP, NULL); 867 868 /* RemoteApp working directory */ 869 settings->remote_app_dir = 870 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 871 IDX_REMOTE_APP_DIR, NULL); 872 873 /* RemoteApp arguments */ 874 settings->remote_app_args = 875 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 876 IDX_REMOTE_APP_ARGS, NULL); 877 878 /* Static virtual channels */ 879 settings->svc_names = NULL; 880 if (argv[IDX_STATIC_CHANNELS][0] != '\0') 881 settings->svc_names = guac_split(argv[IDX_STATIC_CHANNELS], ','); 882 883 /* 884 * Performance flags 885 */ 886 887 settings->wallpaper_enabled = 888 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 889 IDX_ENABLE_WALLPAPER, 0); 890 891 settings->theming_enabled = 892 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 893 IDX_ENABLE_THEMING, 0); 894 895 settings->font_smoothing_enabled = 896 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 897 IDX_ENABLE_FONT_SMOOTHING, 0); 898 899 settings->full_window_drag_enabled = 900 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 901 IDX_ENABLE_FULL_WINDOW_DRAG, 0); 902 903 settings->desktop_composition_enabled = 904 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 905 IDX_ENABLE_DESKTOP_COMPOSITION, 0); 906 907 settings->menu_animations_enabled = 908 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 909 IDX_ENABLE_MENU_ANIMATIONS, 0); 910 911 settings->disable_bitmap_caching = 912 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 913 IDX_DISABLE_BITMAP_CACHING, 0); 914 915 settings->disable_offscreen_caching = 916 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 917 IDX_DISABLE_OFFSCREEN_CACHING, 0); 918 919 /* FreeRDP does not consider the glyph cache implementation to be stable as 920 * of 2.0.0, and it MUST NOT be used. Usage of the glyph cache results in 921 * unexpected disconnects when using older versions of Windows and recent 922 * versions of FreeRDP. See: https://issues.apache.org/jira/browse/GUACAMOLE-1191 */ 923 settings->disable_glyph_caching = 1; 924 925 /* In case the user expects glyph caching to be enabled, either explicitly 926 * or by default, warn that this will not be the case as the glyph cache 927 * is not considered stable. */ 928 if (!guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 929 IDX_DISABLE_GLYPH_CACHING, 0)) { 930 guac_user_log(user, GUAC_LOG_DEBUG, "Glyph caching is currently " 931 "universally disabled, regardless of the value of the \"%s\" " 932 "parameter, as glyph caching support is not considered stable " 933 "by FreeRDP as of the FreeRDP 2.0.0 release. See: " 934 "https://issues.apache.org/jira/browse/GUACAMOLE-1191", 935 GUAC_RDP_CLIENT_ARGS[IDX_DISABLE_GLYPH_CACHING]); 936 } 937 938 /* Session color depth */ 939 settings->color_depth = 940 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 941 IDX_COLOR_DEPTH, RDP_DEFAULT_DEPTH); 942 943 /* Preconnection ID */ 944 settings->preconnection_id = -1; 945 if (argv[IDX_PRECONNECTION_ID][0] != '\0') { 946 947 /* Parse preconnection ID, warn if invalid */ 948 int preconnection_id = atoi(argv[IDX_PRECONNECTION_ID]); 949 if (preconnection_id < 0) 950 guac_user_log(user, GUAC_LOG_WARNING, 951 "Ignoring invalid preconnection ID: %i", 952 preconnection_id); 953 954 /* Otherwise, assign specified ID */ 955 else { 956 settings->preconnection_id = preconnection_id; 957 guac_user_log(user, GUAC_LOG_DEBUG, 958 "Preconnection ID: %i", settings->preconnection_id); 959 } 960 961 } 962 963 /* Preconnection BLOB */ 964 settings->preconnection_blob = NULL; 965 if (argv[IDX_PRECONNECTION_BLOB][0] != '\0') { 966 settings->preconnection_blob = guac_strdup(argv[IDX_PRECONNECTION_BLOB]); 967 guac_user_log(user, GUAC_LOG_DEBUG, 968 "Preconnection BLOB: \"%s\"", settings->preconnection_blob); 969 } 970 971 /* Audio enable/disable */ 972 settings->audio_enabled = 973 !guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 974 IDX_DISABLE_AUDIO, 0); 975 976 /* Printing enable/disable */ 977 settings->printing_enabled = 978 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 979 IDX_ENABLE_PRINTING, 0); 980 981 /* Name of redirected printer */ 982 settings->printer_name = 983 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 984 IDX_PRINTER_NAME, "Guacamole Printer"); 985 986 /* Drive enable/disable */ 987 settings->drive_enabled = 988 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 989 IDX_ENABLE_DRIVE, 0); 990 991 /* Name of the drive being passed through */ 992 settings->drive_name = 993 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 994 IDX_DRIVE_NAME, "Guacamole Filesystem"); 995 996 /* The path on the server to connect the drive. */ 997 settings->drive_path = 998 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 999 IDX_DRIVE_PATH, ""); 1000 1001 /* If the server path should be created if it doesn't already exist. */ 1002 settings->create_drive_path = 1003 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1004 IDX_CREATE_DRIVE_PATH, 0); 1005 1006 /* If file downloads over RDP should be disabled. */ 1007 settings->disable_download = 1008 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1009 IDX_DISABLE_DOWNLOAD, 0); 1010 1011 /* If file uploads over RDP should be disabled. */ 1012 settings->disable_upload = 1013 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1014 IDX_DISABLE_UPLOAD, 0); 1015 1016 /* Pick keymap based on argument */ 1017 settings->server_layout = NULL; 1018 if (argv[IDX_SERVER_LAYOUT][0] != '\0') 1019 settings->server_layout = 1020 guac_rdp_keymap_find(argv[IDX_SERVER_LAYOUT]); 1021 1022 /* If no keymap requested, use default */ 1023 if (settings->server_layout == NULL) 1024 settings->server_layout = guac_rdp_keymap_find(GUAC_DEFAULT_KEYMAP); 1025 1026 /* Timezone if provided by client, or use handshake version */ 1027 settings->timezone = 1028 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1029 IDX_TIMEZONE, user->info.timezone); 1030 1031#ifdef ENABLE_COMMON_SSH 1032 /* SFTP enable/disable */ 1033 settings->enable_sftp = 1034 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1035 IDX_ENABLE_SFTP, 0); 1036 1037 /* Hostname for SFTP connection */ 1038 settings->sftp_hostname = 1039 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1040 IDX_SFTP_HOSTNAME, settings->hostname); 1041 1042 /* The public SSH host key. */ 1043 settings->sftp_host_key = 1044 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1045 IDX_SFTP_HOST_KEY, NULL); 1046 1047 /* Port for SFTP connection */ 1048 settings->sftp_port = 1049 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1050 IDX_SFTP_PORT, "22"); 1051 1052 /* Username for SSH/SFTP authentication */ 1053 settings->sftp_username = 1054 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1055 IDX_SFTP_USERNAME, 1056 settings->username != NULL ? settings->username : ""); 1057 1058 /* Password for SFTP (if not using private key) */ 1059 settings->sftp_password = 1060 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1061 IDX_SFTP_PASSWORD, ""); 1062 1063 /* Private key for SFTP (if not using password) */ 1064 settings->sftp_private_key = 1065 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1066 IDX_SFTP_PRIVATE_KEY, NULL); 1067 1068 /* Passphrase for decrypting the SFTP private key (if applicable */ 1069 settings->sftp_passphrase = 1070 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1071 IDX_SFTP_PASSPHRASE, ""); 1072 1073 /* Default upload directory */ 1074 settings->sftp_directory = 1075 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1076 IDX_SFTP_DIRECTORY, NULL); 1077 1078 /* SFTP root directory */ 1079 settings->sftp_root_directory = 1080 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1081 IDX_SFTP_ROOT_DIRECTORY, "/"); 1082 1083 /* Default keepalive value */ 1084 settings->sftp_server_alive_interval = 1085 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 1086 IDX_SFTP_SERVER_ALIVE_INTERVAL, 0); 1087 1088 /* Whether or not to disable file download over SFTP. */ 1089 settings->sftp_disable_download = 1090 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1091 IDX_SFTP_DISABLE_DOWNLOAD, 0); 1092 1093 /* Whether or not to disable file upload over SFTP. */ 1094 settings->sftp_disable_upload = 1095 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1096 IDX_SFTP_DISABLE_UPLOAD, 0); 1097#endif 1098 1099 /* Read recording path */ 1100 settings->recording_path = 1101 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1102 IDX_RECORDING_PATH, NULL); 1103 1104 /* Read recording name */ 1105 settings->recording_name = 1106 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1107 IDX_RECORDING_NAME, GUAC_RDP_DEFAULT_RECORDING_NAME); 1108 1109 /* Parse output exclusion flag */ 1110 settings->recording_exclude_output = 1111 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1112 IDX_RECORDING_EXCLUDE_OUTPUT, 0); 1113 1114 /* Parse mouse exclusion flag */ 1115 settings->recording_exclude_mouse = 1116 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1117 IDX_RECORDING_EXCLUDE_MOUSE, 0); 1118 1119 /* Parse touch exclusion flag */ 1120 settings->recording_exclude_touch = 1121 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1122 IDX_RECORDING_EXCLUDE_TOUCH, 0); 1123 1124 /* Parse key event inclusion flag */ 1125 settings->recording_include_keys = 1126 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1127 IDX_RECORDING_INCLUDE_KEYS, 0); 1128 1129 /* Parse path creation flag */ 1130 settings->create_recording_path = 1131 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1132 IDX_CREATE_RECORDING_PATH, 0); 1133 1134 /* No resize method */ 1135 if (strcmp(argv[IDX_RESIZE_METHOD], "") == 0) { 1136 guac_user_log(user, GUAC_LOG_INFO, "Resize method: none"); 1137 settings->resize_method = GUAC_RESIZE_NONE; 1138 } 1139 1140 /* Resize method: "reconnect" */ 1141 else if (strcmp(argv[IDX_RESIZE_METHOD], "reconnect") == 0) { 1142 guac_user_log(user, GUAC_LOG_INFO, "Resize method: reconnect"); 1143 settings->resize_method = GUAC_RESIZE_RECONNECT; 1144 } 1145 1146 /* Resize method: "display-update" */ 1147 else if (strcmp(argv[IDX_RESIZE_METHOD], "display-update") == 0) { 1148 guac_user_log(user, GUAC_LOG_INFO, "Resize method: display-update"); 1149 settings->resize_method = GUAC_RESIZE_DISPLAY_UPDATE; 1150 } 1151 1152 /* Default to no resize method if invalid */ 1153 else { 1154 guac_user_log(user, GUAC_LOG_INFO, "Resize method \"%s\" invalid. ", 1155 "Defaulting to no resize method.", argv[IDX_RESIZE_METHOD]); 1156 settings->resize_method = GUAC_RESIZE_NONE; 1157 } 1158 1159 /* Multi-touch input enable/disable */ 1160 settings->enable_touch = 1161 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1162 IDX_ENABLE_TOUCH, 0); 1163 1164 /* Audio input enable/disable */ 1165 settings->enable_audio_input = 1166 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1167 IDX_ENABLE_AUDIO_INPUT, 0); 1168 1169 /* Set gateway hostname */ 1170 settings->gateway_hostname = 1171 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1172 IDX_GATEWAY_HOSTNAME, NULL); 1173 1174 /* If gateway port specified, use it */ 1175 settings->gateway_port = 1176 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 1177 IDX_GATEWAY_PORT, 443); 1178 1179 /* Set gateway domain */ 1180 settings->gateway_domain = 1181 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1182 IDX_GATEWAY_DOMAIN, NULL); 1183 1184 /* Set gateway username */ 1185 settings->gateway_username = 1186 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1187 IDX_GATEWAY_USERNAME, NULL); 1188 1189 /* Set gateway password */ 1190 settings->gateway_password = 1191 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1192 IDX_GATEWAY_PASSWORD, NULL); 1193 1194 /* Set load balance info */ 1195 settings->load_balance_info = 1196 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1197 IDX_LOAD_BALANCE_INFO, NULL); 1198 1199 /* Parse clipboard copy disable flag */ 1200 settings->disable_copy = 1201 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1202 IDX_DISABLE_COPY, 0); 1203 1204 /* Parse clipboard paste disable flag */ 1205 settings->disable_paste = 1206 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1207 IDX_DISABLE_PASTE, 0); 1208 1209 /* Normalize clipboard line endings to Unix format */ 1210 if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "unix") == 0) { 1211 guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Unix (LF)"); 1212 settings->normalize_clipboard = 1; 1213 settings->clipboard_crlf = 0; 1214 } 1215 1216 /* Normalize clipboard line endings to Windows format */ 1217 else if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "windows") == 0) { 1218 guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Windows (CRLF)"); 1219 settings->normalize_clipboard = 1; 1220 settings->clipboard_crlf = 1; 1221 } 1222 1223 /* Preserve clipboard line ending format */ 1224 else if (strcmp(argv[IDX_NORMALIZE_CLIPBOARD], "preserve") == 0) { 1225 guac_user_log(user, GUAC_LOG_INFO, "Clipboard line ending normalization: Preserve (none)"); 1226 settings->normalize_clipboard = 0; 1227 settings->clipboard_crlf = 0; 1228 } 1229 1230 /* If nothing given, default to preserving line endings */ 1231 else { 1232 guac_user_log(user, GUAC_LOG_INFO, "No clipboard line-ending normalization specified. Defaulting to preserving the format of all line endings."); 1233 settings->normalize_clipboard = 0; 1234 settings->clipboard_crlf = 0; 1235 } 1236 1237 1238 /* Parse Wake-on-LAN (WoL) settings */ 1239 settings->wol_send_packet = 1240 guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv, 1241 IDX_WOL_SEND_PACKET, 0); 1242 1243 if (settings->wol_send_packet) { 1244 1245 /* If WoL has been requested but no MAC address given, log a warning. */ 1246 if(strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) { 1247 guac_user_log(user, GUAC_LOG_WARNING, "WoL requested but no MAC ", 1248 "address specified. WoL will not be sent."); 1249 settings->wol_send_packet = 0; 1250 } 1251 1252 /* Parse the WoL MAC address. */ 1253 settings->wol_mac_addr = 1254 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1255 IDX_WOL_MAC_ADDR, NULL); 1256 1257 /* Parse the WoL broadcast address. */ 1258 settings->wol_broadcast_addr = 1259 guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv, 1260 IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST); 1261 1262 /* Parse the WoL broadcast port. */ 1263 settings->wol_udp_port = (unsigned short) 1264 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 1265 IDX_WOL_UDP_PORT, GUAC_WOL_PORT); 1266 1267 /* Parse the WoL wait time. */ 1268 settings->wol_wait_time = 1269 guac_user_parse_args_int(user, GUAC_RDP_CLIENT_ARGS, argv, 1270 IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME); 1271 1272 } 1273 1274 /* Success */ 1275 return settings; 1276 1277} 1278 1279void guac_rdp_settings_free(guac_rdp_settings* settings) { 1280 1281 /* Free settings strings */ 1282 guac_mem_free(settings->client_name); 1283 guac_mem_free(settings->domain); 1284 guac_mem_free(settings->drive_name); 1285 guac_mem_free(settings->drive_path); 1286 guac_mem_free(settings->hostname); 1287 guac_mem_free(settings->initial_program); 1288 guac_mem_free(settings->password); 1289 guac_mem_free(settings->preconnection_blob); 1290 guac_mem_free(settings->recording_name); 1291 guac_mem_free(settings->recording_path); 1292 guac_mem_free(settings->remote_app); 1293 guac_mem_free(settings->remote_app_args); 1294 guac_mem_free(settings->remote_app_dir); 1295 guac_mem_free(settings->timezone); 1296 guac_mem_free(settings->username); 1297 guac_mem_free(settings->printer_name); 1298 1299 /* Free channel name array */ 1300 if (settings->svc_names != NULL) { 1301 1302 /* Free all elements of array */ 1303 char** current = &(settings->svc_names[0]); 1304 while (*current != NULL) { 1305 guac_mem_free(*current); 1306 current++; 1307 } 1308 1309 /* Free array itself */ 1310 guac_mem_free(settings->svc_names); 1311 1312 } 1313 1314#ifdef ENABLE_COMMON_SSH 1315 /* Free SFTP settings */ 1316 guac_mem_free(settings->sftp_directory); 1317 guac_mem_free(settings->sftp_root_directory); 1318 guac_mem_free(settings->sftp_host_key); 1319 guac_mem_free(settings->sftp_hostname); 1320 guac_mem_free(settings->sftp_passphrase); 1321 guac_mem_free(settings->sftp_password); 1322 guac_mem_free(settings->sftp_port); 1323 guac_mem_free(settings->sftp_private_key); 1324 guac_mem_free(settings->sftp_username); 1325#endif 1326 1327 /* Free RD gateway information */ 1328 guac_mem_free(settings->gateway_hostname); 1329 guac_mem_free(settings->gateway_domain); 1330 guac_mem_free(settings->gateway_username); 1331 guac_mem_free(settings->gateway_password); 1332 1333 /* Free load balancer information string */ 1334 guac_mem_free(settings->load_balance_info); 1335 1336 /* Free Wake-on-LAN strings */ 1337 guac_mem_free(settings->wol_mac_addr); 1338 guac_mem_free(settings->wol_broadcast_addr); 1339 1340 /* Free settings structure */ 1341 guac_mem_free(settings); 1342 1343} 1344 1345int guac_rdp_get_width(freerdp* rdp) { 1346 return rdp->settings->DesktopWidth; 1347} 1348 1349int guac_rdp_get_height(freerdp* rdp) { 1350 return rdp->settings->DesktopHeight; 1351} 1352 1353int guac_rdp_get_depth(freerdp* rdp) { 1354 return rdp->settings->ColorDepth; 1355} 1356 1357/** 1358 * Given the settings structure of the Guacamole RDP client, calculates the 1359 * standard performance flag value to send to the RDP server. The value of 1360 * these flags is dictated by the RDP standard. 1361 * 1362 * @param guac_settings 1363 * The settings structure to read performance settings from. 1364 * 1365 * @returns 1366 * The standard RDP performance flag value representing the union of all 1367 * performance settings within the given settings structure. 1368 */ 1369static int guac_rdp_get_performance_flags(guac_rdp_settings* guac_settings) { 1370 1371 /* No performance flags initially */ 1372 int flags = PERF_FLAG_NONE; 1373 1374 /* Desktop wallpaper */ 1375 if (!guac_settings->wallpaper_enabled) 1376 flags |= PERF_DISABLE_WALLPAPER; 1377 1378 /* Theming of desktop/windows */ 1379 if (!guac_settings->theming_enabled) 1380 flags |= PERF_DISABLE_THEMING; 1381 1382 /* Font smoothing (ClearType) */ 1383 if (guac_settings->font_smoothing_enabled) 1384 flags |= PERF_ENABLE_FONT_SMOOTHING; 1385 1386 /* Full-window drag */ 1387 if (!guac_settings->full_window_drag_enabled) 1388 flags |= PERF_DISABLE_FULLWINDOWDRAG; 1389 1390 /* Desktop composition (Aero) */ 1391 if (guac_settings->desktop_composition_enabled) 1392 flags |= PERF_ENABLE_DESKTOP_COMPOSITION; 1393 1394 /* Menu animations */ 1395 if (!guac_settings->menu_animations_enabled) 1396 flags |= PERF_DISABLE_MENUANIMATIONS; 1397 1398 return flags; 1399 1400} 1401 1402void guac_rdp_push_settings(guac_client* client, 1403 guac_rdp_settings* guac_settings, freerdp* rdp) { 1404 1405 rdpSettings* rdp_settings = rdp->settings; 1406 1407 /* Authentication */ 1408 rdp_settings->Domain = guac_strdup(guac_settings->domain); 1409 rdp_settings->Username = guac_strdup(guac_settings->username); 1410 rdp_settings->Password = guac_strdup(guac_settings->password); 1411 1412 /* Connection */ 1413 rdp_settings->ServerHostname = guac_strdup(guac_settings->hostname); 1414 rdp_settings->ServerPort = guac_settings->port; 1415 1416 /* Session */ 1417 rdp_settings->ColorDepth = guac_settings->color_depth; 1418 rdp_settings->DesktopWidth = guac_settings->width; 1419 rdp_settings->DesktopHeight = guac_settings->height; 1420 rdp_settings->AlternateShell = guac_strdup(guac_settings->initial_program); 1421 rdp_settings->KeyboardLayout = guac_settings->server_layout->freerdp_keyboard_layout; 1422 1423 /* Performance flags */ 1424 /* Explicitly set flag value */ 1425 rdp_settings->PerformanceFlags = guac_rdp_get_performance_flags(guac_settings); 1426 1427 /* Set individual flags - some FreeRDP versions overwrite the above */ 1428 rdp_settings->AllowFontSmoothing = guac_settings->font_smoothing_enabled; 1429 rdp_settings->DisableWallpaper = !guac_settings->wallpaper_enabled; 1430 rdp_settings->DisableFullWindowDrag = !guac_settings->full_window_drag_enabled; 1431 rdp_settings->DisableMenuAnims = !guac_settings->menu_animations_enabled; 1432 rdp_settings->DisableThemes = !guac_settings->theming_enabled; 1433 rdp_settings->AllowDesktopComposition = guac_settings->desktop_composition_enabled; 1434 1435 /* Client name */ 1436 if (guac_settings->client_name != NULL) { 1437 guac_strlcpy(rdp_settings->ClientHostname, guac_settings->client_name, 1438 RDP_CLIENT_HOSTNAME_SIZE); 1439 } 1440 1441 /* Console */ 1442 rdp_settings->ConsoleSession = guac_settings->console; 1443 rdp_settings->RemoteConsoleAudio = guac_settings->console_audio; 1444 1445 /* Audio */ 1446 rdp_settings->AudioPlayback = guac_settings->audio_enabled; 1447 1448 /* Audio capture */ 1449 rdp_settings->AudioCapture = guac_settings->enable_audio_input; 1450 1451 /* Display Update channel */ 1452 rdp_settings->SupportDisplayControl = 1453 (guac_settings->resize_method == GUAC_RESIZE_DISPLAY_UPDATE); 1454 1455 /* Timezone redirection */ 1456 if (guac_settings->timezone) { 1457 if (setenv("TZ", guac_settings->timezone, 1)) { 1458 guac_client_log(client, GUAC_LOG_WARNING, 1459 "Unable to forward timezone: TZ environment variable " 1460 "could not be set: %s", strerror(errno)); 1461 } 1462 } 1463 1464 /* Device redirection */ 1465 rdp_settings->DeviceRedirection = guac_settings->audio_enabled 1466 || guac_settings->drive_enabled 1467 || guac_settings->printing_enabled; 1468 1469 /* Security */ 1470 switch (guac_settings->security_mode) { 1471 1472 /* Legacy RDP encryption */ 1473 case GUAC_SECURITY_RDP: 1474 rdp_settings->RdpSecurity = TRUE; 1475 rdp_settings->TlsSecurity = FALSE; 1476 rdp_settings->NlaSecurity = FALSE; 1477 rdp_settings->ExtSecurity = FALSE; 1478 rdp_settings->UseRdpSecurityLayer = TRUE; 1479 rdp_settings->EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE; 1480 rdp_settings->EncryptionMethods = 1481 ENCRYPTION_METHOD_40BIT 1482 | ENCRYPTION_METHOD_128BIT 1483 | ENCRYPTION_METHOD_FIPS; 1484 break; 1485 1486 /* TLS encryption */ 1487 case GUAC_SECURITY_TLS: 1488 rdp_settings->RdpSecurity = FALSE; 1489 rdp_settings->TlsSecurity = TRUE; 1490 rdp_settings->NlaSecurity = FALSE; 1491 rdp_settings->ExtSecurity = FALSE; 1492 break; 1493 1494 /* Network level authentication */ 1495 case GUAC_SECURITY_NLA: 1496 rdp_settings->RdpSecurity = FALSE; 1497 rdp_settings->TlsSecurity = FALSE; 1498 rdp_settings->NlaSecurity = TRUE; 1499 rdp_settings->ExtSecurity = FALSE; 1500 break; 1501 1502 /* Extended network level authentication */ 1503 case GUAC_SECURITY_EXTENDED_NLA: 1504 rdp_settings->RdpSecurity = FALSE; 1505 rdp_settings->TlsSecurity = FALSE; 1506 rdp_settings->NlaSecurity = FALSE; 1507 rdp_settings->ExtSecurity = TRUE; 1508 break; 1509 1510 /* Hyper-V "VMConnect" negotiation mode */ 1511 case GUAC_SECURITY_VMCONNECT: 1512 rdp_settings->RdpSecurity = FALSE; 1513 rdp_settings->TlsSecurity = TRUE; 1514 rdp_settings->NlaSecurity = TRUE; 1515 rdp_settings->ExtSecurity = FALSE; 1516 rdp_settings->VmConnectMode = TRUE; 1517 break; 1518 1519 /* All security types */ 1520 case GUAC_SECURITY_ANY: 1521 rdp_settings->RdpSecurity = TRUE; 1522 rdp_settings->TlsSecurity = TRUE; 1523 1524 /* Explicitly disable NLA if FIPS mode is enabled - it won't work */ 1525 if (guac_fips_enabled()) { 1526 1527 guac_client_log(client, GUAC_LOG_INFO, 1528 "FIPS mode is enabled. Excluding NLA security mode from security negotiation " 1529 "(see: https://github.com/FreeRDP/FreeRDP/issues/3412)."); 1530 rdp_settings->NlaSecurity = FALSE; 1531 1532 } 1533 1534 /* NLA mode is allowed if FIPS is not enabled */ 1535 else 1536 rdp_settings->NlaSecurity = TRUE; 1537 1538 rdp_settings->ExtSecurity = FALSE; 1539 break; 1540 1541 } 1542 1543 /* Authentication */ 1544 rdp_settings->Authentication = !guac_settings->disable_authentication; 1545 rdp_settings->IgnoreCertificate = guac_settings->ignore_certificate; 1546 1547 /* RemoteApp */ 1548 if (guac_settings->remote_app != NULL) { 1549 rdp_settings->Workarea = TRUE; 1550 rdp_settings->RemoteApplicationMode = TRUE; 1551 rdp_settings->RemoteAppLanguageBarSupported = TRUE; 1552 rdp_settings->RemoteApplicationProgram = guac_strdup(guac_settings->remote_app); 1553 rdp_settings->ShellWorkingDirectory = guac_strdup(guac_settings->remote_app_dir); 1554 rdp_settings->RemoteApplicationCmdLine = guac_strdup(guac_settings->remote_app_args); 1555 } 1556 1557 /* Preconnection ID */ 1558 if (guac_settings->preconnection_id != -1) { 1559 rdp_settings->NegotiateSecurityLayer = FALSE; 1560 rdp_settings->SendPreconnectionPdu = TRUE; 1561 rdp_settings->PreconnectionId = guac_settings->preconnection_id; 1562 } 1563 1564 /* Preconnection BLOB */ 1565 if (guac_settings->preconnection_blob != NULL) { 1566 rdp_settings->NegotiateSecurityLayer = FALSE; 1567 rdp_settings->SendPreconnectionPdu = TRUE; 1568 rdp_settings->PreconnectionBlob = guac_strdup(guac_settings->preconnection_blob); 1569 } 1570 1571 /* Enable use of RD gateway if a gateway hostname is provided */ 1572 if (guac_settings->gateway_hostname != NULL) { 1573 1574 /* Enable RD gateway */ 1575 rdp_settings->GatewayEnabled = TRUE; 1576 1577 /* RD gateway connection details */ 1578 rdp_settings->GatewayHostname = guac_strdup(guac_settings->gateway_hostname); 1579 rdp_settings->GatewayPort = guac_settings->gateway_port; 1580 1581 /* RD gateway credentials */ 1582 rdp_settings->GatewayUseSameCredentials = FALSE; 1583 rdp_settings->GatewayDomain = guac_strdup(guac_settings->gateway_domain); 1584 rdp_settings->GatewayUsername = guac_strdup(guac_settings->gateway_username); 1585 rdp_settings->GatewayPassword = guac_strdup(guac_settings->gateway_password); 1586 1587 } 1588 1589 /* Store load balance info (and calculate length) if provided */ 1590 if (guac_settings->load_balance_info != NULL) { 1591 rdp_settings->LoadBalanceInfo = (BYTE*) guac_strdup(guac_settings->load_balance_info); 1592 rdp_settings->LoadBalanceInfoLength = strlen(guac_settings->load_balance_info); 1593 } 1594 1595 rdp_settings->BitmapCacheEnabled = !guac_settings->disable_bitmap_caching; 1596 rdp_settings->OffscreenSupportLevel = !guac_settings->disable_offscreen_caching; 1597 rdp_settings->GlyphSupportLevel = !guac_settings->disable_glyph_caching ? GLYPH_SUPPORT_FULL : GLYPH_SUPPORT_NONE; 1598 rdp_settings->OsMajorType = OSMAJORTYPE_UNSPECIFIED; 1599 rdp_settings->OsMinorType = OSMINORTYPE_UNSPECIFIED; 1600 rdp_settings->DesktopResize = TRUE; 1601 1602 /* Claim support only for specific updates, independent of FreeRDP defaults */ 1603 ZeroMemory(rdp_settings->OrderSupport, GUAC_RDP_ORDER_SUPPORT_LENGTH); 1604 rdp_settings->OrderSupport[NEG_DSTBLT_INDEX] = TRUE; 1605 rdp_settings->OrderSupport[NEG_SCRBLT_INDEX] = TRUE; 1606 rdp_settings->OrderSupport[NEG_MEMBLT_INDEX] = !guac_settings->disable_bitmap_caching; 1607 rdp_settings->OrderSupport[NEG_MEMBLT_V2_INDEX] = !guac_settings->disable_bitmap_caching; 1608 rdp_settings->OrderSupport[NEG_GLYPH_INDEX_INDEX] = !guac_settings->disable_glyph_caching; 1609 rdp_settings->OrderSupport[NEG_FAST_INDEX_INDEX] = !guac_settings->disable_glyph_caching; 1610 rdp_settings->OrderSupport[NEG_FAST_GLYPH_INDEX] = !guac_settings->disable_glyph_caching; 1611 1612#ifdef HAVE_RDPSETTINGS_ALLOWUNANOUNCEDORDERSFROMSERVER 1613 /* Do not consider server use of unannounced orders to be a fatal error */ 1614 rdp_settings->AllowUnanouncedOrdersFromServer = TRUE; 1615#endif 1616 1617} 1618