From aa3a9cde6cc82f1afcb82e9f7b9246aa369a052b Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 1 Jul 2020 19:11:52 -0700 Subject: [PATCH] GUACAMOLE-221: Migrate Kubernetes handling of "argv" to guac_argv_*() convenience API. --- src/protocols/kubernetes/argv.c | 180 ++++------------------------ src/protocols/kubernetes/argv.h | 25 +++- src/protocols/kubernetes/client.c | 7 ++ src/protocols/kubernetes/settings.c | 7 +- src/protocols/kubernetes/user.c | 2 +- 5 files changed, 52 insertions(+), 169 deletions(-) diff --git a/src/protocols/kubernetes/argv.c b/src/protocols/kubernetes/argv.c index c37595de..aab158c8 100644 --- a/src/protocols/kubernetes/argv.c +++ b/src/protocols/kubernetes/argv.c @@ -29,172 +29,33 @@ #include #include -/** - * All Kubernetes connection settings which may be updated by unprivileged - * users through "argv" streams. - */ -typedef enum guac_kubernetes_argv_setting { - - /** - * The color scheme of the terminal. - */ - GUAC_KUBERNETES_ARGV_SETTING_COLOR_SCHEME, - - /** - * The name of the font family used by the terminal. - */ - GUAC_KUBERNETES_ARGV_SETTING_FONT_NAME, - - /** - * The size of the font used by the terminal, in points. - */ - GUAC_KUBERNETES_ARGV_SETTING_FONT_SIZE - -} guac_kubernetes_argv_setting; - -/** - * The value or current status of a connection parameter received over an - * "argv" stream. - */ -typedef struct guac_kubernetes_argv { - - /** - * The specific setting being updated. - */ - guac_kubernetes_argv_setting setting; - - /** - * Buffer space for containing the received argument value. - */ - char buffer[GUAC_KUBERNETES_ARGV_MAX_LENGTH]; - - /** - * The number of bytes received so far. - */ - int length; - -} guac_kubernetes_argv; - -/** - * Handler for "blob" instructions which appends the data from received blobs - * to the end of the in-progress argument value buffer. - * - * @see guac_user_blob_handler - */ -static int guac_kubernetes_argv_blob_handler(guac_user* user, - guac_stream* stream, void* data, int length) { - - guac_kubernetes_argv* argv = (guac_kubernetes_argv*) stream->data; - - /* Calculate buffer size remaining, including space for null terminator, - * adjusting received length accordingly */ - int remaining = sizeof(argv->buffer) - argv->length - 1; - if (length > remaining) - length = remaining; - - /* Append received data to end of buffer */ - memcpy(argv->buffer + argv->length, data, length); - argv->length += length; - - return 0; - -} - -/** - * Handler for "end" instructions which applies the changes specified by the - * argument value buffer associated with the stream. - * - * @see guac_user_end_handler - */ -static int guac_kubernetes_argv_end_handler(guac_user* user, - guac_stream* stream) { - - int size; +int guac_kubernetes_argv_callback(guac_user* user, const char* mimetype, + const char* name, const char* value, void* data) { guac_client* client = user->client; guac_kubernetes_client* kubernetes_client = (guac_kubernetes_client*) client->data; guac_terminal* terminal = kubernetes_client->term; - /* Append null terminator to value */ - guac_kubernetes_argv* argv = (guac_kubernetes_argv*) stream->data; - argv->buffer[argv->length] = '\0'; + /* Update color scheme */ + if (strcmp(name, GUAC_KUBERNETES_ARGV_COLOR_SCHEME) == 0) + guac_terminal_apply_color_scheme(terminal, value); - /* Apply changes to chosen setting */ - switch (argv->setting) { - - /* Update color scheme */ - case GUAC_KUBERNETES_ARGV_SETTING_COLOR_SCHEME: - guac_terminal_apply_color_scheme(terminal, argv->buffer); - guac_client_stream_argv(client, client->socket, "text/plain", - "color-scheme", argv->buffer); - break; - - /* Update font name */ - case GUAC_KUBERNETES_ARGV_SETTING_FONT_NAME: - guac_terminal_apply_font(terminal, argv->buffer, -1, 0); - guac_client_stream_argv(client, client->socket, "text/plain", - "font-name", argv->buffer); - break; - - /* Update font size */ - case GUAC_KUBERNETES_ARGV_SETTING_FONT_SIZE: - - /* Update only if font size is sane */ - size = atoi(argv->buffer); - if (size > 0) { - guac_terminal_apply_font(terminal, NULL, size, - kubernetes_client->settings->resolution); - guac_client_stream_argv(client, client->socket, "text/plain", - "font-size", argv->buffer); - } - - break; + /* Update font name */ + else if (strcmp(name, GUAC_KUBERNETES_ARGV_FONT_NAME) == 0) + guac_terminal_apply_font(terminal, value, -1, 0); + /* Update only if font size is sane */ + else if (strcmp(name, GUAC_KUBERNETES_ARGV_FONT_SIZE) == 0) { + int size = atoi(value); + if (size > 0) + guac_terminal_apply_font(terminal, NULL, size, + kubernetes_client->settings->resolution); } /* Update Kubernetes terminal size */ guac_kubernetes_resize(client, terminal->term_height, terminal->term_width); - free(argv); - return 0; - -} - -int guac_kubernetes_argv_handler(guac_user* user, guac_stream* stream, - char* mimetype, char* name) { - - guac_kubernetes_argv_setting setting; - - /* Allow users to update the color scheme and font details */ - if (strcmp(name, "color-scheme") == 0) - setting = GUAC_KUBERNETES_ARGV_SETTING_COLOR_SCHEME; - else if (strcmp(name, "font-name") == 0) - setting = GUAC_KUBERNETES_ARGV_SETTING_FONT_NAME; - else if (strcmp(name, "font-size") == 0) - setting = GUAC_KUBERNETES_ARGV_SETTING_FONT_SIZE; - - /* No other connection parameters may be updated */ - else { - guac_protocol_send_ack(user->socket, stream, "Not allowed.", - GUAC_PROTOCOL_STATUS_CLIENT_FORBIDDEN); - guac_socket_flush(user->socket); - return 0; - } - - guac_kubernetes_argv* argv = malloc(sizeof(guac_kubernetes_argv)); - argv->setting = setting; - argv->length = 0; - - /* Prepare stream to receive argument value */ - stream->blob_handler = guac_kubernetes_argv_blob_handler; - stream->end_handler = guac_kubernetes_argv_end_handler; - stream->data = argv; - - /* Signal stream is ready */ - guac_protocol_send_ack(user->socket, stream, "Ready for updated " - "parameter.", GUAC_PROTOCOL_STATUS_SUCCESS); - guac_socket_flush(user->socket); return 0; } @@ -205,20 +66,21 @@ void* guac_kubernetes_send_current_argv(guac_user* user, void* data) { guac_terminal* terminal = kubernetes_client->term; /* Send current color scheme */ - guac_user_stream_argv(user, user->socket, "text/plain", "color-scheme", - terminal->color_scheme); + guac_user_stream_argv(user, user->socket, "text/plain", + GUAC_KUBERNETES_ARGV_COLOR_SCHEME, terminal->color_scheme); /* Send current font name */ - guac_user_stream_argv(user, user->socket, "text/plain", "font-name", - terminal->font_name); + guac_user_stream_argv(user, user->socket, "text/plain", + GUAC_KUBERNETES_ARGV_FONT_NAME, terminal->font_name); /* Send current font size */ char font_size[64]; sprintf(font_size, "%i", terminal->font_size); - guac_user_stream_argv(user, user->socket, "text/plain", "font-size", - font_size); + guac_user_stream_argv(user, user->socket, "text/plain", + GUAC_KUBERNETES_ARGV_FONT_SIZE, font_size); return NULL; + } diff --git a/src/protocols/kubernetes/argv.h b/src/protocols/kubernetes/argv.h index 2fc6c1ba..307ebc71 100644 --- a/src/protocols/kubernetes/argv.h +++ b/src/protocols/kubernetes/argv.h @@ -23,19 +23,32 @@ #include "config.h" +#include #include /** - * The maximum number of bytes to allow for any argument value received via an - * argv stream, including null terminator. + * The name of the parameter that specifies/updates the color scheme used by + * the terminal emulator. */ -#define GUAC_KUBERNETES_ARGV_MAX_LENGTH 16384 +#define GUAC_KUBERNETES_ARGV_COLOR_SCHEME "color-scheme" /** - * Handles an incoming stream from a Guacamole "argv" instruction, updating the - * given connection parameter if that parameter is allowed to be updated. + * The name of the parameter that specifies/updates the name of the font used + * by the terminal emulator. */ -guac_user_argv_handler guac_kubernetes_argv_handler; +#define GUAC_KUBERNETES_ARGV_FONT_NAME "font-name" + +/** + * The name of the parameter that specifies/updates the font size used by the + * terminal emulator. + */ +#define GUAC_KUBERNETES_ARGV_FONT_SIZE "font-size" + +/** + * Handles a received argument value from a Guacamole "argv" instruction, + * updating the given connection parameter. + */ +guac_argv_callback guac_kubernetes_argv_callback; /** * Sends the current values of all non-sensitive parameters which may be set diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c index 1a1eb3a7..fb3d881b 100644 --- a/src/protocols/kubernetes/client.c +++ b/src/protocols/kubernetes/client.c @@ -17,12 +17,14 @@ * under the License. */ +#include "argv.h" #include "client.h" #include "common/clipboard.h" #include "kubernetes.h" #include "settings.h" #include "user.h" +#include #include #include @@ -100,6 +102,11 @@ int guac_client_init(guac_client* client) { client->join_handler = guac_kubernetes_user_join_handler; client->free_handler = guac_kubernetes_client_free_handler; + /* Register handlers for argument values that may be sent after the handshake */ + guac_argv_register(GUAC_KUBERNETES_ARGV_COLOR_SCHEME, guac_kubernetes_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); + guac_argv_register(GUAC_KUBERNETES_ARGV_FONT_NAME, guac_kubernetes_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); + guac_argv_register(GUAC_KUBERNETES_ARGV_FONT_SIZE, guac_kubernetes_argv_callback, NULL, GUAC_ARGV_OPTION_ECHO); + /* Set locale and warn if not UTF-8 */ setlocale(LC_CTYPE, ""); if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0) { diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 4ed5f515..3421b1e0 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -17,6 +17,7 @@ * under the License. */ +#include "argv.h" #include "settings.h" #include @@ -35,9 +36,9 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = { "client-key", "ca-cert", "ignore-cert", - "font-name", - "font-size", - "color-scheme", + GUAC_KUBERNETES_ARGV_FONT_NAME, + GUAC_KUBERNETES_ARGV_FONT_SIZE, + GUAC_KUBERNETES_ARGV_COLOR_SCHEME, "typescript-path", "typescript-name", "create-typescript-path", diff --git a/src/protocols/kubernetes/user.c b/src/protocols/kubernetes/user.c index d1fcd5da..b09d837e 100644 --- a/src/protocols/kubernetes/user.c +++ b/src/protocols/kubernetes/user.c @@ -93,7 +93,7 @@ int guac_kubernetes_user_join_handler(guac_user* user, int argc, char** argv) { user->pipe_handler = guac_kubernetes_pipe_handler; /* Updates to connection parameters */ - user->argv_handler = guac_kubernetes_argv_handler; + user->argv_handler = guac_argv_handler; /* Display size change events */ user->size_handler = guac_kubernetes_user_size_handler;