diff --git a/sesman/sesexec/sesexec_discover.c b/sesman/sesexec/sesexec_discover.c index d4a2ea7f8..fe67f6478 100644 --- a/sesman/sesexec/sesexec_discover.c +++ b/sesman/sesexec/sesexec_discover.c @@ -28,20 +28,128 @@ #include #endif +#include + #include "sesexec_discover.h" +#include "trans.h" +#include "sesexec.h" +#include "session.h" +#include "sesman_config.h" +#include "os_calls.h" +#include "ercp.h" +#include "login_info.h" + +/* + * Module-scope globals + */ +static struct trans *g_discover_trans = NULL; + +/*****************************************************************************/ +static int +discover_trans_conn_in(struct trans *trans, struct trans *new_trans) +{ + const struct session_parameters *sp; + int rv = 0; + + if (trans == NULL || new_trans == NULL || trans != g_discover_trans) + { + return 1; + } + + LOG_DEVEL(LOG_LEVEL_DEBUG, "discover_trans_conn_in:"); + + if (sesexec_is_ecp_active()) + { + int pid = 0; + (void)g_sck_get_peer_cred(new_trans->sck, &pid, 0, 0); + + LOG(LOG_LEVEL_WARNING, + "Connection attempt to sesexec PID %d from PID %d" + " while ECP is still active", + g_pid, pid); + + trans_delete(new_trans); + } + else if ((sp = session_get_parameters(g_session_data)) == NULL) + { + // If we haven't got session parameters, we shouldn't be here + LOG(LOG_LEVEL_ERROR, "Bugcheck: Can't get active session params"); + trans_delete(new_trans); + rv = 1; + } + else + { + // Reconnect to sesman and tell it about our existing + // session + ercp_init_trans(new_trans); + new_trans->trans_data_in = sesexec_ercp_data_in; + new_trans->callback_data = (void *)new_trans; + + // Note, this call makes further privilege checks that may still + // fail. If they do however, we wish to carry on running. These + // failed checks will be logged. + if (sesexec_set_ecp_transport(new_trans) == 0) + { + (void)ercp_send_session_announce_event( + new_trans, + sp->display, + g_login_info->uid, + sp->type, + sp->width, + sp->height, + sp->bpp, + &sp->guid, + g_login_info->ip_addr, + session_get_start_time(g_session_data)); + } + } + return rv; +} /******************************************************************************/ int sesexec_discover_enable(void) { - return 0; + int rv = 1; + if (g_session_data == NULL) + { + LOG(LOG_LEVEL_ERROR, "Cant enable discovery without an active session"); + } + else if (g_discover_trans != NULL) + { + LOG(LOG_LEVEL_ERROR, "Logic error: discovery is already active"); + } + else if ((g_discover_trans = + trans_create(TRANS_MODE_UNIX, 8192, 8192)) == NULL) + { + LOG(LOG_LEVEL_ERROR, "Out of memory enabling discovery"); + } + else + { + char discover_port[XRDP_SOCKETS_MAXPATH]; + + snprintf(discover_port, sizeof(discover_port), "%s/%u", + g_cfg->listen_port, + session_get_parameters(g_session_data)->display); + g_discover_trans->is_term = sesexec_is_term; + g_discover_trans->trans_conn_in = discover_trans_conn_in; + if ((rv = trans_listen(g_discover_trans, discover_port)) != 0) + { + LOG(LOG_LEVEL_ERROR, "Transport error enabling discovery [%s]", + g_get_strerror()); + } + } + + return rv; } /******************************************************************************/ - int sesexec_discover_disable(void) { + trans_delete(g_discover_trans); + g_discover_trans = NULL; + return 0; } @@ -51,13 +159,28 @@ int sesexec_discover_get_wait_objs(intptr_t robjs[], int *robjs_count, int max_count) { - return 0; + int rv; + if (g_discover_trans == NULL) + { + rv = 0; + } + else if (*robjs_count >= max_count) + { + rv = 1; + } + else + { + rv = trans_get_wait_objs(g_discover_trans, robjs, robjs_count); + } + + return rv; } /******************************************************************************/ - int sesexec_discover_check_wait_objs(void) { - return 0; + return (g_discover_trans == NULL) + ? 0 + : trans_check_wait_objs(g_discover_trans); }