Merge pull request #523 from jsorg71/vpf

vnc: change password file to use guid hash
This commit is contained in:
jsorg71 2016-12-06 12:05:23 -08:00 committed by GitHub
commit bbae1a98c6
14 changed files with 167 additions and 85 deletions

View File

@ -2530,6 +2530,34 @@ g_htoi(char *str)
return rv;
}
/*****************************************************************************/
/* returns number of bytes copied into out_str */
int APP_CC
g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
int bytes_out_str)
{
int rv;
int index;
char *lout_str;
const tui8 *lbytes;
rv = 0;
lbytes = (const tui8 *) bytes;
lout_str = out_str;
for (index = 0; index < num_bytes; index++)
{
if (bytes_out_str < 3)
{
break;
}
g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
lout_str += 2;
bytes_out_str -= 2;
rv += 2;
}
return rv;
}
/*****************************************************************************/
int APP_CC
g_pos(const char *str, const char *to_find)

View File

@ -134,6 +134,8 @@ int APP_CC g_strcasecmp(const char* c1, const char* c2);
int APP_CC g_strncasecmp(const char* c1, const char* c2, int len);
int APP_CC g_atoi(const char* str);
int APP_CC g_htoi(char* str);
int APP_CC g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
int bytes_out_str);
int APP_CC g_pos(const char* str, const char* to_find);
int APP_CC g_mbstowcs(twchar* dest, const char* src, int n);
int APP_CC g_wcstombs(char* dest, const twchar* src, int n);

View File

@ -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)

View File

@ -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

View File

@ -88,6 +88,7 @@ struct SCP_SESSION
char* program;
char* directory;
char* client_ip;
tui8 guid[16];
};
struct SCP_DISCONNECTED_SESSION

View File

@ -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))

View File

@ -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);
/**
*

View File

@ -77,7 +77,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
if (s_item != 0)
{
display = s_item->display;
g_memcpy(s->guid, s_item->guid, 16);
if (0 != s->client_ip)
{
log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
@ -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

View File

@ -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);

View File

@ -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,9 @@ 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);
char guid_str[64];
g_bytes_to_hexstr(s->guid, 16, guid_str, 64);
env_check_password_file(passwd_file, guid_str);
xserver_params = list_create();
xserver_params->auto_free = 1;
@ -759,13 +759,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 +790,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 +798,13 @@ 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);
g_memcpy(temp->item->guid, s->guid, 16);
ltime = g_time1();
localtime_r(&ltime, &stime);
@ -867,13 +868,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);
}
/******************************************************************************/

View File

@ -76,6 +76,7 @@ struct session_item
struct session_date disconnect_time;
struct session_date idle_time;
char client_ip[256];
tui8 guid[16];
};
struct session_chain
@ -104,9 +105,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);

View File

@ -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,16 @@ 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];
g_bytes_to_hexstr(v->guid, 16, guid_str, 64);
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 +1442,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;
}

View File

@ -114,4 +114,6 @@ struct vnc
struct stream *clip_data_s;
int delay_ms;
struct trans *trans;
int got_guid;
tui8 guid[16];
};

View File

@ -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*/