diff --git a/.gitignore b/.gitignore index a1dcd57e44..a874126cef 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,5 @@ tools/devel/tcp_proxy/tcp_proxy xrdp/xrdp xrdp/xrdp.ini xrdp_configure_options.h +.project +.cproject diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index f45195e89f..44d2af940b 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -92,6 +92,7 @@ struct xrdp_client_info int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache 2 = arbitrary dimensions */ char connection_description[256]; + char clientname[INFO_CLIENT_NAME_BYTES / 2]; int max_bpp; int jpeg; /* non standard bitmap cache v2 cap */ int offscreen_support_level; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index c5b342722f..2ae8e8672e 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1951,7 +1951,9 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) int highColorDepth; int supportedColorDepths; int earlyCapabilityFlags; - char clientName[INFO_CLIENT_NAME_BYTES / 2] = { '\0' }; + self->rdp_layer->client_info.clientname[0] = 0; + +// self->rdp_layer->client_info.clientname[(INFO_CLIENT_NAME_BYTES / 2) - 1] = '\0'; /* TS_UD_CS_CORE requiered fields */ in_uint8s(s, 4); /* version */ @@ -1970,8 +1972,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) in_uint8s(s, 2); /* SASSequence */ in_uint8s(s, 4); /* keyboardLayout */ in_uint8s(s, 4); /* clientBuild */ - unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, clientName, sizeof(clientName) - 1); /* clientName */ - LOG(LOG_LEVEL_INFO, "Connected client computer name: %s", clientName); + unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, self->rdp_layer->client_info.clientname, sizeof(self->rdp_layer->client_info.clientname) - 1); /* clientname */ + LOG(LOG_LEVEL_INFO, "Connected client computer name: %s", self->rdp_layer->client_info.clientname); in_uint8s(s, 4); /* keyboardType */ in_uint8s(s, 4); /* keyboardSubType */ in_uint8s(s, 4); /* keyboardFunctionKey */ @@ -1987,7 +1989,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) self->rdp_layer->client_info.height, (colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" : colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"), - clientName); + self->rdp_layer->client_info.clientname); /* TS_UD_CS_CORE optional fields */ in_uint16_le(s, postBeta2ColorDepth); diff --git a/sesman/config.c b/sesman/config.c index 481ae760d7..5e866e6a0f 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -317,6 +317,10 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n, { se->policy = SESMAN_CFG_SESS_POLICY_UBC; } + else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBN_S)) + { + se->policy = SESMAN_CFG_SESS_POLICY_UBN; + } else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDI_S)) { se->policy = SESMAN_CFG_SESS_POLICY_UBDI; @@ -325,6 +329,10 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n, { se->policy = SESMAN_CFG_SESS_POLICY_UBDC; } + else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDN_S)) + { + se->policy = SESMAN_CFG_SESS_POLICY_UBDN; + } else /* silently ignore typos */ { se->policy = SESMAN_CFG_SESS_POLICY_DFLT; diff --git a/sesman/config.h b/sesman/config.h index d9dbcefee7..401b490309 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -74,14 +74,17 @@ #define SESMAN_CFG_SESS_POLICY_UBD_S "UBD" #define SESMAN_CFG_SESS_POLICY_UBI_S "UBI" #define SESMAN_CFG_SESS_POLICY_UBC_S "UBC" +#define SESMAN_CFG_SESS_POLICY_UBN_S "UBN" #define SESMAN_CFG_SESS_POLICY_UBDI_S "UBDI" #define SESMAN_CFG_SESS_POLICY_UBDC_S "UBDC" +#define SESMAN_CFG_SESS_POLICY_UBDN_S "UBDN" enum SESMAN_CFG_SESS_POLICY_BITS { SESMAN_CFG_SESS_POLICY_D = 0x01, SESMAN_CFG_SESS_POLICY_I = 0x02, - SESMAN_CFG_SESS_POLICY_C = 0x04 + SESMAN_CFG_SESS_POLICY_C = 0x04, + SESMAN_CFG_SESS_POLICY_N = 0x08 }; enum SESMAN_CFG_SESS_POLICY @@ -90,8 +93,10 @@ enum SESMAN_CFG_SESS_POLICY SESMAN_CFG_SESS_POLICY_UBD = SESMAN_CFG_SESS_POLICY_D, SESMAN_CFG_SESS_POLICY_UBI = SESMAN_CFG_SESS_POLICY_I, SESMAN_CFG_SESS_POLICY_UBC = SESMAN_CFG_SESS_POLICY_C, + SESMAN_CFG_SESS_POLICY_UBN = SESMAN_CFG_SESS_POLICY_N, SESMAN_CFG_SESS_POLICY_UBDI = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_I, - SESMAN_CFG_SESS_POLICY_UBDC = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_C + SESMAN_CFG_SESS_POLICY_UBDC = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_C, + SESMAN_CFG_SESS_POLICY_UBDN = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_N }; /** diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index ef9480e317..ba787d1791 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -357,6 +357,32 @@ scp_session_set_hostname(struct SCP_SESSION *s, const char *str) return 0; } +/*******************************************************************/ +int +scp_session_set_clientname(struct SCP_SESSION *s, const char *str) +{ + if (0 == str) + { + LOG(LOG_LEVEL_WARNING, "[session:%d] set_clientname: null clientname", __LINE__); + return 1; + } + + if (0 != s->clientname) + { + g_free(s->clientname); + } + + s->clientname = g_strdup(str); + + if (0 == s->clientname) + { + LOG(LOG_LEVEL_WARNING, "[session:%d] set_clientname: strdup error", __LINE__); + return 1; + } + + return 0; +} + /*******************************************************************/ int scp_session_set_errstr(struct SCP_SESSION *s, const char *str) @@ -440,6 +466,7 @@ scp_session_destroy(struct SCP_SESSION *s) g_free(s->program); g_free(s->directory); g_free(s->connection_description); + g_free(s->clientname); g_free(s->errstr); g_free(s); } @@ -465,6 +492,7 @@ scp_session_clone(const struct SCP_SESSION *s) result->program = g_strdup(s->program); result->directory = g_strdup(s->directory); result->connection_description = g_strdup(s->connection_description); + result->clientname = g_strdup(s->clientname); /* Did all the string copies succeed? */ if ((s->username != NULL && result->username == NULL) || @@ -474,7 +502,8 @@ scp_session_clone(const struct SCP_SESSION *s) (s->domain != NULL && result->domain == NULL) || (s->program != NULL && result->program == NULL) || (s->directory != NULL && result->directory == NULL) || - (s->connection_description != NULL && result->connection_description == NULL)) + (s->connection_description != NULL && result->connection_description == NULL) || + (s->clientname != NULL && result->clientname == NULL)) { scp_session_destroy(result); result = NULL; diff --git a/sesman/libscp/libscp_session.h b/sesman/libscp/libscp_session.h index 8c3f1d2c07..d8032ff54f 100644 --- a/sesman/libscp/libscp_session.h +++ b/sesman/libscp/libscp_session.h @@ -90,6 +90,9 @@ scp_session_set_connection_description(struct SCP_SESSION *s, const char *str); int scp_session_set_hostname(struct SCP_SESSION *s, const char *str); +int +scp_session_set_clientname(struct SCP_SESSION *s, const char *str); + int scp_session_set_addr(struct SCP_SESSION *s, int type, const void *addr); diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 2f66b4d67e..442ea63084 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -91,6 +91,7 @@ struct SCP_SESSION int return_sid; int retries; int current_try; + char* clientname; }; struct SCP_DISCONNECTED_SESSION diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index c67f5cfad5..5aeae2b0fc 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -364,6 +364,19 @@ scp_v0s_accept(struct trans *atrans, struct SCP_SESSION *session) scp_session_set_connection_description(session, buf); } } + if (s_check_rem(in_s, 2)) + { + /* reading clientname */ + if (!in_string16(in_s, buf, "clientname")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (buf[0] != '\0') + { + scp_session_set_clientname(session, buf); + } + } } else if (code == SCP_GW_AUTHENTICATION) { diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index ecc9f88a8b..cf0a9a0e24 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -77,7 +77,7 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s) else if (data) { s_item = session_get_bydata(s->username, s->width, s->height, - s->bpp, s->type, s->connection_description); + s->bpp, s->type, s->connection_description, s->clientname); if (s_item != 0) { @@ -86,9 +86,9 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s) if (0 != s->connection_description) { LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d, ip %s", + "display :%d.0, session_pid %d, ip %s, clientname %s", s->username, display, s_item->pid, - s->connection_description); + s->connection_description, s->clientname); } else { @@ -113,7 +113,7 @@ scp_v0_process(struct trans *t, struct SCP_SESSION *s) if (0 != s->connection_description) { LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->connection_description); + "username %s, ip %s, clientname %s", s->username, s->connection_description, s->clientname); } else { diff --git a/sesman/session.c b/sesman/session.c index d20185819c..ce8694b8c7 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -92,7 +92,7 @@ dumpItemsToString(struct list *self, char *outstr, int len) /******************************************************************************/ struct session_item * session_get_bydata(const char *name, int width, int height, int bpp, int type, - const char *connection_description) + const char *connection_description, const char *clientname) { struct session_chain *tmp; enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy; @@ -127,8 +127,8 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, } LOG(LOG_LEVEL_DEBUG, - "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s", - policy, name, width, height, bpp, type, connection_description); + "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s Name %s", + policy, name, width, height, bpp, type, connection_description, clientname); while (tmp != 0) { @@ -145,12 +145,13 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, } LOG(LOG_LEVEL_DEBUG, - "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s", + "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s Name %s", tmp->item, tmp->item->name, tmp->item->width, tmp->item->height, tmp->item->bpp, tmp->item->type, - tmp->item->connection_description); + tmp->item->connection_description, + tmp->item->clientname); if (g_strncmp(name, tmp->item->name, 255) == 0 && (!(policy & SESMAN_CFG_SESS_POLICY_D) || @@ -159,6 +160,8 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, (g_strcmp(ip, tmp_ip) == 0)) && (!(policy & SESMAN_CFG_SESS_POLICY_C) || (g_strncmp(connection_description, tmp->item->connection_description, 255) == 0)) && + (!(policy & SESMAN_CFG_SESS_POLICY_N) || + (g_strncmp(clientname, tmp->item->clientname, 255) == 0)) && tmp->item->bpp == bpp && tmp->item->type == type) { @@ -464,6 +467,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) passwd_file = 0; + LOG(LOG_LEVEL_TRACE, "Check if clientname %s is still correct", + s->clientname); + /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) { @@ -592,6 +598,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) display, g_cfg->env_names, g_cfg->env_values); + g_setenv("CLIENTNAME", s->clientname, 1); if (x_server_running(display)) { auth_set_env(data); @@ -690,6 +697,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) display, g_cfg->env_names, g_cfg->env_values); + g_setenv("CLIENTNAME", s->clientname, 1); } else { @@ -698,6 +706,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) display, g_cfg->env_names, g_cfg->env_values); + g_setenv("CLIENTNAME", s->clientname, 1); } /* setting Xserver environment variables */ @@ -708,6 +717,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) g_snprintf(text, 255, "%d", g_cfg->sess.kill_disconnected); g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1); g_setenv("XRDP_SOCKET_PATH", XRDP_SOCKET_PATH, 1); + g_setenv("CLIENTNAME", s->clientname, 1); /* prepare the Xauthority stuff */ if (g_getenv("XAUTHORITY") != NULL) @@ -873,15 +883,15 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) chansrv_pid = session_start_chansrv(s->username, display); LOG(LOG_LEVEL_INFO, - "Session started successfully for user %s on display %d", - s->username, display); + "Session from client %s started successfully for user %s on display %d", + s->clientname, s->username, display); /* Monitor the amount of time we wait for the * window manager. This is approximately how long the window * manager was running for */ - LOG(LOG_LEVEL_INFO, "Session in progress on display %d, waiting " + LOG(LOG_LEVEL_INFO, "Session from client %s in progress on display %d, waiting " "until the window manager (pid %d) exits to end the session", - display, window_manager_pid); + s->clientname, display, window_manager_pid); wm_wait_time = g_time1(); wm_exit_status = g_waitpid_status(window_manager_pid); wm_wait_time = g_time1() - wm_wait_time; @@ -945,10 +955,10 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) } else { - LOG(LOG_LEVEL_INFO, "Starting session: session_pid %d, " + LOG(LOG_LEVEL_INFO, "Starting session for client %s: session_pid %d, " "display :%d.0, width %d, height %d, bpp %d, client ip %s, " "user name %s", - pid, display, s->width, s->height, s->bpp, s->connection_description, s->username); + s->clientname, pid, display, s->width, s->height, s->bpp, s->connection_description, s->username); temp->item->pid = pid; temp->item->display = display; temp->item->width = s->width; @@ -956,6 +966,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) temp->item->bpp = s->bpp; temp->item->data = data; g_strncpy(temp->item->connection_description, s->connection_description, 255); /* store client ip data */ + g_strncpy(temp->item->clientname, s->clientname, 255); /* store clientname */ g_strncpy(temp->item->name, s->username, 255); g_memcpy(temp->item->guid, s->guid, 16); diff --git a/sesman/session.h b/sesman/session.h index 174e65df45..f5de22a52b 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -77,6 +77,7 @@ struct session_item struct session_date idle_time; char connection_description[256]; tui8 guid[16]; + char clientname[256]; }; struct session_chain @@ -93,7 +94,7 @@ struct session_chain */ struct session_item * session_get_bydata(const char *name, int width, int height, int bpp, int type, - const char *connection_description); + const char *connection_description, const char *clientname); #ifndef session_find_item #define session_find_item(a, b, c, d, e, f) session_get_bydata(a, b, c, d, e, f); #endif diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 13a165f007..ce4acde8aa 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -266,6 +266,11 @@ xrdp_mm_send_login(struct xrdp_mm *self) out_uint16_be(s, index); out_uint8a(s, self->wm->client_info->connection_description, index); + /* send clientname */ + index = g_strlen(self->wm->client_info->clientname); + out_uint16_be(s, index); + out_uint8a(s, self->wm->client_info->clientname, index); + s_mark_end(s); s_pop_layer(s, channel_hdr);