Merge 1.1.0 changes back to master.
diff --git a/Dockerfile b/Dockerfile
index f5f7a42..094842c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -75,7 +75,7 @@
> ${PREFIX_DIR}/DEPENDENCIES
# Use same Debian as the base for the runtime image
-FROM debian:${DEBIAN_VERSION}
+FROM debian:${DEBIAN_VERSION}-slim
# Base directory for installed build artifacts.
# Due to limitations of the Docker image build process, this value is
diff --git a/configure.ac b/configure.ac
index e1950ef..7fc7d33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -528,11 +528,39 @@
fi
#
+# TLS Locking Support within libVNCServer
+#
+
+if test "x${have_libvncserver}" = "xyes"
+then
+
+ have_vnc_tls_locking=yes
+ AC_CHECK_MEMBERS([rfbClient.LockWriteToTLS, rfbClient.UnlockWriteToTLS],
+ [], [have_vnc_tls_locking=no],
+ [[#include <rfb/rfbclient.h>]])
+
+ if test "x${have_vnc_tls_locking}" = "xno"
+ then
+ AC_MSG_WARN([
+ --------------------------------------------
+ This version of libvncclient lacks support
+ for TLS locking. VNC connections that use
+ TLS may experience instability as documented
+ in GUACAMOLE-414])
+ else
+ AC_DEFINE([ENABLE_VNC_TLS_LOCKING],,
+ [Whether support for TLS locking within VNC is enabled.])
+ fi
+
+fi
+
+#
# FreeRDP
#
have_freerdp=disabled
RDP_LIBS=
+WINPR_LIBS=
AC_ARG_WITH([rdp],
[AS_HELP_STRING([--with-rdp],
[support RDP @<:@default=check@:>@])],
@@ -734,6 +762,21 @@
[#include <freerdp/utils/stream.h>])])
fi
+# Find location of Stream_New and Stream_free
+if test "x${have_freerdp}" = "xyes" -a "x${have_winpr}" = "xyes"
+then
+ AC_CHECK_LIB([winpr], [Stream_New, Stream_Free],
+ [WINPR_LIBS="$WINPR_LIBS -lwinpr"],
+ [AC_CHECK_LIB([winpr-utils], [Stream_New, Stream_Free],
+ [WINPR_LIBS="$WINPR_LIBS -lwinpr-utils"],
+ [AC_MSG_WARN([
+ ------------------------------------------
+ Unable to locate stream functions in winpr
+ libraries. RDP will be disabled.
+ ------------------------------------------])
+ have_freerdp=no])])
+fi
+
# Check for types in WinPR
if test "x${have_freerdp}" = "xyes"
then
@@ -1042,6 +1085,7 @@
AM_CONDITIONAL([ENABLE_RDP], [test "x${have_freerdp}" = "xyes"])
AC_SUBST(RDP_LIBS)
+AC_SUBST(WINPR_LIBS)
#
# libssh2
diff --git a/src/protocols/kubernetes/kubernetes.c b/src/protocols/kubernetes/kubernetes.c
index bd84f6c..7158a98 100644
--- a/src/protocols/kubernetes/kubernetes.c
+++ b/src/protocols/kubernetes/kubernetes.c
@@ -239,7 +239,7 @@
/* Create terminal */
kubernetes_client->term = guac_terminal_create(client,
- kubernetes_client->clipboard,
+ kubernetes_client->clipboard, settings->disable_copy,
settings->max_scrollback, settings->font_name, settings->font_size,
settings->resolution, settings->width, settings->height,
settings->color_scheme, settings->backspace);
diff --git a/src/protocols/kubernetes/settings.c b/src/protocols/kubernetes/settings.c
index 0ae3dc2..4ed5f51 100644
--- a/src/protocols/kubernetes/settings.c
+++ b/src/protocols/kubernetes/settings.c
@@ -50,6 +50,8 @@
"read-only",
"backspace",
"scrollback",
+ "disable-copy",
+ "disable-paste",
NULL
};
@@ -216,6 +218,20 @@
*/
IDX_SCROLLBACK,
+ /**
+ * Whether outbound clipboard access should be blocked. If set to "true",
+ * it will not be possible to copy data from the terminal to the client
+ * using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_COPY,
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set to "true", it
+ * will not be possible to paste data from the client to the terminal using
+ * the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_PASTE,
+
KUBERNETES_ARGS_COUNT
};
@@ -364,6 +380,16 @@
guac_user_parse_args_int(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
IDX_BACKSPACE, 127);
+ /* Parse clipboard copy disable flag */
+ settings->disable_copy =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_DISABLE_COPY, false);
+
+ /* Parse clipboard paste disable flag */
+ settings->disable_paste =
+ guac_user_parse_args_boolean(user, GUAC_KUBERNETES_CLIENT_ARGS, argv,
+ IDX_DISABLE_PASTE, false);
+
/* Parsing was successful */
return settings;
diff --git a/src/protocols/kubernetes/settings.h b/src/protocols/kubernetes/settings.h
index 6267a18..eef4973 100644
--- a/src/protocols/kubernetes/settings.h
+++ b/src/protocols/kubernetes/settings.h
@@ -171,6 +171,20 @@
int resolution;
/**
+ * Whether outbound clipboard access should be blocked. If set, it will not
+ * be possible to copy data from the terminal to the client using the
+ * clipboard.
+ */
+ bool disable_copy;
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set, it will not
+ * be possible to paste data from the client to the terminal using the
+ * clipboard.
+ */
+ bool disable_paste;
+
+ /**
* The path in which the typescript should be saved, if enabled. If no
* typescript should be saved, this will be NULL.
*/
diff --git a/src/protocols/kubernetes/user.c b/src/protocols/kubernetes/user.c
index e7f6d8f..d1fcd5d 100644
--- a/src/protocols/kubernetes/user.c
+++ b/src/protocols/kubernetes/user.c
@@ -81,10 +81,13 @@
/* 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;
+ /* General mouse/keyboard events */
+ user->key_handler = guac_kubernetes_user_key_handler;
+ user->mouse_handler = guac_kubernetes_user_mouse_handler;
+
+ /* Inbound (client to server) clipboard transfer */
+ if (!settings->disable_paste)
+ user->clipboard_handler = guac_kubernetes_clipboard_handler;
/* STDIN redirection */
user->pipe_handler = guac_kubernetes_pipe_handler;
diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am
index 1ba406c..d679a71 100644
--- a/src/protocols/rdp/Makefile.am
+++ b/src/protocols/rdp/Makefile.am
@@ -156,7 +156,8 @@
-version-info 0:0:0 \
@CAIRO_LIBS@ \
@PTHREAD_LIBS@ \
- @RDP_LIBS@
+ @RDP_LIBS@ \
+ @WINPR_LIBS@
libguac_client_rdp_la_LIBADD = \
@COMMON_LTLIB@ \
@@ -175,7 +176,8 @@
guacdr_ldflags = \
-module -avoid-version -shared \
@PTHREAD_LIBS@ \
- @RDP_LIBS@
+ @RDP_LIBS@ \
+ @WINPR_LIBS@
guacdr_libadd = \
@COMMON_LTLIB@ \
@@ -194,7 +196,8 @@
guacai_ldflags = \
-module -avoid-version -shared \
@PTHREAD_LIBS@ \
- @RDP_LIBS@
+ @RDP_LIBS@ \
+ @WINPR_LIBS@
guacai_libadd = \
@COMMON_LTLIB@ \
@@ -213,7 +216,8 @@
guacsnd_ldflags = \
-module -avoid-version -shared \
@PTHREAD_LIBS@ \
- @RDP_LIBS@
+ @RDP_LIBS@ \
+ @WINPR_LIBS@
guacsnd_libadd = \
@COMMON_LTLIB@ \
@@ -232,7 +236,8 @@
guacsvc_ldflags = \
-module -avoid-version -shared \
@PTHREAD_LIBS@ \
- @RDP_LIBS@
+ @RDP_LIBS@ \
+ @WINPR_LIBS@
guacsvc_libadd = \
@COMMON_LTLIB@ \
@@ -265,6 +270,7 @@
$(srcdir)/keymaps/es_es_qwerty.keymap \
$(srcdir)/keymaps/fr_fr_azerty.keymap \
$(srcdir)/keymaps/fr_ch_qwertz.keymap \
+ $(srcdir)/keymaps/hu_hu_qwertz.keymap \
$(srcdir)/keymaps/it_it_qwerty.keymap \
$(srcdir)/keymaps/ja_jp_qwerty.keymap \
$(srcdir)/keymaps/pt_br_qwerty.keymap \
diff --git a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c
index cc367c4..45de442 100644
--- a/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c
+++ b/src/protocols/rdp/guac_rdpsnd/rdpsnd_service.c
@@ -110,35 +110,36 @@
* If next PDU is SNDWAVE (due to receiving WaveInfo PDU previously),
* ignore the header and parse as a Wave PDU.
*/
- if (rdpsnd->next_pdu_is_wave) {
+ if (rdpsnd->next_pdu_is_wave)
guac_rdpsnd_wave_handler(rdpsnd, input_stream, &header);
- return;
- }
-
+
/* Dispatch message to standard handlers */
- switch (header.message_type) {
+ else {
+ switch (header.message_type) {
- /* Server Audio Formats and Version PDU */
- case SNDC_FORMATS:
- guac_rdpsnd_formats_handler(rdpsnd, input_stream, &header);
- break;
+ /* Server Audio Formats and Version PDU */
+ case SNDC_FORMATS:
+ guac_rdpsnd_formats_handler(rdpsnd, input_stream, &header);
+ break;
- /* Training PDU */
- case SNDC_TRAINING:
- guac_rdpsnd_training_handler(rdpsnd, input_stream, &header);
- break;
+ /* Training PDU */
+ case SNDC_TRAINING:
+ guac_rdpsnd_training_handler(rdpsnd, input_stream, &header);
+ break;
- /* WaveInfo PDU */
- case SNDC_WAVE:
- guac_rdpsnd_wave_info_handler(rdpsnd, input_stream, &header);
- break;
+ /* WaveInfo PDU */
+ case SNDC_WAVE:
+ guac_rdpsnd_wave_info_handler(rdpsnd, input_stream, &header);
+ break;
- /* Close PDU */
- case SNDC_CLOSE:
- guac_rdpsnd_close_handler(rdpsnd, input_stream, &header);
- break;
+ /* Close PDU */
+ case SNDC_CLOSE:
+ guac_rdpsnd_close_handler(rdpsnd, input_stream, &header);
+ break;
+ }
}
+ Stream_Free(input_stream, TRUE);
}
diff --git a/src/protocols/rdp/keymaps/hu_hu_qwertz.keymap b/src/protocols/rdp/keymaps/hu_hu_qwertz.keymap
new file mode 100644
index 0000000..bcb6a67
--- /dev/null
+++ b/src/protocols/rdp/keymaps/hu_hu_qwertz.keymap
@@ -0,0 +1,100 @@
+#
+# 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.
+#
+
+parent "base"
+name "hu-hu-qwertz"
+freerdp "KBD_HUNGARIAN"
+
+#
+# Basic keys
+#
+
+map -altgr -shift 0x29 0x02..0x0D ~ "0123456789öüó"
+map -altgr -shift 0x10..0x1B ~ "qwertzuıopőú"
+map -altgr -shift 0x1E..0x28 0x2B ~ "asdfghjkléáű"
+map -altgr -shift 0x56 0x2C..0x35 ~ "íyxcvbnm,.-"
+
+map -altgr +shift 0x29 0x02..0x0D ~ "§'"+!%/=()ÖÜÓ"
+map -altgr +shift 0x10..0x1B ~ "QWERTZUIOPŐÚ"
+map -altgr +shift 0x1E..0x28 0x2B ~ "ASDFGHJKLÉÁŰ"
+map -altgr +shift 0x56 0x2C..0x35 ~ "ÍYXCVBNM?:_"
+
+
+#
+# Keys requiring AltGr
+#
+
+map +altgr -shift 0x02 ~ "~"
+map +altgr -shift 0x08 ~ "`"
+
+map +altgr -shift 0x10 ~ "\"
+map +altgr -shift 0x11 ~ "|"
+map +altgr -shift 0x12 ~ "Ä"
+map +altgr -shift 0x16 ~ "€"
+map +altgr -shift 0x17 ~ "Í"
+map +altgr -shift 0x1A ~ "÷"
+map +altgr -shift 0x1B ~ "×"
+
+map +altgr -shift 0x1E ~ "ä"
+map +altgr -shift 0x1F ~ "đ"
+map +altgr -shift 0x20 ~ "Đ"
+map +altgr -shift 0x21 ~ "["
+map +altgr -shift 0x22 ~ "]"
+map +altgr -shift 0x24 ~ "í"
+map +altgr -shift 0x25 ~ "ł"
+map +altgr -shift 0x26 ~ "Ł"
+map +altgr -shift 0x27 ~ "$"
+map +altgr -shift 0x28 ~ "ß"
+map +altgr -shift 0x2B ~ "¤"
+
+map +altgr -shift 0x56 ~ "<"
+map +altgr -shift 0x2C ~ ">"
+map +altgr -shift 0x2D ~ "#"
+map +altgr -shift 0x2E ~ "&"
+map +altgr -shift 0x2F ~ "@"
+map +altgr -shift 0x30 ~ "{"
+map +altgr -shift 0x31 ~ "}"
+map +altgr -shift 0x32 ~ "<"
+map +altgr -shift 0x33 ~ ";"
+map +altgr -shift 0x34 ~ ">"
+map +altgr -shift 0x35 ~ "*"
+
+
+#
+# Keys requiring AltGr & Shift
+#
+
+
+#
+# Dead keys
+#
+
+map +altgr -shift 0x03 ~ 0xFE5A # Dead caron
+map +altgr -shift 0x04 ~ 0xFE52 # Dead circumflex
+map +altgr -shift 0x05 ~ 0xFE55 # Dead breve
+map +altgr -shift 0x06 ~ 0xFE58 # Dead abovering
+map +altgr -shift 0x07 ~ 0xFE5C # Dead ogonek
+map +altgr -shift 0x09 ~ 0xFE56 # Dead abovedot
+map +altgr -shift 0x0A ~ 0xFE51 # Dead acute
+map +altgr -shift 0x0B ~ 0xFE59 # Dead doubleacute
+map +altgr -shift 0x0C ~ 0xFE57 # Dead diaeresis
+map +altgr -shift 0x0D ~ 0xFE5B # Dead cedilla
+
+
+# END
diff --git a/src/protocols/rdp/rdp.c b/src/protocols/rdp/rdp.c
index 86f5096..d0df053 100644
--- a/src/protocols/rdp/rdp.c
+++ b/src/protocols/rdp/rdp.c
@@ -240,11 +240,13 @@
guac_rdp_audio_load_plugin(instance->context, dvc_list);
}
- /* Load clipboard plugin */
- if (freerdp_channels_load_plugin(channels, instance->settings,
- "cliprdr", NULL))
+ /* Load clipboard plugin if not disabled */
+ if (!(settings->disable_copy && settings->disable_paste)
+ && freerdp_channels_load_plugin(channels, instance->settings,
+ "cliprdr", NULL)) {
guac_client_log(client, GUAC_LOG_WARNING,
"Failed to load cliprdr plugin. Clipboard will not work.");
+ }
/* If RDPSND/RDPDR required, load them */
if (settings->printing_enabled
diff --git a/src/protocols/rdp/rdp_cliprdr.c b/src/protocols/rdp/rdp_cliprdr.c
index 5301911..903752c 100644
--- a/src/protocols/rdp/rdp_cliprdr.c
+++ b/src/protocols/rdp/rdp_cliprdr.c
@@ -230,6 +230,10 @@
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
char received_data[GUAC_RDP_CLIPBOARD_MAX_LENGTH];
+ /* Ignore received text if outbound clipboard transfer is disabled */
+ if (rdp_client->settings->disable_copy)
+ return;
+
guac_iconv_read* reader;
const char* input = (char*) event->data;
char* output = received_data;
diff --git a/src/protocols/rdp/rdp_fs.c b/src/protocols/rdp/rdp_fs.c
index 0e7345f..24d7c3e 100644
--- a/src/protocols/rdp/rdp_fs.c
+++ b/src/protocols/rdp/rdp_fs.c
@@ -403,7 +403,7 @@
}
-int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, int offset,
+int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, uint64_t offset,
void* buffer, int length) {
int bytes_read;
@@ -427,7 +427,7 @@
}
-int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, int offset,
+int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, uint64_t offset,
void* buffer, int length) {
int bytes_written;
diff --git a/src/protocols/rdp/rdp_fs.h b/src/protocols/rdp/rdp_fs.h
index 7ceb5ff..e8299ef 100644
--- a/src/protocols/rdp/rdp_fs.h
+++ b/src/protocols/rdp/rdp_fs.h
@@ -492,7 +492,7 @@
* error occurs. All error codes are negative values and correspond to
* GUAC_RDP_FS constants, such as GUAC_RDP_FS_ENOENT.
*/
-int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, int offset,
+int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, uint64_t offset,
void* buffer, int length);
/**
@@ -520,7 +520,7 @@
* occurs. All error codes are negative values and correspond to
* GUAC_RDP_FS constants, such as GUAC_RDP_FS_ENOENT.
*/
-int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, int offset,
+int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, uint64_t offset,
void* buffer, int length);
/**
diff --git a/src/protocols/rdp/rdp_settings.c b/src/protocols/rdp/rdp_settings.c
index 51214a6..11cc861 100644
--- a/src/protocols/rdp/rdp_settings.c
+++ b/src/protocols/rdp/rdp_settings.c
@@ -119,6 +119,8 @@
"load-balance-info",
#endif
+ "disable-copy",
+ "disable-paste",
NULL
};
@@ -546,6 +548,20 @@
IDX_LOAD_BALANCE_INFO,
#endif
+ /**
+ * Whether outbound clipboard access should be blocked. If set to "true",
+ * it will not be possible to copy data from the remote desktop to the
+ * client using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_COPY,
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set to "true", it
+ * will not be possible to paste data from the client to the remote desktop
+ * using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_PASTE,
+
RDP_ARGS_COUNT
};
@@ -1008,6 +1024,16 @@
IDX_LOAD_BALANCE_INFO, NULL);
#endif
+ /* Parse clipboard copy disable flag */
+ settings->disable_copy =
+ guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
+ IDX_DISABLE_COPY, 0);
+
+ /* Parse clipboard paste disable flag */
+ settings->disable_paste =
+ guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
+ IDX_DISABLE_PASTE, 0);
+
/* Success */
return settings;
diff --git a/src/protocols/rdp/rdp_settings.h b/src/protocols/rdp/rdp_settings.h
index 6955ed5..9edbede 100644
--- a/src/protocols/rdp/rdp_settings.h
+++ b/src/protocols/rdp/rdp_settings.h
@@ -269,6 +269,20 @@
char** svc_names;
/**
+ * Whether outbound clipboard access should be blocked. If set, it will not
+ * be possible to copy data from the remote desktop to the client using the
+ * clipboard.
+ */
+ int disable_copy;
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set, it will not
+ * be possible to paste data from the client to the remote desktop using
+ * the clipboard.
+ */
+ int disable_paste;
+
+ /**
* Whether the desktop wallpaper should be visible. If unset, the desktop
* wallpaper will be hidden, reducing the amount of bandwidth required.
*/
diff --git a/src/protocols/rdp/rdp_stream.h b/src/protocols/rdp/rdp_stream.h
index c9c3838..deec4f9 100644
--- a/src/protocols/rdp/rdp_stream.h
+++ b/src/protocols/rdp/rdp_stream.h
@@ -57,7 +57,7 @@
* The overall offset within the file that the next write should
* occur at.
*/
- int offset;
+ uint64_t offset;
/**
* The ID of the file being written to.
diff --git a/src/protocols/rdp/user.c b/src/protocols/rdp/user.c
index 6aa71ae..025848a 100644
--- a/src/protocols/rdp/user.c
+++ b/src/protocols/rdp/user.c
@@ -97,10 +97,13 @@
/* Only handle events if not read-only */
if (!settings->read_only) {
- /* General mouse/keyboard/clipboard events */
- user->mouse_handler = guac_rdp_user_mouse_handler;
- user->key_handler = guac_rdp_user_key_handler;
- user->clipboard_handler = guac_rdp_clipboard_handler;
+ /* General mouse/keyboard events */
+ user->mouse_handler = guac_rdp_user_mouse_handler;
+ user->key_handler = guac_rdp_user_key_handler;
+
+ /* Inbound (client to server) clipboard transfer */
+ if (!settings->disable_paste)
+ user->clipboard_handler = guac_rdp_clipboard_handler;
/* Display size change events */
user->size_handler = guac_rdp_user_size_handler;
diff --git a/src/protocols/ssh/settings.c b/src/protocols/ssh/settings.c
index a0af9f9..7dab321 100644
--- a/src/protocols/ssh/settings.c
+++ b/src/protocols/ssh/settings.c
@@ -62,6 +62,8 @@
"scrollback",
"locale",
"timezone",
+ "disable-copy",
+ "disable-paste",
NULL
};
@@ -258,6 +260,20 @@
*/
IDX_TIMEZONE,
+ /**
+ * Whether outbound clipboard access should be blocked. If set to "true",
+ * it will not be possible to copy data from the terminal to the client
+ * using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_COPY,
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set to "true", it
+ * will not be possible to paste data from the client to the terminal using
+ * the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_PASTE,
+
SSH_ARGS_COUNT
};
@@ -426,6 +442,16 @@
guac_user_parse_args_string(user, GUAC_SSH_CLIENT_ARGS, argv,
IDX_TIMEZONE, user->info.timezone);
+ /* Parse clipboard copy disable flag */
+ settings->disable_copy =
+ guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
+ IDX_DISABLE_COPY, false);
+
+ /* Parse clipboard paste disable flag */
+ settings->disable_paste =
+ guac_user_parse_args_boolean(user, GUAC_SSH_CLIENT_ARGS, argv,
+ IDX_DISABLE_PASTE, false);
+
/* Parsing was successful */
return settings;
diff --git a/src/protocols/ssh/settings.h b/src/protocols/ssh/settings.h
index baa634a..bab21bd 100644
--- a/src/protocols/ssh/settings.h
+++ b/src/protocols/ssh/settings.h
@@ -156,6 +156,20 @@
int resolution;
/**
+ * Whether outbound clipboard access should be blocked. If set, it will not
+ * be possible to copy data from the terminal to the client using the
+ * clipboard.
+ */
+ bool disable_copy;
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set, it will not
+ * be possible to paste data from the client to the terminal using the
+ * clipboard.
+ */
+ bool disable_paste;
+
+ /**
* Whether SFTP is enabled.
*/
bool enable_sftp;
diff --git a/src/protocols/ssh/ssh.c b/src/protocols/ssh/ssh.c
index 456c214..8957205 100644
--- a/src/protocols/ssh/ssh.c
+++ b/src/protocols/ssh/ssh.c
@@ -223,9 +223,10 @@
/* Create terminal */
ssh_client->term = guac_terminal_create(client, ssh_client->clipboard,
- settings->max_scrollback, settings->font_name, settings->font_size,
- settings->resolution, settings->width, settings->height,
- settings->color_scheme, settings->backspace);
+ settings->disable_copy, 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 (ssh_client->term == NULL) {
diff --git a/src/protocols/ssh/user.c b/src/protocols/ssh/user.c
index ccf2447..8ea30a4 100644
--- a/src/protocols/ssh/user.c
+++ b/src/protocols/ssh/user.c
@@ -81,10 +81,13 @@
/* Only handle events if not read-only */
if (!settings->read_only) {
- /* General mouse/keyboard/clipboard events */
- user->key_handler = guac_ssh_user_key_handler;
- user->mouse_handler = guac_ssh_user_mouse_handler;
- user->clipboard_handler = guac_ssh_clipboard_handler;
+ /* General mouse/keyboard events */
+ user->key_handler = guac_ssh_user_key_handler;
+ user->mouse_handler = guac_ssh_user_mouse_handler;
+
+ /* Inbound (client to server) clipboard transfer */
+ if (!settings->disable_paste)
+ user->clipboard_handler = guac_ssh_clipboard_handler;
/* STDIN redirection */
user->pipe_handler = guac_ssh_pipe_handler;
diff --git a/src/protocols/telnet/settings.c b/src/protocols/telnet/settings.c
index 85b4fb8..e72359c 100644
--- a/src/protocols/telnet/settings.c
+++ b/src/protocols/telnet/settings.c
@@ -55,6 +55,8 @@
"scrollback",
"login-success-regex",
"login-failure-regex",
+ "disable-copy",
+ "disable-paste",
NULL
};
@@ -216,6 +218,20 @@
*/
IDX_LOGIN_FAILURE_REGEX,
+ /**
+ * Whether outbound clipboard access should be blocked. If set to "true",
+ * it will not be possible to copy data from the terminal to the client
+ * using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_COPY,
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set to "true", it
+ * will not be possible to paste data from the client to the terminal using
+ * the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_PASTE,
+
TELNET_ARGS_COUNT
};
@@ -428,6 +444,16 @@
guac_user_parse_args_string(user, GUAC_TELNET_CLIENT_ARGS, argv,
IDX_TERMINAL_TYPE, "linux");
+ /* Parse clipboard copy disable flag */
+ settings->disable_copy =
+ guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
+ IDX_DISABLE_COPY, false);
+
+ /* Parse clipboard paste disable flag */
+ settings->disable_paste =
+ guac_user_parse_args_boolean(user, GUAC_TELNET_CLIENT_ARGS, argv,
+ IDX_DISABLE_PASTE, false);
+
/* Parsing was successful */
return settings;
diff --git a/src/protocols/telnet/settings.h b/src/protocols/telnet/settings.h
index 86302b7..691669c 100644
--- a/src/protocols/telnet/settings.h
+++ b/src/protocols/telnet/settings.h
@@ -172,6 +172,20 @@
int resolution;
/**
+ * Whether outbound clipboard access should be blocked. If set, it will not
+ * be possible to copy data from the terminal to the client using the
+ * clipboard.
+ */
+ bool disable_copy;
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set, it will not
+ * be possible to paste data from the client to the terminal using the
+ * clipboard.
+ */
+ bool disable_paste;
+
+ /**
* The path in which the typescript should be saved, if enabled. If no
* typescript should be saved, this will be NULL.
*/
diff --git a/src/protocols/telnet/telnet.c b/src/protocols/telnet/telnet.c
index e100fae..5a5ca30 100644
--- a/src/protocols/telnet/telnet.c
+++ b/src/protocols/telnet/telnet.c
@@ -570,7 +570,7 @@
/* Create terminal */
telnet_client->term = guac_terminal_create(client,
- telnet_client->clipboard,
+ telnet_client->clipboard, settings->disable_copy,
settings->max_scrollback, settings->font_name, settings->font_size,
settings->resolution, settings->width, settings->height,
settings->color_scheme, settings->backspace);
diff --git a/src/protocols/telnet/user.c b/src/protocols/telnet/user.c
index 08cfc6f..63408cc 100644
--- a/src/protocols/telnet/user.c
+++ b/src/protocols/telnet/user.c
@@ -80,10 +80,13 @@
/* Only handle events if not read-only */
if (!settings->read_only) {
- /* General mouse/keyboard/clipboard events */
- user->key_handler = guac_telnet_user_key_handler;
- user->mouse_handler = guac_telnet_user_mouse_handler;
- user->clipboard_handler = guac_telnet_clipboard_handler;
+ /* General mouse/keyboard events */
+ user->key_handler = guac_telnet_user_key_handler;
+ user->mouse_handler = guac_telnet_user_mouse_handler;
+
+ /* Inbound (client to server) clipboard transfer */
+ if (!settings->disable_paste)
+ user->clipboard_handler = guac_telnet_clipboard_handler;
/* STDIN redirection */
user->pipe_handler = guac_telnet_pipe_handler;
diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c
index 9cc85a1..cee1d4d 100644
--- a/src/protocols/vnc/client.c
+++ b/src/protocols/vnc/client.c
@@ -36,6 +36,7 @@
#include <guacamole/client.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
@@ -48,6 +49,11 @@
guac_vnc_client* vnc_client = calloc(1, sizeof(guac_vnc_client));
client->data = vnc_client;
+#ifdef ENABLE_VNC_TLS_LOCKING
+ /* Initialize the write lock */
+ pthread_mutex_init(&(vnc_client->tls_lock), NULL);
+#endif
+
/* Init clipboard */
vnc_client->clipboard = guac_common_clipboard_alloc(GUAC_VNC_CLIPBOARD_MAX_LENGTH);
@@ -125,6 +131,11 @@
if (settings != NULL)
guac_vnc_settings_free(settings);
+#ifdef ENABLE_VNC_TLS_LOCKING
+ /* Clean up TLS lock mutex. */
+ pthread_mutex_destroy(&(vnc_client->tls_lock));
+#endif
+
/* Free generic data struct */
free(client->data);
diff --git a/src/protocols/vnc/clipboard.c b/src/protocols/vnc/clipboard.c
index a49f565..c3b1bd1 100644
--- a/src/protocols/vnc/clipboard.c
+++ b/src/protocols/vnc/clipboard.c
@@ -125,6 +125,10 @@
guac_client* gc = rfbClientGetClientData(client, GUAC_VNC_CLIENT_KEY);
guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
+ /* Ignore received text if outbound clipboard transfer is disabled */
+ if (vnc_client->settings->disable_copy)
+ return;
+
char received_data[GUAC_VNC_CLIPBOARD_MAX_LENGTH];
const char* input = text;
diff --git a/src/protocols/vnc/settings.c b/src/protocols/vnc/settings.c
index 623e668..a21aea8 100644
--- a/src/protocols/vnc/settings.c
+++ b/src/protocols/vnc/settings.c
@@ -77,7 +77,8 @@
"recording-exclude-mouse",
"recording-include-keys",
"create-recording-path",
-
+ "disable-copy",
+ "disable-paste",
NULL
};
@@ -298,6 +299,20 @@
*/
IDX_CREATE_RECORDING_PATH,
+ /**
+ * Whether outbound clipboard access should be blocked. If set to "true",
+ * it will not be possible to copy data from the remote desktop to the
+ * client using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_COPY,
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set to "true", it
+ * will not be possible to paste data from the client to the remote desktop
+ * using the clipboard. By default, clipboard access is not blocked.
+ */
+ IDX_DISABLE_PASTE,
+
VNC_ARGS_COUNT
};
@@ -493,6 +508,16 @@
guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
IDX_CREATE_RECORDING_PATH, false);
+ /* Parse clipboard copy disable flag */
+ settings->disable_copy =
+ guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
+ IDX_DISABLE_COPY, false);
+
+ /* Parse clipboard paste disable flag */
+ settings->disable_paste =
+ guac_user_parse_args_boolean(user, GUAC_VNC_CLIENT_ARGS, argv,
+ IDX_DISABLE_PASTE, false);
+
return settings;
}
diff --git a/src/protocols/vnc/settings.h b/src/protocols/vnc/settings.h
index 3e2ebd5..13a3d87 100644
--- a/src/protocols/vnc/settings.h
+++ b/src/protocols/vnc/settings.h
@@ -127,6 +127,20 @@
*/
char* clipboard_encoding;
+ /**
+ * Whether outbound clipboard access should be blocked. If set, it will not
+ * be possible to copy data from the remote desktop to the client using the
+ * clipboard.
+ */
+ bool disable_copy;
+
+ /**
+ * Whether inbound clipboard access should be blocked. If set, it will not
+ * be possible to paste data from the client to the remote desktop using
+ * the clipboard.
+ */
+ bool disable_paste;
+
#ifdef ENABLE_COMMON_SSH
/**
* Whether SFTP should be enabled for the VNC connection.
diff --git a/src/protocols/vnc/user.c b/src/protocols/vnc/user.c
index da3b843..0dee504 100644
--- a/src/protocols/vnc/user.c
+++ b/src/protocols/vnc/user.c
@@ -91,10 +91,13 @@
/* Only handle events if not read-only */
if (!settings->read_only) {
- /* General mouse/keyboard/clipboard events */
- user->mouse_handler = guac_vnc_user_mouse_handler;
- user->key_handler = guac_vnc_user_key_handler;
- user->clipboard_handler = guac_vnc_clipboard_handler;
+ /* General mouse/keyboard events */
+ user->mouse_handler = guac_vnc_user_mouse_handler;
+ user->key_handler = guac_vnc_user_key_handler;
+
+ /* Inbound (client to server) clipboard transfer */
+ if (!settings->disable_paste)
+ user->clipboard_handler = guac_vnc_clipboard_handler;
#ifdef ENABLE_COMMON_SSH
/* Set generic (non-filesystem) file upload handler */
diff --git a/src/protocols/vnc/vnc.c b/src/protocols/vnc/vnc.c
index afffaac..17033a6 100644
--- a/src/protocols/vnc/vnc.c
+++ b/src/protocols/vnc/vnc.c
@@ -55,6 +55,66 @@
char* GUAC_VNC_CLIENT_KEY = "GUAC_VNC";
+#ifdef ENABLE_VNC_TLS_LOCKING
+/**
+ * A callback function that is called by the VNC library prior to writing
+ * data to a TLS-encrypted socket. This returns the rfbBool FALSE value
+ * if there's an error locking the mutex, or rfbBool TRUE otherwise.
+ *
+ * @param rfb_client
+ * The rfbClient for which to lock the TLS mutex.
+ *
+ * @returns
+ * rfbBool FALSE if an error occurs locking the mutex, otherwise
+ * TRUE.
+ */
+static rfbBool guac_vnc_lock_write_to_tls(rfbClient* rfb_client) {
+
+ /* Retrieve the Guacamole data structures */
+ guac_client* gc = rfbClientGetClientData(rfb_client, GUAC_VNC_CLIENT_KEY);
+ guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
+
+ /* Lock write access */
+ int retval = pthread_mutex_lock(&(vnc_client->tls_lock));
+ if (retval) {
+ guac_client_log(gc, GUAC_LOG_ERROR, "Error locking TLS write mutex: %s",
+ strerror(retval));
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+/**
+ * A callback function for use by the VNC library that is called once
+ * the client is finished writing to a TLS-encrypted socket. A rfbBool
+ * FALSE value is returned if an error occurs unlocking the mutex,
+ * otherwise TRUE is returned.
+ *
+ * @param rfb_client
+ * The rfbClient for which to unlock the TLS mutex.
+ *
+ * @returns
+ * rfbBool FALSE if an error occurs unlocking the mutex, otherwise
+ * TRUE.
+ */
+static rfbBool guac_vnc_unlock_write_to_tls(rfbClient* rfb_client) {
+
+ /* Retrieve the Guacamole data structures */
+ guac_client* gc = rfbClientGetClientData(rfb_client, GUAC_VNC_CLIENT_KEY);
+ guac_vnc_client* vnc_client = (guac_vnc_client*) gc->data;
+
+ /* Unlock write access */
+ int retval = pthread_mutex_unlock(&(vnc_client->tls_lock));
+ if (retval) {
+ guac_client_log(gc, GUAC_LOG_ERROR, "Error unlocking TLS write mutex: %s",
+ strerror(retval));
+ return FALSE;
+ }
+ return TRUE;
+}
+#endif
+
rfbClient* guac_vnc_get_client(guac_client* client) {
rfbClient* rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */
@@ -68,6 +128,12 @@
rfb_client->GotFrameBufferUpdate = guac_vnc_update;
rfb_client->GotCopyRect = guac_vnc_copyrect;
+#ifdef ENABLE_VNC_TLS_LOCKING
+ /* TLS Locking and Unlocking */
+ rfb_client->LockWriteToTLS = guac_vnc_lock_write_to_tls;
+ rfb_client->UnlockWriteToTLS = guac_vnc_unlock_write_to_tls;
+#endif
+
/* Do not handle clipboard and local cursor if read-only */
if (vnc_settings->read_only == 0) {
@@ -403,4 +469,3 @@
return NULL;
}
-
diff --git a/src/protocols/vnc/vnc.h b/src/protocols/vnc/vnc.h
index ce2d20a..7c189cf 100644
--- a/src/protocols/vnc/vnc.h
+++ b/src/protocols/vnc/vnc.h
@@ -55,6 +55,13 @@
*/
pthread_t client_thread;
+#ifdef ENABLE_VNC_TLS_LOCKING
+ /**
+ * The TLS mutex lock for the client.
+ */
+ pthread_mutex_t tls_lock;
+#endif
+
/**
* The underlying VNC client.
*/
diff --git a/src/terminal/select.c b/src/terminal/select.c
index 20fc3cd..0a075eb 100644
--- a/src/terminal/select.c
+++ b/src/terminal/select.c
@@ -375,8 +375,10 @@
}
/* Send data */
- guac_common_clipboard_send(terminal->clipboard, client);
- guac_socket_flush(socket);
+ if (!terminal->disable_copy) {
+ guac_common_clipboard_send(terminal->clipboard, client);
+ guac_socket_flush(socket);
+ }
guac_terminal_notify(terminal);
diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c
index 05bf720..b76a6ea 100644
--- a/src/terminal/terminal.c
+++ b/src/terminal/terminal.c
@@ -306,8 +306,8 @@
}
guac_terminal* guac_terminal_create(guac_client* client,
- guac_common_clipboard* clipboard, int max_scrollback,
- const char* font_name, int font_size, int dpi,
+ guac_common_clipboard* clipboard, bool disable_copy,
+ int max_scrollback, const char* font_name, int font_size, int dpi,
int width, int height, const char* color_scheme,
const int backspace) {
@@ -392,6 +392,7 @@
term->current_attributes = default_char.attributes;
term->default_char = default_char;
term->clipboard = clipboard;
+ term->disable_copy = disable_copy;
/* Calculate character size */
int rows = height / term->display->char_height;
diff --git a/src/terminal/terminal/terminal.h b/src/terminal/terminal/terminal.h
index e7746cb..4185837 100644
--- a/src/terminal/terminal/terminal.h
+++ b/src/terminal/terminal/terminal.h
@@ -530,6 +530,14 @@
*/
char backspace;
+ /**
+ * Whether copying from the terminal clipboard should be blocked. If set,
+ * the contents of the terminal can still be copied, but will be usable
+ * only within the terminal itself. The clipboard contents will not be
+ * automatically streamed to the client.
+ */
+ bool disable_copy;
+
};
/**
@@ -552,6 +560,12 @@
* clipboard instructions. This clipboard will not be automatically
* freed when this terminal is freed.
*
+ * @param disable_copy
+ * Whether copying from the terminal clipboard should be blocked. If set,
+ * the contents of the terminal can still be copied, but will be usable
+ * only within the terminal itself. The clipboard contents will not be
+ * automatically streamed to the client.
+ *
* @param max_scrollback
* The maximum number of rows to allow within the scrollback buffer. The
* user may still alter the size of the scrollback buffer using terminal
@@ -591,8 +605,8 @@
* which renders all text to the given client.
*/
guac_terminal* guac_terminal_create(guac_client* client,
- guac_common_clipboard* clipboard, int max_scrollback,
- const char* font_name, int font_size, int dpi,
+ guac_common_clipboard* clipboard, bool disable_copy,
+ int max_scrollback, const char* font_name, int font_size, int dpi,
int width, int height, const char* color_scheme,
const int backspace);