[pkg-remote-commits] [xrdp] 02/02: Backport fix for CVE-2013-1430.
Dominik George
natureshadow-guest at moszumanska.debian.org
Sun Jan 1 19:53:03 UTC 2017
This is an automated email from the git hooks/post-receive script.
natureshadow-guest pushed a commit to branch jessie
in repository xrdp.
commit d37da507ff36e588ac2c4d1853db36b758cb8a4f
Author: Dominik George <nik at naturalnet.de>
Date: Sun Jan 1 20:43:57 2017 +0100
Backport fix for CVE-2013-1430.
---
debian/changelog | 7 +
debian/patches/cve-2013-1430.patch | 425 +++++++++++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 433 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index b013cb4..a9479d2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+xrdp (0.6.1-2+deb8u1) jessie-security; urgency=high
+
+ * Security fix for CVE-2013-1430.
+ + Backported from 0.9.1.
+
+ -- Dominik George <nik at naturalnet.de> Sun, 01 Jan 2017 20:43:07 +0100
+
xrdp (0.6.1-2) unstable; urgency=medium
[ Johannes Schauer ]
diff --git a/debian/patches/cve-2013-1430.patch b/debian/patches/cve-2013-1430.patch
new file mode 100644
index 0000000..9ecd689
--- /dev/null
+++ b/debian/patches/cve-2013-1430.patch
@@ -0,0 +1,425 @@
+Subject: Backport of fix for CVE-2013-1430 from 0.9.1 to 0.6.1
+ Fixes insecure VNC password file, which contained the user password
+ encrypted with a known DES key.
+From: Dominik George <nik at naturalnet.de>
+--- a/sesman/scp_v0.c
++++ b/sesman/scp_v0.c
+@@ -61,6 +61,11 @@ scp_v0_process(struct SCP_CONNECTION* c,
+ LOG_DBG(&(g_cfg->log), "pre auth");
+ if (1 == access_login_allowed(s->username))
+ {
++ tui8 guid[16];
++
++ g_random((char*)guid, 16);
++ scp_session_set_guid(s, guid);
++
+ if (0 != s->client_ip)
+ {
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
+@@ -75,14 +80,14 @@ scp_v0_process(struct SCP_CONNECTION* c,
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ display = session_start(s->width, s->height, s->bpp, s->username,
+ s->password, data, SESMAN_SESSION_TYPE_XVNC,
+- s->domain, s->program, s->directory, s->client_ip);
++ s->domain, s->program, s->directory, s->client_ip, s->guid);
+ }
+ else
+ {
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ display = session_start(s->width, s->height, s->bpp, s->username,
+ s->password, data, SESMAN_SESSION_TYPE_XRDP,
+- s->domain, s->program, s->directory, s->client_ip);
++ s->domain, s->program, s->directory, s->client_ip, s->guid);
+ }
+ }
+ else
+@@ -97,7 +102,7 @@ scp_v0_process(struct SCP_CONNECTION* c,
+ }
+ else
+ {
+- scp_v0s_allow_connection(c, display);
++ scp_v0s_allow_connection(c, display, s->guid);
+ }
+ }
+ else
+--- a/sesman/libscp/libscp_v0.h
++++ b/sesman/libscp/libscp_v0.h
+@@ -62,7 +62,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c,
+ *
+ */
+ enum SCP_SERVER_STATES_E
+-scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d);
++scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d, const tui8* guid);
+
+ /**
+ *
+--- a/sesman/libscp/libscp_v0.c
++++ b/sesman/libscp/libscp_v0.c
+@@ -289,13 +289,20 @@ scp_v0s_accept(struct SCP_CONNECTION* c,
+
+ /******************************************************************************/
+ enum SCP_SERVER_STATES_E
+-scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d)
++scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d, const tui8* guid)
+ {
++ int msg_size;
++
++ msg_size = guid == 0 ? 14 : 14 + 16;
+ out_uint32_be(c->out_s, 0); /* version */
+- out_uint32_be(c->out_s, 14); /* size */
++ out_uint32_be(c->out_s, msg_size); /* size */
+ out_uint16_be(c->out_s, 3); /* cmd */
+ out_uint16_be(c->out_s, 1); /* data */
+ out_uint16_be(c->out_s, d); /* data */
++ if (msg_size > 14)
++ {
++ out_uint8a(c->out_s, guid, 16);
++ }
+ s_mark_end(c->out_s);
+
+ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+--- a/sesman/libscp/libscp_types.h
++++ b/sesman/libscp/libscp_types.h
+@@ -87,6 +87,7 @@ struct SCP_SESSION
+ char* program;
+ char* directory;
+ char* client_ip;
++ tui8 guid[16];
+ };
+
+ struct SCP_DISCONNECTED_SESSION
+--- a/sesman/libscp/libscp_session.h
++++ b/sesman/libscp/libscp_session.h
+@@ -92,6 +92,9 @@ scp_session_set_display(struct SCP_SESSI
+ int
+ scp_session_set_errstr(struct SCP_SESSION* s, char* str);
+
++int
++scp_session_set_guid(struct SCP_SESSION* s, const tui8* guid);
++
+ /**
+ *
+ * @brief destroys a session object
+--- a/sesman/libscp/libscp_session.c
++++ b/sesman/libscp/libscp_session.c
+@@ -393,6 +393,21 @@ scp_session_set_addr(struct SCP_SESSION*
+ }
+
+ /*******************************************************************/
++int
++scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid)
++{
++ if (0 == guid)
++ {
++ log_message(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__);
++ return 1;
++ }
++
++ g_memcpy(s->guid, guid, 16);
++
++ return 0;
++}
++
++/*******************************************************************/
+ void
+ scp_session_destroy(struct SCP_SESSION* s)
+ {
+--- a/sesman/scp_v1.c
++++ b/sesman/scp_v1.c
+@@ -120,14 +120,14 @@ scp_v1_process(struct SCP_CONNECTION* c,
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting Xvnc session...");
+ display = session_start(s->width, s->height, s->bpp, s->username,
+ s->password, data, SESMAN_SESSION_TYPE_XVNC,
+- s->domain, s->program, s->directory, s->client_ip);
++ s->domain, s->program, s->directory, s->client_ip, s->guid);
+ }
+ else
+ {
+ log_message(&(g_cfg->log), LOG_LEVEL_INFO, "starting X11rdp session...");
+ display = session_start(s->width, s->height, s->bpp, s->username,
+ s->password, data, SESMAN_SESSION_TYPE_XRDP,
+- s->domain, s->program, s->directory, s->client_ip);
++ s->domain, s->program, s->directory, s->client_ip, s->guid);
+ }
+
+ e = scp_v1s_connect_new_session(c, display);
+--- a/sesman/session.c
++++ b/sesman/session.c
+@@ -46,6 +46,7 @@ static char* g_sync_domain;
+ static char* g_sync_program;
+ static char* g_sync_directory;
+ static char* g_sync_client_ip;
++static const tui8* g_sync_guid;
+ static tbus g_sync_data;
+ static tui8 g_sync_type;
+ static int g_sync_result;
+@@ -318,7 +319,7 @@ wait_for_xserver(int display)
+ static int APP_CC
+ session_start_fork(int width, int height, int bpp, char* username,
+ char* password, tbus data, tui8 type, char* domain,
+- char* program, char* directory, char* client_ip)
++ char* program, char* directory, char* client_ip, const tui8* guid)
+ {
+ int display = 0;
+ int pid = 0;
+@@ -476,7 +477,20 @@ session_start_fork(int width, int height
+ else if (xpid == 0) /* child */
+ {
+ env_set_user(username, passwd_file, display);
+- env_check_password_file(passwd_file, password);
++ if (guid != 0)
++ {
++ char guid_str[64];
++ char *pguid_str;
++ int index;
++ pguid_str = guid_str;
++ for (index = 0; index < 16; index++)
++ {
++ g_snprintf(pguid_str, 4, "%2.2x", guid[index]);
++ pguid_str += 2;
++ }
++ guid_str[32] = 0;
++ env_check_password_file(passwd_file, guid_str);
++ }
+ if (type == SESMAN_SESSION_TYPE_XVNC)
+ {
+ xserver_params = list_create();
+@@ -597,7 +611,7 @@ session_start_fork(int width, int height
+ int DEFAULT_CC
+ session_start(int width, int height, int bpp, char* username, char* password,
+ long data, tui8 type, char* domain, char* program,
+- char* directory, char* client_ip)
++ char* directory, char* client_ip, const tui8* guid)
+ {
+ int display;
+
+@@ -613,6 +627,7 @@ session_start(int width, int height, int
+ g_sync_program = program;
+ g_sync_directory = directory;
+ g_sync_client_ip = client_ip;
++ g_sync_guid = guid;
+ g_sync_data = data;
+ g_sync_type = type;
+ /* set event for main thread to see */
+@@ -634,7 +649,7 @@ session_sync_start(void)
+ g_sync_result = session_start_fork(g_sync_width, g_sync_height, g_sync_bpp,
+ g_sync_username, g_sync_password,
+ g_sync_data, g_sync_type, g_sync_domain,
+- g_sync_program, g_sync_directory, g_sync_client_ip);
++ g_sync_program, g_sync_directory, g_sync_client_ip, g_sync_guid);
+ lock_sync_sem_release();
+ return 0;
+ }
+--- a/sesman/session.h
++++ b/sesman/session.h
+@@ -105,7 +105,7 @@ session_get_bydata(char* name, int width
+ int DEFAULT_CC
+ session_start(int width, int height, int bpp, char* username, char* password,
+ long data, tui8 type, char* domain, char* program,
+- char* directory, char* client_ip);
++ char* directory, char* client_ip, const tui8* guid);
+
+ /**
+ *
+--- a/vnc/vnc.c
++++ b/vnc/vnc.c
+@@ -21,20 +21,56 @@
+ */
+
+ #include "vnc.h"
++#include "ssl_calls.h"
+
+ /******************************************************************************/
+ /* taken from vncauth.c */
+-void DEFAULT_CC
+-rfbEncryptBytes(char* bytes, char* passwd)
++/* performing the des3 crypt on the password so it can not be seen
++ on the wire
++ 'bytes' in, contains 16 bytes server random
++ out, random and 'passwd' conbined */
++static void APP_CC
++rfbEncryptBytes(char *bytes, const char *passwd)
+ {
+- char key[12];
++ char key[24];
++ void *des;
++ int len;
+
+ /* key is simply password padded with nulls */
+ g_memset(key, 0, sizeof(key));
+- g_strncpy(key, passwd, 8);
+- rfbDesKey((unsigned char*)key, EN0); /* 0, encrypt */
+- rfbDes((unsigned char*)bytes, (unsigned char*)bytes);
+- rfbDes((unsigned char*)(bytes + 8), (unsigned char*)(bytes + 8));
++ len = MIN(g_strlen(passwd), 8);
++ g_mirror_memcpy(key, passwd, len);
++ des = ssl_des3_encrypt_info_create(key, 0);
++ ssl_des3_encrypt(des, 8, bytes, bytes);
++ ssl_des3_info_delete(des);
++ des = ssl_des3_encrypt_info_create(key, 0);
++ ssl_des3_encrypt(des, 8, bytes + 8, bytes + 8);
++ ssl_des3_info_delete(des);
++}
++
++/******************************************************************************/
++/* sha1 hash 'passwd', create a string from the hash and call rfbEncryptBytes */
++static void APP_CC
++rfbHashEncryptBytes(char *bytes, const char *passwd)
++{
++ char passwd_hash[20];
++ char passwd_hash_text[40];
++ void *sha1;
++ int passwd_bytes;
++
++ /* create password hash from password */
++ passwd_bytes = g_strlen(passwd);
++ sha1 = ssl_sha1_info_create();
++ ssl_sha1_transform(sha1, "xrdp_vnc", 8);
++ ssl_sha1_transform(sha1, passwd, passwd_bytes);
++ ssl_sha1_transform(sha1, passwd, passwd_bytes);
++ ssl_sha1_complete(sha1, passwd_hash);
++ ssl_sha1_info_delete(sha1);
++ g_snprintf(passwd_hash_text, 39, "%2.2x%2.2x%2.2x%2.2x",
++ (tui8)passwd_hash[0], (tui8)passwd_hash[1],
++ (tui8)passwd_hash[2], (tui8)passwd_hash[3]);
++ passwd_hash_text[39] = 0;
++ rfbEncryptBytes(bytes, passwd_hash_text);
+ }
+
+ /******************************************************************************/
+@@ -904,7 +940,24 @@ connections", 0);
+ error = lib_recv(v, s->data, 16);
+ if (error == 0)
+ {
+- rfbEncryptBytes(s->data, v->password);
++ if (v->got_guid)
++ {
++ char guid_str[64];
++ char *pguid_str;
++ int index;
++ pguid_str = guid_str;
++ for (index = 0; index < 16; index++)
++ {
++ g_snprintf(pguid_str, 4, "%2.2x", v->guid[index]);
++ pguid_str += 2;
++ }
++ guid_str[32] = 0;
++ rfbHashEncryptBytes(s->data, guid_str);
++ }
++ else
++ {
++ rfbEncryptBytes(s->data, v->password);
++ }
+ error = lib_send(v, s->data, 16);
+ }
+ }
+@@ -1161,6 +1214,11 @@ lib_mod_set_param(struct vnc* v, char* n
+ {
+ v->keylayout = g_atoi(value);
+ }
++ else if (g_strcasecmp(name, "guid") == 0)
++ {
++ v->got_guid = 1;
++ g_memcpy(v->guid, value, 16);
++ }
+ return 0;
+ }
+
+--- a/vnc/vnc.h
++++ b/vnc/vnc.h
+@@ -117,4 +117,6 @@ struct vnc
+ char* clip_data;
+ int clip_data_size;
+ tbus sck_obj;
++ int got_guid;
++ tui8 guid[16];
+ };
+--- a/xrdp/xrdp_mm.c
++++ b/xrdp/xrdp_mm.c
+@@ -364,7 +364,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
+
+ /*****************************************************************************/
+ static int APP_CC
+-xrdp_mm_setup_mod2(struct xrdp_mm* self)
++xrdp_mm_setup_mod2(struct xrdp_mm* self, tui8* guid)
+ {
+ char text[256];
+ char* name;
+@@ -419,6 +419,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm* self)
+ self->mod->mod_set_param(self->mod, "hostname", name);
+ g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout);
+ self->mod->mod_set_param(self->mod, "keylayout", text);
++ if (guid != 0)
++ {
++ self->mod->mod_set_param(self->mod, "guid", (char*)guid);
++ }
+ for (i = 0; i < self->login_names->count; i++)
+ {
+ name = (char*)list_get_item(self->login_names, i);
+@@ -677,13 +681,22 @@ xrdp_mm_process_login_response(struct xr
+ char text[256];
+ char ip[256];
+ char port[256];
++ tui8 guid[16];
++ tui8* pguid;
+
+ g_memset(text,0,sizeof(char) * 256);
+ g_memset(ip,0,sizeof(char) * 256);
+ g_memset(port,0,sizeof(char) * 256);
++ g_memset(guid,0,sizeof(tui8) * 16);
+ rv = 0;
+ in_uint16_be(s, ok);
+ in_uint16_be(s, display);
++ pguid = 0;
++ if (s_check_rem(s, 16))
++ {
++ in_uint8a(s, guid, 16);
++ pguid = guid;
++ }
+ if (ok)
+ {
+ self->display = display;
+@@ -692,7 +705,7 @@ xrdp_mm_process_login_response(struct xr
+ xrdp_wm_log_msg(self->wm, text);
+ if (xrdp_mm_setup_mod1(self) == 0)
+ {
+- if (xrdp_mm_setup_mod2(self) == 0)
++ if (xrdp_mm_setup_mod2(self, pguid) == 0)
+ {
+ xrdp_mm_get_value(self, "ip", ip, 255);
+ xrdp_wm_set_login_mode(self->wm, 10);
+@@ -987,7 +1000,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
+ {
+ if (xrdp_mm_setup_mod1(self) == 0)
+ {
+- if (xrdp_mm_setup_mod2(self) == 0)
++ if (xrdp_mm_setup_mod2(self, pguid) == 0)
+ {
+ xrdp_wm_set_login_mode(self->wm, 10);
+ }
+--- a/sesman/env.c
++++ b/sesman/env.c
+@@ -103,9 +103,21 @@ env_set_user(char* username, char* passw
+ if (0 == g_cfg->auth_file_path)
+ {
+ /* if no auth_file_path is set, then we go for
+- $HOME/.vnc/sesman_username_passwd */
++ $HOME/.vnc/sesman_username_passwd:DISPLAY */
+ g_mkdir(".vnc");
+- g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
++
++ /* Try legacy name first, remove if found */
++ g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd",
++ pw_dir, username);
++ if (g_file_exist(*passwd_file))
++ {
++ log_message(LOG_LEVEL_WARNING, "Removing insecure "
++ "password file %s", *passwd_file);
++ g_file_delete(*passwd_file);
++ }
++
++ g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d",
++ pw_dir, username, display);
+ }
+ else
+ {
diff --git a/debian/patches/series b/debian/patches/series
index 055dcd7..c682a0f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -5,3 +5,4 @@
10-km-0414.patch
xrdp-default-keymap.patch
libtoolize_check.patch
+cve-2013-1430.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-remote/xrdp.git
More information about the pkg-remote-commits
mailing list