From 7683a17d69d2cc4f1a46bdee9b171d012ded00ef Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Fri, 14 Aug 2020 15:35:37 +0300 Subject: [PATCH 1/7] GUACAMOLE-1174: Added exec call implementation for kubernetes protocol --- src/protocols/kubernetes/kubernetes.c | 6 ++-- src/protocols/kubernetes/settings.c | 22 +++++++++++++ src/protocols/kubernetes/settings.h | 16 ++++++++++ src/protocols/kubernetes/url.c | 45 ++++++++++++++++++--------- src/protocols/kubernetes/url.h | 11 +++++-- 5 files changed, 82 insertions(+), 18 deletions(-) diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c index 7158a989..263d99fc 100644 --- a/src/protocols/kubernetes/kubernetes.c +++ b/src/protocols/kubernetes/kubernetes.c @@ -213,10 +213,12 @@ void* guac_kubernetes_client_thread(void* data) { } /* Generate endpoint for attachment URL */ - if (guac_kubernetes_endpoint_attach(endpoint_path, sizeof(endpoint_path), + if (guac_kubernetes_endpoint_uri(endpoint_path, sizeof(endpoint_path), settings->kubernetes_namespace, settings->kubernetes_pod, - settings->kubernetes_container)) { + settings->kubernetes_container, + settings->use_exec, + settings->exec_command)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to generate path for Kubernetes API endpoint: " "Resulting path too long"); diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 3421b1e0..74370d4b 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -31,6 +31,8 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = { "namespace", "pod", "container", + "use-exec", + "exec-command", "use-ssl", "client-cert", "client-key", @@ -86,6 +88,16 @@ enum KUBERNETES_ARGS_IDX { */ IDX_CONTAINER, + /** + * Whether exec call should be used. If omitted, attach call will be used. + */ + IDX_USE_EXEC, + + /** + * The command used by exec call. + */ + IDX_EXEC_COMMAND, + /** * Whether SSL/TLS should be used. If omitted, SSL/TLS will not be used. */ @@ -275,6 +287,16 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, IDX_CONTAINER, NULL); + /* Parse whether exec call should be used */ + settings->use_exec = + guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, + IDX_USE_EXEC, false); + + /* Read exec command (optional) */ + settings->exec_command = + guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, + IDX_EXEC_COMMAND, GUAC_KUBERNETES_DEFAULT_EXEC_COMMAND); + /* Parse whether SSL should be used */ settings->use_ssl = guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h index eef4973e..597ebd53 100644 --- a/src/protocols/kubernetes/settings.h +++ b/src/protocols/kubernetes/settings.h @@ -47,6 +47,12 @@ */ #define GUAC_KUBERNETES_DEFAULT_NAMESPACE "default" +/** + * The command that should be used by default for exec call if no + * specific command is provided. + */ +#define GUAC_KUBERNETES_DEFAULT_EXEC_COMMAND "/bin/sh" + /** * The filename to use for the typescript, if not specified. */ @@ -97,6 +103,16 @@ typedef struct guac_kubernetes_settings { */ char* kubernetes_container; + /** + * Whether exec call should be used, default attach. + */ + bool use_exec; + + /** + * Exec command, default /bin/sh. + */ + char* exec_command; + /** * Whether SSL/TLS should be used. */ diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c index 78c116e5..97156269 100644 --- a/src/protocols/kubernetes/url.c +++ b/src/protocols/kubernetes/url.c @@ -89,15 +89,16 @@ int guac_kubernetes_escape_url_component(char* output, int length, } -int guac_kubernetes_endpoint_attach(char* buffer, int length, +int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, - const char* kubernetes_container) { + const char* kubernetes_container, int use_exec, const char* exec_command) { int written; char escaped_namespace[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; char escaped_pod[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; char escaped_container[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; + char escaped_exec_command[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; /* Escape Kubernetes namespace */ if (guac_kubernetes_escape_url_component(escaped_namespace, @@ -109,26 +110,42 @@ int guac_kubernetes_endpoint_attach(char* buffer, int length, sizeof(escaped_pod), kubernetes_pod)) return 1; - /* Generate attachment endpoint URL */ - if (kubernetes_container != NULL) { + /* Generate endpoint path depending on the call type */ + char* call="attach"; + if (use_exec) + call = "exec"; + char endpoint_path[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; + snprintf(endpoint_path, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH*3, + "/api/v1/namespaces/%s/pods/%s/%s", escaped_namespace, escaped_pod, call); + + /* Generate endpoint params */ + char endpoint_params[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]=""; + int param_length=0; + + if(use_exec){ + /* Escape exec command */ + if (guac_kubernetes_escape_url_component(escaped_exec_command, + sizeof(escaped_exec_command), exec_command)) + return 1; + + param_length += snprintf(endpoint_params, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH, + "command=%s&", escaped_exec_command); + } + + if (kubernetes_container != NULL) { /* Escape container name */ if (guac_kubernetes_escape_url_component(escaped_container, sizeof(escaped_container), kubernetes_container)) return 1; - written = snprintf(buffer, length, - "/api/v1/namespaces/%s/pods/%s/attach" - "?container=%s&stdin=true&stdout=true&tty=true", - escaped_namespace, escaped_pod, escaped_container); - } - else { - written = snprintf(buffer, length, - "/api/v1/namespaces/%s/pods/%s/attach" - "?stdin=true&stdout=true&tty=true", - escaped_namespace, escaped_pod); + snprintf(endpoint_params+param_length, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH-param_length, + "container=%s&", escaped_container); } + /* Combine path and params to uri */ + written = snprintf(buffer, length, "%s?%sstdin=true&stdout=true&tty=true", + endpoint_path, endpoint_params); /* Endpoint URL was successfully generated if it was written to the given * buffer without truncation */ return !(written < length - 1); diff --git a/src/protocols/kubernetes/url.h b/src/protocols/kubernetes/url.h index 285baa21..8827e7ec 100644 --- a/src/protocols/kubernetes/url.h +++ b/src/protocols/kubernetes/url.h @@ -72,14 +72,21 @@ int guac_kubernetes_escape_url_component(char* output, int length, * @param kubernetes_container * The name of the container to attach to, or NULL to arbitrarily attach * to the first container in the pod. + * + * @param use_exec + * Whether use call exec. + * Execute a command in a container and attach to it instead of main container process. + * + * @param exec_command + * The command used in conjunction with exec call. * * @return * Zero if the endpoint path was successfully written to the provided * buffer, non-zero if insufficient space exists within the buffer. */ -int guac_kubernetes_endpoint_attach(char* buffer, int length, +int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, - const char* kubernetes_container); + const char* kubernetes_container, int use_exec, const char* exec_command); #endif From 164f792b86a9e87976ce30b510958708b238f3a7 Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Wed, 23 Sep 2020 14:50:01 +0300 Subject: [PATCH 2/7] GUACAMOLE-1174: Remove option use-exec, add snprintf result validation, fix code formatting. --- src/protocols/kubernetes/kubernetes.c | 1 - src/protocols/kubernetes/settings.c | 15 ++----------- src/protocols/kubernetes/settings.h | 14 ++---------- src/protocols/kubernetes/url.c | 32 ++++++++++++++++++--------- src/protocols/kubernetes/url.h | 11 ++++----- 5 files changed, 29 insertions(+), 44 deletions(-) diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c index 263d99fc..c793ad46 100644 --- a/src/protocols/kubernetes/kubernetes.c +++ b/src/protocols/kubernetes/kubernetes.c @@ -217,7 +217,6 @@ void* guac_kubernetes_client_thread(void* data) { settings->kubernetes_namespace, settings->kubernetes_pod, settings->kubernetes_container, - settings->use_exec, settings->exec_command)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to generate path for Kubernetes API endpoint: " diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 74370d4b..9de7a859 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -31,7 +31,6 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = { "namespace", "pod", "container", - "use-exec", "exec-command", "use-ssl", "client-cert", @@ -89,12 +88,7 @@ enum KUBERNETES_ARGS_IDX { IDX_CONTAINER, /** - * Whether exec call should be used. If omitted, attach call will be used. - */ - IDX_USE_EXEC, - - /** - * The command used by exec call. + * The command used by exec call. If omitted, attach call will be used. */ IDX_EXEC_COMMAND, @@ -287,15 +281,10 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user, guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, IDX_CONTAINER, NULL); - /* Parse whether exec call should be used */ - settings->use_exec = - guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, - IDX_USE_EXEC, false); - /* Read exec command (optional) */ settings->exec_command = guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv, - IDX_EXEC_COMMAND, GUAC_KUBERNETES_DEFAULT_EXEC_COMMAND); + IDX_EXEC_COMMAND, NULL); /* Parse whether SSL should be used */ settings->use_ssl = diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h index 597ebd53..1ad58058 100644 --- a/src/protocols/kubernetes/settings.h +++ b/src/protocols/kubernetes/settings.h @@ -47,12 +47,6 @@ */ #define GUAC_KUBERNETES_DEFAULT_NAMESPACE "default" -/** - * The command that should be used by default for exec call if no - * specific command is provided. - */ -#define GUAC_KUBERNETES_DEFAULT_EXEC_COMMAND "/bin/sh" - /** * The filename to use for the typescript, if not specified. */ @@ -104,12 +98,8 @@ typedef struct guac_kubernetes_settings { char* kubernetes_container; /** - * Whether exec call should be used, default attach. - */ - bool use_exec; - - /** - * Exec command, default /bin/sh. + * The command to generate api endpoint for call exec. + * If omitted call attach will be used. */ char* exec_command; diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c index 97156269..9b8c55ac 100644 --- a/src/protocols/kubernetes/url.c +++ b/src/protocols/kubernetes/url.c @@ -91,7 +91,7 @@ int guac_kubernetes_escape_url_component(char* output, int length, int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, - const char* kubernetes_container, int use_exec, const char* exec_command) { + const char* kubernetes_container, const char* exec_command) { int written; @@ -111,26 +111,32 @@ int guac_kubernetes_endpoint_uri(char* buffer, int length, return 1; /* Generate endpoint path depending on the call type */ - char* call="attach"; - if (use_exec) + char* call = "attach"; + if (exec_command != NULL) call = "exec"; char endpoint_path[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; - snprintf(endpoint_path, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH*3, - "/api/v1/namespaces/%s/pods/%s/%s", escaped_namespace, escaped_pod, call); + + written = snprintf(endpoint_path, sizeof(endpoint_path), + "/api/v1/namespaces/%s/pods/%s/%s", escaped_namespace, escaped_pod, call); + + if (written < 0 || written >= sizeof(endpoint_path)) + return 1; /* Generate endpoint params */ char endpoint_params[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]=""; - int param_length=0; - if(use_exec){ + if (exec_command != NULL) { /* Escape exec command */ if (guac_kubernetes_escape_url_component(escaped_exec_command, sizeof(escaped_exec_command), exec_command)) return 1; - param_length += snprintf(endpoint_params, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH, - "command=%s&", escaped_exec_command); + written = snprintf(endpoint_params, sizeof(endpoint_params), + "command=%s&", escaped_exec_command); + + if (written < 0 || written >= sizeof(endpoint_params)) + return 1; } if (kubernetes_container != NULL) { @@ -139,13 +145,17 @@ int guac_kubernetes_endpoint_uri(char* buffer, int length, sizeof(escaped_container), kubernetes_container)) return 1; - snprintf(endpoint_params+param_length, GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH-param_length, + written = snprintf(endpoint_params, sizeof(endpoint_params), "container=%s&", escaped_container); + + if (written < 0 || written >= sizeof(endpoint_params)) + return 1; } /* Combine path and params to uri */ written = snprintf(buffer, length, "%s?%sstdin=true&stdout=true&tty=true", - endpoint_path, endpoint_params); + endpoint_path, endpoint_params); + /* Endpoint URL was successfully generated if it was written to the given * buffer without truncation */ return !(written < length - 1); diff --git a/src/protocols/kubernetes/url.h b/src/protocols/kubernetes/url.h index 8827e7ec..4d5e92e0 100644 --- a/src/protocols/kubernetes/url.h +++ b/src/protocols/kubernetes/url.h @@ -72,13 +72,10 @@ int guac_kubernetes_escape_url_component(char* output, int length, * @param kubernetes_container * The name of the container to attach to, or NULL to arbitrarily attach * to the first container in the pod. - * - * @param use_exec - * Whether use call exec. - * Execute a command in a container and attach to it instead of main container process. - * + * * @param exec_command - * The command used in conjunction with exec call. + * The command used to run a new process and attach to it, + * instead of the main container process. * * @return * Zero if the endpoint path was successfully written to the provided @@ -86,7 +83,7 @@ int guac_kubernetes_escape_url_component(char* output, int length, */ int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, - const char* kubernetes_container, int use_exec, const char* exec_command); + const char* kubernetes_container, const char* exec_command); #endif From 6b58e2e5a964805bc80145af8481729fd40fb17d Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Tue, 20 Oct 2020 12:26:19 +0300 Subject: [PATCH 3/7] GUACAMOLE-1174: Free exec_command setting. --- src/protocols/kubernetes/settings.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c index 9de7a859..1d437bc2 100644 --- a/src/protocols/kubernetes/settings.c +++ b/src/protocols/kubernetes/settings.c @@ -417,6 +417,9 @@ void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) { free(settings->kubernetes_pod); free(settings->kubernetes_container); + /* Free Kubernetes exec command */ + free(settings->exec_command); + /* Free SSL/TLS details */ free(settings->client_cert); free(settings->client_key); From 79239e3be0c18dcd894d200ae078218765fab58d Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Tue, 20 Oct 2020 12:35:25 +0300 Subject: [PATCH 4/7] GUACAMOLE-1174: Create function for appending endpoint params, fix endpoint params overwriting. --- src/protocols/kubernetes/url.c | 44 +++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c index 9b8c55ac..610f811d 100644 --- a/src/protocols/kubernetes/url.c +++ b/src/protocols/kubernetes/url.c @@ -89,6 +89,23 @@ int guac_kubernetes_escape_url_component(char* output, int length, } +int guac_kubernetes_append_endpoint_param(char* buffer, int length, + const char* param_name, const char* param_value) { + + char escaped_param_value[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; + + /* Escape value */ + if (guac_kubernetes_escape_url_component(escaped_param_value, + sizeof(escaped_param_value), param_value)) + return 1; + + int written; + written = snprintf(buffer + strlen(buffer), length - strlen(buffer), + "%s=%s&", param_name, escaped_param_value); + + return (written < 0 || written >= length); +} + int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, const char* kubernetes_container, const char* exec_command) { @@ -124,31 +141,20 @@ int guac_kubernetes_endpoint_uri(char* buffer, int length, return 1; /* Generate endpoint params */ - char endpoint_params[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]=""; + char endpoint_params[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; + endpoint_params[0] = 0; if (exec_command != NULL) { - /* Escape exec command */ - if (guac_kubernetes_escape_url_component(escaped_exec_command, - sizeof(escaped_exec_command), exec_command)) - return 1; - - written = snprintf(endpoint_params, sizeof(endpoint_params), - "command=%s&", escaped_exec_command); - - if (written < 0 || written >= sizeof(endpoint_params)) + /* Append exec command param */ + if (guac_kubernetes_append_endpoint_param(endpoint_params, + sizeof(endpoint_params), "command", exec_command)) return 1; } if (kubernetes_container != NULL) { - /* Escape container name */ - if (guac_kubernetes_escape_url_component(escaped_container, - sizeof(escaped_container), kubernetes_container)) - return 1; - - written = snprintf(endpoint_params, sizeof(endpoint_params), - "container=%s&", escaped_container); - - if (written < 0 || written >= sizeof(endpoint_params)) + /* Append kubernetes container param */ + if (guac_kubernetes_append_endpoint_param(endpoint_params, + sizeof(endpoint_params), "container", kubernetes_container)) return 1; } From 7a1ba51baef5a6e8e8d85f6a5b68c022d6ba0fa1 Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Wed, 18 Nov 2020 14:52:24 +0200 Subject: [PATCH 5/7] GUACAMOLE-1174: Determine parameter delimiter, compute the buffer string length, fix the buffer string length usage, verify buffer null terminated. --- src/protocols/kubernetes/url.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c index 610f811d..74ab429c 100644 --- a/src/protocols/kubernetes/url.c +++ b/src/protocols/kubernetes/url.c @@ -99,10 +99,37 @@ int guac_kubernetes_append_endpoint_param(char* buffer, int length, sizeof(escaped_param_value), param_value)) return 1; - int written; - written = snprintf(buffer + strlen(buffer), length - strlen(buffer), - "%s=%s&", param_name, escaped_param_value); + char* str = buffer; + int str_len = 0; + int qmark = 0; + + while (*str != '\0') { + + /* Look for a question mark */ + if (*str=='?') qmark = 1; + + /* Compute the buffer string length */ + str_len++; + + /* Verify the buffer null terminated */ + if (str_len >= length) return 1; + + /* Next character */ + str++; + } + + /* Determine the parameter delimiter */ + char delimiter = '?'; + if (qmark) delimiter = '&'; + + /* Write the parameter to the buffer */ + int written; + written = snprintf(buffer + str_len, length - str_len, + "%c%s=%s", delimiter, param_name, escaped_param_value); + + /* The parameter was successfully added if it was written to the given + * buffer without truncation */ return (written < 0 || written >= length); } From 7809447c3ffd7c0fddef807231e994f52a6c15ed Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Wed, 18 Nov 2020 14:57:59 +0200 Subject: [PATCH 6/7] GUACAMOLE-1174: Add parameters to the endpoint path using function guac_kubernetes_append_endpoint_param. --- src/protocols/kubernetes/url.c | 46 +++++++++++++--------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c index 74ab429c..4bca0157 100644 --- a/src/protocols/kubernetes/url.c +++ b/src/protocols/kubernetes/url.c @@ -137,12 +137,8 @@ int guac_kubernetes_endpoint_uri(char* buffer, int length, const char* kubernetes_namespace, const char* kubernetes_pod, const char* kubernetes_container, const char* exec_command) { - int written; - char escaped_namespace[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; char escaped_pod[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; - char escaped_container[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; - char escaped_exec_command[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; /* Escape Kubernetes namespace */ if (guac_kubernetes_escape_url_component(escaped_namespace, @@ -154,44 +150,38 @@ int guac_kubernetes_endpoint_uri(char* buffer, int length, sizeof(escaped_pod), kubernetes_pod)) return 1; - /* Generate endpoint path depending on the call type */ + /* Determine the call type */ char* call = "attach"; if (exec_command != NULL) call = "exec"; - char endpoint_path[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; + int written; - written = snprintf(endpoint_path, sizeof(endpoint_path), + /* Generate the endpoint path and write to the buffer */ + written = snprintf(buffer, length, "/api/v1/namespaces/%s/pods/%s/%s", escaped_namespace, escaped_pod, call); - - if (written < 0 || written >= sizeof(endpoint_path)) + + /* Operation successful if the endpoint path was written to the given + * buffer without truncation */ + if (written < 0 || written >= length) return 1; - /* Generate endpoint params */ - char endpoint_params[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH]; - endpoint_params[0] = 0; - + /* Append exec command parameter */ if (exec_command != NULL) { - /* Append exec command param */ - if (guac_kubernetes_append_endpoint_param(endpoint_params, - sizeof(endpoint_params), "command", exec_command)) + if (guac_kubernetes_append_endpoint_param(buffer, + length, "command", exec_command)) return 1; } + /* Append kubernetes container parameter */ if (kubernetes_container != NULL) { - /* Append kubernetes container param */ - if (guac_kubernetes_append_endpoint_param(endpoint_params, - sizeof(endpoint_params), "container", kubernetes_container)) + if (guac_kubernetes_append_endpoint_param(buffer, + length, "container", kubernetes_container)) return 1; } - /* Combine path and params to uri */ - written = snprintf(buffer, length, "%s?%sstdin=true&stdout=true&tty=true", - endpoint_path, endpoint_params); - - /* Endpoint URL was successfully generated if it was written to the given - * buffer without truncation */ - return !(written < length - 1); - + /* Append stdin, stdout and tty parameters */ + return (guac_kubernetes_append_endpoint_param(buffer, length, "stdin", "true")) + || (guac_kubernetes_append_endpoint_param(buffer, length, "stdout", "true")) + || (guac_kubernetes_append_endpoint_param(buffer, length, "tty", "true")); } - From 004f57e19a42ddf5b14f355835302b8042a16afb Mon Sep 17 00:00:00 2001 From: Yaroslav Nikonorov Date: Wed, 18 Nov 2020 15:30:34 +0200 Subject: [PATCH 7/7] GUACAMOLE-1174: Add prototype and docstrings for guac_kubernetes_append_endpoint_param function. --- src/protocols/kubernetes/url.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/protocols/kubernetes/url.h b/src/protocols/kubernetes/url.h index 4d5e92e0..96e50982 100644 --- a/src/protocols/kubernetes/url.h +++ b/src/protocols/kubernetes/url.h @@ -49,6 +49,31 @@ int guac_kubernetes_escape_url_component(char* output, int length, const char* str); +/** + * Append the parameter to the endpoint path. + * Value within the path will be URL-escaped as necessary. + * + * @param buffer + * The buffer which should receive the parameter. It could contain the endpoint path. + * The parameter will be written to the end of the buffer. + * + * @param length + * The number of bytes available in the given buffer. + * + * @param param_name + * The name of the parameter. + * + * @param param_value + * The value of the parameter. + * + * @return + * Zero if the parameter was successfully attached to the buffer, + * non-zero if insufficient space exists within the buffer or + * buffer not null terminated. + */ +int guac_kubernetes_append_endpoint_param(char* buffer, int length, + const char* param_name, const char* param_value); + /** * Generates the full path to the Kubernetes API endpoint which handles * attaching to running containers within specific pods. Values within the path