From 305b06d7fdc0f45c071846627822f0dcb23dfc5a Mon Sep 17 00:00:00 2001 From: gpatel-fr <44170243+gpatel-fr@users.noreply.github.com> Date: Thu, 18 Oct 2018 17:35:02 +0200 Subject: [PATCH] Add TLS 1.1 and 1.2 support --- doc/rdesktop.1 | 4 ++++ rdesktop.c | 10 ++++++++-- tcp.c | 22 ++++++++++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/doc/rdesktop.1 b/doc/rdesktop.1 index 60b5c11..d5d8fd7 100644 --- a/doc/rdesktop.1 +++ b/doc/rdesktop.1 @@ -115,6 +115,10 @@ Any subsequential call to the above command line example will make use of the se connection sharing feature which spawns another notepad in the current connection to the specified server and then exit. +.TP +.BR "-V " +Set the Transport Level Security (also known as SSL) Version used. +Should be one of the following values: 1.0, 1.1, 1.2. If the option is missing 1.0 is assumed. .TP .BR "-B" Use the BackingStore of the Xserver instead of the integrated one in diff --git a/rdesktop.c b/rdesktop.c index d625d2e..a06c1a3 100644 --- a/rdesktop.c +++ b/rdesktop.c @@ -113,6 +113,7 @@ RD_BOOL g_seamless_rdp = False; RD_BOOL g_use_password_as_pin = False; char g_seamless_shell[512]; char g_seamless_spawn_cmd[512]; +char g_tls_version[4]; RD_BOOL g_seamless_persistent_mode = True; RD_BOOL g_user_quit = False; uint32 g_embed_wnd; @@ -184,6 +185,7 @@ usage(char *program) fprintf(stderr, " -b: force bitmap updates\n"); fprintf(stderr, " -L: local codepage\n"); fprintf(stderr, " -A: path to SeamlessRDP shell, this enables SeamlessRDP mode\n"); + fprintf(stderr, " -V: tls version (1.0, 1.1, 1.2, defaults to 1.0)\n"); fprintf(stderr, " -B: use BackingStore of X-server (if available)\n"); fprintf(stderr, " -e: disable encryption (French TS)\n"); fprintf(stderr, " -E: disable encryption from client to server\n"); @@ -805,13 +807,13 @@ main(int argc, char *argv[]) flags = RDP_INFO_MOUSE | RDP_INFO_DISABLECTRLALTDEL | RDP_INFO_UNICODE | RDP_INFO_MAXIMIZESHELL | RDP_INFO_ENABLEWINDOWSKEY; - g_seamless_spawn_cmd[0] = domain[0] = g_password[0] = shell[0] = directory[0] = 0; + g_seamless_spawn_cmd[0] = g_tls_version[0] = domain[0] = g_password[0] = shell[0] = directory[0] = 0; g_embed_wnd = 0; g_num_devices = 0; while ((c = getopt(argc, argv, - "A:u:L:d:s:c:p:n:k:g:o:fbBeEitmMzCDKS:T:NX:a:x:Pr:045vh?")) != -1) + "A:V:u:L:d:s:c:p:n:k:g:o:fbBeEitmMzCDKS:T:NX:a:x:Pr:045vh?")) != -1) { switch (c) { @@ -820,6 +822,10 @@ main(int argc, char *argv[]) STRNCPY(g_seamless_shell, optarg, sizeof(g_seamless_shell)); break; + case 'V': + STRNCPY(g_tls_version, optarg, sizeof(g_tls_version)); + break; + case 'u': g_username = (char *) xmalloc(strlen(optarg) + 1); STRNCPY(g_username, optarg, strlen(optarg) + 1); diff --git a/tcp.c b/tcp.c index 1db56f2..9bde3e8 100644 --- a/tcp.c +++ b/tcp.c @@ -77,6 +77,7 @@ int g_tcp_port_rdp = TCP_PORT_RDP; extern RD_BOOL g_exit_mainloop; extern RD_BOOL g_network_error; extern RD_BOOL g_reconnect_loop; +extern char g_tls_version[]; /* wait till socket is ready to write or timeout */ static RD_BOOL @@ -316,11 +317,28 @@ tcp_tls_connect(void) /* create process context */ if (g_ssl_ctx == NULL) { - g_ssl_ctx = SSL_CTX_new(TLSv1_client_method()); + + const SSL_METHOD *(*tlsmeth) (void) = NULL; + if (g_tls_version[0] == 0) + tlsmeth = TLSv1_method; + else if (!strcmp(g_tls_version, "1.0")) + tlsmeth = TLSv1_method; + else if (!strcmp(g_tls_version, "1.1")) + tlsmeth = TLSv1_1_method; + else if (!strcmp(g_tls_version, "1.2")) + tlsmeth = TLSv1_2_method; + if (tlsmeth == NULL) + { + logger(Core, Error, + "tcp_tls_connect(), TLS method should be 1.0, 1.1, or 1.2\n"); + goto fail; + } + + g_ssl_ctx = SSL_CTX_new(tlsmeth()); if (g_ssl_ctx == NULL) { logger(Core, Error, - "tcp_tls_connect(), SSL_CTX_new() failed to create TLS v1.0 context\n"); + "tcp_tls_connect(), SSL_CTX_new() failed to create TLS v1.x context\n"); goto fail; }