From 57905d71ada103ae397e441e2c14b6f64c365a69 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sat, 3 Dec 2016 23:12:48 -0800 Subject: [PATCH] vnc: change password file to use guid hash --- sesman/libscp/libscp_session.c | 15 ++++++ sesman/libscp/libscp_session.h | 3 ++ sesman/libscp/libscp_types.h | 1 + sesman/libscp/libscp_v0.c | 11 ++++- sesman/libscp/libscp_v0.h | 2 +- sesman/scp_v0.c | 22 ++++----- sesman/scp_v1.c | 8 +--- sesman/session.c | 83 ++++++++++++++++++---------------- sesman/session.h | 4 +- vnc/vnc.c | 67 ++++++++++++++++++++------- vnc/vnc.h | 2 + xrdp/xrdp_mm.c | 19 ++++++-- 12 files changed, 153 insertions(+), 84 deletions(-) diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 210414c3..527d6d29 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -415,6 +415,21 @@ scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr) return 0; } +/*******************************************************************/ +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) diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index 51b6d03e..9b92d3dd 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -91,6 +91,9 @@ scp_session_set_display(struct SCP_SESSION* s, SCP_DISPLAY display); int scp_session_set_errstr(struct SCP_SESSION* s, const char *str); +int +scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid); + /** * * @brief destroys a session object diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 78d53e56..8cb9166c 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -88,6 +88,7 @@ struct SCP_SESSION char* program; char* directory; char* client_ip; + tui8 guid[16]; }; struct SCP_DISCONNECTED_SESSION diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index 7fbdd2e8..93f9e072 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -364,13 +364,20 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) /******************************************************************************/ 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)) diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h index 16e49e05..21fc16cd 100644 --- a/sesman/libscp/libscp_v0.h +++ b/sesman/libscp/libscp_v0.h @@ -61,7 +61,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); * */ 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); /** * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index 565dacb8..0b913a09 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -99,6 +99,11 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) 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(LOG_LEVEL_INFO, "++ created session (access granted): " @@ -113,27 +118,18 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) if (SCP_SESSION_TYPE_XVNC == s->type) { log_message( 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); + display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); } else if (SCP_SESSION_TYPE_XRDP == s->type) { log_message(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); + display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); } else if (SCP_SESSION_TYPE_XORG == s->type) { /* type is SCP_SESSION_TYPE_XORG */ log_message(LOG_LEVEL_INFO, "starting Xorg session..."); - display = session_start(s->width, s->height, s->bpp, s->username, - s->password, data, SESMAN_SESSION_TYPE_XORG, - s->domain, s->program, s->directory, - s->client_ip); + display = session_start(data, SESMAN_SESSION_TYPE_XORG, s); } } else @@ -148,7 +144,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) } else { - scp_v0s_allow_connection(c, display); + scp_v0s_allow_connection(c, display, s->guid); } } else diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index df138147..36e3892f 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -122,16 +122,12 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s) if (SCP_SESSION_TYPE_XVNC == s->type) { log_message(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); + display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); } else { log_message(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); + display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); } e = scp_v1s_connect_new_session(c, display); diff --git a/sesman/session.c b/sesman/session.c index 581af1ae..778e8b4c 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -408,9 +408,7 @@ wait_for_xserver(int display) /******************************************************************************/ /* called with the main thread */ 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) +session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) { int display = 0; int pid = 0; @@ -445,7 +443,7 @@ session_start_fork(int width, int height, int bpp, char *username, if (g_session_count >= g_cfg->sess.max_sessions) { log_message(LOG_LEVEL_INFO, "max concurrent session limit " - "exceeded. login for user %s denied", username); + "exceeded. login for user %s denied", s->username); return 0; } @@ -454,7 +452,7 @@ session_start_fork(int width, int height, int bpp, char *username, if (temp == 0) { log_message(LOG_LEVEL_ERROR, "cannot create new chain " - "element - user %s", username); + "element - user %s", s->username); return 0; } @@ -464,7 +462,7 @@ session_start_fork(int width, int height, int bpp, char *username, { g_free(temp); log_message(LOG_LEVEL_ERROR, "cannot create new session " - "item - user %s", username); + "item - user %s", s->username); return 0; } @@ -487,8 +485,8 @@ session_start_fork(int width, int height, int bpp, char *username, { g_delete_wait_obj(g_term_event); g_tcp_close(g_sck); - g_sprintf(geometry, "%dx%d", width, height); - g_sprintf(depth, "%d", bpp); + g_sprintf(geometry, "%dx%d", s->width, s->height); + g_sprintf(depth, "%d", s->bpp); g_sprintf(screen, ":%d", display); #ifdef __FreeBSD__ /* @@ -543,7 +541,7 @@ session_start_fork(int width, int height, int bpp, char *username, } else if (pampid == 0) { - env_set_user(username, + env_set_user(s->username, 0, display, g_cfg->session_variables1, @@ -551,21 +549,21 @@ session_start_fork(int width, int height, int bpp, char *username, if (x_server_running(display)) { auth_set_env(data); - if (directory != 0) + if (s->directory != 0) { - if (directory[0] != 0) + if (s->directory[0] != 0) { - g_set_current_dir(directory); + g_set_current_dir(s->directory); } } - if (program != 0) + if (s->program != 0) { - if (program[0] != 0) + if (s->program[0] != 0) { - g_execlp3(program, program, 0); + g_execlp3(s->program, s->program, 0); log_message(LOG_LEVEL_ALWAYS, "error starting program %s for user %s - pid %d", - program, username, g_getpid()); + s->program, s->username, g_getpid()); } } /* try to execute user window manager if enabled */ @@ -576,7 +574,7 @@ session_start_fork(int width, int height, int bpp, char *username, { g_execlp3(text, g_cfg->user_wm, 0); log_message(LOG_LEVEL_ALWAYS, "error starting user " - "wm for user %s - pid %d", username, g_getpid()); + "wm for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ log_message(LOG_LEVEL_DEBUG, "errno: %d, " "description: %s", g_get_errno(), g_get_strerror()); @@ -594,7 +592,7 @@ session_start_fork(int width, int height, int bpp, char *username, g_execlp3(text, g_cfg->default_wm, 0); log_message(LOG_LEVEL_ALWAYS, "error starting default " - "wm for user %s - pid %d", username, g_getpid()); + "wm for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " "%s", g_get_errno(), g_get_strerror()); @@ -609,7 +607,7 @@ session_start_fork(int width, int height, int bpp, char *username, /* should not get here */ log_message(LOG_LEVEL_ALWAYS, "error starting xterm " - "for user %s - pid %d", username, g_getpid()); + "for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " "%s", g_get_errno(), g_get_strerror()); @@ -642,7 +640,7 @@ session_start_fork(int width, int height, int bpp, char *username, { if (type == SESMAN_SESSION_TYPE_XVNC) { - env_set_user(username, + env_set_user(s->username, &passwd_file, display, g_cfg->session_variables1, @@ -650,7 +648,7 @@ session_start_fork(int width, int height, int bpp, char *username, } else { - env_set_user(username, + env_set_user(s->username, 0, display, g_cfg->session_variables1, @@ -688,10 +686,10 @@ session_start_fork(int width, int height, int bpp, char *username, log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); /* some args are passed via env vars */ - g_sprintf(geometry, "%d", width); + g_sprintf(geometry, "%d", s->width); g_setenv("XRDP_START_WIDTH", geometry, 1); - g_sprintf(geometry, "%d", height); + g_sprintf(geometry, "%d", s->height); g_setenv("XRDP_START_HEIGHT", geometry, 1); /* fire up Xorg */ @@ -699,7 +697,20 @@ session_start_fork(int width, int height, int bpp, char *username, } else if (type == SESMAN_SESSION_TYPE_XVNC) { - env_check_password_file(passwd_file, password); + if (s->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", s->guid[index]); + pguid_str += 2; + } + guid_str[32] = 0; + env_check_password_file(passwd_file, guid_str); + } xserver_params = list_create(); xserver_params->auto_free = 1; @@ -759,13 +770,13 @@ session_start_fork(int width, int height, int bpp, char *username, else { log_message(LOG_LEVEL_ALWAYS, "bad session type - " - "user %s - pid %d", username, g_getpid()); + "user %s - pid %d", s->username, g_getpid()); g_exit(1); } /* should not get here */ log_message(LOG_LEVEL_ALWAYS, "error starting X server " - "- user %s - pid %d", username, g_getpid()); + "- user %s - pid %d", s->username, g_getpid()); /* logging parameters */ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " @@ -790,7 +801,7 @@ session_start_fork(int width, int height, int bpp, char *username, g_snprintf(text, 255, ":%d.0", display); g_setenv("DISPLAY", text, 1); /* new style waiting for clients */ - session_start_sessvc(xpid, wmpid, data, username, display); + session_start_sessvc(xpid, wmpid, data, s->username, display); } } } @@ -798,12 +809,12 @@ session_start_fork(int width, int height, int bpp, char *username, { temp->item->pid = pid; temp->item->display = display; - temp->item->width = width; - temp->item->height = height; - temp->item->bpp = bpp; + temp->item->width = s->width; + temp->item->height = s->height; + temp->item->bpp = s->bpp; temp->item->data = data; - g_strncpy(temp->item->client_ip, client_ip, 255); /* store client ip data */ - g_strncpy(temp->item->name, username, 255); + g_strncpy(temp->item->client_ip, s->client_ip, 255); /* store client ip data */ + g_strncpy(temp->item->name, s->username, 255); ltime = g_time1(); localtime_r(<ime, &stime); @@ -867,13 +878,9 @@ session_reconnect_fork(int display, char *username) /* called by a worker thread, ask the main thread to call session_sync_start and wait till done */ 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) +session_start(long data, tui8 type, struct SCP_SESSION *s) { - return session_start_fork(width, height, bpp, username, - password, data, type, domain, - program, directory, client_ip); + return session_start_fork(data, type, s); } /******************************************************************************/ diff --git a/sesman/session.h b/sesman/session.h index 80dbdaba..e5b15834 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -104,9 +104,7 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, * */ 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); +session_start(long data, tui8 type, struct SCP_SESSION *s); int DEFAULT_CC session_reconnect(int display, char* username); diff --git a/vnc/vnc.c b/vnc/vnc.c index 8da35f5a..040a67c4 100644 --- a/vnc/vnc.c +++ b/vnc/vnc.c @@ -49,15 +49,37 @@ lib_send_copy(struct vnc *v, struct stream *s) /******************************************************************************/ /* 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[24]; + void *des; + int len; + + /* key is simply password padded with nulls */ + g_memset(key, 0, sizeof(key)); + 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 *des; void *sha1; - int len; int passwd_bytes; /* create password hash from password */ @@ -72,18 +94,7 @@ rfbEncryptBytes(char *bytes, char *passwd) (tui8)passwd_hash[0], (tui8)passwd_hash[1], (tui8)passwd_hash[2], (tui8)passwd_hash[3]); passwd_hash_text[39] = 0; - passwd = passwd_hash_text; - - /* key is simply password padded with nulls */ - g_memset(key, 0, sizeof(key)); - 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); + rfbEncryptBytes(bytes, passwd_hash_text); } /******************************************************************************/ @@ -1083,7 +1094,24 @@ lib_mod_connect(struct vnc *v) if (error == 0) { init_stream(s, 8192); - 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); + } s->p += 16; s_mark_end(s); error = trans_force_write_s(v->trans, s); @@ -1422,6 +1450,11 @@ lib_mod_set_param(struct vnc *v, const char *name, char *value) { v->delay_ms = g_atoi(value); } + else if (g_strcasecmp(name, "guid") == 0) + { + v->got_guid = 1; + g_memcpy(v->guid, value, 16); + } return 0; } diff --git a/vnc/vnc.h b/vnc/vnc.h index 34f408ca..0bc3835d 100644 --- a/vnc/vnc.h +++ b/vnc/vnc.h @@ -114,4 +114,6 @@ struct vnc struct stream *clip_data_s; int delay_ms; struct trans *trans; + int got_guid; + tui8 guid[16]; }; diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index f1a01efa..8d1c251c 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -483,7 +483,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; @@ -563,6 +563,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++) { @@ -1195,11 +1199,18 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) int rv; char ip[256]; char port[256]; + tui8 guid[16]; + tui8* pguid; 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; @@ -1208,7 +1219,7 @@ xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) 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); @@ -1969,7 +1980,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, 0) == 0) { xrdp_wm_set_login_mode(self->wm, 10); rv = 0; /*success*/