cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

settings.c (19125B)


      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 "config.h"
     21
     22#include "argv.h"
     23#include "client.h"
     24#include "common/defaults.h"
     25#include "settings.h"
     26#include "terminal/terminal.h"
     27
     28#include <guacamole/mem.h>
     29#include <guacamole/user.h>
     30#include <guacamole/wol-constants.h>
     31
     32#include <stdlib.h>
     33#include <string.h>
     34#include <time.h>
     35
     36/* Client plugin arguments */
     37const char* GUAC_SSH_CLIENT_ARGS[] = {
     38    "hostname",
     39    "host-key",
     40    "port",
     41    "username",
     42    "password",
     43    GUAC_SSH_ARGV_FONT_NAME,
     44    GUAC_SSH_ARGV_FONT_SIZE,
     45    "enable-sftp",
     46    "sftp-root-directory",
     47    "sftp-disable-download",
     48    "sftp-disable-upload",
     49    "private-key",
     50    "passphrase",
     51#ifdef ENABLE_SSH_AGENT
     52    "enable-agent",
     53#endif
     54    GUAC_SSH_ARGV_COLOR_SCHEME,
     55    "command",
     56    "typescript-path",
     57    "typescript-name",
     58    "create-typescript-path",
     59    "recording-path",
     60    "recording-name",
     61    "recording-exclude-output",
     62    "recording-exclude-mouse",
     63    "recording-include-keys",
     64    "create-recording-path",
     65    "read-only",
     66    "server-alive-interval",
     67    "backspace",
     68    "terminal-type",
     69    "scrollback",
     70    "locale",
     71    "timezone",
     72    "disable-copy",
     73    "disable-paste",
     74    "wol-send-packet",
     75    "wol-mac-addr",
     76    "wol-broadcast-addr",
     77    "wol-udp-port",
     78    "wol-wait-time",
     79    NULL
     80};
     81
     82enum SSH_ARGS_IDX {
     83
     84    /**
     85     * The hostname to connect to. Required.
     86     */
     87    IDX_HOSTNAME,
     88
     89    /**
     90     * The Base64-encoded public SSH host key.  Optional.
     91     */
     92    IDX_HOST_KEY,
     93
     94    /**
     95     * The port to connect to. Optional.
     96     */
     97    IDX_PORT,
     98
     99    /**
    100     * The name of the user to login as. Optional.
    101     */
    102    IDX_USERNAME,
    103
    104    /**
    105     * The password to use when logging in. Optional.
    106     */
    107    IDX_PASSWORD,
    108
    109    /**
    110     * The name of the font to use within the terminal.
    111     */
    112    IDX_FONT_NAME,
    113
    114    /**
    115     * The size of the font to use within the terminal, in points.
    116     */
    117    IDX_FONT_SIZE,
    118
    119    /**
    120     * Whether SFTP should be enabled.
    121     */
    122    IDX_ENABLE_SFTP,
    123
    124    /**
    125     * The path of the directory within the SSH server to expose as a
    126     * filesystem guac_object. If omitted, "/" will be used by default.
    127     */
    128    IDX_SFTP_ROOT_DIRECTORY,
    129    
    130    /**
    131     * "true" if file downloads over SFTP should be blocked.  "false" or blank
    132     * if file downloads should be allowed.
    133     */
    134    IDX_SFTP_DISABLE_DOWNLOAD,
    135    
    136    /**
    137     * "true" if file uploads over SFTP should be blocked.  "false" or blank if
    138     * file uploads should be allowed.
    139     */
    140    IDX_SFTP_DISABLE_UPLOAD,
    141
    142    /**
    143     * The private key to use for authentication, if any.
    144     */
    145    IDX_PRIVATE_KEY,
    146
    147    /**
    148     * The passphrase required to decrypt the private key, if any.
    149     */
    150    IDX_PASSPHRASE,
    151
    152#ifdef ENABLE_SSH_AGENT
    153    /**
    154     * Whether SSH agent forwarding support should be enabled.
    155     */
    156    IDX_ENABLE_AGENT,
    157#endif
    158
    159    /**
    160     * The color scheme to use, as a series of semicolon-separated color-value
    161     * pairs: "background: <color>", "foreground: <color>", or
    162     * "color<n>: <color>", where <n> is a number from 0 to 255, and <color> is
    163     * "color<n>" or an X11 color code (e.g. "aqua" or "rgb:12/34/56").
    164     * The color scheme can also be one of the special values: "black-white",
    165     * "white-black", "gray-black", or "green-black".
    166     */
    167    IDX_COLOR_SCHEME,
    168
    169    /**
    170     * The command to run instead if the default shell. If omitted, a normal
    171     * shell session will be created.
    172     */
    173    IDX_COMMAND,
    174
    175    /**
    176     * The full absolute path to the directory in which typescripts should be
    177     * written.
    178     */
    179    IDX_TYPESCRIPT_PATH,
    180
    181    /**
    182     * The name that should be given to typescripts which are written in the
    183     * given path. Each typescript will consist of two files: "NAME" and
    184     * "NAME.timing".
    185     */
    186    IDX_TYPESCRIPT_NAME,
    187
    188    /**
    189     * Whether the specified typescript path should automatically be created
    190     * if it does not yet exist.
    191     */
    192    IDX_CREATE_TYPESCRIPT_PATH,
    193
    194    /**
    195     * The full absolute path to the directory in which screen recordings
    196     * should be written.
    197     */
    198    IDX_RECORDING_PATH,
    199
    200    /**
    201     * The name that should be given to screen recordings which are written in
    202     * the given path.
    203     */
    204    IDX_RECORDING_NAME,
    205
    206    /**
    207     * Whether output which is broadcast to each connected client (graphics,
    208     * streams, etc.) should NOT be included in the session recording. Output
    209     * is included by default, as it is necessary for any recording which must
    210     * later be viewable as video.
    211     */
    212    IDX_RECORDING_EXCLUDE_OUTPUT,
    213
    214    /**
    215     * Whether changes to mouse state, such as position and buttons pressed or
    216     * released, should NOT be included in the session recording. Mouse state
    217     * is included by default, as it is necessary for the mouse cursor to be
    218     * rendered in any resulting video.
    219     */
    220    IDX_RECORDING_EXCLUDE_MOUSE,
    221
    222    /**
    223     * Whether keys pressed and released should be included in the session
    224     * recording. Key events are NOT included by default within the recording,
    225     * as doing so has privacy and security implications.  Including key events
    226     * may be necessary in certain auditing contexts, but should only be done
    227     * with caution. Key events can easily contain sensitive information, such
    228     * as passwords, credit card numbers, etc.
    229     */
    230    IDX_RECORDING_INCLUDE_KEYS,
    231
    232    /**
    233     * Whether the specified screen recording path should automatically be
    234     * created if it does not yet exist.
    235     */
    236    IDX_CREATE_RECORDING_PATH,
    237
    238    /**
    239     * "true" if this connection should be read-only (user input should be
    240     * dropped), "false" or blank otherwise.
    241     */
    242    IDX_READ_ONLY,
    243
    244    /**
    245     * Number of seconds between sending alive packets.  A default of 0
    246     * tells SSH not to send these packets.  A value of 1 is automatically
    247     * changed by libssh2 to 2 to avoid busy-loop corner cases.
    248     */
    249    IDX_SERVER_ALIVE_INTERVAL,
    250
    251    /**
    252     * The ASCII code, as an integer, to send for the backspace key, as configured
    253     * by the SSH connection from the client.  By default this will be
    254     * GUAC_TERMINAL_DEFAULT_BACKSPACE.
    255     */
    256    IDX_BACKSPACE,
    257
    258    /**
    259     * The terminal emulator type that is passed to the remote system (e.g.
    260     * "xterm" or "xterm-256color"). "linux" is used if unspecified.
    261     */
    262    IDX_TERMINAL_TYPE,
    263
    264    /**
    265     * The maximum size of the scrollback buffer in rows.
    266     */
    267    IDX_SCROLLBACK,
    268
    269    /**
    270     * The locale that should be forwarded to the remote system via the LANG
    271     * environment variable. By default, no locale is forwarded. This setting
    272     * will only have an effect if the SSH server allows the LANG environment
    273     * variable to be set.
    274     */
    275    IDX_LOCALE,
    276     
    277    /**
    278     * The timezone that is to be passed to the remote system, via the
    279     * TZ environment variable.  By default, no timezone is forwarded
    280     * and the timezone of the remote system will be used.  This
    281     * setting will only work if the SSH server allows the TZ variable
    282     * to be set.  Timezones should be in standard IANA format, see:
    283     * https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
    284     */
    285    IDX_TIMEZONE,
    286
    287    /**
    288     * Whether outbound clipboard access should be blocked. If set to "true",
    289     * it will not be possible to copy data from the terminal to the client
    290     * using the clipboard. By default, clipboard access is not blocked.
    291     */
    292    IDX_DISABLE_COPY,
    293
    294    /**
    295     * Whether inbound clipboard access should be blocked. If set to "true", it
    296     * will not be possible to paste data from the client to the terminal using
    297     * the clipboard. By default, clipboard access is not blocked.
    298     */
    299    IDX_DISABLE_PASTE,
    300    
    301    /**
    302     * Whether the magic WoL packet should be sent prior to starting the
    303     * connection.  If set to "true", the system will attempt to send the WoL
    304     * packet and wait for the host to wake up.  By default the WoL packet
    305     * is not sent.
    306     */
    307    IDX_WOL_SEND_PACKET,
    308    
    309    /**
    310     * The MAC address to put in the magic WoL packet to wake the remote system.
    311     * By default no MAC address is specified.  If WoL is enabled by a MAC
    312     * address is not provided a warning will be logged and the WoL packet will
    313     * not be sent.
    314     */
    315    IDX_WOL_MAC_ADDR,
    316    
    317    /**
    318     * The broadcast address to which to send the magic WoL packet to wake the
    319     * remote system.
    320     */
    321    IDX_WOL_BROADCAST_ADDR,
    322    
    323    /**
    324     * The UDP port to use when sending the WoL packet. 
    325     */
    326    IDX_WOL_UDP_PORT,
    327    
    328    /**
    329     * The amount of time to wait after sending the magic WoL packet prior to
    330     * continuing the connection attempt.  The default is no wait time
    331     * (0 seconds).
    332     */
    333    IDX_WOL_WAIT_TIME,
    334
    335    SSH_ARGS_COUNT
    336};
    337
    338guac_ssh_settings* guac_ssh_parse_args(guac_user* user,
    339        int argc, const char** argv) {
    340
    341    /* Validate arg count */
    342    if (argc != SSH_ARGS_COUNT) {
    343        guac_user_log(user, GUAC_LOG_WARNING, "Incorrect number of connection "
    344                "parameters provided: expected %i, got %i.",
    345                SSH_ARGS_COUNT, argc);
    346        return NULL;
    347    }
    348
    349    guac_ssh_settings* settings = guac_mem_zalloc(sizeof(guac_ssh_settings));
    350
    351    /* Read parameters */
    352    settings->hostname =
    353        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    354                IDX_HOSTNAME, "");
    355
    356    settings->host_key =
    357        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    358                IDX_HOST_KEY, NULL);
    359
    360    settings->username =
    361        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    362                IDX_USERNAME, NULL);
    363
    364    settings->password =
    365        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    366                IDX_PASSWORD, NULL);
    367
    368    /* Init public key auth information */
    369    settings->key_base64 =
    370        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    371                IDX_PRIVATE_KEY, NULL);
    372
    373    settings->key_passphrase =
    374        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    375                IDX_PASSPHRASE, NULL);
    376
    377    /* Read maximum scrollback size */
    378    settings->max_scrollback =
    379        guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    380                IDX_SCROLLBACK, GUAC_TERMINAL_DEFAULT_MAX_SCROLLBACK);
    381
    382    /* Read font name */
    383    settings->font_name =
    384        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    385                IDX_FONT_NAME, GUAC_TERMINAL_DEFAULT_FONT_NAME);
    386
    387    /* Read font size */
    388    settings->font_size =
    389        guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    390                IDX_FONT_SIZE, GUAC_TERMINAL_DEFAULT_FONT_SIZE);
    391
    392    /* Copy requested color scheme */
    393    settings->color_scheme =
    394        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    395                IDX_COLOR_SCHEME, GUAC_TERMINAL_DEFAULT_COLOR_SCHEME);
    396
    397    /* Pull width/height/resolution directly from user */
    398    settings->width      = user->info.optimal_width;
    399    settings->height     = user->info.optimal_height;
    400    settings->resolution = user->info.optimal_resolution;
    401
    402    /* Parse SFTP enable */
    403    settings->enable_sftp =
    404        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    405                IDX_ENABLE_SFTP, false);
    406
    407    /* SFTP root directory */
    408    settings->sftp_root_directory =
    409        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    410                IDX_SFTP_ROOT_DIRECTORY, "/");
    411    
    412    /* Disable file downloads. */
    413    settings->sftp_disable_download =
    414        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    415                IDX_SFTP_DISABLE_DOWNLOAD, false);
    416    
    417    /* Disable file uploads. */
    418    settings->sftp_disable_upload =
    419        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    420                IDX_SFTP_DISABLE_UPLOAD, false);
    421
    422#ifdef ENABLE_SSH_AGENT
    423    settings->enable_agent =
    424        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    425                IDX_ENABLE_AGENT, false);
    426#endif
    427
    428    /* Read port */
    429    settings->port =
    430        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    431                IDX_PORT, GUAC_SSH_DEFAULT_PORT);
    432
    433    /* Read-only mode */
    434    settings->read_only =
    435        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    436                IDX_READ_ONLY, false);
    437
    438    /* Read command, if any */
    439    settings->command =
    440        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    441                IDX_COMMAND, NULL);
    442
    443    /* Read typescript path */
    444    settings->typescript_path =
    445        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    446                IDX_TYPESCRIPT_PATH, NULL);
    447
    448    /* Read typescript name */
    449    settings->typescript_name =
    450        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    451                IDX_TYPESCRIPT_NAME, GUAC_SSH_DEFAULT_TYPESCRIPT_NAME);
    452
    453    /* Parse path creation flag */
    454    settings->create_typescript_path =
    455        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    456                IDX_CREATE_TYPESCRIPT_PATH, false);
    457
    458    /* Read recording path */
    459    settings->recording_path =
    460        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    461                IDX_RECORDING_PATH, NULL);
    462
    463    /* Read recording name */
    464    settings->recording_name =
    465        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    466                IDX_RECORDING_NAME, GUAC_SSH_DEFAULT_RECORDING_NAME);
    467
    468    /* Parse output exclusion flag */
    469    settings->recording_exclude_output =
    470        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    471                IDX_RECORDING_EXCLUDE_OUTPUT, false);
    472
    473    /* Parse mouse exclusion flag */
    474    settings->recording_exclude_mouse =
    475        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    476                IDX_RECORDING_EXCLUDE_MOUSE, false);
    477
    478    /* Parse key event inclusion flag */
    479    settings->recording_include_keys =
    480        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    481                IDX_RECORDING_INCLUDE_KEYS, false);
    482
    483    /* Parse path creation flag */
    484    settings->create_recording_path =
    485        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    486                IDX_CREATE_RECORDING_PATH, false);
    487
    488    /* Parse server alive interval */
    489    settings->server_alive_interval =
    490        guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    491                IDX_SERVER_ALIVE_INTERVAL, 0);
    492
    493    /* Parse backspace key setting */
    494    settings->backspace =
    495        guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    496                IDX_BACKSPACE, GUAC_TERMINAL_DEFAULT_BACKSPACE);
    497
    498    /* Read terminal emulator type. */
    499    settings->terminal_type =
    500        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    501                IDX_TERMINAL_TYPE, "linux");
    502
    503    /* Read locale */
    504    settings->locale =
    505        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    506                IDX_LOCALE, NULL);
    507
    508    /* Read the timezone parameter, or use client handshake. */
    509    settings->timezone =
    510        guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    511                IDX_TIMEZONE, user->info.timezone);
    512
    513    /* Parse clipboard copy disable flag */
    514    settings->disable_copy =
    515        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    516                IDX_DISABLE_COPY, false);
    517
    518    /* Parse clipboard paste disable flag */
    519    settings->disable_paste =
    520        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    521                IDX_DISABLE_PASTE, false);
    522    
    523    /* Parse Wake-on-LAN (WoL) parameters. */
    524    settings->wol_send_packet =
    525        guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
    526                IDX_WOL_SEND_PACKET, false);
    527    
    528    if (settings->wol_send_packet) {
    529        
    530        if (strcmp(argv[IDX_WOL_MAC_ADDR], "") == 0) {
    531            guac_user_log(user, GUAC_LOG_WARNING, "WoL was enabled, but no ",
    532                    "MAC address was provide.  WoL will not be sent.");
    533            settings->wol_send_packet = false;
    534        }
    535        
    536        settings->wol_mac_addr =
    537            guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    538                IDX_WOL_MAC_ADDR, NULL);
    539        
    540        settings->wol_broadcast_addr =
    541            guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
    542                IDX_WOL_BROADCAST_ADDR, GUAC_WOL_LOCAL_IPV4_BROADCAST);
    543        
    544        settings->wol_udp_port = (unsigned short)
    545            guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    546                IDX_WOL_UDP_PORT, GUAC_WOL_PORT);
    547        
    548        settings->wol_wait_time =
    549            guac_user_parse_args_int(user, GUAC_SSH_CLIENT_ARGS, argv,
    550                IDX_WOL_WAIT_TIME, GUAC_WOL_DEFAULT_BOOT_WAIT_TIME);
    551        
    552    }
    553
    554    /* Parsing was successful */
    555    return settings;
    556
    557}
    558
    559void guac_ssh_settings_free(guac_ssh_settings* settings) {
    560
    561    /* Free network connection information */
    562    guac_mem_free(settings->hostname);
    563    guac_mem_free(settings->host_key);
    564    guac_mem_free(settings->port);
    565
    566    /* Free credentials */
    567    guac_mem_free(settings->username);
    568    guac_mem_free(settings->password);
    569    guac_mem_free(settings->key_base64);
    570    guac_mem_free(settings->key_passphrase);
    571
    572    /* Free display preferences */
    573    guac_mem_free(settings->font_name);
    574    guac_mem_free(settings->color_scheme);
    575
    576    /* Free requested command */
    577    guac_mem_free(settings->command);
    578
    579    /* Free SFTP settings */
    580    guac_mem_free(settings->sftp_root_directory);
    581
    582    /* Free typescript settings */
    583    guac_mem_free(settings->typescript_name);
    584    guac_mem_free(settings->typescript_path);
    585
    586    /* Free screen recording settings */
    587    guac_mem_free(settings->recording_name);
    588    guac_mem_free(settings->recording_path);
    589
    590    /* Free terminal emulator type. */
    591    guac_mem_free(settings->terminal_type);
    592
    593    /* Free locale */
    594    guac_mem_free(settings->locale);
    595
    596    /* Free the client timezone. */
    597    guac_mem_free(settings->timezone);
    598    
    599    /* Free Wake-on-LAN settings. */
    600    guac_mem_free(settings->wol_mac_addr);
    601    guac_mem_free(settings->wol_broadcast_addr);
    602
    603    /* Free overall structure */
    604    guac_mem_free(settings);
    605
    606}