You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/09/26 12:44:22 UTC
[01/19] guacamole-server git commit: GUACAMOLE-623: Add missing
documentation for URL character test.
Repository: guacamole-server
Updated Branches:
refs/heads/master 54fda2136 -> 43db1965e
GUACAMOLE-623: Add missing documentation for URL character test.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/5e3aec6d
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/5e3aec6d
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/5e3aec6d
Branch: refs/heads/master
Commit: 5e3aec6df2ec3578e47030665f7b12c3c3cadd51
Parents: 371eed1
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 21:08:19 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/url.c | 11 +++++++++++
1 file changed, 11 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5e3aec6d/src/protocols/kubernetes/url.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c
index 434cc87..78c116e 100644
--- a/src/protocols/kubernetes/url.c
+++ b/src/protocols/kubernetes/url.c
@@ -23,6 +23,17 @@
#include <stdlib.h>
#include <string.h>
+/**
+ * Returns whether the given character is a character that need not be
+ * escaped when included as part of a component of a URL.
+ *
+ * @param c
+ * The character to test.
+ *
+ * @return
+ * Zero if the character does not need to be escaped when included as
+ * part of a component of a URL, non-zero otherwise.
+ */
static int guac_kubernetes_is_url_safe(char c) {
return (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z')
[06/19] guacamole-server git commit: GUACAMOLE-623: Do not return -1
from libwebsockets callback. Doing so results in automatic cleanup of part of
the context, resulting in a segfault when lws_context_destroy() is invoked.
Posted by vn...@apache.org.
GUACAMOLE-623: Do not return -1 from libwebsockets callback. Doing so results in automatic cleanup of part of the context, resulting in a segfault when lws_context_destroy() is invoked.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/cbe59350
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/cbe59350
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/cbe59350
Branch: refs/heads/master
Commit: cbe593503f4cf819af32abc0b661662aa3fadc9e
Parents: f72877b
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 00:25:49 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/kubernetes.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/cbe59350/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index ae2a894..e38d5e3 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -109,7 +109,7 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
* pointer passed by libwebsockets may be NULL for some events) */
guac_client* client = (guac_client*) user;
if (client != NULL && client->state != GUAC_CLIENT_RUNNING)
- return -1;
+ return lws_callback_http_dummy(wsi, reason, user, in, length);
switch (reason) {
[03/19] guacamole-server git commit: GUACAMOLE-623: Add warning when
Kubernetes support will not be built. Fix summary output from configure.
Posted by vn...@apache.org.
GUACAMOLE-623: Add warning when Kubernetes support will not be built. Fix summary output from configure.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/77a86612
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/77a86612
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/77a86612
Branch: refs/heads/master
Commit: 77a866129b3b6592f122a5912c349a03f0c4b4e2
Parents: c5f67a3
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 20:09:36 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
configure.ac | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/77a86612/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 7c0bb73..df36eab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1190,7 +1190,12 @@ then
AC_CHECK_LIB([websockets],
[lws_create_context],
[WEBSOCKETS_LIBS="$WEBSOCKETS_LIBS -lwebsockets"],
- [have_libwebsockets=no])
+ [AC_MSG_WARN([
+ --------------------------------------------
+ Unable to find libwebsockets.
+ Support for Kubernetes will be disabled.
+ --------------------------------------------])
+ have_libwebsockets=no])
fi
# Check for client-specific closed event, which must be used in favor of the
@@ -1339,7 +1344,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION
libVNCServer ........ ${have_libvncserver}
libvorbis ........... ${have_vorbis}
libpulse ............ ${have_pulse}
- libwebsockets ....... ${have_websockets}
+ libwebsockets ....... ${have_libwebsockets}
libwebp ............. ${have_webp}
wsock32 ............. ${have_winsock}
[13/19] guacamole-server git commit: GUACAMOLE-623: Generate
Kubernetes API endpoint dynamically.
Posted by vn...@apache.org.
GUACAMOLE-623: Generate Kubernetes API endpoint dynamically.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/ed560938
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/ed560938
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/ed560938
Branch: refs/heads/master
Commit: ed560938886e92dbe656d610966585b8178c2d73
Parents: 34f8f8b
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 18:39:06 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/Makefile.am | 2 +
src/protocols/kubernetes/kubernetes.c | 27 ++++++-
src/protocols/kubernetes/settings.c | 53 ++++++++++--
src/protocols/kubernetes/settings.h | 24 ++++++
src/protocols/kubernetes/url.c | 126 +++++++++++++++++++++++++++++
src/protocols/kubernetes/url.h | 87 ++++++++++++++++++++
6 files changed, 311 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/Makefile.am b/src/protocols/kubernetes/Makefile.am
index d864967..9e50feb 100644
--- a/src/protocols/kubernetes/Makefile.am
+++ b/src/protocols/kubernetes/Makefile.am
@@ -29,6 +29,7 @@ libguac_client_kubernetes_la_SOURCES = \
pipe.c \
settings.c \
kubernetes.c \
+ url.c \
user.c
noinst_HEADERS = \
@@ -38,6 +39,7 @@ noinst_HEADERS = \
pipe.h \
settings.h \
kubernetes.h \
+ url.h \
user.h
libguac_client_kubernetes_la_CFLAGS = \
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 53a8580..380d1d3 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -21,6 +21,7 @@
#include "common/recording.h"
#include "kubernetes.h"
#include "terminal/terminal.h"
+#include "url.h"
#include <guacamole/client.h>
#include <guacamole/protocol.h>
@@ -345,6 +346,28 @@ void* guac_kubernetes_client_thread(void* data) {
guac_kubernetes_settings* settings = kubernetes_client->settings;
pthread_t input_thread;
+ char endpoint_path[GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH];
+
+ /* Verify that the pod name was specified (it's always required) */
+ if (settings->kubernetes_pod == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "The name of the Kubernetes pod is a required parameter.");
+ goto fail;
+ }
+
+ /* Generate endpoint for attachment URL */
+ if (guac_kubernetes_endpoint_attach(endpoint_path, sizeof(endpoint_path),
+ settings->kubernetes_namespace,
+ settings->kubernetes_pod,
+ settings->kubernetes_container)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Unable to generate path for Kubernetes API endpoint: "
+ "Resulting path too long");
+ goto fail;
+ }
+
+ guac_client_log(client, GUAC_LOG_DEBUG, "The endpoint for attaching to "
+ "the requested Kubernetes pod is \"%s\".", endpoint_path);
/* Set up screen recording, if requested */
if (settings->recording_path != NULL) {
@@ -434,9 +457,9 @@ void* guac_kubernetes_client_thread(void* data) {
goto fail;
}
- /* FIXME: Generate path dynamically */
+ /* Generate path dynamically */
connection_info.context = kubernetes_client->context;
- connection_info.path = "/api/v1/namespaces/default/pods/my-shell-68974bb7f7-rpjgr/attach?container=my-shell&stdin=true&stdout=true&tty=true";
+ connection_info.path = endpoint_path;
/* Open WebSocket connection to Kubernetes */
kubernetes_client->wsi = lws_client_connect_via_info(&connection_info);
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 50daa6f..4f9f3f2 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -32,6 +32,9 @@
const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
"hostname",
"port",
+ "namespace",
+ "pod",
+ "container",
"use-ssl",
"client-cert-file",
"client-key-file",
@@ -68,6 +71,24 @@ enum KUBERNETES_ARGS_IDX {
IDX_PORT,
/**
+ * The name of the Kubernetes namespace of the pod containing the container
+ * being attached to. If omitted, the default namespace will be used.
+ */
+ IDX_NAMESPACE,
+
+ /**
+ * The name of the Kubernetes pod containing with the container being
+ * attached to. Required.
+ */
+ IDX_POD,
+
+ /**
+ * The name of the container to attach to. If omitted, the first container
+ * in the pod will be used.
+ */
+ IDX_CONTAINER,
+
+ /**
* Whether SSL/TLS should be used. If omitted, SSL/TLS will not be used.
*/
IDX_USE_SSL,
@@ -215,11 +236,31 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
guac_kubernetes_settings* settings =
calloc(1, sizeof(guac_kubernetes_settings));
- /* Read parameters */
+ /* Read hostname */
settings->hostname =
guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
IDX_HOSTNAME, "");
+ /* Read port */
+ settings->port =
+ guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_PORT, GUAC_KUBERNETES_DEFAULT_PORT);
+
+ /* Read Kubernetes namespace */
+ settings->kubernetes_namespace =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_NAMESPACE, GUAC_KUBERNETES_DEFAULT_NAMESPACE);
+
+ /* Read name of Kubernetes pod (required) */
+ settings->kubernetes_pod =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_POD, NULL);
+
+ /* Read container of pod (optional) */
+ settings->kubernetes_container =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_CONTAINER, NULL);
+
/* Parse whether SSL should be used */
settings->use_ssl =
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
@@ -276,11 +317,6 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
settings->height = user->info.optimal_height;
settings->resolution = user->info.optimal_resolution;
- /* Read port */
- settings->port =
- guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
- IDX_PORT, GUAC_KUBERNETES_DEFAULT_PORT);
-
/* Read typescript path */
settings->typescript_path =
guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
@@ -341,6 +377,11 @@ void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) {
/* Free network connection information */
free(settings->hostname);
+ /* Free Kubernetes pod/container details */
+ free(settings->kubernetes_namespace);
+ free(settings->kubernetes_pod);
+ free(settings->kubernetes_container);
+
/* Free SSL/TLS details */
free(settings->client_cert_file);
free(settings->client_key_file);
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index 8f42f8c..c2e479e 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -45,6 +45,12 @@
#define GUAC_KUBERNETES_DEFAULT_PORT 8080
/**
+ * The name of the Kubernetes namespace that should be used by default if no
+ * specific Kubernetes namespace is provided.
+ */
+#define GUAC_KUBERNETES_DEFAULT_NAMESPACE "default"
+
+/**
* The filename to use for the typescript, if not specified.
*/
#define GUAC_KUBERNETES_DEFAULT_TYPESCRIPT_NAME "typescript"
@@ -77,6 +83,24 @@ typedef struct guac_kubernetes_settings {
int port;
/**
+ * The name of the Kubernetes namespace of the pod containing the container
+ * being attached to.
+ */
+ char* kubernetes_namespace;
+
+ /**
+ * The name of the Kubernetes pod containing with the container being
+ * attached to.
+ */
+ char* kubernetes_pod;
+
+ /**
+ * The name of the container to attach to, or NULL to arbitrarily attach to
+ * the first container in the pod.
+ */
+ char* kubernetes_container;
+
+ /**
* Whether SSL/TLS should be used.
*/
bool use_ssl;
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/url.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c
new file mode 100644
index 0000000..cfd6f74
--- /dev/null
+++ b/src/protocols/kubernetes/url.c
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "url.h"
+
+#include <stdio.h>
+#include <string.h>
+
+static int guac_kubernetes_is_url_safe(char c) {
+ return (c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')
+ || (c >= '0' && c <= '9')
+ || strchr("-_.!~*'()", c) != NULL;
+}
+
+int guac_kubernetes_escape_url_component(char* output, int length,
+ const char* str) {
+
+ char* current = output;
+ while (*str != '\0') {
+
+ char c = *str;
+
+ /* Store alphanumeric characters verbatim */
+ if (guac_kubernetes_is_url_safe(c)) {
+
+ /* Verify space exists for single character */
+ if (length < 1)
+ return 1;
+
+ *(current++) = c;
+ length--;
+
+ }
+
+ /* Escape EVERYTHING else as hex */
+ else {
+
+ /* Verify space exists for hex-encoded character */
+ if (length < 4)
+ return 1;
+
+ snprintf(current, 4, "%%%02X", (int) c);
+
+ current += 3;
+ length -= 3;
+ }
+
+ /* Next character */
+ str++;
+
+ }
+
+ /* Verify space exists for null terminator */
+ if (length < 1)
+ return 1;
+
+ /* Append null terminator */
+ *current = '\0';
+ return 0;
+
+}
+
+int guac_kubernetes_endpoint_attach(char* buffer, int length,
+ const char* kubernetes_namespace, const char* kubernetes_pod,
+ const char* kubernetes_container) {
+
+ 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];
+
+ /* Escape Kubernetes namespace */
+ if (guac_kubernetes_escape_url_component(escaped_namespace,
+ sizeof(escaped_namespace), kubernetes_namespace))
+ return 1;
+
+ /* Escape name of Kubernetes pod */
+ if (guac_kubernetes_escape_url_component(escaped_pod,
+ sizeof(escaped_pod), kubernetes_pod))
+ return 1;
+
+ /* Generate attachment endpoint URL */
+ 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);
+ }
+
+ /* Endpoint URL was successfully generated if it was written to the given
+ * buffer without truncation */
+ return !(written < length - 1);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/ed560938/src/protocols/kubernetes/url.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/url.h b/src/protocols/kubernetes/url.h
new file mode 100644
index 0000000..19084ee
--- /dev/null
+++ b/src/protocols/kubernetes/url.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_URL_H
+#define GUAC_KUBERNETES_URL_H
+
+#include "config.h"
+
+/**
+ * The maximum number of characters allowed in the full path for any Kubernetes
+ * endpoint.
+ */
+#define GUAC_KUBERNETES_MAX_ENDPOINT_LENGTH 1024
+
+/**
+ * Escapes the given string such that it can be included safely within a URL.
+ * This function duplicates the behavior of JavaScript's encodeURIComponent(),
+ * escaping all but the following characters: A-Z a-z 0-9 - _ . ! ~ * ' ( )
+ *
+ * @param output
+ * The buffer which should receive the escaped string. This buffer may be
+ * touched even if escaping is unsuccessful.
+ *
+ * @param length
+ * The number of bytes available in the given output buffer.
+ *
+ * @param str
+ * The string to escape.
+ *
+ * @return
+ * Zero if the string was successfully escaped and written into the
+ * provided output buffer without being truncated, including null
+ * terminator, non-zero otherwise.
+ */
+int guac_kubernetes_escape_url_component(char* output, int length,
+ const char* str);
+
+/**
+ * Generates the full path to the Kubernetes API endpoint which handles
+ * attaching to running containers within specific pods. Values within the path
+ * will be URL-escaped as necessary.
+ *
+ * @param buffer
+ * The buffer which should receive the endpoint path. This buffer may be
+ * touched even if the endpoint path could not be generated.
+ *
+ * @param length
+ * The number of bytes available in the given buffer.
+ *
+ * @param kubernetes_namespace
+ * The name of the Kubernetes namespace of the pod containing the container
+ * being attached to.
+ *
+ * @param kubernetes_pod
+ * The name of the Kubernetes pod containing with the container being
+ * attached to.
+ *
+ * @param kubernetes_container
+ * The name of the container to attach to, or NULL to arbitrarily attach
+ * to the first container in the pod.
+ *
+ * @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,
+ const char* kubernetes_namespace, const char* kubernetes_pod,
+ const char* kubernetes_container);
+
+#endif
+
[18/19] guacamole-server git commit: GUACAMOLE-623: Move I/O-related
functions into separate files.
Posted by vn...@apache.org.
GUACAMOLE-623: Move I/O-related functions into separate files.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/2e505735
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/2e505735
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/2e505735
Branch: refs/heads/master
Commit: 2e50573531411a49c98dcb44a29fe2ad8a983609
Parents: 5e3aec6
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 22:55:02 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:52 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/Makefile.am | 2 +
src/protocols/kubernetes/io.c | 143 +++++++++++++++++++++++++
src/protocols/kubernetes/io.h | 144 +++++++++++++++++++++++++
src/protocols/kubernetes/kubernetes.c | 165 +----------------------------
src/protocols/kubernetes/kubernetes.h | 59 +----------
5 files changed, 292 insertions(+), 221 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/2e505735/src/protocols/kubernetes/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/Makefile.am b/src/protocols/kubernetes/Makefile.am
index 9e50feb..e818ff7 100644
--- a/src/protocols/kubernetes/Makefile.am
+++ b/src/protocols/kubernetes/Makefile.am
@@ -26,6 +26,7 @@ libguac_client_kubernetes_la_SOURCES = \
client.c \
clipboard.c \
input.c \
+ io.c \
pipe.c \
settings.c \
kubernetes.c \
@@ -36,6 +37,7 @@ noinst_HEADERS = \
client.h \
clipboard.h \
input.h \
+ io.h \
pipe.h \
settings.h \
kubernetes.h \
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/2e505735/src/protocols/kubernetes/io.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/io.c b/src/protocols/kubernetes/io.c
new file mode 100644
index 0000000..bfa37b1
--- /dev/null
+++ b/src/protocols/kubernetes/io.c
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "kubernetes.h"
+#include "terminal/terminal.h"
+
+#include <guacamole/client.h>
+#include <libwebsockets.h>
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <string.h>
+
+void guac_kubernetes_receive_data(guac_client* client,
+ const char* buffer, size_t length) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Strip channel index from beginning of buffer */
+ int channel = *(buffer++);
+ length--;
+
+ switch (channel) {
+
+ /* Write STDOUT / STDERR directly to terminal as output */
+ case GUAC_KUBERNETES_CHANNEL_STDOUT:
+ case GUAC_KUBERNETES_CHANNEL_STDERR:
+ guac_terminal_write(kubernetes_client->term, buffer, length);
+ break;
+
+ /* Ignore data on other channels */
+ default:
+ guac_client_log(client, GUAC_LOG_DEBUG, "Received %i bytes along "
+ "channel %i.", length, channel);
+
+ }
+
+}
+
+void guac_kubernetes_send_message(guac_client* client,
+ int channel, const char* data, int length) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
+
+ /* Add message to buffer if space is available */
+ if (kubernetes_client->outbound_messages_waiting
+ < GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES) {
+
+ /* Calculate storage position of next message */
+ int index = (kubernetes_client->outbound_messages_top
+ + kubernetes_client->outbound_messages_waiting)
+ % GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
+
+ /* Obtain pointer to message slot at calculated position */
+ guac_kubernetes_message* message =
+ &(kubernetes_client->outbound_messages[index]);
+
+ /* Copy details of message into buffer */
+ message->channel = channel;
+ memcpy(message->data, data, length);
+ message->length = length;
+
+ /* One more message is now waiting */
+ kubernetes_client->outbound_messages_waiting++;
+
+ /* Notify libwebsockets that we need a callback to send pending
+ * messages */
+ lws_callback_on_writable(kubernetes_client->wsi);
+ lws_cancel_service(kubernetes_client->context);
+
+ }
+
+ /* Warn if data has to be dropped */
+ else
+ guac_client_log(client, GUAC_LOG_WARNING, "Send buffer could not be "
+ "flushed in time to handle additional data. Outbound "
+ "message dropped.");
+
+ pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
+
+}
+
+bool guac_kubernetes_write_pending_message(guac_client* client) {
+
+ bool messages_remain;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
+
+ /* Send one message from top of buffer */
+ if (kubernetes_client->outbound_messages_waiting > 0) {
+
+ /* Obtain pointer to message at top */
+ int top = kubernetes_client->outbound_messages_top;
+ guac_kubernetes_message* message =
+ &(kubernetes_client->outbound_messages[top]);
+
+ /* Write message including channel index */
+ lws_write(kubernetes_client->wsi,
+ ((unsigned char*) message) + LWS_PRE,
+ message->length + 1, LWS_WRITE_BINARY);
+
+ /* Advance top to next message */
+ kubernetes_client->outbound_messages_top++;
+ kubernetes_client->outbound_messages_top %=
+ GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
+
+ /* One less message is waiting */
+ kubernetes_client->outbound_messages_waiting--;
+
+ }
+
+ /* Record whether messages remained at time of completion */
+ messages_remain = (kubernetes_client->outbound_messages_waiting > 0);
+
+ pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
+
+ return messages_remain;
+
+}
+
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/2e505735/src/protocols/kubernetes/io.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/io.h b/src/protocols/kubernetes/io.h
new file mode 100644
index 0000000..40f2c69
--- /dev/null
+++ b/src/protocols/kubernetes/io.h
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_IO_H
+#define GUAC_KUBERNETES_IO_H
+
+#include <guacamole/client.h>
+#include <libwebsockets.h>
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/**
+ * The maximum amount of data to include in any particular WebSocket message
+ * to Kubernetes. This excludes the storage space required for the channel
+ * index.
+ */
+#define GUAC_KUBERNETES_MAX_MESSAGE_SIZE 1024
+
+/**
+ * The index of the Kubernetes channel used for STDIN.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDIN 0
+
+/**
+ * The index of the Kubernetes channel used for STDOUT.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDOUT 1
+
+/**
+ * The index of the Kubernetes channel used for STDERR.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDERR 2
+
+/**
+ * The index of the Kubernetes channel used for terminal resize messages.
+ */
+#define GUAC_KUBERNETES_CHANNEL_RESIZE 4
+
+/**
+ * An outbound message to be received by Kubernetes over WebSocket.
+ */
+typedef struct guac_kubernetes_message {
+
+ /**
+ * lws_write() requires leading padding of LWS_PRE bytes to provide
+ * scratch space for WebSocket framing.
+ */
+ uint8_t _padding[LWS_PRE];
+
+ /**
+ * The index of the channel receiving the data, such as
+ * GUAC_KUBERNETES_CHANNEL_STDIN.
+ */
+ uint8_t channel;
+
+ /**
+ * The data that should be sent to Kubernetes (along with the channel
+ * index).
+ */
+ char data[GUAC_KUBERNETES_MAX_MESSAGE_SIZE];
+
+ /**
+ * The length of the data to be sent, excluding the channel index.
+ */
+ int length;
+
+} guac_kubernetes_message;
+
+
+/**
+ * Handles data received from Kubernetes over WebSocket, decoding the channel
+ * index of the received data and forwarding that data accordingly.
+ *
+ * @param client
+ * The guac_client associated with the connection to Kubernetes.
+ *
+ * @param buffer
+ * The data received from Kubernetes.
+ *
+ * @param length
+ * The size of the data received from Kubernetes, in bytes.
+ */
+void guac_kubernetes_receive_data(guac_client* client,
+ const char* buffer, size_t length);
+
+/**
+ * Requests that the given data be sent along the given channel to the
+ * Kubernetes server when the WebSocket connection is next available for
+ * writing. If the WebSocket connection has not been available for writing for
+ * long enough that the outbound message buffer is full, the request to send
+ * this particular message will be dropped.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @param channel
+ * The Kubernetes channel on which to send the message,
+ * such as GUAC_KUBERNETES_CHANNEL_STDIN.
+ *
+ * @param data
+ * A buffer containing the data to send.
+ *
+ * @param length
+ * The number of bytes to send.
+ */
+void guac_kubernetes_send_message(guac_client* client,
+ int channel, const char* data, int length);
+
+/**
+ * Writes the oldest pending message within the outbound message queue,
+ * as scheduled with guac_kubernetes_send_message(), removing that message
+ * from the queue. This function MAY NOT be invoked outside the libwebsockets
+ * event callback and MUST only be invoked in the context of a
+ * LWS_CALLBACK_CLIENT_WRITEABLE event. If no messages are pending, this
+ * function has no effect.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @return
+ * true if messages still remain to be written within the outbound message
+ * queue, false otherwise.
+ */
+bool guac_kubernetes_write_pending_message(guac_client* client);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/2e505735/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 3644d6e..4e7928e 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -18,8 +18,9 @@
*/
#include "config.h"
-#include "kubernetes.h"
#include "common/recording.h"
+#include "io.h"
+#include "kubernetes.h"
#include "terminal/terminal.h"
#include "url.h"
@@ -30,168 +31,6 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-
-/**
- * Handles data received from Kubernetes over WebSocket, decoding the channel
- * index of the received data and forwarding that data accordingly.
- *
- * @param client
- * The guac_client associated with the connection to Kubernetes.
- *
- * @param buffer
- * The data received from Kubernetes.
- *
- * @param length
- * The size of the data received from Kubernetes, in bytes.
- */
-static void guac_kubernetes_receive_data(guac_client* client,
- const char* buffer, size_t length) {
-
- guac_kubernetes_client* kubernetes_client =
- (guac_kubernetes_client*) client->data;
-
- /* Strip channel index from beginning of buffer */
- int channel = *(buffer++);
- length--;
-
- switch (channel) {
-
- /* Write STDOUT / STDERR directly to terminal as output */
- case GUAC_KUBERNETES_CHANNEL_STDOUT:
- case GUAC_KUBERNETES_CHANNEL_STDERR:
- guac_terminal_write(kubernetes_client->term, buffer, length);
- break;
-
- /* Ignore data on other channels */
- default:
- guac_client_log(client, GUAC_LOG_DEBUG, "Received %i bytes along "
- "channel %i.", length, channel);
-
- }
-
-}
-
-/**
- * Requests that the given data be sent along the given channel to the
- * Kubernetes server when the WebSocket connection is next available for
- * writing. If the WebSocket connection has not been available for writing for
- * long enough that the outbound message buffer is full, the request to send
- * this particular message will be dropped.
- *
- * @param client
- * The guac_client associated with the Kubernetes connection.
- *
- * @param channel
- * The Kubernetes channel on which to send the message,
- * such as GUAC_KUBERNETES_CHANNEL_STDIN.
- *
- * @param data
- * A buffer containing the data to send.
- *
- * @param length
- * The number of bytes to send.
- */
-static void guac_kubernetes_send_message(guac_client* client,
- int channel, const char* data, int length) {
-
- guac_kubernetes_client* kubernetes_client =
- (guac_kubernetes_client*) client->data;
-
- pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
-
- /* Add message to buffer if space is available */
- if (kubernetes_client->outbound_messages_waiting
- < GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES) {
-
- /* Calculate storage position of next message */
- int index = (kubernetes_client->outbound_messages_top
- + kubernetes_client->outbound_messages_waiting)
- % GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
-
- /* Obtain pointer to message slot at calculated position */
- guac_kubernetes_message* message =
- &(kubernetes_client->outbound_messages[index]);
-
- /* Copy details of message into buffer */
- message->channel = channel;
- memcpy(message->data, data, length);
- message->length = length;
-
- /* One more message is now waiting */
- kubernetes_client->outbound_messages_waiting++;
-
- /* Notify libwebsockets that we need a callback to send pending
- * messages */
- lws_callback_on_writable(kubernetes_client->wsi);
- lws_cancel_service(kubernetes_client->context);
-
- }
-
- /* Warn if data has to be dropped */
- else
- guac_client_log(client, GUAC_LOG_WARNING, "Send buffer could not be "
- "flushed in time to handle additional data. Outbound "
- "message dropped.");
-
- pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
-
-}
-
-/**
- * Writes the oldest pending message within the outbound message queue,
- * as scheduled with guac_kubernetes_send_message(), removing that message
- * from the queue. This function MAY NOT be invoked outside the libwebsockets
- * event callback and MUST only be invoked in the context of a
- * LWS_CALLBACK_CLIENT_WRITEABLE event. If no messages are pending, this
- * function has no effect.
- *
- * @param client
- * The guac_client associated with the Kubernetes connection.
- *
- * @return
- * true if messages still remain to be written within the outbound message
- * queue, false otherwise.
- */
-static bool guac_kubernetes_write_pending_message(guac_client* client) {
-
- bool messages_remain;
- guac_kubernetes_client* kubernetes_client =
- (guac_kubernetes_client*) client->data;
-
- pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
-
- /* Send one message from top of buffer */
- if (kubernetes_client->outbound_messages_waiting > 0) {
-
- /* Obtain pointer to message at top */
- int top = kubernetes_client->outbound_messages_top;
- guac_kubernetes_message* message =
- &(kubernetes_client->outbound_messages[top]);
-
- /* Write message including channel index */
- lws_write(kubernetes_client->wsi,
- ((unsigned char*) message) + LWS_PRE,
- message->length + 1, LWS_WRITE_BINARY);
-
- /* Advance top to next message */
- kubernetes_client->outbound_messages_top++;
- kubernetes_client->outbound_messages_top %=
- GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
-
- /* One less message is waiting */
- kubernetes_client->outbound_messages_waiting--;
-
- }
-
- /* Record whether messages remained at time of completion */
- messages_remain = (kubernetes_client->outbound_messages_waiting > 0);
-
- pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
-
- return messages_remain;
-
-}
/**
* Callback invoked by libwebsockets for events related to a WebSocket being
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/2e505735/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index 8c9a25e..c37ca4c 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -22,6 +22,7 @@
#include "common/clipboard.h"
#include "common/recording.h"
+#include "io.h"
#include "settings.h"
#include "terminal/terminal.h"
@@ -29,7 +30,6 @@
#include <libwebsockets.h>
#include <pthread.h>
-#include <stdint.h>
/**
* The name of the WebSocket protocol specific to Kubernetes which should be
@@ -38,33 +38,6 @@
#define GUAC_KUBERNETES_LWS_PROTOCOL "v4.channel.k8s.io"
/**
- * The index of the Kubernetes channel used for STDIN.
- */
-#define GUAC_KUBERNETES_CHANNEL_STDIN 0
-
-/**
- * The index of the Kubernetes channel used for STDOUT.
- */
-#define GUAC_KUBERNETES_CHANNEL_STDOUT 1
-
-/**
- * The index of the Kubernetes channel used for STDERR.
- */
-#define GUAC_KUBERNETES_CHANNEL_STDERR 2
-
-/**
- * The index of the Kubernetes channel used for terminal resize messages.
- */
-#define GUAC_KUBERNETES_CHANNEL_RESIZE 4
-
-/**
- * The maximum amount of data to include in any particular WebSocket message
- * to Kubernetes. This excludes the storage space required for the channel
- * index.
- */
-#define GUAC_KUBERNETES_MAX_MESSAGE_SIZE 1024
-
-/**
* The maximum number of messages to allow within the outbound message buffer.
* If messages are sent despite the buffer being full, those messages will be
* dropped.
@@ -78,36 +51,6 @@
#define GUAC_KUBERNETES_SERVICE_INTERVAL 1000
/**
- * An outbound message to be received by Kubernetes over WebSocket.
- */
-typedef struct guac_kubernetes_message {
-
- /**
- * lws_write() requires leading padding of LWS_PRE bytes to provide
- * scratch space for WebSocket framing.
- */
- uint8_t _padding[LWS_PRE];
-
- /**
- * The index of the channel receiving the data, such as
- * GUAC_KUBERNETES_CHANNEL_STDIN.
- */
- uint8_t channel;
-
- /**
- * The data that should be sent to Kubernetes (along with the channel
- * index).
- */
- char data[GUAC_KUBERNETES_MAX_MESSAGE_SIZE];
-
- /**
- * The length of the data to be sent, excluding the channel index.
- */
- int length;
-
-} guac_kubernetes_message;
-
-/**
* Kubernetes-specific client data.
*/
typedef struct guac_kubernetes_client {
[15/19] guacamole-server git commit: GUACAMOLE-623: libwebsockets
requires an integer port number.
Posted by vn...@apache.org.
GUACAMOLE-623: libwebsockets requires an integer port number.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/5bae422b
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/5bae422b
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/5bae422b
Branch: refs/heads/master
Commit: 5bae422b29939c2e08aff13b33bdb8c2b9ab2ed9
Parents: b8bd0e4
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 9 21:49:58 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/settings.c | 3 +--
src/protocols/kubernetes/settings.h | 4 ++--
2 files changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5bae422b/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 1f04b40..5ee6671 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -278,7 +278,7 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
/* Read port */
settings->port =
- guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
IDX_PORT, GUAC_KUBERNETES_DEFAULT_PORT);
/* Read typescript path */
@@ -340,7 +340,6 @@ void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) {
/* Free network connection information */
free(settings->hostname);
- free(settings->port);
/* Free SSL/TLS details */
free(settings->client_cert_file);
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/5bae422b/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index 3e89ce5..fea6cf1 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -42,7 +42,7 @@
* The port to connect to when initiating any Kubernetes connection, if no
* other port is specified.
*/
-#define GUAC_KUBERNETES_DEFAULT_PORT "8443"
+#define GUAC_KUBERNETES_DEFAULT_PORT 8443
/**
* The filename to use for the typescript, if not specified.
@@ -74,7 +74,7 @@ typedef struct guac_kubernetes_settings {
/**
* The port of the Kubernetes server to connect to.
*/
- char* port;
+ int port;
/**
* Whether SSL/TLS should be used.
[07/19] guacamole-server git commit: GUACAMOLE-623: Default to
unencrypted Kubernetes connections.
Posted by vn...@apache.org.
GUACAMOLE-623: Default to unencrypted Kubernetes connections.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/519c90a8
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/519c90a8
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/519c90a8
Branch: refs/heads/master
Commit: 519c90a88760ae4db4ad4db8b0f4f02dcef599b4
Parents: 5bae422
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 9 22:54:50 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/settings.c | 4 ++--
src/protocols/kubernetes/settings.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/519c90a8/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 5ee6671..50daa6f 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -68,7 +68,7 @@ enum KUBERNETES_ARGS_IDX {
IDX_PORT,
/**
- * Whether SSL/TLS should be used. SSL is used by default.
+ * Whether SSL/TLS should be used. If omitted, SSL/TLS will not be used.
*/
IDX_USE_SSL,
@@ -223,7 +223,7 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
/* Parse whether SSL should be used */
settings->use_ssl =
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
- IDX_USE_SSL, true);
+ IDX_USE_SSL, false);
/* Read SSL/TLS connection details only if enabled */
if (settings->use_ssl) {
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/519c90a8/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index fea6cf1..8f42f8c 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -42,7 +42,7 @@
* The port to connect to when initiating any Kubernetes connection, if no
* other port is specified.
*/
-#define GUAC_KUBERNETES_DEFAULT_PORT 8443
+#define GUAC_KUBERNETES_DEFAULT_PORT 8080
/**
* The filename to use for the typescript, if not specified.
[02/19] guacamole-server git commit: GUACAMOLE-623: Add missin
includes. Remove unnecessary includes.
Posted by vn...@apache.org.
GUACAMOLE-623: Add missin includes. Remove unnecessary includes.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/371eed1f
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/371eed1f
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/371eed1f
Branch: refs/heads/master
Commit: 371eed1f93c353e0bf2159bcffd77cf6d8bd9716
Parents: 77a8661
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 21:05:23 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/client.c | 9 ++++-----
src/protocols/kubernetes/client.h | 6 +-----
src/protocols/kubernetes/clipboard.c | 2 --
src/protocols/kubernetes/clipboard.h | 2 --
src/protocols/kubernetes/input.c | 5 +----
src/protocols/kubernetes/input.h | 2 --
src/protocols/kubernetes/kubernetes.c | 10 ++--------
src/protocols/kubernetes/kubernetes.h | 4 +++-
src/protocols/kubernetes/pipe.c | 5 +++--
src/protocols/kubernetes/pipe.h | 2 --
src/protocols/kubernetes/settings.c | 5 -----
src/protocols/kubernetes/settings.h | 3 ---
src/protocols/kubernetes/url.c | 2 +-
src/protocols/kubernetes/url.h | 2 --
src/protocols/kubernetes/user.c | 6 +++---
src/protocols/kubernetes/user.h | 2 --
16 files changed, 18 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
index 450e1e8..58f4728 100644
--- a/src/protocols/kubernetes/client.c
+++ b/src/protocols/kubernetes/client.c
@@ -17,22 +17,21 @@
* under the License.
*/
-#include "config.h"
#include "client.h"
-#include "common/recording.h"
+#include "common/clipboard.h"
#include "kubernetes.h"
#include "settings.h"
-#include "terminal/terminal.h"
#include "user.h"
+#include <guacamole/client.h>
+#include <libwebsockets.h>
+
#include <langinfo.h>
#include <locale.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
-#include <guacamole/client.h>
-
/**
* Static reference to the guac_client associated with the active Kubernetes
* connection. As guacd guarantees that each main client connection is
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/client.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.h b/src/protocols/kubernetes/client.h
index 2e96d10..0b847da 100644
--- a/src/protocols/kubernetes/client.h
+++ b/src/protocols/kubernetes/client.h
@@ -20,11 +20,7 @@
#ifndef GUAC_KUBERNETES_CLIENT_H
#define GUAC_KUBERNETES_CLIENT_H
-#include "config.h"
-#include "terminal/terminal.h"
-
-#include <pthread.h>
-#include <sys/types.h>
+#include <guacamole/client.h>
/**
* The maximum number of bytes to allow within the clipboard.
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/clipboard.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/clipboard.c b/src/protocols/kubernetes/clipboard.c
index 87a34b0..f168206 100644
--- a/src/protocols/kubernetes/clipboard.c
+++ b/src/protocols/kubernetes/clipboard.c
@@ -17,11 +17,9 @@
* under the License.
*/
-#include "config.h"
#include "clipboard.h"
#include "common/clipboard.h"
#include "kubernetes.h"
-#include "terminal/terminal.h"
#include <guacamole/client.h>
#include <guacamole/stream.h>
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/clipboard.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/clipboard.h b/src/protocols/kubernetes/clipboard.h
index 009219c..87a393c 100644
--- a/src/protocols/kubernetes/clipboard.h
+++ b/src/protocols/kubernetes/clipboard.h
@@ -20,8 +20,6 @@
#ifndef GUAC_KUBERNETES_CLIPBOARD_H
#define GUAC_KUBERNETES_CLIPBOARD_H
-#include "config.h"
-
#include <guacamole/user.h>
/**
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/input.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/input.c b/src/protocols/kubernetes/input.c
index e73772e..814578e 100644
--- a/src/protocols/kubernetes/input.c
+++ b/src/protocols/kubernetes/input.c
@@ -17,18 +17,15 @@
* under the License.
*/
-#include "config.h"
#include "common/recording.h"
-#include "kubernetes.h"
#include "input.h"
+#include "kubernetes.h"
#include "terminal/terminal.h"
#include <guacamole/client.h>
#include <guacamole/user.h>
#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
int guac_kubernetes_user_mouse_handler(guac_user* user,
int x, int y, int mask) {
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/input.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/input.h b/src/protocols/kubernetes/input.h
index ac65835..6f24cf2 100644
--- a/src/protocols/kubernetes/input.h
+++ b/src/protocols/kubernetes/input.h
@@ -20,8 +20,6 @@
#ifndef GUAC_KUBERNETES_INPUT_H
#define GUAC_KUBERNETES_INPUT_H
-#include "config.h"
-
#include <guacamole/user.h>
/**
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 9850c6d..3644d6e 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -18,8 +18,8 @@
*/
#include "config.h"
-#include "common/recording.h"
#include "kubernetes.h"
+#include "common/recording.h"
#include "terminal/terminal.h"
#include "url.h"
@@ -27,16 +27,10 @@
#include <guacamole/protocol.h>
#include <libwebsockets.h>
-#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <poll.h>
#include <pthread.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <unistd.h>
/**
* Handles data received from Kubernetes over WebSocket, decoding the channel
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index fedf77a..8c9a25e 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -20,13 +20,15 @@
#ifndef GUAC_KUBERNETES_H
#define GUAC_KUBERNETES_H
-#include "config.h"
#include "common/clipboard.h"
#include "common/recording.h"
#include "settings.h"
#include "terminal/terminal.h"
+#include <guacamole/client.h>
#include <libwebsockets.h>
+
+#include <pthread.h>
#include <stdint.h>
/**
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/pipe.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/pipe.c b/src/protocols/kubernetes/pipe.c
index 242105b..8f18530 100644
--- a/src/protocols/kubernetes/pipe.c
+++ b/src/protocols/kubernetes/pipe.c
@@ -17,12 +17,13 @@
* under the License.
*/
-#include "config.h"
#include "kubernetes.h"
-#include "pipe.h"
#include "terminal/terminal.h"
+#include "pipe.h"
+#include <guacamole/client.h>
#include <guacamole/protocol.h>
+#include <guacamole/stream-types.h>
#include <guacamole/socket.h>
#include <guacamole/user.h>
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/pipe.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/pipe.h b/src/protocols/kubernetes/pipe.h
index 7acae3c..47565bf 100644
--- a/src/protocols/kubernetes/pipe.h
+++ b/src/protocols/kubernetes/pipe.h
@@ -21,8 +21,6 @@
#ifndef GUAC_KUBERNETES_PIPE_H
#define GUAC_KUBERNETES_PIPE_H
-#include "config.h"
-
#include <guacamole/user.h>
/**
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 4f9f3f2..122a858 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -17,16 +17,11 @@
* under the License.
*/
-#include "config.h"
-
#include "settings.h"
#include <guacamole/user.h>
-#include <sys/types.h>
#include <stdlib.h>
-#include <string.h>
-#include <time.h>
/* Client plugin arguments */
const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index c2e479e..a86d14a 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -20,11 +20,8 @@
#ifndef GUAC_KUBERNETES_SETTINGS_H
#define GUAC_KUBERNETES_SETTINGS_H
-#include "config.h"
-
#include <guacamole/user.h>
-#include <sys/types.h>
#include <stdbool.h>
/**
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/url.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/url.c b/src/protocols/kubernetes/url.c
index cfd6f74..434cc87 100644
--- a/src/protocols/kubernetes/url.c
+++ b/src/protocols/kubernetes/url.c
@@ -17,10 +17,10 @@
* under the License.
*/
-#include "config.h"
#include "url.h"
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
static int guac_kubernetes_is_url_safe(char c) {
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/url.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/url.h b/src/protocols/kubernetes/url.h
index 19084ee..285baa2 100644
--- a/src/protocols/kubernetes/url.h
+++ b/src/protocols/kubernetes/url.h
@@ -20,8 +20,6 @@
#ifndef GUAC_KUBERNETES_URL_H
#define GUAC_KUBERNETES_URL_H
-#include "config.h"
-
/**
* The maximum number of characters allowed in the full path for any Kubernetes
* endpoint.
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/user.c b/src/protocols/kubernetes/user.c
index 62666cb..f90260e 100644
--- a/src/protocols/kubernetes/user.c
+++ b/src/protocols/kubernetes/user.c
@@ -17,9 +17,8 @@
* under the License.
*/
-#include "config.h"
-
#include "clipboard.h"
+#include "common/cursor.h"
#include "input.h"
#include "kubernetes.h"
#include "pipe.h"
@@ -28,11 +27,12 @@
#include "user.h"
#include <guacamole/client.h>
+#include <guacamole/protocol.h>
#include <guacamole/socket.h>
#include <guacamole/user.h>
#include <pthread.h>
-#include <string.h>
+#include <stdlib.h>
int guac_kubernetes_user_join_handler(guac_user* user, int argc, char** argv) {
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/371eed1f/src/protocols/kubernetes/user.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/user.h b/src/protocols/kubernetes/user.h
index d235b2b..55d49fd 100644
--- a/src/protocols/kubernetes/user.h
+++ b/src/protocols/kubernetes/user.h
@@ -20,8 +20,6 @@
#ifndef GUAC_KUBERNETES_USER_H
#define GUAC_KUBERNETES_USER_H
-#include "config.h"
-
#include <guacamole/user.h>
/**
[12/19] guacamole-server git commit: GUACAMOLE-623: Add support for
terminal resize. Redraw Kubernetes container upon connect.
Posted by vn...@apache.org.
GUACAMOLE-623: Add support for terminal resize. Redraw Kubernetes container upon connect.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/fe7edce5
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/fe7edce5
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/fe7edce5
Branch: refs/heads/master
Commit: fe7edce5694a718ce233b4d4c85b386be4240262
Parents: b7c938c
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 02:50:15 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/input.c | 4 ++-
src/protocols/kubernetes/kubernetes.c | 55 +++++++++++++++++++++++++++++-
src/protocols/kubernetes/kubernetes.h | 38 +++++++++++++++++++++
3 files changed, 95 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/fe7edce5/src/protocols/kubernetes/input.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/input.c b/src/protocols/kubernetes/input.c
index 9bf5b71..e73772e 100644
--- a/src/protocols/kubernetes/input.c
+++ b/src/protocols/kubernetes/input.c
@@ -88,7 +88,9 @@ int guac_kubernetes_user_size_handler(guac_user* user, int width, int height) {
/* Resize terminal */
guac_terminal_resize(terminal, width, height);
- /* TODO: Update Kubernetes terminal window size if connected */
+ /* Update Kubernetes terminal window size if connected */
+ guac_kubernetes_resize(client, terminal->term_height,
+ terminal->term_width);
return 0;
}
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/fe7edce5/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index aadb448..53a8580 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -246,6 +246,11 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
case LWS_CALLBACK_CLIENT_ESTABLISHED:
guac_client_log(client, GUAC_LOG_INFO,
"Kubernetes connection successful.");
+
+ /* Schedule check for pending messages in case messages were added
+ * to the outbound message buffer prior to the connection being
+ * fully established */
+ lws_callback_on_writable(wsi);
break;
/* Data received via WebSocket */
@@ -260,7 +265,6 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
* yet more messages remain */
if (guac_kubernetes_write_pending_message(client))
lws_callback_on_writable(wsi);
-
break;
/* TODO: Add configure test */
@@ -451,6 +455,11 @@ void* guac_kubernetes_client_thread(void* data) {
goto fail;
}
+ /* Force a redraw of the attached display (there will be no content
+ * otherwise, given the stream nature of attaching to a running
+ * container) */
+ guac_kubernetes_force_redraw(client);
+
/* As long as client is connected, continue polling libwebsockets */
while (client->state == GUAC_CLIENT_RUNNING) {
@@ -485,3 +494,47 @@ fail:
}
+void guac_kubernetes_resize(guac_client* client, int rows, int columns) {
+
+ char buffer[64];
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Send request only if different from last request */
+ if (kubernetes_client->rows != rows ||
+ kubernetes_client->columns != columns) {
+
+ kubernetes_client->rows = rows;
+ kubernetes_client->columns = columns;
+
+ /* Construct terminal resize message for Kubernetes */
+ int length = snprintf(buffer, sizeof(buffer),
+ "{\"Width\":%i,\"Height\":%i}", columns, rows);
+
+ /* Schedule message for sending */
+ guac_kubernetes_send_message(client, GUAC_KUBERNETES_CHANNEL_RESIZE,
+ buffer, length);
+
+ }
+
+}
+
+void guac_kubernetes_force_redraw(guac_client* client) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Get current terminal dimensions */
+ guac_terminal* term = kubernetes_client->term;
+ int rows = term->term_height;
+ int columns = term->term_width;
+
+ /* Force a redraw by increasing the terminal size by one character in
+ * each dimension and then resizing it back to normal (the same technique
+ * used by kubectl */
+ guac_kubernetes_resize(client, rows + 1, columns + 1);
+ guac_kubernetes_resize(client, rows, columns);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/fe7edce5/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index 761a897..fedf77a 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -168,6 +168,18 @@ typedef struct guac_kubernetes_client {
guac_terminal* term;
/**
+ * The number of rows last sent to Kubernetes in a terminal resize
+ * request.
+ */
+ int rows;
+
+ /**
+ * The number of columns last sent to Kubernetes in a terminal resize
+ * request.
+ */
+ int columns;
+
+ /**
* The in-progress session recording, or NULL if no recording is in
* progress.
*/
@@ -181,5 +193,31 @@ typedef struct guac_kubernetes_client {
*/
void* guac_kubernetes_client_thread(void* data);
+/**
+ * Sends a message to the Kubernetes server requesting that the terminal be
+ * resized to the given dimensions. This message may be queued until the
+ * underlying WebSocket connection is ready to send.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @param rows
+ * The new terminal size in rows.
+ *
+ * @param columns
+ * The new terminal size in columns.
+ */
+void guac_kubernetes_resize(guac_client* client, int rows, int columns);
+
+/**
+ * Sends messages to the Kubernetes server such that the terminal is forced
+ * to redraw. This function should be invoked at the beginning of each
+ * session in order to restore expected display state.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ */
+void guac_kubernetes_force_redraw(guac_client* client);
+
#endif
[17/19] guacamole-server git commit: GUACAMOLE-623: Add support for
SSL.
Posted by vn...@apache.org.
GUACAMOLE-623: Add support for SSL.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/83a531bc
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/83a531bc
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/83a531bc
Branch: refs/heads/master
Commit: 83a531bc89a5c79371f42d1ec5142c484a08479a
Parents: 2e50573
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Sep 11 03:03:17 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:52 2018 -0700
----------------------------------------------------------------------
configure.ac | 1 +
src/protocols/kubernetes/Makefile.am | 3 +
src/protocols/kubernetes/client.c | 16 +--
src/protocols/kubernetes/client.h | 7 +
src/protocols/kubernetes/kubernetes.c | 46 +++----
src/protocols/kubernetes/settings.c | 48 +++----
src/protocols/kubernetes/settings.h | 24 ++--
src/protocols/kubernetes/ssl.c | 210 +++++++++++++++++++++++++++++
src/protocols/kubernetes/ssl.h | 41 ++++++
9 files changed, 326 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index df36eab..d26db39 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1225,6 +1225,7 @@ AC_ARG_ENABLE([kubernetes],
AM_CONDITIONAL([ENABLE_KUBERNETES], [test "x${enable_kubernetes}" = "xyes" \
-a "x${have_libwebsockets}" = "xyes" \
+ -a "x${have_ssl}" = "xyes" \
-a "x${have_terminal}" = "xyes"])
#
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/Makefile.am b/src/protocols/kubernetes/Makefile.am
index e818ff7..56db4d6 100644
--- a/src/protocols/kubernetes/Makefile.am
+++ b/src/protocols/kubernetes/Makefile.am
@@ -29,6 +29,7 @@ libguac_client_kubernetes_la_SOURCES = \
io.c \
pipe.c \
settings.c \
+ ssl.c \
kubernetes.c \
url.c \
user.c
@@ -40,6 +41,7 @@ noinst_HEADERS = \
io.h \
pipe.h \
settings.h \
+ ssl.h \
kubernetes.h \
url.h \
user.h
@@ -57,5 +59,6 @@ libguac_client_kubernetes_la_LIBADD = \
libguac_client_kubernetes_la_LDFLAGS = \
-version-info 0:0:0 \
@PTHREAD_LIBS@ \
+ @SSL_LIBS@ \
@WEBSOCKETS_LIBS@
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
index 58f4728..331e03d 100644
--- a/src/protocols/kubernetes/client.c
+++ b/src/protocols/kubernetes/client.c
@@ -32,12 +32,7 @@
#include <stdlib.h>
#include <string.h>
-/**
- * Static reference to the guac_client associated with the active Kubernetes
- * connection. As guacd guarantees that each main client connection is
- * isolated within its own process, this is safe.
- */
-static guac_client* guac_kubernetes_lws_log_client = NULL;
+guac_client* guac_kubernetes_lws_current_client = NULL;
/**
* Logging callback invoked by libwebsockets to log a single line of logging
@@ -53,15 +48,18 @@ static guac_client* guac_kubernetes_lws_log_client = NULL;
* The line of logging output to log.
*/
static void guac_kubernetes_log(int level, const char* line) {
- if (guac_kubernetes_lws_log_client != NULL)
- guac_client_log(guac_kubernetes_lws_log_client, GUAC_LOG_DEBUG,
+ if (guac_kubernetes_lws_current_client != NULL)
+ guac_client_log(guac_kubernetes_lws_current_client, GUAC_LOG_DEBUG,
"libwebsockets: %s", line);
}
int guac_client_init(guac_client* client) {
+ /* Ensure reference to main guac_client remains available in all
+ * libwebsockets contexts */
+ guac_kubernetes_lws_current_client = client;
+
/* Redirect libwebsockets logging */
- guac_kubernetes_lws_log_client = client;
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO,
guac_kubernetes_log);
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/client.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.h b/src/protocols/kubernetes/client.h
index 0b847da..ec4ba32 100644
--- a/src/protocols/kubernetes/client.h
+++ b/src/protocols/kubernetes/client.h
@@ -28,6 +28,13 @@
#define GUAC_KUBERNETES_CLIPBOARD_MAX_LENGTH 262144
/**
+ * Static reference to the guac_client associated with the active Kubernetes
+ * connection. While libwebsockets provides some means of storing and
+ * retrieving custom data in some structures, this is not always available.
+ */
+extern guac_client* guac_kubernetes_lws_current_client;
+
+/**
* Free handler. Required by libguac and called when the guac_client is
* disconnected and must be cleaned up.
*/
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 4e7928e..f314c59 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -18,9 +18,11 @@
*/
#include "config.h"
+#include "client.h"
#include "common/recording.h"
#include "io.h"
#include "kubernetes.h"
+#include "ssl.h"
#include "terminal/terminal.h"
#include "url.h"
@@ -43,8 +45,9 @@
* The reason (event) that this callback was invoked.
*
* @param user
- * Arbitrary data assocated with the WebSocket session. This will always
- * be a pointer to the guac_client instance.
+ * Arbitrary data assocated with the WebSocket session. In some cases,
+ * this is actually event-specific data (such as the
+ * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERT event).
*
* @param in
* A pointer to arbitrary, reason-specific data.
@@ -60,14 +63,19 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
enum lws_callback_reasons reason, void* user,
void* in, size_t length) {
- /* Request connection closure if client is stopped (note that the user
- * pointer passed by libwebsockets may be NULL for some events) */
- guac_client* client = (guac_client*) user;
- if (client != NULL && client->state != GUAC_CLIENT_RUNNING)
+ guac_client* client = guac_kubernetes_lws_current_client;
+
+ /* Do not handle any further events if connection is closing */
+ if (client->state != GUAC_CLIENT_RUNNING)
return lws_callback_http_dummy(wsi, reason, user, in, length);
switch (reason) {
+ /* Complete initialization of SSL */
+ case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS:
+ guac_kubernetes_init_ssl(client, (SSL_CTX*) user);
+ break;
+
/* Failed to connect */
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND,
@@ -256,29 +264,13 @@ void* guac_kubernetes_client_thread(void* data) {
};
/* If requested, use an SSL/TLS connection for communication with
- * Kubernetes */
+ * Kubernetes. Note that we disable hostname checks here because we
+ * do our own validation - libwebsockets does not validate properly if
+ * IP addresses are used. */
if (settings->use_ssl) {
-
- /* Enable use of SSL/TLS */
context_info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
- connection_info.ssl_connection = LCCSCF_USE_SSL;
-
- /* Bypass certificate checks if requested */
- if (settings->ignore_cert) {
- connection_info.ssl_connection |=
- LCCSCF_ALLOW_SELFSIGNED
- | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK
- | LCCSCF_ALLOW_EXPIRED;
- }
-
- /* Otherwise use the given CA certificate to validate (if any) */
- else
- context_info.client_ssl_ca_filepath = settings->ca_cert_file;
-
- /* Certificate and key file for SSL/TLS client auth */
- context_info.client_ssl_cert_filepath = settings->client_cert_file;
- context_info.client_ssl_private_key_filepath = settings->client_key_file;
-
+ connection_info.ssl_connection = LCCSCF_USE_SSL
+ | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK;
}
/* Create libwebsockets context */
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 122a858..4f00a44 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -31,9 +31,9 @@ const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
"pod",
"container",
"use-ssl",
- "client-cert-file",
- "client-key-file",
- "ca-cert-file",
+ "client-cert",
+ "client-key",
+ "ca-cert",
"ignore-cert",
"font-name",
"font-size",
@@ -89,24 +89,26 @@ enum KUBERNETES_ARGS_IDX {
IDX_USE_SSL,
/**
- * The filename of the certificate to use if performing SSL/TLS client
- * authentication to authenticate with the Kubernetes server. If omitted,
- * SSL client authentication will not be performed.
+ * The certificate to use if performing SSL/TLS client authentication to
+ * authenticate with the Kubernetes server, in PEM format. If omitted, SSL
+ * client authentication will not be performed.
*/
- IDX_CLIENT_CERT_FILE,
+ IDX_CLIENT_CERT,
/**
- * The filename of the key to use if performing SSL/TLS client
- * authentication to authenticate with the Kubernetes server. If omitted,
- * SSL client authentication will not be performed.
+ * The key to use if performing SSL/TLS client authentication to
+ * authenticate with the Kubernetes server, in PEM format. If omitted, SSL
+ * client authentication will not be performed.
*/
- IDX_CLIENT_KEY_FILE,
+ IDX_CLIENT_KEY,
/**
- * The filename of the certificate of the certificate authority that signed
- * the certificate of the Kubernetes server.
+ * The certificate of the certificate authority that signed the certificate
+ * of the Kubernetes server, in PEM format. If omitted. verification of
+ * the Kubernetes server certificate will use the systemwide certificate
+ * authorities.
*/
- IDX_CA_CERT_FILE,
+ IDX_CA_CERT,
/**
* Whether the certificate used by the Kubernetes server for SSL/TLS should
@@ -264,17 +266,17 @@ guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
/* Read SSL/TLS connection details only if enabled */
if (settings->use_ssl) {
- settings->client_cert_file =
+ settings->client_cert =
guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
- argv, IDX_CLIENT_CERT_FILE, NULL);
+ argv, IDX_CLIENT_CERT, NULL);
- settings->client_key_file =
+ settings->client_key =
guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
- argv, IDX_CLIENT_KEY_FILE, NULL);
+ argv, IDX_CLIENT_KEY, NULL);
- settings->ca_cert_file =
+ settings->ca_cert =
guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
- argv, IDX_CA_CERT_FILE, NULL);
+ argv, IDX_CA_CERT, NULL);
settings->ignore_cert =
guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS,
@@ -378,9 +380,9 @@ void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) {
free(settings->kubernetes_container);
/* Free SSL/TLS details */
- free(settings->client_cert_file);
- free(settings->client_key_file);
- free(settings->ca_cert_file);
+ free(settings->client_cert);
+ free(settings->client_key);
+ free(settings->ca_cert);
/* Free display preferences */
free(settings->font_name);
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index a86d14a..6267a18 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -103,24 +103,26 @@ typedef struct guac_kubernetes_settings {
bool use_ssl;
/**
- * The filename of the certificate to use if performing SSL/TLS client
- * authentication to authenticate with the Kubernetes server. If omitted,
- * SSL client authentication will not be performed.
+ * The certificate to use if performing SSL/TLS client authentication to
+ * authenticate with the Kubernetes server, in PEM format. If omitted, SSL
+ * client authentication will not be performed.
*/
- char* client_cert_file;
+ char* client_cert;
/**
- * The filename of the key to use if performing SSL/TLS client
- * authentication to authenticate with the Kubernetes server. If omitted,
- * SSL client authentication will not be performed.
+ * The key to use if performing SSL/TLS client authentication to
+ * authenticate with the Kubernetes server, in PEM format. If omitted, SSL
+ * client authentication will not be performed.
*/
- char* client_key_file;
+ char* client_key;
/**
- * The filename of the certificate of the certificate authority that signed
- * the certificate of the Kubernetes server.
+ * The certificate of the certificate authority that signed the certificate
+ * of the Kubernetes server, in PEM format. If omitted. verification of
+ * the Kubernetes server certificate will use the systemwide certificate
+ * authorities.
*/
- char* ca_cert_file;
+ char* ca_cert;
/**
* Whether the certificate used by the Kubernetes server for SSL/TLS should
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/ssl.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/ssl.c b/src/protocols/kubernetes/ssl.c
new file mode 100644
index 0000000..6ebafc6
--- /dev/null
+++ b/src/protocols/kubernetes/ssl.c
@@ -0,0 +1,210 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "kubernetes.h"
+#include "settings.h"
+
+#include <guacamole/client.h>
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+#include <openssl/ssl.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+
+/**
+ * Tests whether the given hostname is, in fact, an IP address.
+ *
+ * @param hostname
+ * The hostname to test.
+ *
+ * @return
+ * Non-zero if the given hostname is an IP address, zero otherwise.
+ */
+static int guac_kubernetes_is_address(const char* hostname) {
+
+ /* Attempt to interpret the hostname as an IP address */
+ ASN1_OCTET_STRING* ip = a2i_IPADDRESS(hostname);
+
+ /* If unsuccessful, the hostname is not an IP address */
+ if (ip == NULL)
+ return 0;
+
+ /* Converted hostname must be freed */
+ ASN1_OCTET_STRING_free(ip);
+ return 1;
+
+}
+
+/**
+ * Parses the given PEM certificate, returning a new OpenSSL X509 structure
+ * representing that certificate.
+ *
+ * @param pem
+ * The PEM certificate.
+ *
+ * @return
+ * An X509 structure representing the given certificate, or NULL if the
+ * certificate was unreadable.
+ */
+static X509* guac_kubernetes_read_cert(char* pem) {
+
+ /* Prepare a BIO which provides access to the in-memory CA cert */
+ BIO* bio = BIO_new_mem_buf(pem, -1);
+ if (bio == NULL)
+ return NULL;
+
+ /* Read the CA cert as PEM */
+ X509* certificate = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+ if (certificate == NULL) {
+ BIO_free(bio);
+ return NULL;
+ }
+
+ return certificate;
+
+}
+
+/**
+ * Parses the given PEM private key, returning a new OpenSSL EVP_PKEY structure
+ * representing that key.
+ *
+ * @param pem
+ * The PEM private key.
+ *
+ * @return
+ * An EVP_KEY representing the given private key, or NULL if the private
+ * key was unreadable.
+ */
+static EVP_PKEY* guac_kubernetes_read_key(char* pem) {
+
+ /* Prepare a BIO which provides access to the in-memory key */
+ BIO* bio = BIO_new_mem_buf(pem, -1);
+ if (bio == NULL)
+ return NULL;
+
+ /* Read the private key as PEM */
+ EVP_PKEY* key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
+ if (key == NULL) {
+ BIO_free(bio);
+ return NULL;
+ }
+
+ return key;
+
+}
+
+void guac_kubernetes_init_ssl(guac_client* client, SSL_CTX* context) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ guac_kubernetes_settings* settings = kubernetes_client->settings;
+
+ /* Bypass certificate checks if requested */
+ if (settings->ignore_cert)
+ SSL_CTX_set_verify(context, SSL_VERIFY_NONE, NULL);
+
+ /* Otherwise use the given CA certificate to validate (if any) */
+ else if (settings->ca_cert != NULL) {
+
+ /* Read CA certificate from configuration data */
+ X509* ca_cert = guac_kubernetes_read_cert(settings->ca_cert);
+ if (ca_cert == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Provided CA certificate is unreadable");
+ return;
+ }
+
+ /* Add certificate to CA store */
+ X509_STORE* ca_store = SSL_CTX_get_cert_store(context);
+ if (!X509_STORE_add_cert(ca_store, ca_cert)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Unable to add CA certificate to certificate store of "
+ "SSL context");
+ return;
+ }
+
+ }
+
+ /* Certificate for SSL/TLS client auth */
+ if (settings->client_cert != NULL) {
+
+ /* Read client certificate from configuration data */
+ X509* client_cert = guac_kubernetes_read_cert(settings->client_cert);
+ if (client_cert == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Provided client certificate is unreadable");
+ return;
+ }
+
+ /* Use parsed certificate for authentication */
+ if (!SSL_CTX_use_certificate(context, client_cert)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Client certificate could not be used for SSL/TLS "
+ "client authentication");
+ return;
+ }
+
+ }
+
+ /* Private key for SSL/TLS client auth */
+ if (settings->client_key != NULL) {
+
+ /* Read client private key from configuration data */
+ EVP_PKEY* client_key = guac_kubernetes_read_key(settings->client_key);
+ if (client_key == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Provided client private key is unreadable");
+ return;
+ }
+
+ /* Use parsed key for authentication */
+ if (!SSL_CTX_use_PrivateKey(context, client_key)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Client private key could not be used for SSL/TLS "
+ "client authentication");
+ return;
+ }
+
+ }
+
+ /* Enable hostname checking */
+ X509_VERIFY_PARAM *param = SSL_CTX_get0_param(context);
+ X509_VERIFY_PARAM_set_hostflags(param,
+ X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+
+ /* Validate properly depending on whether hostname is an IP address */
+ if (guac_kubernetes_is_address(settings->hostname)) {
+ if (!X509_VERIFY_PARAM_set1_ip_asc(param, settings->hostname)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Server IP address validation could not be enabled");
+ return;
+ }
+ }
+ else {
+ if (!X509_VERIFY_PARAM_set1_host(param, settings->hostname, 0)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Server hostname validation could not be enabled");
+ return;
+ }
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/83a531bc/src/protocols/kubernetes/ssl.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/ssl.h b/src/protocols/kubernetes/ssl.h
new file mode 100644
index 0000000..cca02bd
--- /dev/null
+++ b/src/protocols/kubernetes/ssl.h
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_SSL_H
+#define GUAC_KUBERNETES_SSL_H
+
+#include "settings.h"
+
+#include <openssl/ssl.h>
+
+/**
+ * Initializes the given SSL/TLS context using the configuration parameters
+ * associated with the given guac_client, setting up hostname/address
+ * validation and client authentication.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @param context
+ * The SSL_CTX in use by libwebsockets.
+ */
+void guac_kubernetes_init_ssl(guac_client* client, SSL_CTX* context);
+
+#endif
+
[08/19] guacamole-server git commit: GUACAMOLE-623: Send typed data
to Kubernetes via the STDIN channel.
Posted by vn...@apache.org.
GUACAMOLE-623: Send typed data to Kubernetes via the STDIN channel.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/b7c938c2
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/b7c938c2
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/b7c938c2
Branch: refs/heads/master
Commit: b7c938c239f0c61b6122c817c6ce44309d61bd1f
Parents: f35517b
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 02:16:36 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/kubernetes.c | 151 ++++++++++++++++++++++++++---
src/protocols/kubernetes/kubernetes.h | 26 ++++-
2 files changed, 164 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b7c938c2/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 62fb6ee..aadb448 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -78,6 +78,127 @@ static void guac_kubernetes_receive_data(guac_client* client,
}
/**
+ * Requests that the given data be sent along the given channel to the
+ * Kubernetes server when the WebSocket connection is next available for
+ * writing. If the WebSocket connection has not been available for writing for
+ * long enough that the outbound message buffer is full, the request to send
+ * this particular message will be dropped.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @param channel
+ * The Kubernetes channel on which to send the message,
+ * such as GUAC_KUBERNETES_CHANNEL_STDIN.
+ *
+ * @param data
+ * A buffer containing the data to send.
+ *
+ * @param length
+ * The number of bytes to send.
+ */
+static void guac_kubernetes_send_message(guac_client* client,
+ int channel, const char* data, int length) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
+
+ /* Add message to buffer if space is available */
+ if (kubernetes_client->outbound_messages_waiting
+ < GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES) {
+
+ /* Calculate storage position of next message */
+ int index = (kubernetes_client->outbound_messages_top
+ + kubernetes_client->outbound_messages_waiting)
+ % GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
+
+ /* Obtain pointer to message slot at calculated position */
+ guac_kubernetes_message* message =
+ &(kubernetes_client->outbound_messages[index]);
+
+ /* Copy details of message into buffer */
+ message->channel = channel;
+ memcpy(message->data, data, length);
+ message->length = length;
+
+ /* One more message is now waiting */
+ kubernetes_client->outbound_messages_waiting++;
+
+ /* Notify libwebsockets that we need a callback to send pending
+ * messages */
+ lws_callback_on_writable(kubernetes_client->wsi);
+ lws_cancel_service(kubernetes_client->context);
+
+ }
+
+ /* Warn if data has to be dropped */
+ else
+ guac_client_log(client, GUAC_LOG_WARNING, "Send buffer could not be "
+ "flushed in time to handle additional data. Outbound "
+ "message dropped.");
+
+ pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
+
+}
+
+/**
+ * Writes the oldest pending message within the outbound message queue,
+ * as scheduled with guac_kubernetes_send_message(), removing that message
+ * from the queue. This function MAY NOT be invoked outside the libwebsockets
+ * event callback and MUST only be invoked in the context of a
+ * LWS_CALLBACK_CLIENT_WRITEABLE event. If no messages are pending, this
+ * function has no effect.
+ *
+ * @param client
+ * The guac_client associated with the Kubernetes connection.
+ *
+ * @return
+ * true if messages still remain to be written within the outbound message
+ * queue, false otherwise.
+ */
+static bool guac_kubernetes_write_pending_message(guac_client* client) {
+
+ bool messages_remain;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ pthread_mutex_lock(&(kubernetes_client->outbound_message_lock));
+
+ /* Send one message from top of buffer */
+ if (kubernetes_client->outbound_messages_waiting > 0) {
+
+ /* Obtain pointer to message at top */
+ int top = kubernetes_client->outbound_messages_top;
+ guac_kubernetes_message* message =
+ &(kubernetes_client->outbound_messages[top]);
+
+ /* Write message including channel index */
+ lws_write(kubernetes_client->wsi,
+ ((unsigned char*) message) + LWS_PRE,
+ message->length + 1, LWS_WRITE_BINARY);
+
+ /* Advance top to next message */
+ kubernetes_client->outbound_messages_top++;
+ kubernetes_client->outbound_messages_top %=
+ GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES;
+
+ /* One less message is waiting */
+ kubernetes_client->outbound_messages_waiting--;
+
+ }
+
+ /* Record whether messages remained at time of completion */
+ messages_remain = (kubernetes_client->outbound_messages_waiting > 0);
+
+ pthread_mutex_unlock(&(kubernetes_client->outbound_message_lock));
+
+ return messages_remain;
+
+}
+
+/**
* Callback invoked by libwebsockets for events related to a WebSocket being
* used for communicating with an attached Kubernetes pod.
*
@@ -132,8 +253,14 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
guac_kubernetes_receive_data(client, (const char*) in, length);
break;
- /* TODO: Only send data here. Request callback for writing via lws_callback_on_writable(some struct lws*) */
+ /* WebSocket is ready for writing */
case LWS_CALLBACK_CLIENT_WRITEABLE:
+
+ /* Send any pending messages, requesting another callback if
+ * yet more messages remain */
+ if (guac_kubernetes_write_pending_message(client))
+ lws_callback_on_writable(wsi);
+
break;
/* TODO: Add configure test */
@@ -189,14 +316,15 @@ static void* guac_kubernetes_input_thread(void* data) {
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
- char buffer[8192];
+ char buffer[GUAC_KUBERNETES_MAX_MESSAGE_SIZE];
int bytes_read;
/* Write all data read */
while ((bytes_read = guac_terminal_read_stdin(kubernetes_client->term, buffer, sizeof(buffer))) > 0) {
- /* TODO: Send to Kubernetes */
- guac_terminal_write(kubernetes_client->term, buffer, bytes_read);
+ /* Send received data to Kubernetes along STDIN channel */
+ guac_kubernetes_send_message(client, GUAC_KUBERNETES_CHANNEL_STDIN,
+ buffer, bytes_read);
}
@@ -206,8 +334,6 @@ static void* guac_kubernetes_input_thread(void* data) {
void* guac_kubernetes_client_thread(void* data) {
- struct lws_context* context = NULL;
-
guac_client* client = (guac_client*) data;
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
@@ -297,15 +423,15 @@ void* guac_kubernetes_client_thread(void* data) {
}
/* Create libwebsockets context */
- context = lws_create_context(&context_info);
- if (!context) {
+ kubernetes_client->context = lws_create_context(&context_info);
+ if (!kubernetes_client->context) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Initialization of libwebsockets failed");
goto fail;
}
/* FIXME: Generate path dynamically */
- connection_info.context = context;
+ connection_info.context = kubernetes_client->context;
connection_info.path = "/api/v1/namespaces/default/pods/my-shell-68974bb7f7-rpjgr/attach?container=my-shell&stdin=true&stdout=true&tty=true";
/* Open WebSocket connection to Kubernetes */
@@ -329,7 +455,8 @@ void* guac_kubernetes_client_thread(void* data) {
while (client->state == GUAC_CLIENT_RUNNING) {
/* Cease polling libwebsockets if an error condition is signalled */
- if (lws_service(context, 1000) < 0)
+ if (lws_service(kubernetes_client->context,
+ GUAC_KUBERNETES_SERVICE_INTERVAL) < 0)
break;
}
@@ -350,8 +477,8 @@ fail:
guac_common_recording_free(kubernetes_client->recording);
/* Free WebSocket context if successfully allocated */
- if (context != NULL)
- lws_context_destroy(context);
+ if (kubernetes_client->context != NULL)
+ lws_context_destroy(kubernetes_client->context);
guac_client_log(client, GUAC_LOG_INFO, "Kubernetes connection ended.");
return NULL;
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b7c938c2/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index 8fb917d..761a897 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -56,6 +56,13 @@
#define GUAC_KUBERNETES_CHANNEL_RESIZE 4
/**
+ * The maximum amount of data to include in any particular WebSocket message
+ * to Kubernetes. This excludes the storage space required for the channel
+ * index.
+ */
+#define GUAC_KUBERNETES_MAX_MESSAGE_SIZE 1024
+
+/**
* The maximum number of messages to allow within the outbound message buffer.
* If messages are sent despite the buffer being full, those messages will be
* dropped.
@@ -63,11 +70,23 @@
#define GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES 8
/**
+ * The maximum number of milliseconds to wait for a libwebsockets event to
+ * occur before entering another iteration of the libwebsockets event loop.
+ */
+#define GUAC_KUBERNETES_SERVICE_INTERVAL 1000
+
+/**
* An outbound message to be received by Kubernetes over WebSocket.
*/
typedef struct guac_kubernetes_message {
/**
+ * lws_write() requires leading padding of LWS_PRE bytes to provide
+ * scratch space for WebSocket framing.
+ */
+ uint8_t _padding[LWS_PRE];
+
+ /**
* The index of the channel receiving the data, such as
* GUAC_KUBERNETES_CHANNEL_STDIN.
*/
@@ -77,7 +96,7 @@ typedef struct guac_kubernetes_message {
* The data that should be sent to Kubernetes (along with the channel
* index).
*/
- char data[1024];
+ char data[GUAC_KUBERNETES_MAX_MESSAGE_SIZE];
/**
* The length of the data to be sent, excluding the channel index.
@@ -97,6 +116,11 @@ typedef struct guac_kubernetes_client {
guac_kubernetes_settings* settings;
/**
+ * The libwebsockets context associated with the connected WebSocket.
+ */
+ struct lws_context* context;
+
+ /**
* The connected WebSocket.
*/
struct lws* wsi;
[11/19] guacamole-server git commit: GUACAMOLE-623: Redirect
libwebsockets logging to guacd's debug level log.
Posted by vn...@apache.org.
GUACAMOLE-623: Redirect libwebsockets logging to guacd's debug level log.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/34f8f8b3
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/34f8f8b3
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/34f8f8b3
Branch: refs/heads/master
Commit: 34f8f8b30d84e7622005f2ba0ab704758cc88767
Parents: fe7edce
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 15:01:48 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/client.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/34f8f8b3/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
index 77aa647..450e1e8 100644
--- a/src/protocols/kubernetes/client.c
+++ b/src/protocols/kubernetes/client.c
@@ -33,8 +33,39 @@
#include <guacamole/client.h>
+/**
+ * Static reference to the guac_client associated with the active Kubernetes
+ * connection. As guacd guarantees that each main client connection is
+ * isolated within its own process, this is safe.
+ */
+static guac_client* guac_kubernetes_lws_log_client = NULL;
+
+/**
+ * Logging callback invoked by libwebsockets to log a single line of logging
+ * output. As libwebsockets messages are all generally low-level, the log
+ * level provided by libwebsockets is ignored here, with all messages logged
+ * instead at guacd's debug level.
+ *
+ * @param level
+ * The libwebsockets log level associated with the log message. This value
+ * is ignored by this implementation of the logging callback.
+ *
+ * @param line
+ * The line of logging output to log.
+ */
+static void guac_kubernetes_log(int level, const char* line) {
+ if (guac_kubernetes_lws_log_client != NULL)
+ guac_client_log(guac_kubernetes_lws_log_client, GUAC_LOG_DEBUG,
+ "libwebsockets: %s", line);
+}
+
int guac_client_init(guac_client* client) {
+ /* Redirect libwebsockets logging */
+ guac_kubernetes_lws_log_client = client;
+ lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO,
+ guac_kubernetes_log);
+
/* Set client args */
client->args = GUAC_KUBERNETES_CLIENT_ARGS;
[09/19] guacamole-server git commit: GUACAMOLE-623: Add outbound
message buffer.
Posted by vn...@apache.org.
GUACAMOLE-623: Add outbound message buffer.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/f35517b3
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/f35517b3
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/f35517b3
Branch: refs/heads/master
Commit: f35517b3ff42f268e20f84282bc93130fa86e98d
Parents: cbe5935
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 01:26:13 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/client.c | 13 ++-----
src/protocols/kubernetes/kubernetes.c | 31 ++++++++++++----
src/protocols/kubernetes/kubernetes.h | 58 ++++++++++++++++++++++++++++++
3 files changed, 84 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/f35517b3/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
index 1b5d175..77aa647 100644
--- a/src/protocols/kubernetes/client.c
+++ b/src/protocols/kubernetes/client.c
@@ -67,17 +67,8 @@ int guac_kubernetes_client_free_handler(guac_client* client) {
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
- /* Clean up recording, if in progress */
- if (kubernetes_client->recording != NULL)
- guac_common_recording_free(kubernetes_client->recording);
-
- /* Kill terminal */
- guac_terminal_free(kubernetes_client->term);
-
- /* TODO: Wait for and free WebSocket session, if connected */
- /*if (kubernetes_client->websocket != NULL) {
- pthread_join(kubernetes_client->client_thread, NULL);
- }*/
+ /* Wait client thread to terminate */
+ pthread_join(kubernetes_client->client_thread, NULL);
/* Free settings */
if (kubernetes_client->settings != NULL)
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/f35517b3/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index e38d5e3..62fb6ee 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -206,6 +206,8 @@ static void* guac_kubernetes_input_thread(void* data) {
void* guac_kubernetes_client_thread(void* data) {
+ struct lws_context* context = NULL;
+
guac_client* client = (guac_client*) data;
guac_kubernetes_client* kubernetes_client =
(guac_kubernetes_client*) client->data;
@@ -236,7 +238,7 @@ void* guac_kubernetes_client_thread(void* data) {
if (kubernetes_client->term == NULL) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Terminal initialization failed");
- return NULL;
+ goto fail;
}
/* Set up typescript, if requested */
@@ -295,11 +297,11 @@ void* guac_kubernetes_client_thread(void* data) {
}
/* Create libwebsockets context */
- struct lws_context* context = lws_create_context(&context_info);
+ context = lws_create_context(&context_info);
if (!context) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Initialization of libwebsockets failed");
- return NULL;
+ goto fail;
}
/* FIXME: Generate path dynamically */
@@ -311,13 +313,16 @@ void* guac_kubernetes_client_thread(void* data) {
if (kubernetes_client->wsi == NULL) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
"Connection via libwebsockets failed");
- return NULL;
+ goto fail;
}
+ /* Init outbound message buffer */
+ pthread_mutex_init(&(kubernetes_client->outbound_message_lock), NULL);
+
/* Start input thread */
if (pthread_create(&(input_thread), NULL, guac_kubernetes_input_thread, (void*) client)) {
guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
- return NULL;
+ goto fail;
}
/* As long as client is connected, continue polling libwebsockets */
@@ -330,11 +335,23 @@ void* guac_kubernetes_client_thread(void* data) {
}
/* Kill client and Wait for input thread to die */
+ guac_terminal_stop(kubernetes_client->term);
guac_client_stop(client);
pthread_join(input_thread, NULL);
- /* All done with libwebsockets */
- lws_context_destroy(context);
+fail:
+
+ /* Kill and free terminal, if allocated */
+ if (kubernetes_client->term != NULL)
+ guac_terminal_free(kubernetes_client->term);
+
+ /* Clean up recording, if in progress */
+ if (kubernetes_client->recording != NULL)
+ guac_common_recording_free(kubernetes_client->recording);
+
+ /* Free WebSocket context if successfully allocated */
+ if (context != NULL)
+ lws_context_destroy(context);
guac_client_log(client, GUAC_LOG_INFO, "Kubernetes connection ended.");
return NULL;
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/f35517b3/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index 89b6678..8fb917d 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -56,6 +56,37 @@
#define GUAC_KUBERNETES_CHANNEL_RESIZE 4
/**
+ * The maximum number of messages to allow within the outbound message buffer.
+ * If messages are sent despite the buffer being full, those messages will be
+ * dropped.
+ */
+#define GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES 8
+
+/**
+ * An outbound message to be received by Kubernetes over WebSocket.
+ */
+typedef struct guac_kubernetes_message {
+
+ /**
+ * The index of the channel receiving the data, such as
+ * GUAC_KUBERNETES_CHANNEL_STDIN.
+ */
+ uint8_t channel;
+
+ /**
+ * The data that should be sent to Kubernetes (along with the channel
+ * index).
+ */
+ char data[1024];
+
+ /**
+ * The length of the data to be sent, excluding the channel index.
+ */
+ int length;
+
+} guac_kubernetes_message;
+
+/**
* Kubernetes-specific client data.
*/
typedef struct guac_kubernetes_client {
@@ -71,6 +102,33 @@ typedef struct guac_kubernetes_client {
struct lws* wsi;
/**
+ * Outbound message ring buffer for outbound WebSocket messages. As
+ * libwebsockets uses an event loop for all operations, outbound messages
+ * may be sent only in context of a particular event received via a
+ * callback. Until that event is received, pending data must accumulate in
+ * a buffer.
+ */
+ guac_kubernetes_message outbound_messages[GUAC_KUBERNETES_MAX_OUTBOUND_MESSAGES];
+
+ /**
+ * The number of messages currently waiting in the outbound message
+ * buffer.
+ */
+ int outbound_messages_waiting;
+
+ /**
+ * The index of the oldest entry in the outbound message buffer. Newer
+ * messages follow this entry.
+ */
+ int outbound_messages_top;
+
+ /**
+ * Lock which is acquired when the outbound message buffer is being read
+ * or manipulated.
+ */
+ pthread_mutex_t outbound_message_lock;
+
+ /**
* The Kubernetes client thread.
*/
pthread_t client_thread;
[05/19] guacamole-server git commit: GUACAMOLE-623: Add base skeleton
for Kubernetes protocol support.
Posted by vn...@apache.org.
GUACAMOLE-623: Add base skeleton for Kubernetes protocol support.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/b8bd0e4c
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/b8bd0e4c
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/b8bd0e4c
Branch: refs/heads/master
Commit: b8bd0e4c6a63995c18050fa4f88fa09b97f7a90c
Parents: 54fda21
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 9 20:03:40 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
Makefile.am | 4 +
configure.ac | 60 ++++-
src/protocols/kubernetes/Makefile.am | 57 +++++
src/protocols/kubernetes/client.c | 91 +++++++
src/protocols/kubernetes/client.h | 41 ++++
src/protocols/kubernetes/clipboard.c | 67 ++++++
src/protocols/kubernetes/clipboard.h | 43 ++++
src/protocols/kubernetes/input.c | 95 ++++++++
src/protocols/kubernetes/input.h | 46 ++++
src/protocols/kubernetes/kubernetes.c | 136 +++++++++++
src/protocols/kubernetes/kubernetes.h | 71 ++++++
src/protocols/kubernetes/pipe.c | 51 ++++
src/protocols/kubernetes/pipe.h | 42 ++++
src/protocols/kubernetes/settings.c | 366 +++++++++++++++++++++++++++++
src/protocols/kubernetes/settings.h | 256 ++++++++++++++++++++
src/protocols/kubernetes/user.c | 116 +++++++++
src/protocols/kubernetes/user.h | 38 +++
17 files changed, 1572 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/Makefile.am
----------------------------------------------------------------------
diff --git a/Makefile.am b/Makefile.am
index e923376..91c8abe 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,10 @@ if ENABLE_PULSE
SUBDIRS += src/pulse
endif
+if ENABLE_KUBERNETES
+SUBDIRS += src/protocols/kubernetes
+endif
+
if ENABLE_RDP
SUBDIRS += src/protocols/rdp
endif
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 6b20c97..ae78324 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1173,6 +1173,46 @@ AM_CONDITIONAL([ENABLE_WEBP], [test "x${have_webp}" = "xyes"])
AC_SUBST(WEBP_LIBS)
#
+# libwebsockets
+#
+
+have_libwebsockets=disabled
+WEBSOCKETS_LIBS=
+AC_ARG_WITH([websockets],
+ [AS_HELP_STRING([--with-websockets],
+ [support WebSockets @<:@default=check@:>@])],
+ [],
+ [with_websockets=check])
+
+if test "x$with_websockets" != "xno"
+then
+ have_libwebsockets=yes
+ AC_CHECK_LIB([websockets],
+ [lws_create_context],
+ [WEBSOCKETS_LIBS="$WEBSOCKETS_LIBS -lwebsockets"],
+ [have_libwebsockets=no])
+fi
+
+AM_CONDITIONAL([ENABLE_WEBSOCKETS],
+ [test "x${have_libwebsockets}" = "xyes"])
+
+AC_SUBST(WEBSOCKETS_LIBS)
+
+#
+# Kubernetes
+#
+
+AC_ARG_ENABLE([kubernetes],
+ [AS_HELP_STRING([--disable-kubernetes],
+ [do not build support for attaching to Kubernetes pods])],
+ [],
+ [enable_kubernetes=yes])
+
+AM_CONDITIONAL([ENABLE_KUBERNETES], [test "x${enable_kubernetes}" = "xyes" \
+ -a "x${have_libwebsockets}" = "xyes" \
+ -a "x${have_terminal}" = "xyes"])
+
+#
# guacd
#
@@ -1230,6 +1270,7 @@ AC_CONFIG_FILES([Makefile
src/guaclog/Makefile
src/guaclog/man/guaclog.1
src/pulse/Makefile
+ src/protocols/kubernetes/Makefile
src/protocols/rdp/Makefile
src/protocols/ssh/Makefile
src/protocols/telnet/Makefile
@@ -1240,10 +1281,11 @@ AC_OUTPUT
# Protocol build status
#
-AM_COND_IF([ENABLE_RDP], [build_rdp=yes], [build_rdp=no])
-AM_COND_IF([ENABLE_SSH], [build_ssh=yes], [build_ssh=no])
-AM_COND_IF([ENABLE_TELNET], [build_telnet=yes], [build_telnet=no])
-AM_COND_IF([ENABLE_VNC], [build_vnc=yes], [build_vnc=no])
+AM_COND_IF([ENABLE_KUBERNETES], [build_kubernetes=yes], [build_kubernetes=no])
+AM_COND_IF([ENABLE_RDP], [build_rdp=yes], [build_rdp=no])
+AM_COND_IF([ENABLE_SSH], [build_ssh=yes], [build_ssh=no])
+AM_COND_IF([ENABLE_TELNET], [build_telnet=yes], [build_telnet=no])
+AM_COND_IF([ENABLE_VNC], [build_vnc=yes], [build_vnc=no])
#
# Service / tool build status
@@ -1287,15 +1329,17 @@ $PACKAGE_NAME version $PACKAGE_VERSION
libVNCServer ........ ${have_libvncserver}
libvorbis ........... ${have_vorbis}
libpulse ............ ${have_pulse}
+ libwebsockets ....... ${have_websockets}
libwebp ............. ${have_webp}
wsock32 ............. ${have_winsock}
Protocol support:
- RDP ....... ${build_rdp}
- SSH ....... ${build_ssh}
- Telnet .... ${build_telnet}
- VNC ....... ${build_vnc}
+ Kubernetes .... ${build_kubernetes}
+ RDP ........... ${build_rdp}
+ SSH ........... ${build_ssh}
+ Telnet ........ ${build_telnet}
+ VNC ........... ${build_vnc}
Services / tools:
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/Makefile.am
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/Makefile.am b/src/protocols/kubernetes/Makefile.am
new file mode 100644
index 0000000..d864967
--- /dev/null
+++ b/src/protocols/kubernetes/Makefile.am
@@ -0,0 +1,57 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4
+
+lib_LTLIBRARIES = libguac-client-kubernetes.la
+
+libguac_client_kubernetes_la_SOURCES = \
+ client.c \
+ clipboard.c \
+ input.c \
+ pipe.c \
+ settings.c \
+ kubernetes.c \
+ user.c
+
+noinst_HEADERS = \
+ client.h \
+ clipboard.h \
+ input.h \
+ pipe.h \
+ settings.h \
+ kubernetes.h \
+ user.h
+
+libguac_client_kubernetes_la_CFLAGS = \
+ -Werror -Wall -Iinclude \
+ @LIBGUAC_INCLUDE@ \
+ @TERMINAL_INCLUDE@
+
+libguac_client_kubernetes_la_LIBADD = \
+ @COMMON_LTLIB@ \
+ @LIBGUAC_LTLIB@ \
+ @TERMINAL_LTLIB@
+
+libguac_client_kubernetes_la_LDFLAGS = \
+ -version-info 0:0:0 \
+ @PTHREAD_LIBS@ \
+ @WEBSOCKETS_LIBS@
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
new file mode 100644
index 0000000..1b5d175
--- /dev/null
+++ b/src/protocols/kubernetes/client.c
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "client.h"
+#include "common/recording.h"
+#include "kubernetes.h"
+#include "settings.h"
+#include "terminal/terminal.h"
+#include "user.h"
+
+#include <langinfo.h>
+#include <locale.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <guacamole/client.h>
+
+int guac_client_init(guac_client* client) {
+
+ /* Set client args */
+ client->args = GUAC_KUBERNETES_CLIENT_ARGS;
+
+ /* Allocate client instance data */
+ guac_kubernetes_client* kubernetes_client = calloc(1, sizeof(guac_kubernetes_client));
+ client->data = kubernetes_client;
+
+ /* Init clipboard */
+ kubernetes_client->clipboard = guac_common_clipboard_alloc(GUAC_KUBERNETES_CLIPBOARD_MAX_LENGTH);
+
+ /* Set handlers */
+ client->join_handler = guac_kubernetes_user_join_handler;
+ client->free_handler = guac_kubernetes_client_free_handler;
+
+ /* Set locale and warn if not UTF-8 */
+ setlocale(LC_CTYPE, "");
+ if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0) {
+ guac_client_log(client, GUAC_LOG_INFO,
+ "Current locale does not use UTF-8. Some characters may "
+ "not render correctly.");
+ }
+
+ /* Success */
+ return 0;
+
+}
+
+int guac_kubernetes_client_free_handler(guac_client* client) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Clean up recording, if in progress */
+ if (kubernetes_client->recording != NULL)
+ guac_common_recording_free(kubernetes_client->recording);
+
+ /* Kill terminal */
+ guac_terminal_free(kubernetes_client->term);
+
+ /* TODO: Wait for and free WebSocket session, if connected */
+ /*if (kubernetes_client->websocket != NULL) {
+ pthread_join(kubernetes_client->client_thread, NULL);
+ }*/
+
+ /* Free settings */
+ if (kubernetes_client->settings != NULL)
+ guac_kubernetes_settings_free(kubernetes_client->settings);
+
+ guac_common_clipboard_free(kubernetes_client->clipboard);
+ free(kubernetes_client);
+ return 0;
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/client.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.h b/src/protocols/kubernetes/client.h
new file mode 100644
index 0000000..2e96d10
--- /dev/null
+++ b/src/protocols/kubernetes/client.h
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_CLIENT_H
+#define GUAC_KUBERNETES_CLIENT_H
+
+#include "config.h"
+#include "terminal/terminal.h"
+
+#include <pthread.h>
+#include <sys/types.h>
+
+/**
+ * The maximum number of bytes to allow within the clipboard.
+ */
+#define GUAC_KUBERNETES_CLIPBOARD_MAX_LENGTH 262144
+
+/**
+ * Free handler. Required by libguac and called when the guac_client is
+ * disconnected and must be cleaned up.
+ */
+guac_client_free_handler guac_kubernetes_client_free_handler;
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/clipboard.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/clipboard.c b/src/protocols/kubernetes/clipboard.c
new file mode 100644
index 0000000..87a34b0
--- /dev/null
+++ b/src/protocols/kubernetes/clipboard.c
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "clipboard.h"
+#include "common/clipboard.h"
+#include "kubernetes.h"
+#include "terminal/terminal.h"
+
+#include <guacamole/client.h>
+#include <guacamole/stream.h>
+#include <guacamole/user.h>
+
+int guac_kubernetes_clipboard_handler(guac_user* user, guac_stream* stream,
+ char* mimetype) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Clear clipboard and prepare for new data */
+ guac_common_clipboard_reset(kubernetes_client->clipboard, mimetype);
+
+ /* Set handlers for clipboard stream */
+ stream->blob_handler = guac_kubernetes_clipboard_blob_handler;
+ stream->end_handler = guac_kubernetes_clipboard_end_handler;
+
+ return 0;
+}
+
+int guac_kubernetes_clipboard_blob_handler(guac_user* user,
+ guac_stream* stream, void* data, int length) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Append new data */
+ guac_common_clipboard_append(kubernetes_client->clipboard, data, length);
+
+ return 0;
+}
+
+int guac_kubernetes_clipboard_end_handler(guac_user* user,
+ guac_stream* stream) {
+
+ /* Nothing to do - clipboard is implemented within client */
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/clipboard.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/clipboard.h b/src/protocols/kubernetes/clipboard.h
new file mode 100644
index 0000000..009219c
--- /dev/null
+++ b/src/protocols/kubernetes/clipboard.h
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_CLIPBOARD_H
+#define GUAC_KUBERNETES_CLIPBOARD_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+
+/**
+ * Handler for inbound clipboard streams.
+ */
+guac_user_clipboard_handler guac_kubernetes_clipboard_handler;
+
+/**
+ * Handler for data received along clipboard streams.
+ */
+guac_user_blob_handler guac_kubernetes_clipboard_blob_handler;
+
+/**
+ * Handler for end-of-stream related to clipboard.
+ */
+guac_user_end_handler guac_kubernetes_clipboard_end_handler;
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/input.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/input.c b/src/protocols/kubernetes/input.c
new file mode 100644
index 0000000..9bf5b71
--- /dev/null
+++ b/src/protocols/kubernetes/input.c
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "common/recording.h"
+#include "kubernetes.h"
+#include "input.h"
+#include "terminal/terminal.h"
+
+#include <guacamole/client.h>
+#include <guacamole/user.h>
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int guac_kubernetes_user_mouse_handler(guac_user* user,
+ int x, int y, int mask) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Skip if terminal not yet ready */
+ guac_terminal* term = kubernetes_client->term;
+ if (term == NULL)
+ return 0;
+
+ /* Report mouse position within recording */
+ if (kubernetes_client->recording != NULL)
+ guac_common_recording_report_mouse(kubernetes_client->recording, x, y,
+ mask);
+
+ guac_terminal_send_mouse(term, user, x, y, mask);
+ return 0;
+
+}
+
+int guac_kubernetes_user_key_handler(guac_user* user, int keysym, int pressed) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Report key state within recording */
+ if (kubernetes_client->recording != NULL)
+ guac_common_recording_report_key(kubernetes_client->recording,
+ keysym, pressed);
+
+ /* Skip if terminal not yet ready */
+ guac_terminal* term = kubernetes_client->term;
+ if (term == NULL)
+ return 0;
+
+ guac_terminal_send_key(term, keysym, pressed);
+ return 0;
+
+}
+
+int guac_kubernetes_user_size_handler(guac_user* user, int width, int height) {
+
+ /* Get terminal */
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Skip if terminal not yet ready */
+ guac_terminal* terminal = kubernetes_client->term;
+ if (terminal == NULL)
+ return 0;
+
+ /* Resize terminal */
+ guac_terminal_resize(terminal, width, height);
+
+ /* TODO: Update Kubernetes terminal window size if connected */
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/input.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/input.h b/src/protocols/kubernetes/input.h
new file mode 100644
index 0000000..ac65835
--- /dev/null
+++ b/src/protocols/kubernetes/input.h
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_INPUT_H
+#define GUAC_KUBERNETES_INPUT_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+
+/**
+ * Handler for key events. Required by libguac and called whenever key events
+ * are received.
+ */
+guac_user_key_handler guac_kubernetes_user_key_handler;
+
+/**
+ * Handler for mouse events. Required by libguac and called whenever mouse
+ * events are received.
+ */
+guac_user_mouse_handler guac_kubernetes_user_mouse_handler;
+
+/**
+ * Handler for size events. Required by libguac and called whenever the remote
+ * display (window) is resized.
+ */
+guac_user_size_handler guac_kubernetes_user_size_handler;
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
new file mode 100644
index 0000000..231d78d
--- /dev/null
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -0,0 +1,136 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "common/recording.h"
+#include "kubernetes.h"
+#include "terminal/terminal.h"
+
+#include <guacamole/client.h>
+#include <guacamole/protocol.h>
+
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+/**
+ * Input thread, started by the main Kubernetes client thread. This thread
+ * continuously reads from the terminal's STDIN and transfers all read
+ * data to the Kubernetes connection.
+ *
+ * @param data
+ * The current guac_client instance.
+ *
+ * @return
+ * Always NULL.
+ */
+static void* guac_kubernetes_input_thread(void* data) {
+
+ guac_client* client = (guac_client*) data;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ char buffer[8192];
+ int bytes_read;
+
+ /* Write all data read */
+ while ((bytes_read = guac_terminal_read_stdin(kubernetes_client->term, buffer, sizeof(buffer))) > 0) {
+
+ /* TODO: Send to Kubernetes */
+ guac_terminal_write(kubernetes_client->term, buffer, bytes_read);
+
+ }
+
+ return NULL;
+
+}
+
+void* guac_kubernetes_client_thread(void* data) {
+
+ guac_client* client = (guac_client*) data;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ guac_kubernetes_settings* settings = kubernetes_client->settings;
+
+ pthread_t input_thread;
+
+ /* Set up screen recording, if requested */
+ if (settings->recording_path != NULL) {
+ kubernetes_client->recording = guac_common_recording_create(client,
+ settings->recording_path,
+ settings->recording_name,
+ settings->create_recording_path,
+ !settings->recording_exclude_output,
+ !settings->recording_exclude_mouse,
+ settings->recording_include_keys);
+ }
+
+ /* Create terminal */
+ kubernetes_client->term = guac_terminal_create(client,
+ kubernetes_client->clipboard,
+ settings->max_scrollback, settings->font_name, settings->font_size,
+ settings->resolution, settings->width, settings->height,
+ settings->color_scheme, settings->backspace);
+
+ /* Fail if terminal init failed */
+ if (kubernetes_client->term == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Terminal initialization failed");
+ return NULL;
+ }
+
+ /* Set up typescript, if requested */
+ if (settings->typescript_path != NULL) {
+ guac_terminal_create_typescript(kubernetes_client->term,
+ settings->typescript_path,
+ settings->typescript_name,
+ settings->create_typescript_path);
+ }
+
+ /* TODO: Open WebSocket connection to Kubernetes */
+
+ /* Logged in */
+ guac_client_log(client, GUAC_LOG_INFO,
+ "Kubernetes connection successful.");
+
+ /* Start input thread */
+ if (pthread_create(&(input_thread), NULL, guac_kubernetes_input_thread, (void*) client)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Unable to start input thread");
+ return NULL;
+ }
+
+ /* TODO: While data available, write to terminal */
+
+ /* Kill client and Wait for input thread to die */
+ guac_client_stop(client);
+ pthread_join(input_thread, NULL);
+
+ guac_client_log(client, GUAC_LOG_INFO, "Kubernetes connection ended.");
+ return NULL;
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
new file mode 100644
index 0000000..f8035ae
--- /dev/null
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_H
+#define GUAC_KUBERNETES_H
+
+#include "config.h"
+#include "common/clipboard.h"
+#include "common/recording.h"
+#include "settings.h"
+#include "terminal/terminal.h"
+
+#include <stdint.h>
+
+/**
+ * Kubernetes-specific client data.
+ */
+typedef struct guac_kubernetes_client {
+
+ /**
+ * Kubernetes connection settings.
+ */
+ guac_kubernetes_settings* settings;
+
+ /**
+ * The Kubernetes client thread.
+ */
+ pthread_t client_thread;
+
+ /**
+ * The current clipboard contents.
+ */
+ guac_common_clipboard* clipboard;
+
+ /**
+ * The terminal which will render all output from the Kubernetes pod.
+ */
+ guac_terminal* term;
+
+ /**
+ * The in-progress session recording, or NULL if no recording is in
+ * progress.
+ */
+ guac_common_recording* recording;
+
+} guac_kubernetes_client;
+
+/**
+ * Main Kubernetes client thread, handling transfer of STDOUT/STDERR of an
+ * attached Kubernetes pod to STDOUT of the terminal.
+ */
+void* guac_kubernetes_client_thread(void* data);
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/pipe.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/pipe.c b/src/protocols/kubernetes/pipe.c
new file mode 100644
index 0000000..242105b
--- /dev/null
+++ b/src/protocols/kubernetes/pipe.c
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+#include "kubernetes.h"
+#include "pipe.h"
+#include "terminal/terminal.h"
+
+#include <guacamole/protocol.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+#include <string.h>
+
+int guac_kubernetes_pipe_handler(guac_user* user, guac_stream* stream,
+ char* mimetype, char* name) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Redirect STDIN if pipe has required name */
+ if (strcmp(name, GUAC_KUBERNETES_STDIN_PIPE_NAME) == 0) {
+ guac_terminal_send_stream(kubernetes_client->term, user, stream);
+ return 0;
+ }
+
+ /* No other inbound pipe streams are supported */
+ guac_protocol_send_ack(user->socket, stream, "No such input stream.",
+ GUAC_PROTOCOL_STATUS_RESOURCE_NOT_FOUND);
+ guac_socket_flush(user->socket);
+ return 0;
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/pipe.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/pipe.h b/src/protocols/kubernetes/pipe.h
new file mode 100644
index 0000000..7acae3c
--- /dev/null
+++ b/src/protocols/kubernetes/pipe.h
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef GUAC_KUBERNETES_PIPE_H
+#define GUAC_KUBERNETES_PIPE_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+
+/**
+ * The name reserved for the inbound pipe stream which forces the terminal
+ * emulator's STDIN to be received from the pipe.
+ */
+#define GUAC_KUBERNETES_STDIN_PIPE_NAME "STDIN"
+
+/**
+ * Handles an incoming stream from a Guacamole "pipe" instruction. If the pipe
+ * is named "STDIN", the the contents of the pipe stream are redirected to
+ * STDIN of the terminal emulator for as long as the pipe is open.
+ */
+guac_user_pipe_handler guac_kubernetes_pipe_handler;
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/settings.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
new file mode 100644
index 0000000..1f04b40
--- /dev/null
+++ b/src/protocols/kubernetes/settings.c
@@ -0,0 +1,366 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "settings.h"
+
+#include <guacamole/user.h>
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+/* Client plugin arguments */
+const char* GUAC_KUBERNETES_CLIENT_ARGS[] = {
+ "hostname",
+ "port",
+ "use-ssl",
+ "client-cert-file",
+ "client-key-file",
+ "ca-cert-file",
+ "ignore-cert",
+ "font-name",
+ "font-size",
+ "color-scheme",
+ "typescript-path",
+ "typescript-name",
+ "create-typescript-path",
+ "recording-path",
+ "recording-name",
+ "recording-exclude-output",
+ "recording-exclude-mouse",
+ "recording-include-keys",
+ "create-recording-path",
+ "read-only",
+ "backspace",
+ "scrollback",
+ NULL
+};
+
+enum KUBERNETES_ARGS_IDX {
+
+ /**
+ * The hostname to connect to. Required.
+ */
+ IDX_HOSTNAME,
+
+ /**
+ * The port to connect to. Optional.
+ */
+ IDX_PORT,
+
+ /**
+ * Whether SSL/TLS should be used. SSL is used by default.
+ */
+ IDX_USE_SSL,
+
+ /**
+ * The filename of the certificate to use if performing SSL/TLS client
+ * authentication to authenticate with the Kubernetes server. If omitted,
+ * SSL client authentication will not be performed.
+ */
+ IDX_CLIENT_CERT_FILE,
+
+ /**
+ * The filename of the key to use if performing SSL/TLS client
+ * authentication to authenticate with the Kubernetes server. If omitted,
+ * SSL client authentication will not be performed.
+ */
+ IDX_CLIENT_KEY_FILE,
+
+ /**
+ * The filename of the certificate of the certificate authority that signed
+ * the certificate of the Kubernetes server.
+ */
+ IDX_CA_CERT_FILE,
+
+ /**
+ * Whether the certificate used by the Kubernetes server for SSL/TLS should
+ * be ignored if it cannot be validated.
+ */
+ IDX_IGNORE_CERT,
+
+ /**
+ * The name of the font to use within the terminal.
+ */
+ IDX_FONT_NAME,
+
+ /**
+ * The size of the font to use within the terminal, in points.
+ */
+ IDX_FONT_SIZE,
+
+ /**
+ * The color scheme to use, as a series of semicolon-separated color-value
+ * pairs: "background: <color>", "foreground: <color>", or
+ * "color<n>: <color>", where <n> is a number from 0 to 255, and <color> is
+ * "color<n>" or an X11 color code (e.g. "aqua" or "rgb:12/34/56").
+ * The color scheme can also be one of the special values: "black-white",
+ * "white-black", "gray-black", or "green-black".
+ */
+ IDX_COLOR_SCHEME,
+
+ /**
+ * The full absolute path to the directory in which typescripts should be
+ * written.
+ */
+ IDX_TYPESCRIPT_PATH,
+
+ /**
+ * The name that should be given to typescripts which are written in the
+ * given path. Each typescript will consist of two files: "NAME" and
+ * "NAME.timing".
+ */
+ IDX_TYPESCRIPT_NAME,
+
+ /**
+ * Whether the specified typescript path should automatically be created
+ * if it does not yet exist.
+ */
+ IDX_CREATE_TYPESCRIPT_PATH,
+
+ /**
+ * The full absolute path to the directory in which screen recordings
+ * should be written.
+ */
+ IDX_RECORDING_PATH,
+
+ /**
+ * The name that should be given to screen recordings which are written in
+ * the given path.
+ */
+ IDX_RECORDING_NAME,
+
+ /**
+ * Whether output which is broadcast to each connected client (graphics,
+ * streams, etc.) should NOT be included in the session recording. Output
+ * is included by default, as it is necessary for any recording which must
+ * later be viewable as video.
+ */
+ IDX_RECORDING_EXCLUDE_OUTPUT,
+
+ /**
+ * Whether changes to mouse state, such as position and buttons pressed or
+ * released, should NOT be included in the session recording. Mouse state
+ * is included by default, as it is necessary for the mouse cursor to be
+ * rendered in any resulting video.
+ */
+ IDX_RECORDING_EXCLUDE_MOUSE,
+
+ /**
+ * Whether keys pressed and released should be included in the session
+ * recording. Key events are NOT included by default within the recording,
+ * as doing so has privacy and security implications. Including key events
+ * may be necessary in certain auditing contexts, but should only be done
+ * with caution. Key events can easily contain sensitive information, such
+ * as passwords, credit card numbers, etc.
+ */
+ IDX_RECORDING_INCLUDE_KEYS,
+
+ /**
+ * Whether the specified screen recording path should automatically be
+ * created if it does not yet exist.
+ */
+ IDX_CREATE_RECORDING_PATH,
+
+ /**
+ * "true" if this connection should be read-only (user input should be
+ * dropped), "false" or blank otherwise.
+ */
+ IDX_READ_ONLY,
+
+ /**
+ * ASCII code, as an integer to use for the backspace key, or 127
+ * if not specified.
+ */
+ IDX_BACKSPACE,
+
+ /**
+ * The maximum size of the scrollback buffer in rows.
+ */
+ IDX_SCROLLBACK,
+
+ KUBERNETES_ARGS_COUNT
+};
+
+guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
+ int argc, const char** argv) {
+
+ /* Validate arg count */
+ if (argc != KUBERNETES_ARGS_COUNT) {
+ guac_user_log(user, GUAC_LOG_WARNING, "Incorrect number of connection "
+ "parameters provided: expected %i, got %i.",
+ KUBERNETES_ARGS_COUNT, argc);
+ return NULL;
+ }
+
+ guac_kubernetes_settings* settings =
+ calloc(1, sizeof(guac_kubernetes_settings));
+
+ /* Read parameters */
+ settings->hostname =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_HOSTNAME, "");
+
+ /* Parse whether SSL should be used */
+ settings->use_ssl =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_USE_SSL, true);
+
+ /* Read SSL/TLS connection details only if enabled */
+ if (settings->use_ssl) {
+
+ settings->client_cert_file =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
+ argv, IDX_CLIENT_CERT_FILE, NULL);
+
+ settings->client_key_file =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
+ argv, IDX_CLIENT_KEY_FILE, NULL);
+
+ settings->ca_cert_file =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS,
+ argv, IDX_CA_CERT_FILE, NULL);
+
+ settings->ignore_cert =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS,
+ argv, IDX_IGNORE_CERT, false);
+
+ }
+
+ /* Read-only mode */
+ settings->read_only =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_READ_ONLY, false);
+
+ /* Read maximum scrollback size */
+ settings->max_scrollback =
+ guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_SCROLLBACK, GUAC_KUBERNETES_DEFAULT_MAX_SCROLLBACK);
+
+ /* Read font name */
+ settings->font_name =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_FONT_NAME, GUAC_KUBERNETES_DEFAULT_FONT_NAME);
+
+ /* Read font size */
+ settings->font_size =
+ guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_FONT_SIZE, GUAC_KUBERNETES_DEFAULT_FONT_SIZE);
+
+ /* Copy requested color scheme */
+ settings->color_scheme =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_COLOR_SCHEME, "");
+
+ /* Pull width/height/resolution directly from user */
+ settings->width = user->info.optimal_width;
+ settings->height = user->info.optimal_height;
+ settings->resolution = user->info.optimal_resolution;
+
+ /* Read port */
+ settings->port =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_PORT, GUAC_KUBERNETES_DEFAULT_PORT);
+
+ /* Read typescript path */
+ settings->typescript_path =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_TYPESCRIPT_PATH, NULL);
+
+ /* Read typescript name */
+ settings->typescript_name =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_TYPESCRIPT_NAME, GUAC_KUBERNETES_DEFAULT_TYPESCRIPT_NAME);
+
+ /* Parse path creation flag */
+ settings->create_typescript_path =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_CREATE_TYPESCRIPT_PATH, false);
+
+ /* Read recording path */
+ settings->recording_path =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_RECORDING_PATH, NULL);
+
+ /* Read recording name */
+ settings->recording_name =
+ guac_user_parse_args_string(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_RECORDING_NAME, GUAC_KUBERNETES_DEFAULT_RECORDING_NAME);
+
+ /* Parse output exclusion flag */
+ settings->recording_exclude_output =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_RECORDING_EXCLUDE_OUTPUT, false);
+
+ /* Parse mouse exclusion flag */
+ settings->recording_exclude_mouse =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_RECORDING_EXCLUDE_MOUSE, false);
+
+ /* Parse key event inclusion flag */
+ settings->recording_include_keys =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_RECORDING_INCLUDE_KEYS, false);
+
+ /* Parse path creation flag */
+ settings->create_recording_path =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_CREATE_RECORDING_PATH, false);
+
+ /* Parse backspace key code */
+ settings->backspace =
+ guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_BACKSPACE, 127);
+
+ /* Parsing was successful */
+ return settings;
+
+}
+
+void guac_kubernetes_settings_free(guac_kubernetes_settings* settings) {
+
+ /* Free network connection information */
+ free(settings->hostname);
+ free(settings->port);
+
+ /* Free SSL/TLS details */
+ free(settings->client_cert_file);
+ free(settings->client_key_file);
+ free(settings->ca_cert_file);
+
+ /* Free display preferences */
+ free(settings->font_name);
+ free(settings->color_scheme);
+
+ /* Free typescript settings */
+ free(settings->typescript_name);
+ free(settings->typescript_path);
+
+ /* Free screen recording settings */
+ free(settings->recording_name);
+ free(settings->recording_path);
+
+ /* Free overall structure */
+ free(settings);
+
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/settings.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
new file mode 100644
index 0000000..3e89ce5
--- /dev/null
+++ b/src/protocols/kubernetes/settings.h
@@ -0,0 +1,256 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_SETTINGS_H
+#define GUAC_KUBERNETES_SETTINGS_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+
+/**
+ * The name of the font to use for the terminal if no name is specified.
+ */
+#define GUAC_KUBERNETES_DEFAULT_FONT_NAME "monospace"
+
+/**
+ * The size of the font to use for the terminal if no font size is specified,
+ * in points.
+ */
+#define GUAC_KUBERNETES_DEFAULT_FONT_SIZE 12
+
+/**
+ * The port to connect to when initiating any Kubernetes connection, if no
+ * other port is specified.
+ */
+#define GUAC_KUBERNETES_DEFAULT_PORT "8443"
+
+/**
+ * The filename to use for the typescript, if not specified.
+ */
+#define GUAC_KUBERNETES_DEFAULT_TYPESCRIPT_NAME "typescript"
+
+/**
+ * The filename to use for the screen recording, if not specified.
+ */
+#define GUAC_KUBERNETES_DEFAULT_RECORDING_NAME "recording"
+
+/**
+ * The default maximum scrollback size in rows.
+ */
+#define GUAC_KUBERNETES_DEFAULT_MAX_SCROLLBACK 1000
+
+/**
+ * Settings for the Kubernetes connection. The values for this structure are
+ * parsed from the arguments given during the Guacamole protocol handshake
+ * using the guac_kubernetes_parse_args() function.
+ */
+typedef struct guac_kubernetes_settings {
+
+ /**
+ * The hostname of the Kubernetes server to connect to.
+ */
+ char* hostname;
+
+ /**
+ * The port of the Kubernetes server to connect to.
+ */
+ char* port;
+
+ /**
+ * Whether SSL/TLS should be used.
+ */
+ bool use_ssl;
+
+ /**
+ * The filename of the certificate to use if performing SSL/TLS client
+ * authentication to authenticate with the Kubernetes server. If omitted,
+ * SSL client authentication will not be performed.
+ */
+ char* client_cert_file;
+
+ /**
+ * The filename of the key to use if performing SSL/TLS client
+ * authentication to authenticate with the Kubernetes server. If omitted,
+ * SSL client authentication will not be performed.
+ */
+ char* client_key_file;
+
+ /**
+ * The filename of the certificate of the certificate authority that signed
+ * the certificate of the Kubernetes server.
+ */
+ char* ca_cert_file;
+
+ /**
+ * Whether the certificate used by the Kubernetes server for SSL/TLS should
+ * be ignored if it cannot be validated.
+ */
+ bool ignore_cert;
+
+ /**
+ * Whether this connection is read-only, and user input should be dropped.
+ */
+ bool read_only;
+
+ /**
+ * The maximum size of the scrollback buffer in rows.
+ */
+ int max_scrollback;
+
+ /**
+ * The name of the font to use for display rendering.
+ */
+ char* font_name;
+
+ /**
+ * The size of the font to use, in points.
+ */
+ int font_size;
+
+ /**
+ * The name of the color scheme to use.
+ */
+ char* color_scheme;
+
+ /**
+ * The desired width of the terminal display, in pixels.
+ */
+ int width;
+
+ /**
+ * The desired height of the terminal display, in pixels.
+ */
+ int height;
+
+ /**
+ * The desired screen resolution, in DPI.
+ */
+ int resolution;
+
+ /**
+ * The path in which the typescript should be saved, if enabled. If no
+ * typescript should be saved, this will be NULL.
+ */
+ char* typescript_path;
+
+ /**
+ * The filename to use for the typescript, if enabled.
+ */
+ char* typescript_name;
+
+ /**
+ * Whether the typescript path should be automatically created if it does
+ * not already exist.
+ */
+ bool create_typescript_path;
+
+ /**
+ * The path in which the screen recording should be saved, if enabled. If
+ * no screen recording should be saved, this will be NULL.
+ */
+ char* recording_path;
+
+ /**
+ * The filename to use for the screen recording, if enabled.
+ */
+ char* recording_name;
+
+ /**
+ * Whether the screen recording path should be automatically created if it
+ * does not already exist.
+ */
+ bool create_recording_path;
+
+ /**
+ * Whether output which is broadcast to each connected client (graphics,
+ * streams, etc.) should NOT be included in the session recording. Output
+ * is included by default, as it is necessary for any recording which must
+ * later be viewable as video.
+ */
+ bool recording_exclude_output;
+
+ /**
+ * Whether changes to mouse state, such as position and buttons pressed or
+ * released, should NOT be included in the session recording. Mouse state
+ * is included by default, as it is necessary for the mouse cursor to be
+ * rendered in any resulting video.
+ */
+ bool recording_exclude_mouse;
+
+ /**
+ * Whether keys pressed and released should be included in the session
+ * recording. Key events are NOT included by default within the recording,
+ * as doing so has privacy and security implications. Including key events
+ * may be necessary in certain auditing contexts, but should only be done
+ * with caution. Key events can easily contain sensitive information, such
+ * as passwords, credit card numbers, etc.
+ */
+ bool recording_include_keys;
+
+ /**
+ * The ASCII code, as an integer, that the Kubernetes client will use when
+ * the backspace key is pressed. By default, this is 127, ASCII delete, if
+ * not specified in the client settings.
+ */
+ int backspace;
+
+} guac_kubernetes_settings;
+
+/**
+ * Parses all given args, storing them in a newly-allocated settings object. If
+ * the args fail to parse, NULL is returned.
+ *
+ * @param user
+ * The user who submitted the given arguments while joining the
+ * connection.
+ *
+ * @param argc
+ * The number of arguments within the argv array.
+ *
+ * @param argv
+ * The values of all arguments provided by the user.
+ *
+ * @return
+ * A newly-allocated settings object which must be freed with
+ * guac_kubernetes_settings_free() when no longer needed. If the arguments
+ * fail to parse, NULL is returned.
+ */
+guac_kubernetes_settings* guac_kubernetes_parse_args(guac_user* user,
+ int argc, const char** argv);
+
+/**
+ * Frees the given guac_kubernetes_settings object, having been previously
+ * allocated via guac_kubernetes_parse_args().
+ *
+ * @param settings
+ * The settings object to free.
+ */
+void guac_kubernetes_settings_free(guac_kubernetes_settings* settings);
+
+/**
+ * NULL-terminated array of accepted client args.
+ */
+extern const char* GUAC_KUBERNETES_CLIENT_ARGS[];
+
+#endif
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/user.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/user.c b/src/protocols/kubernetes/user.c
new file mode 100644
index 0000000..62666cb
--- /dev/null
+++ b/src/protocols/kubernetes/user.c
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "config.h"
+
+#include "clipboard.h"
+#include "input.h"
+#include "kubernetes.h"
+#include "pipe.h"
+#include "settings.h"
+#include "terminal/terminal.h"
+#include "user.h"
+
+#include <guacamole/client.h>
+#include <guacamole/socket.h>
+#include <guacamole/user.h>
+
+#include <pthread.h>
+#include <string.h>
+
+int guac_kubernetes_user_join_handler(guac_user* user, int argc, char** argv) {
+
+ guac_client* client = user->client;
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Parse provided arguments */
+ guac_kubernetes_settings* settings = guac_kubernetes_parse_args(user,
+ argc, (const char**) argv);
+
+ /* Fail if settings cannot be parsed */
+ if (settings == NULL) {
+ guac_user_log(user, GUAC_LOG_INFO,
+ "Badly formatted client arguments.");
+ return 1;
+ }
+
+ /* Store settings at user level */
+ user->data = settings;
+
+ /* Connect to Kubernetes if owner */
+ if (user->owner) {
+
+ /* Store owner's settings at client level */
+ kubernetes_client->settings = settings;
+
+ /* Start client thread */
+ if (pthread_create(&(kubernetes_client->client_thread), NULL,
+ guac_kubernetes_client_thread, (void*) client)) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Unable to start Kubernetes client thread");
+ return 1;
+ }
+
+ }
+
+ /* If not owner, synchronize with current display */
+ else {
+ guac_terminal_dup(kubernetes_client->term, user, user->socket);
+ guac_socket_flush(user->socket);
+ }
+
+ /* Only handle events if not read-only */
+ if (!settings->read_only) {
+
+ /* General mouse/keyboard/clipboard events */
+ user->key_handler = guac_kubernetes_user_key_handler;
+ user->mouse_handler = guac_kubernetes_user_mouse_handler;
+ user->clipboard_handler = guac_kubernetes_clipboard_handler;
+
+ /* STDIN redirection */
+ user->pipe_handler = guac_kubernetes_pipe_handler;
+
+ /* Display size change events */
+ user->size_handler = guac_kubernetes_user_size_handler;
+
+ }
+
+ return 0;
+
+}
+
+int guac_kubernetes_user_leave_handler(guac_user* user) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) user->client->data;
+
+ /* Update shared cursor state */
+ guac_common_cursor_remove_user(kubernetes_client->term->cursor, user);
+
+ /* Free settings if not owner (owner settings will be freed with client) */
+ if (!user->owner) {
+ guac_kubernetes_settings* settings =
+ (guac_kubernetes_settings*) user->data;
+ guac_kubernetes_settings_free(settings);
+ }
+
+ return 0;
+}
+
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/b8bd0e4c/src/protocols/kubernetes/user.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/user.h b/src/protocols/kubernetes/user.h
new file mode 100644
index 0000000..d235b2b
--- /dev/null
+++ b/src/protocols/kubernetes/user.h
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef GUAC_KUBERNETES_USER_H
+#define GUAC_KUBERNETES_USER_H
+
+#include "config.h"
+
+#include <guacamole/user.h>
+
+/**
+ * Handler for joining users.
+ */
+guac_user_join_handler guac_kubernetes_user_join_handler;
+
+/**
+ * Handler for leaving users.
+ */
+guac_user_leave_handler guac_kubernetes_user_leave_handler;
+
+#endif
+
[04/19] guacamole-server git commit: GUACAMOLE-623: Handle data
received from Kubernetes.
Posted by vn...@apache.org.
GUACAMOLE-623: Handle data received from Kubernetes.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/f72877bf
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/f72877bf
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/f72877bf
Branch: refs/heads/master
Commit: f72877bf0d7c68fc2c08eb442d749ce096dc8118
Parents: 7165fa9
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 9 23:50:30 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/kubernetes.c | 70 +++++++++++++++++++++++-------
src/protocols/kubernetes/kubernetes.h | 26 +++++++++++
2 files changed, 81 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/f72877bf/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 98e49ec..ae2a894 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -38,10 +38,44 @@
#include <unistd.h>
/**
- * The name of the WebSocket protocol specific to Kubernetes which should be
- * sent to the Kubernetes server when attaching to a pod.
+ * Handles data received from Kubernetes over WebSocket, decoding the channel
+ * index of the received data and forwarding that data accordingly.
+ *
+ * @param client
+ * The guac_client associated with the connection to Kubernetes.
+ *
+ * @param buffer
+ * The data received from Kubernetes.
+ *
+ * @param length
+ * The size of the data received from Kubernetes, in bytes.
*/
-#define GUAC_KUBERNETES_LWS_PROTOCOL "v4.channel.k8s.io"
+static void guac_kubernetes_receive_data(guac_client* client,
+ const char* buffer, size_t length) {
+
+ guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;
+
+ /* Strip channel index from beginning of buffer */
+ int channel = *(buffer++);
+ length--;
+
+ switch (channel) {
+
+ /* Write STDOUT / STDERR directly to terminal as output */
+ case GUAC_KUBERNETES_CHANNEL_STDOUT:
+ case GUAC_KUBERNETES_CHANNEL_STDERR:
+ guac_terminal_write(kubernetes_client->term, buffer, length);
+ break;
+
+ /* Ignore data on other channels */
+ default:
+ guac_client_log(client, GUAC_LOG_DEBUG, "Received %i bytes along "
+ "channel %i.", length, channel);
+
+ }
+
+}
/**
* Callback invoked by libwebsockets for events related to a WebSocket being
@@ -71,16 +105,15 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
enum lws_callback_reasons reason, void* user,
void* in, size_t length) {
+ /* Request connection closure if client is stopped (note that the user
+ * pointer passed by libwebsockets may be NULL for some events) */
guac_client* client = (guac_client*) user;
- /*guac_kubernetes_client* kubernetes_client =
- (guac_kubernetes_client*) client->data;*/
-
- /* Request connection closure if client is stopped */
- if (client->state != GUAC_CLIENT_RUNNING)
+ if (client != NULL && client->state != GUAC_CLIENT_RUNNING)
return -1;
switch (reason) {
+ /* Failed to connect */
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND,
"Error connecting to Kubernetes server: %s",
@@ -88,23 +121,29 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
"available)");
break;
- /* Logged in */
+ /* Connected / logged in */
case LWS_CALLBACK_CLIENT_ESTABLISHED:
guac_client_log(client, GUAC_LOG_INFO,
"Kubernetes connection successful.");
break;
+ /* Data received via WebSocket */
case LWS_CALLBACK_CLIENT_RECEIVE:
- guac_client_log(client, GUAC_LOG_DEBUG, "Received: %s",
- (const char*) in);
+ guac_kubernetes_receive_data(client, (const char*) in, length);
break;
/* TODO: Only send data here. Request callback for writing via lws_callback_on_writable(some struct lws*) */
case LWS_CALLBACK_CLIENT_WRITEABLE:
break;
+ /* TODO: Add configure test */
+#ifdef HAVE_LWS_CALLBACK_CLIENT_CLOSED
+ /* Connection closed (client-specific) */
+ case LWS_CALLBACK_CLIENT_CLOSED:
+#endif
+
+ /* Connection closed */
case LWS_CALLBACK_CLOSED:
- /* TODO: case LWS_CALLBACK_CLIENT_CLOSED: <-- Needs test and #ifdef */
guac_client_stop(client);
guac_client_log(client, GUAC_LOG_DEBUG, "WebSocket connection to "
"Kubernetes server closed.");
@@ -112,8 +151,6 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
/* No other event types are applicable */
default:
- guac_client_log(client, GUAC_LOG_DEBUG, "Unexpected libwebsockets "
- "reason: %i", reason);
break;
}
@@ -213,7 +250,10 @@ void* guac_kubernetes_client_thread(void* data) {
/* Init libwebsockets context creation parameters */
struct lws_context_creation_info context_info = {
.port = CONTEXT_PORT_NO_LISTEN, /* We are not a WebSocket server */
- .protocols = guac_kubernetes_lws_protocols
+ .uid = -1,
+ .gid = -1,
+ .protocols = guac_kubernetes_lws_protocols,
+ .user = client
};
/* Init WebSocket connection parameters which do not vary by Guacmaole
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/f72877bf/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index 89c172f..89b6678 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -30,6 +30,32 @@
#include <stdint.h>
/**
+ * The name of the WebSocket protocol specific to Kubernetes which should be
+ * sent to the Kubernetes server when attaching to a pod.
+ */
+#define GUAC_KUBERNETES_LWS_PROTOCOL "v4.channel.k8s.io"
+
+/**
+ * The index of the Kubernetes channel used for STDIN.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDIN 0
+
+/**
+ * The index of the Kubernetes channel used for STDOUT.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDOUT 1
+
+/**
+ * The index of the Kubernetes channel used for STDERR.
+ */
+#define GUAC_KUBERNETES_CHANNEL_STDERR 2
+
+/**
+ * The index of the Kubernetes channel used for terminal resize messages.
+ */
+#define GUAC_KUBERNETES_CHANNEL_RESIZE 4
+
+/**
* Kubernetes-specific client data.
*/
typedef struct guac_kubernetes_client {
[14/19] guacamole-server git commit: GUACAMOLE-623: Stub out
implementation of WebSocket client for Kubernetes.
Posted by vn...@apache.org.
GUACAMOLE-623: Stub out implementation of WebSocket client for Kubernetes.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/7165fa94
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/7165fa94
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/7165fa94
Branch: refs/heads/master
Commit: 7165fa949d21386d19cbda795fbc849e916461d0
Parents: 519c90a
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Sep 9 22:55:38 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/kubernetes.c | 177 ++++++++++++++++++++++++++++-
src/protocols/kubernetes/kubernetes.h | 6 +
2 files changed, 178 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/7165fa94/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 231d78d..98e49ec 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -24,6 +24,7 @@
#include <guacamole/client.h>
#include <guacamole/protocol.h>
+#include <libwebsockets.h>
#include <errno.h>
#include <netdb.h>
@@ -37,6 +38,104 @@
#include <unistd.h>
/**
+ * The name of the WebSocket protocol specific to Kubernetes which should be
+ * sent to the Kubernetes server when attaching to a pod.
+ */
+#define GUAC_KUBERNETES_LWS_PROTOCOL "v4.channel.k8s.io"
+
+/**
+ * Callback invoked by libwebsockets for events related to a WebSocket being
+ * used for communicating with an attached Kubernetes pod.
+ *
+ * @param wsi
+ * The libwebsockets handle for the WebSocket connection.
+ *
+ * @param reason
+ * The reason (event) that this callback was invoked.
+ *
+ * @param user
+ * Arbitrary data assocated with the WebSocket session. This will always
+ * be a pointer to the guac_client instance.
+ *
+ * @param in
+ * A pointer to arbitrary, reason-specific data.
+ *
+ * @param length
+ * An arbitrary, reason-specific length value.
+ *
+ * @return
+ * An undocumented integer value related the success of handling the
+ * event, or -1 if the WebSocket connection should be closed.
+ */
+static int guac_kubernetes_lws_callback(struct lws* wsi,
+ enum lws_callback_reasons reason, void* user,
+ void* in, size_t length) {
+
+ guac_client* client = (guac_client*) user;
+ /*guac_kubernetes_client* kubernetes_client =
+ (guac_kubernetes_client*) client->data;*/
+
+ /* Request connection closure if client is stopped */
+ if (client->state != GUAC_CLIENT_RUNNING)
+ return -1;
+
+ switch (reason) {
+
+ case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND,
+ "Error connecting to Kubernetes server: %s",
+ in != NULL ? (char*) in : "(no error description "
+ "available)");
+ break;
+
+ /* Logged in */
+ case LWS_CALLBACK_CLIENT_ESTABLISHED:
+ guac_client_log(client, GUAC_LOG_INFO,
+ "Kubernetes connection successful.");
+ break;
+
+ case LWS_CALLBACK_CLIENT_RECEIVE:
+ guac_client_log(client, GUAC_LOG_DEBUG, "Received: %s",
+ (const char*) in);
+ break;
+
+ /* TODO: Only send data here. Request callback for writing via lws_callback_on_writable(some struct lws*) */
+ case LWS_CALLBACK_CLIENT_WRITEABLE:
+ break;
+
+ case LWS_CALLBACK_CLOSED:
+ /* TODO: case LWS_CALLBACK_CLIENT_CLOSED: <-- Needs test and #ifdef */
+ guac_client_stop(client);
+ guac_client_log(client, GUAC_LOG_DEBUG, "WebSocket connection to "
+ "Kubernetes server closed.");
+ break;
+
+ /* No other event types are applicable */
+ default:
+ guac_client_log(client, GUAC_LOG_DEBUG, "Unexpected libwebsockets "
+ "reason: %i", reason);
+ break;
+
+ }
+
+ return lws_callback_http_dummy(wsi, reason, user, in, length);
+
+}
+
+/**
+ * List of all WebSocket protocols which should be declared as supported by
+ * libwebsockets during the initial WebSocket handshake, along with
+ * corresponding event-handling callbacks.
+ */
+struct lws_protocols guac_kubernetes_lws_protocols[] = {
+ {
+ .name = GUAC_KUBERNETES_LWS_PROTOCOL,
+ .callback = guac_kubernetes_lws_callback
+ },
+ { 0 }
+};
+
+/**
* Input thread, started by the main Kubernetes client thread. This thread
* continuously reads from the terminal's STDIN and transfers all read
* data to the Kubernetes connection.
@@ -111,11 +210,69 @@ void* guac_kubernetes_client_thread(void* data) {
settings->create_typescript_path);
}
- /* TODO: Open WebSocket connection to Kubernetes */
+ /* Init libwebsockets context creation parameters */
+ struct lws_context_creation_info context_info = {
+ .port = CONTEXT_PORT_NO_LISTEN, /* We are not a WebSocket server */
+ .protocols = guac_kubernetes_lws_protocols
+ };
+
+ /* Init WebSocket connection parameters which do not vary by Guacmaole
+ * connection parameters or creation of future libwebsockets objects */
+ struct lws_client_connect_info connection_info = {
+ .host = settings->hostname,
+ .address = settings->hostname,
+ .origin = settings->hostname,
+ .port = settings->port,
+ .protocol = GUAC_KUBERNETES_LWS_PROTOCOL,
+ .pwsi = &kubernetes_client->wsi,
+ .userdata = client
+ };
+
+ /* If requested, use an SSL/TLS connection for communication with
+ * Kubernetes */
+ if (settings->use_ssl) {
- /* Logged in */
- guac_client_log(client, GUAC_LOG_INFO,
- "Kubernetes connection successful.");
+ /* Enable use of SSL/TLS */
+ context_info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
+ connection_info.ssl_connection = LCCSCF_USE_SSL;
+
+ /* Bypass certificate checks if requested */
+ if (settings->ignore_cert) {
+ connection_info.ssl_connection |=
+ LCCSCF_ALLOW_SELFSIGNED
+ | LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK
+ | LCCSCF_ALLOW_EXPIRED;
+ }
+
+ /* Otherwise use the given CA certificate to validate (if any) */
+ else
+ context_info.client_ssl_ca_filepath = settings->ca_cert_file;
+
+ /* Certificate and key file for SSL/TLS client auth */
+ context_info.client_ssl_cert_filepath = settings->client_cert_file;
+ context_info.client_ssl_private_key_filepath = settings->client_key_file;
+
+ }
+
+ /* Create libwebsockets context */
+ struct lws_context* context = lws_create_context(&context_info);
+ if (!context) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Initialization of libwebsockets failed");
+ return NULL;
+ }
+
+ /* FIXME: Generate path dynamically */
+ connection_info.context = context;
+ connection_info.path = "/api/v1/namespaces/default/pods/my-shell-68974bb7f7-rpjgr/attach?container=my-shell&stdin=true&stdout=true&tty=true";
+
+ /* Open WebSocket connection to Kubernetes */
+ kubernetes_client->wsi = lws_client_connect_via_info(&connection_info);
+ if (kubernetes_client->wsi == NULL) {
+ guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR,
+ "Connection via libwebsockets failed");
+ return NULL;
+ }
/* Start input thread */
if (pthread_create(&(input_thread), NULL, guac_kubernetes_input_thread, (void*) client)) {
@@ -123,12 +280,22 @@ void* guac_kubernetes_client_thread(void* data) {
return NULL;
}
- /* TODO: While data available, write to terminal */
+ /* As long as client is connected, continue polling libwebsockets */
+ while (client->state == GUAC_CLIENT_RUNNING) {
+
+ /* Cease polling libwebsockets if an error condition is signalled */
+ if (lws_service(context, 1000) < 0)
+ break;
+
+ }
/* Kill client and Wait for input thread to die */
guac_client_stop(client);
pthread_join(input_thread, NULL);
+ /* All done with libwebsockets */
+ lws_context_destroy(context);
+
guac_client_log(client, GUAC_LOG_INFO, "Kubernetes connection ended.");
return NULL;
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/7165fa94/src/protocols/kubernetes/kubernetes.h
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.h b/src/protocols/kubernetes/kubernetes.h
index f8035ae..89c172f 100644
--- a/src/protocols/kubernetes/kubernetes.h
+++ b/src/protocols/kubernetes/kubernetes.h
@@ -26,6 +26,7 @@
#include "settings.h"
#include "terminal/terminal.h"
+#include <libwebsockets.h>
#include <stdint.h>
/**
@@ -39,6 +40,11 @@ typedef struct guac_kubernetes_client {
guac_kubernetes_settings* settings;
/**
+ * The connected WebSocket.
+ */
+ struct lws* wsi;
+
+ /**
* The Kubernetes client thread.
*/
pthread_t client_thread;
[10/19] guacamole-server git commit: GUACAMOLE-623: Add configure
test for LWS_CALLBACK_CLIENT_CLOSED (only defined in recent libwebsockets and
required if present).
Posted by vn...@apache.org.
GUACAMOLE-623: Add configure test for LWS_CALLBACK_CLIENT_CLOSED (only defined in recent libwebsockets and required if present).
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/c5f67a31
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/c5f67a31
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/c5f67a31
Branch: refs/heads/master
Commit: c5f67a31dc6c803da23f70662befc102a9187855
Parents: ed56093
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Sep 10 20:00:44 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:51 2018 -0700
----------------------------------------------------------------------
configure.ac | 10 ++++++++++
src/protocols/kubernetes/kubernetes.c | 1 -
2 files changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/c5f67a31/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index ae78324..7c0bb73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1193,6 +1193,16 @@ then
[have_libwebsockets=no])
fi
+# Check for client-specific closed event, which must be used in favor of the
+# generic closed event if libwebsockets is recent enough to provide this
+if test "x$with_websockets" != "xno"
+then
+ AC_CHECK_DECL([LWS_CALLBACK_CLIENT_CLOSED],
+ [AC_DEFINE([HAVE_LWS_CALLBACK_CLIENT_CLOSED],,
+ [Whether LWS_CALLBACK_CLIENT_CLOSED is defined])],,
+ [#include <libwebsockets.h>])
+fi
+
AM_CONDITIONAL([ENABLE_WEBSOCKETS],
[test "x${have_libwebsockets}" = "xyes"])
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/c5f67a31/src/protocols/kubernetes/kubernetes.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index 380d1d3..9850c6d 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -268,7 +268,6 @@ static int guac_kubernetes_lws_callback(struct lws* wsi,
lws_callback_on_writable(wsi);
break;
- /* TODO: Add configure test */
#ifdef HAVE_LWS_CALLBACK_CLIENT_CLOSED
/* Connection closed (client-specific) */
case LWS_CALLBACK_CLIENT_CLOSED:
[16/19] guacamole-server git commit: GUACAMOLE-623: Clean up logging
(libwebsockets adds newline characters).
Posted by vn...@apache.org.
GUACAMOLE-623: Clean up logging (libwebsockets adds newline characters).
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/61df2956
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/61df2956
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/61df2956
Branch: refs/heads/master
Commit: 61df2956b322a01a777c8169cbbd2b2a2877d696
Parents: 83a531b
Author: Michael Jumper <mj...@apache.org>
Authored: Tue Sep 11 03:17:00 2018 -0700
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Sep 25 21:30:52 2018 -0700
----------------------------------------------------------------------
src/protocols/kubernetes/client.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-server/blob/61df2956/src/protocols/kubernetes/client.c
----------------------------------------------------------------------
diff --git a/src/protocols/kubernetes/client.c b/src/protocols/kubernetes/client.c
index 331e03d..1a1eb3a 100644
--- a/src/protocols/kubernetes/client.c
+++ b/src/protocols/kubernetes/client.c
@@ -48,9 +48,32 @@ guac_client* guac_kubernetes_lws_current_client = NULL;
* The line of logging output to log.
*/
static void guac_kubernetes_log(int level, const char* line) {
- if (guac_kubernetes_lws_current_client != NULL)
- guac_client_log(guac_kubernetes_lws_current_client, GUAC_LOG_DEBUG,
- "libwebsockets: %s", line);
+
+ char buffer[1024];
+
+ /* Drop log message if there's nowhere to log yet */
+ if (guac_kubernetes_lws_current_client == NULL)
+ return;
+
+ /* Trim length of line to fit buffer (plus null terminator) */
+ int length = strlen(line);
+ if (length > sizeof(buffer) - 1)
+ length = sizeof(buffer) - 1;
+
+ /* Copy as much of the received line as will fit in the buffer */
+ memcpy(buffer, line, length);
+
+ /* If the line ends with a newline character, trim the character */
+ if (length > 0 && buffer[length - 1] == '\n')
+ length--;
+
+ /* Null-terminate the trimmed string */
+ buffer[length] = '\0';
+
+ /* Log using guacd's own log facilities */
+ guac_client_log(guac_kubernetes_lws_current_client, GUAC_LOG_DEBUG,
+ "libwebsockets: %s", buffer);
+
}
int guac_client_init(guac_client* client) {
[19/19] guacamole-server git commit: GUACAMOLE-623: Merge support for
terminals of containers in Kubernetes pods.
Posted by vn...@apache.org.
GUACAMOLE-623: Merge support for terminals of containers in Kubernetes pods.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-server/commit/43db1965
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-server/tree/43db1965
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-server/diff/43db1965
Branch: refs/heads/master
Commit: 43db1965efdf73717900e86778750996bd49395e
Parents: 54fda21 61df295
Author: Nick Couchman <vn...@apache.org>
Authored: Wed Sep 26 08:43:30 2018 -0400
Committer: Nick Couchman <vn...@apache.org>
Committed: Wed Sep 26 08:43:30 2018 -0400
----------------------------------------------------------------------
Makefile.am | 4 +
configure.ac | 76 +++++-
src/protocols/kubernetes/Makefile.am | 64 +++++
src/protocols/kubernetes/client.c | 133 ++++++++++
src/protocols/kubernetes/client.h | 44 ++++
src/protocols/kubernetes/clipboard.c | 65 +++++
src/protocols/kubernetes/clipboard.h | 41 +++
src/protocols/kubernetes/input.c | 94 +++++++
src/protocols/kubernetes/input.h | 44 ++++
src/protocols/kubernetes/io.c | 143 ++++++++++
src/protocols/kubernetes/io.h | 144 +++++++++++
src/protocols/kubernetes/kubernetes.c | 387 +++++++++++++++++++++++++++
src/protocols/kubernetes/kubernetes.h | 168 ++++++++++++
src/protocols/kubernetes/pipe.c | 52 ++++
src/protocols/kubernetes/pipe.h | 40 +++
src/protocols/kubernetes/settings.c | 403 +++++++++++++++++++++++++++++
src/protocols/kubernetes/settings.h | 279 ++++++++++++++++++++
src/protocols/kubernetes/ssl.c | 210 +++++++++++++++
src/protocols/kubernetes/ssl.h | 41 +++
src/protocols/kubernetes/url.c | 137 ++++++++++
src/protocols/kubernetes/url.h | 85 ++++++
src/protocols/kubernetes/user.c | 116 +++++++++
src/protocols/kubernetes/user.h | 36 +++
23 files changed, 2798 insertions(+), 8 deletions(-)
----------------------------------------------------------------------