[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