Create pre-session list
This is made from the old sesman_con structure. It describes a connection to sesman which is not yet running a session.
This commit is contained in:
parent
dadb393443
commit
8e291846d5
@ -20,6 +20,8 @@ xrdp_sesman_SOURCES = \
|
|||||||
env.h \
|
env.h \
|
||||||
lock_uds.c \
|
lock_uds.c \
|
||||||
lock_uds.h \
|
lock_uds.h \
|
||||||
|
pre_session_list.c \
|
||||||
|
pre_session_list.h \
|
||||||
scp_process.c \
|
scp_process.c \
|
||||||
scp_process.h \
|
scp_process.h \
|
||||||
sesman.c \
|
sesman.c \
|
||||||
|
261
sesman/pre_session_list.c
Normal file
261
sesman/pre_session_list.c
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Copyright (C) Jay Sorg 2004-2015
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file pre_session_list.h
|
||||||
|
* @brief List of pre-session connections to sesman (definitions)
|
||||||
|
*
|
||||||
|
* @author Matt Burt
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include <config_ac.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "arch.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "os_calls.h"
|
||||||
|
#include "pre_session_list.h"
|
||||||
|
#include "trans.h"
|
||||||
|
|
||||||
|
#define PRE_SESSION_IN_USE(si) \
|
||||||
|
( \
|
||||||
|
(si) != NULL && \
|
||||||
|
( \
|
||||||
|
((si)->client_trans != NULL && (si)->client_trans->status == TRANS_STATUS_UP) || \
|
||||||
|
((si)->sesexec_trans != NULL && (si)->sesexec_trans->status == TRANS_STATUS_UP) \
|
||||||
|
) \
|
||||||
|
)
|
||||||
|
|
||||||
|
static struct list *g_pre_session_list = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a pre_session_item, freeing resources
|
||||||
|
*
|
||||||
|
* After this call, the passed-in pointer is invalid and must not be
|
||||||
|
* referenced.
|
||||||
|
*
|
||||||
|
* Any auth_info struct found in the sesman_con is also deallocated.
|
||||||
|
*
|
||||||
|
* @param sc struct to de-allocate
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
free_pre_session_item(struct pre_session_item *psi)
|
||||||
|
{
|
||||||
|
if (psi != NULL)
|
||||||
|
{
|
||||||
|
trans_delete(psi->client_trans);
|
||||||
|
trans_delete(psi->sesexec_trans);
|
||||||
|
g_free(psi->username);
|
||||||
|
g_free(psi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int
|
||||||
|
pre_session_list_init(unsigned int list_size)
|
||||||
|
{
|
||||||
|
int rv = 1;
|
||||||
|
if (g_pre_session_list == NULL)
|
||||||
|
{
|
||||||
|
g_pre_session_list = list_create_sized(list_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_pre_session_list == NULL)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR, "Can't allocate pre-session list");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_pre_session_list->auto_free = 0;
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
void
|
||||||
|
pre_session_list_cleanup(void)
|
||||||
|
{
|
||||||
|
if (g_pre_session_list != NULL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0 ; i < g_pre_session_list->count ; ++i)
|
||||||
|
{
|
||||||
|
struct pre_session_item *p;
|
||||||
|
p = (struct pre_session_item *)list_get_item(g_pre_session_list, i);
|
||||||
|
free_pre_session_item(p);
|
||||||
|
}
|
||||||
|
list_delete(g_pre_session_list);
|
||||||
|
g_pre_session_list = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
unsigned int
|
||||||
|
pre_session_list_get_count(void)
|
||||||
|
{
|
||||||
|
return g_pre_session_list->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
struct pre_session_item *
|
||||||
|
pre_session_list_new(void)
|
||||||
|
{
|
||||||
|
struct pre_session_item *result = g_new0(struct pre_session_item, 1);
|
||||||
|
if (result != NULL)
|
||||||
|
{
|
||||||
|
g_snprintf(result->peername, sizeof(result->peername), "unknown");
|
||||||
|
result->uid = (uid_t) -1;
|
||||||
|
|
||||||
|
if (!list_add_item(g_pre_session_list, (tintptr)result))
|
||||||
|
{
|
||||||
|
g_free(result);
|
||||||
|
result = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
int
|
||||||
|
pre_session_list_set_peername(struct pre_session_item *psi, const char *name)
|
||||||
|
{
|
||||||
|
int rv = 1;
|
||||||
|
|
||||||
|
if (psi != NULL && name != NULL)
|
||||||
|
{
|
||||||
|
g_snprintf(psi->peername, sizeof(psi->peername), "%s", name);
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int
|
||||||
|
pre_session_list_get_wait_objs(tbus robjs[], int *robjs_count)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < g_pre_session_list->count)
|
||||||
|
{
|
||||||
|
struct pre_session_item *psi;
|
||||||
|
psi = (struct pre_session_item *)list_get_item(g_pre_session_list, i);
|
||||||
|
int psi_in_use = 0;
|
||||||
|
|
||||||
|
if (psi != NULL)
|
||||||
|
{
|
||||||
|
if (psi->client_trans != NULL &&
|
||||||
|
psi->client_trans->status == TRANS_STATUS_UP)
|
||||||
|
{
|
||||||
|
robjs[(*robjs_count)++] = psi->client_trans->sck;
|
||||||
|
psi_in_use = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psi->sesexec_trans != NULL &&
|
||||||
|
psi->sesexec_trans->status == TRANS_STATUS_UP)
|
||||||
|
{
|
||||||
|
robjs[(*robjs_count)++] = psi->sesexec_trans->sck;
|
||||||
|
psi_in_use = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psi_in_use)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free_pre_session_item(psi);
|
||||||
|
list_remove_item(g_pre_session_list, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
int
|
||||||
|
pre_session_list_check_wait_objs(void)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (i < g_pre_session_list->count)
|
||||||
|
{
|
||||||
|
struct pre_session_item *psi;
|
||||||
|
enum pre_session_dispatcher_action action;
|
||||||
|
|
||||||
|
psi = (struct pre_session_item *)list_get_item(g_pre_session_list, i);
|
||||||
|
action = E_PSD_TERMINATE_PRE_SESSION;
|
||||||
|
|
||||||
|
if (PRE_SESSION_IN_USE(psi))
|
||||||
|
{
|
||||||
|
if (psi->client_trans != NULL &&
|
||||||
|
psi->client_trans->status == TRANS_STATUS_UP)
|
||||||
|
{
|
||||||
|
if (trans_check_wait_objs(psi->client_trans) != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR, "pre_session_list_check_wait_objs: "
|
||||||
|
"trans_check_wait_objs(1) failed, removing trans");
|
||||||
|
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (psi->sesexec_trans != NULL &&
|
||||||
|
psi->sesexec_trans->status == TRANS_STATUS_UP)
|
||||||
|
{
|
||||||
|
if (trans_check_wait_objs(psi->sesexec_trans) != 0)
|
||||||
|
{
|
||||||
|
LOG(LOG_LEVEL_ERROR, "pre_session_list_check_wait_objs: "
|
||||||
|
"trans_check_wait_objs(2) failed, removing trans");
|
||||||
|
psi->dispatcher_action = E_PSD_TERMINATE_PRE_SESSION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get any action, and reset the requested one */
|
||||||
|
action = psi->dispatcher_action;
|
||||||
|
psi->dispatcher_action = E_PSD_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case E_PSD_NONE:
|
||||||
|
/* On to the next item on the list */
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case E_PSD_REMOVE_CLIENT_TRANS:
|
||||||
|
trans_delete(psi->client_trans);
|
||||||
|
psi->client_trans = NULL;
|
||||||
|
/* On to the next item on the list */
|
||||||
|
++i;
|
||||||
|
break;
|
||||||
|
case E_PSD_TERMINATE_PRE_SESSION:
|
||||||
|
free_pre_session_item(psi);
|
||||||
|
list_remove_item(g_pre_session_list, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
148
sesman/pre_session_list.h
Normal file
148
sesman/pre_session_list.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Copyright (C) Jay Sorg 2004-2013
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file pre_session_list.h
|
||||||
|
* @brief List of pre-session connections to sesman (declarations)
|
||||||
|
*
|
||||||
|
* Items on this list are moved to the session list once they have
|
||||||
|
* authenticated and a session is started.
|
||||||
|
*
|
||||||
|
* @author Matt Burt
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRE_SESSION_LIST_H
|
||||||
|
#define PRE_SESSION_LIST_H
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "xrdp_constants.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type describing the login state of a pre-session item
|
||||||
|
*/
|
||||||
|
enum ps_login_state
|
||||||
|
{
|
||||||
|
E_PS_LOGIN_NOT_LOGGED_IN = 0,
|
||||||
|
E_PS_LOGIN_SYS,
|
||||||
|
E_PS_LOGIN_UDS
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action we require the dispatcher to do for us
|
||||||
|
*
|
||||||
|
* We can't do some things in an SCP or EICP callback, so we have to
|
||||||
|
* ask the dispatcher to do them. For example, we can't delete the
|
||||||
|
* client_trans as the callback stack won't be expecting this.
|
||||||
|
*/
|
||||||
|
enum pre_session_dispatcher_action
|
||||||
|
{
|
||||||
|
E_PSD_NONE = 0,
|
||||||
|
E_PSD_REMOVE_CLIENT_TRANS,
|
||||||
|
E_PSD_TERMINATE_PRE_SESSION
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type for managing sesman connections from SCP clients (xrdp, etc)
|
||||||
|
* and any sesexec processes we've created for them.
|
||||||
|
*/
|
||||||
|
struct pre_session_item
|
||||||
|
{
|
||||||
|
struct trans *client_trans; ///< SCP link to sesman client
|
||||||
|
struct trans *sesexec_trans; ///< ECP link to sesexec
|
||||||
|
pid_t sesexec_pid; ///< PID of sesexec (if sesexec is active)
|
||||||
|
char peername[15 + 1]; ///< Name of peer, if known, for logging
|
||||||
|
enum ps_login_state login_state; ///< Login state
|
||||||
|
/**
|
||||||
|
* Any action which a callback requires the dispatcher to
|
||||||
|
* do out of scope of the callback */
|
||||||
|
enum pre_session_dispatcher_action dispatcher_action;
|
||||||
|
uid_t uid; ///< User
|
||||||
|
char *username; ///< Username from UID (at time of logon)
|
||||||
|
char start_ip_addr[MAX_PEER_ADDRSTRLEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the module
|
||||||
|
* @param list_size Number of pre-session items allowed
|
||||||
|
* @return 0 for success
|
||||||
|
*
|
||||||
|
* Errors are logged
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pre_session_list_init(unsigned int list_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up the module on program exit
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
pre_session_list_cleanup(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of items on the pre-session list
|
||||||
|
* @return Item count
|
||||||
|
*/
|
||||||
|
unsigned int
|
||||||
|
pre_session_list_get_count(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocates a new pre-session item on the list
|
||||||
|
*
|
||||||
|
* @return pointer to new pre-session object or NULL for no memory
|
||||||
|
*
|
||||||
|
* After allocating the session, you must initialise the sesexec_trans field
|
||||||
|
* with a valid transport.
|
||||||
|
*
|
||||||
|
* The session is removed by pre_session_list_get_wait_objs() or
|
||||||
|
* pre_session_check_wait_objs() when the client
|
||||||
|
* transport goes down (or wasn't allocated in the first place).
|
||||||
|
*/
|
||||||
|
struct pre_session_item *
|
||||||
|
pre_session_list_new(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the peername of a pre-session
|
||||||
|
*
|
||||||
|
* @param psi pre-session-item
|
||||||
|
* @param name Name to set
|
||||||
|
* @result 0 for success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pre_session_list_set_peername(struct pre_session_item *psi, const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the wait objs for the pre-session list module
|
||||||
|
* @param @robjs Objects array to update
|
||||||
|
* @param robjs_count Elements in robjs (by reference)
|
||||||
|
* @return 0 for success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pre_session_list_get_wait_objs(tbus robjs[], int *robjs_count);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check the wait objs for the pre-session list module
|
||||||
|
* @return 0 for success
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pre_session_list_check_wait_objs(void);
|
||||||
|
|
||||||
|
#endif // PRE_SESSION_LIST_H
|
Loading…
Reference in New Issue
Block a user