diff options
author | matt335672 <30179339+matt335672@users.noreply.github.com> | 2022-02-14 12:16:42 +0300 |
---|---|---|
committer | matt335672 <30179339+matt335672@users.noreply.github.com> | 2022-03-15 13:45:00 +0300 |
commit | c0cb03801c365664f936b81c52a9d0a79f702835 (patch) | |
tree | a8419149259a0a4e6c4f9767a17588d1f0c83f55 /sesman | |
parent | 6cf053c9df27179190541c126a57c8a8ceb6bf9d (diff) |
Move sesman to new SCP interface
Diffstat (limited to 'sesman')
-rw-r--r-- | sesman/Makefile.am | 15 | ||||
-rw-r--r-- | sesman/notes.txt | 59 | ||||
-rw-r--r-- | sesman/scp.c | 88 | ||||
-rw-r--r-- | sesman/scp.h | 45 | ||||
-rw-r--r-- | sesman/scp_process.c | 277 | ||||
-rw-r--r-- | sesman/scp_process.h (renamed from sesman/scp_v0.h) | 20 | ||||
-rw-r--r-- | sesman/scp_v0.c | 174 | ||||
-rw-r--r-- | sesman/scp_v1.c | 307 | ||||
-rw-r--r-- | sesman/scp_v1.h | 41 | ||||
-rw-r--r-- | sesman/scp_v1_mng.c | 134 | ||||
-rw-r--r-- | sesman/scp_v1_mng.h | 40 | ||||
-rw-r--r-- | sesman/sesman.c | 68 | ||||
-rw-r--r-- | sesman/sesman.h | 2 | ||||
-rw-r--r-- | sesman/session.c | 278 | ||||
-rw-r--r-- | sesman/session.h | 93 |
15 files changed, 524 insertions, 1117 deletions
diff --git a/sesman/Makefile.am b/sesman/Makefile.am index 7d4efa09..834ea8be 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -9,7 +9,7 @@ AM_CPPFLAGS = \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/sesman/libscp + -I$(top_srcdir)/libipm if SESMAN_BSD AUTH_C = verify_user_bsd.c @@ -45,14 +45,8 @@ xrdp_sesman_SOURCES = \ config.h \ env.c \ env.h \ - scp.c \ - scp.h \ - scp_v0.c \ - scp_v0.h \ - scp_v1.c \ - scp_v1.h \ - scp_v1_mng.c \ - scp_v1_mng.h \ + scp_process.c \ + scp_process.h \ sesman.c \ sesman.h \ session.c \ @@ -64,8 +58,8 @@ xrdp_sesman_SOURCES = \ $(AUTH_C) xrdp_sesman_LDADD = \ + $(top_builddir)/libipm/libipm.la \ $(top_builddir)/common/libcommon.la \ - $(top_builddir)/sesman/libscp/libscp.la \ $(AUTH_LIB) \ -lpthread @@ -90,6 +84,5 @@ dist_sesmansysconf_SCRIPTS = \ reconnectwm.sh SUBDIRS = \ - libscp \ tools \ chansrv diff --git a/sesman/notes.txt b/sesman/notes.txt index af406ca5..edfba381 100644 --- a/sesman/notes.txt +++ b/sesman/notes.txt @@ -7,60 +7,5 @@ ** internal, and may change for even minor releases. ** ************************************************************ - -message header -version 4 - version, 0 or 1 -size 4 - size of PDU including header -cmdset 2 - 0 - -version 0 -cmdset 2 bytes - 0 - Xvnc client to server - 3 - response to 0, 10, or 20 server to client - 4 - SCP_GW_AUTHENTICATION client to server - 10 - X11rdp client to server - 20 - Xorg client to server - -version 1 -cmdset 2 bytes - 0 - SCP_COMMAND_SET_DEFAULT - 1 - SCP_COMMAND_SET_MANAGE - 2 - SCP_COMMAND_SET_RSR - -SCP_COMMAND_SET_DEFAULT -cmd 2 bytes - 1 - main client to server - 3 - password request server to client - 4 - password reply client to server - 30 - connect new session - 40 - list all sessions server to client - 41 - list all sessions response client to server - 42 - list all sessions server to client - 43 - list all sessions response client to server - 44 - list all sessions response client to server - 45 - client to server - 46 - reconnect session - 0xFFFF - SCP_CMD_CONN_ERROR - -SCP_COMMAND_SET_MANAGE -cmd 2 bytes - 1 - manager login - 2 - SCP_CMD_MNG_LOGIN_ALLOW - -v0 -scp_process scp.c - scp_vXs_accept libscp_vX.c - scp_v0s_accept libscp_v0.c - scp_v0_process scp_v0.c - session_start session.c - -v1 -scp_process scp.c - scp_vXs_accept libscp_vX.c - scp_v1s_accept libscp_v1s.c - scp_v1s_mng_accept libscp_v1s_mng.c - scp_v1_process scp_v1.c - scp_v1s_request_password libscp_v1s.c - or - scp_v1_mng_process scp_v1_mng.c - +The SCP protocol is layered on top of libipm, which is in +../libipm. See ../libipm/scp.h for the interface messages to xrdp-sesman diff --git a/sesman/scp.c b/sesman/scp.c deleted file mode 100644 index 62f6af39..00000000 --- a/sesman/scp.c +++ /dev/null @@ -1,88 +0,0 @@ -/** - * 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 scp.c - * @brief scp (sesman control protocol) common code - * scp (sesman control protocol) common code - * This code controls which version is being used and starts the - * appropriate process - * @author Jay Sorg, Simone Fedele - * - */ - -#if defined(HAVE_CONFIG_H) -#include <config_ac.h> -#endif - -#include "sesman.h" - -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_process(struct trans *t, struct SCP_SESSION *sdata) -{ - enum SCP_SERVER_STATES_E result = scp_vXs_accept(t, sdata); - switch (result) - { - case SCP_SERVER_STATE_OK: - if (sdata->version == 0) - { - /* starts processing an scp v0 connection */ - LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v0"); - result = scp_v0_process(t, sdata); - } - else - { - LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v1"); - result = scp_v1_process(t, sdata); - } - break; - case SCP_SERVER_STATE_START_MANAGE: - /* starting a management session */ - LOG(LOG_LEVEL_INFO, - "starting a sesman management session..."); - result = scp_v1_mng_process_msg(t, sdata); - break; - case SCP_SERVER_STATE_VERSION_ERR: - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, or the message sizes - are inconsistent. Shut down the connection and log the - fact */ - LOG(LOG_LEVEL_WARNING, - "protocol violation. connection refused."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - LOG(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - LOG(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - LOG(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); - result = SCP_SERVER_STATE_INTERNAL_ERR; - break; - } - - return result; -} - diff --git a/sesman/scp.h b/sesman/scp.h deleted file mode 100644 index 088da5fd..00000000 --- a/sesman/scp.h +++ /dev/null @@ -1,45 +0,0 @@ -/** - * 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 scp.h - * @brief scp (sesman control protocol) common definitions - * @author Simone Fedele - * - */ - -#ifndef SCP_H -#define SCP_H - -#include "scp_v0.h" -#include "scp_v1.h" -#include "scp_v1_mng.h" - -/** - * - * @brief Starts a an scp protocol thread. - * Starts a an scp protocol thread. - * But does only version control.... - * @param atrans the connection trans - * - */ -enum SCP_SERVER_STATES_E -scp_process(struct trans *t, struct SCP_SESSION *s); - -#endif diff --git a/sesman/scp_process.c b/sesman/scp_process.c new file mode 100644 index 00000000..a15dbc9e --- /dev/null +++ b/sesman/scp_process.c @@ -0,0 +1,277 @@ +/** + * 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 scp.c + * @brief scp (sesman control protocol) handler function + * @author Jay Sorg, Simone Fedele + * + */ + +#if defined(HAVE_CONFIG_H) +#include <config_ac.h> +#endif + +#include "trans.h" +#include "os_calls.h" +#include "scp.h" + +#include "scp_process.h" +#include "access.h" +#include "auth.h" +#include "session.h" + +/******************************************************************************/ + +static int +process_gateway_request(struct trans *trans) +{ + int rv; + const char *username; + const char *password; + + if ((rv = scp_get_gateway_request(trans, &username, &password)) == 0) + { + int errorcode = 0; + tbus data; + + LOG(LOG_LEVEL_INFO, "Received authentication request for user: %s", + username); + + data = auth_userpass(username, password, &errorcode); + if (data) + { + if (1 == access_login_allowed(username)) + { + /* the user is member of the correct groups. */ + LOG(LOG_LEVEL_INFO, "Access permitted for user: %s", + username); + } + else + { + /* all first 32 are reserved for PAM errors */ + errorcode = 32 + 3; + LOG(LOG_LEVEL_INFO, "Username okay but group problem for " + "user: %s", username); + } + } + else + { + /* g_writeln("username or password error"); */ + LOG(LOG_LEVEL_INFO, "Username or password error for user: %s", + username); + } + rv = scp_send_gateway_response(trans, errorcode); + auth_end(data); + } + return rv; +} + +/******************************************************************************/ + +static int +process_create_session_request(struct trans *trans) +{ + int rv; + struct session_parameters sp; + const char *password; + struct guid guid; + + guid_clear(&guid); + int display = 0; + + rv = scp_get_create_session_request( + trans, + &sp.username, &password, + &sp.type, &sp.width, &sp.height, &sp.bpp, + &sp.shell, &sp.directory, &sp.connection_description); + + if (rv == 0) + { + tbus data; + struct session_item *s_item; + int errorcode = 0; + bool_t do_auth_end = 1; + + LOG(LOG_LEVEL_INFO, + "Received request to create %s session for user: %s", + SCP_SESSION_TYPE_TO_STR(sp.type), + sp.username); + + data = auth_userpass(sp.username, password, &errorcode); + if (data) + { + s_item = session_get_bydata(&sp); + if (s_item != 0) + { + display = s_item->display; + guid = s_item->guid; + if (sp.connection_description[0] != '\0') + { + LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d, ip %s", + sp.username, display, s_item->pid, + sp.connection_description); + } + else + { + LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d", sp.username, display, + s_item->pid); + } + + session_reconnect(display, sp.username, data); + } + else + { + LOG_DEVEL(LOG_LEVEL_DEBUG, "pre auth"); + + if (1 == access_login_allowed(sp.username)) + { + if (sp.connection_description[0] != '\0') + { + LOG(LOG_LEVEL_INFO, + "++ created session (access granted): " + "username %s, ip %s", sp.username, + sp.connection_description); + } + else + { + LOG(LOG_LEVEL_INFO, + "++ created session (access granted): " + "username %s", sp.username); + } + + display = session_start(data, &sp, &guid); + + /* if the session started up ok, auth_end will be called on + sig child */ + do_auth_end = display == 0; + } + } + } + else + { + char ip[64]; + g_get_ip_from_description(sp.connection_description, + ip, sizeof(ip)); + /* + * The message is intended for use by fail2ban, so for + * future-proofing we only log the IP address rather than the + * connection description */ + LOG(LOG_LEVEL_INFO, + "AUTHFAIL: user=%s ip=%s time=%d", + sp.username, ip, g_time1()); + } + + if (do_auth_end) + { + auth_end(data); + } + + rv = scp_send_create_session_response(trans, errorcode, display, &guid); + } + + return rv; +} + +/******************************************************************************/ + +static int +process_list_sessions_request(struct trans *trans) +{ + int rv; + + const char *username; + const char *password; + + rv = scp_get_list_sessions_request(trans, &username, &password); + if (rv == 0) + { + enum scp_list_sessions_status status; + int errorcode = 0; + tbus data; + + LOG(LOG_LEVEL_INFO, + "Received request to list sessions for user %s", username); + + data = auth_userpass(username, password, &errorcode); + if (data) + { + struct scp_session_info *info = NULL; + unsigned int cnt = 0; + unsigned int i; + info = session_get_byuser(username, &cnt, + SESMAN_SESSION_STATUS_ALL); + + for (i = 0; rv == 0 && i < cnt; ++i) + { + rv = scp_send_list_sessions_response(trans, + E_SCP_LS_SESSION_INFO, + &info[i]); + } + free_session_info_list(info, cnt); + status = E_SCP_LS_END_OF_LIST; + } + else + { + status = E_SCP_LS_AUTHENTICATION_FAIL; + } + auth_end(data); + + if (rv == 0) + { + rv = scp_send_list_sessions_response(trans, status, NULL); + } + } + + return rv; +} + +/******************************************************************************/ +int +scp_process(struct trans *t) +{ + enum scp_msg_code msgno; + int rv = 0; + + switch ((msgno = scp_msg_in_start(t))) + { + case E_SCP_GATEWAY_REQUEST: + rv = process_gateway_request(t); + break; + + case E_SCP_CREATE_SESSION_REQUEST: + rv = process_create_session_request(t); + break; + + case E_SCP_LIST_SESSIONS_REQUEST: + rv = process_list_sessions_request(t); + break; + + default: + { + char buff[64]; + scp_msgno_to_str(msgno, buff, sizeof(buff)); + LOG(LOG_LEVEL_ERROR, "Ignored SCP message %s", buff); + } + } + return rv; +} + diff --git a/sesman/scp_v0.h b/sesman/scp_process.h index 17d4a36e..c52966b6 100644 --- a/sesman/scp_v0.h +++ b/sesman/scp_process.h @@ -18,18 +18,24 @@ /** * - * @file scp_v0.h - * @brief scp version 0 declarations + * @file scp_process.h + * @brief scp (sesman control protocol) handler function * @author Simone Fedele * */ -#ifndef SCP_V0_H -#define SCP_V0_H +#ifndef SCP_PROCESS_H +#define SCP_PROCESS_H -#include "libscp.h" +struct trans; -enum SCP_SERVER_STATES_E -scp_v0_process(struct trans *t, struct SCP_SESSION *s); +/** + * + * @brief Processes an SCP message + * @param t the connection trans + * + */ +int +scp_process(struct trans *t); #endif diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c deleted file mode 100644 index 195169fa..00000000 --- a/sesman/scp_v0.c +++ /dev/null @@ -1,174 +0,0 @@ -/** - * 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 scp_v0.c - * @brief scp version 0 implementation - * @author Jay Sorg, Simone Fedele - * - */ - -#if defined(HAVE_CONFIG_H) -#include <config_ac.h> -#endif - -#include "sesman.h" - -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v0_process(struct trans *t, struct SCP_SESSION *s) -{ - int display = 0; - tbus data; - struct session_item *s_item; - int errorcode = 0; - bool_t do_auth_end = 1; - - data = auth_userpass(s->username, s->password, &errorcode); - - if (s->type == SCP_GW_AUTHENTICATION) - { - /* this is just authentication in a gateway situation */ - /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ - if (data) - { - if (1 == access_login_allowed(s->username)) - { - /* the user is member of the correct groups. */ - scp_v0s_replyauthentication(t, errorcode); - LOG(LOG_LEVEL_INFO, "Access permitted for user: %s", - s->username); - /* g_writeln("Connection allowed"); */ - } - else - { - scp_v0s_replyauthentication(t, 32 + 3); /* all first 32 are reserved for PAM errors */ - LOG(LOG_LEVEL_INFO, "Username okay but group problem for " - "user: %s", s->username); - /* g_writeln("user password ok, but group problem"); */ - } - } - else - { - /* g_writeln("username or password error"); */ - LOG(LOG_LEVEL_INFO, "Username or password error for user: %s", - s->username); - scp_v0s_replyauthentication(t, errorcode); - } - } - else if (data) - { - s_item = session_get_bydata(s->username, s->width, s->height, - s->bpp, s->type, s->connection_description); - - if (s_item != 0) - { - display = s_item->display; - s->guid = s_item->guid; - if (0 != s->connection_description) - { - LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d, ip %s", - s->username, display, s_item->pid, - s->connection_description); - } - else - { - LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d", s->username, display, - s_item->pid); - } - - session_reconnect(display, s->username, data); - } - else - { - LOG_DEVEL(LOG_LEVEL_DEBUG, "pre auth"); - - if (1 == access_login_allowed(s->username)) - { - struct guid guid = guid_new(); - - scp_session_set_guid(s, &guid); - - if (0 != s->connection_description) - { - LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->connection_description); - } - else - { - LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s", s->username); - } - - if (SCP_SESSION_TYPE_XVNC == s->type) - { - LOG( LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); - } - else if (SCP_SESSION_TYPE_XRDP == s->type) - { - LOG(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); - } - else if (SCP_SESSION_TYPE_XORG == s->type) - { - /* type is SCP_SESSION_TYPE_XORG */ - LOG(LOG_LEVEL_INFO, "starting Xorg session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XORG, s); - } - /* if the session started up ok, auth_end will be called on - sig child */ - do_auth_end = display == 0; - } - else - { - display = 0; - } - } - - if (display == 0) - { - scp_v0s_deny_connection(t); - } - else - { - scp_v0s_allow_connection(t, display, &s->guid); - } - } - else - { - char ip[64]; - g_get_ip_from_description(s->connection_description, ip, sizeof(ip)); - /* - * The message is intended for use by fail2ban, so for - * future-proofing we only log the IP address rather than the - * connection description */ - LOG(LOG_LEVEL_INFO, - "AUTHFAIL: user=%s ip=%s time=%d", - s->username, ip, g_time1()); - scp_v0s_deny_connection(t); - } - if (do_auth_end) - { - auth_end(data); - } - return SCP_SERVER_STATE_END; -} diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c deleted file mode 100644 index 91a47e07..00000000 --- a/sesman/scp_v1.c +++ /dev/null @@ -1,307 +0,0 @@ -/** - * 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 scp_v1.c - * @brief scp version 1 implementation - * @author Jay Sorg, Simone Fedele - * - */ - -#if defined(HAVE_CONFIG_H) -#include <config_ac.h> -#endif - -#include "sesman.h" - -//#include "libscp_types.h" -#include "libscp.h" - -static void -parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f); - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process1(struct trans *t, struct SCP_SESSION *s) -{ - int display = 0; - int scount; - long data; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION *slist; - bool_t do_auth_end = 1; - - if (s->retries == 0) - { - /* First time in */ - s->retries = g_cfg->sec.login_retry; - s->current_try = s->retries; - } - data = auth_userpass(s->username, s->password, NULL); - if (data == 0) - { - if ((s->retries == 0) || (s->current_try > 0)) - { - e = scp_v1s_request_password(t, s, "Wrong username and/or " - "password"); - switch (e) - { - case SCP_SERVER_STATE_OK: - /* one try less */ - if (s->current_try > 0) - { - s->current_try--; - } - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_list_sessions()"); - break; - } - } - else - { - char ip[64]; - g_get_ip_from_description(s->connection_description, - ip, sizeof(ip)); - /* - * The message is intended for use by fail2ban, so for - * future-proofing we only log the IP address rather than the - * connection description */ - LOG(LOG_LEVEL_INFO, - "AUTHFAIL: user=%s ip=%s time=%d", - s->username, ip, g_time1()); - scp_v1s_deny_connection(t, "Login failed"); - return SCP_SERVER_STATE_END; - } - return SCP_SERVER_STATE_OK; - } - - /* testing if login is allowed*/ - if (0 == access_login_allowed(s->username)) - { - scp_v1s_deny_connection(t, "Access to Terminal Server not allowed."); - LOG(LOG_LEVEL_INFO, "User %s not allowed on TS. " - "Connection terminated", s->username); - return SCP_SERVER_STATE_END; - } - - //check if we need password change - - /* list disconnected sessions */ - slist = session_get_byuser(s->username, &scount, - SESMAN_SESSION_STATUS_DISCONNECTED); - - if (scount == 0) - { - /* no disconnected sessions - start a new one */ - LOG(LOG_LEVEL_DEBUG, "No disconnected sessions for this user " - "- we create a new one"); - - if (0 != s->connection_description) - { - LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->connection_description); - } - else - { - LOG(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s", s->username); - } - - if (SCP_SESSION_TYPE_XVNC == s->type) - { - LOG(LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XVNC, s); - } - else if (SCP_SESSION_TYPE_XRDP == s->type) - { - LOG(LOG_LEVEL_INFO, "starting X11rdp session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XRDP, s); - } - else if (SCP_SESSION_TYPE_XORG == s->type) - { - LOG(LOG_LEVEL_INFO, "starting Xorg session..."); - display = session_start(data, SESMAN_SESSION_TYPE_XORG, s); - } - /* if the session started up ok, auth_end will be called on - sig child */ - do_auth_end = display == 0; - e = scp_v1s_connect_new_session(t, display); - switch (e) - { - case SCP_SERVER_STATE_OK: - /* all ok, we got new username and password */ - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_connect_new_session()"); - break; - } - } - else - { - e = scp_v1s_list_sessions40(t); - } - - /* cleanup */ - if (do_auth_end) - { - auth_end(data); - } - g_free(slist); - return SCP_SERVER_STATE_OK; -} - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process4(struct trans *t, struct SCP_SESSION *s) -{ - return SCP_SERVER_STATE_OK; -} - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process41(struct trans *t, struct SCP_SESSION *s) -{ - int scount; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION *slist; - - /* list disconnected sessions */ - slist = session_get_byuser(s->username, &scount, - SESMAN_SESSION_STATUS_DISCONNECTED); - - if (scount == 0) - { - /* */ - return SCP_SERVER_STATE_END; - } - - e = scp_v1s_list_sessions42(t, scount, slist); - if (SCP_SERVER_STATE_OK != e) - { - LOG(LOG_LEVEL_WARNING, "scp_v1s_list_sessions42 failed"); - } - - return SCP_SERVER_STATE_OK; -} - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process43(struct trans *t, struct SCP_SESSION *s) -{ - struct session_item *sitem; - enum SCP_SERVER_STATES_E e; - int display; - - sitem = session_get_bypid(s->return_sid); - if (0 == sitem) - { - e = scp_v1s_connection_error(t, "Internal error"); - LOG(LOG_LEVEL_INFO, "No session exists with PID %d", s->return_sid); - } - else - { - display = sitem->display; - e = scp_v1s_reconnect_session(t, display); - if (SCP_SERVER_STATE_OK != e) - { - LOG(LOG_LEVEL_ERROR, "scp_v1s_reconnect_session failed"); - } - if (0 != s->connection_description) - { - LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->connection_description); - } - else - { - LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); - } - g_free(sitem); - } - return e; -} - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process44(struct trans *t, struct SCP_SESSION *s) -{ - return SCP_SERVER_STATE_OK; -} - -/******************************************************************************/ -static enum SCP_SERVER_STATES_E -scp_v1_process45(struct trans *t, struct SCP_SESSION *s) -{ - return SCP_SERVER_STATE_OK; -} - -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v1_process(struct trans *t, struct SCP_SESSION *s) -{ - ; /* astyle 3.1 needs this, or the switch is badly formatted */ - switch (s->current_cmd) - { - case SCP_CMD_LOGIN: - return scp_v1_process1(t, s); - case SCP_CMD_RESEND_CREDS: - return scp_v1_process4(t, s); - case SCP_CMD_GET_SESSION_LIST: - return scp_v1_process41(t, s); - case SCP_CMD_SELECT_SESSION: - return scp_v1_process43(t, s); - case SCP_CMD_SELECT_SESSION_CANCEL: - return scp_v1_process44(t, s); - case SCP_CMD_FORCE_NEW_CONN: - return scp_v1_process45(t, s); - } - return SCP_SERVER_STATE_END; -} - -static void -parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f) -{ - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG(LOG_LEVEL_WARNING, "version error"); - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - LOG(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - LOG(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - LOG(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } -} diff --git a/sesman/scp_v1.h b/sesman/scp_v1.h deleted file mode 100644 index 4c509cd3..00000000 --- a/sesman/scp_v1.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * 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 scp_v1.h - * @brief scp version 1 declarations - * @author Simone Fedele - * - */ - -#ifndef SCP_V1_H -#define SCP_V1_H - -/** - * - * @brief processes the stream using scp version 1 - * @param in_sck connection socket - * @param in_s input stream - * @param out_s output stream - * - */ -enum SCP_SERVER_STATES_E -scp_v1_process(struct trans *t, struct SCP_SESSION *s); - -#endif diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c deleted file mode 100644 index 2b7ff216..00000000 --- a/sesman/scp_v1_mng.c +++ /dev/null @@ -1,134 +0,0 @@ -/** - * 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 scp_v1_mng.c - * @brief scp version 1 implementation - management - * @author Jay Sorg, Simone Fedele - * - */ - -#if defined(HAVE_CONFIG_H) -#include <config_ac.h> -#endif - -#include "sesman.h" - -#include "libscp.h" - -static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f); - -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s) -{ - long data; - enum SCP_SERVER_STATES_E e; - struct SCP_DISCONNECTED_SESSION *slist = 0; - int scount; - int end = 0; - - data = auth_userpass(s->username, s->password, NULL); - /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/ - - if (!data) - { - scp_v1s_mng_deny_connection(atrans, "Login failed"); - LOG(LOG_LEVEL_INFO, - "[MNG] Login failed for user %s. Connection terminated", s->username); - auth_end(data); - return SCP_SERVER_STATE_END; - } - - /* testing if login is allowed */ - if (0 == access_login_mng_allowed(s->username)) - { - scp_v1s_mng_deny_connection(atrans, "Access to Terminal Server not allowed."); - LOG(LOG_LEVEL_INFO, - "[MNG] User %s not allowed on TS. Connection terminated", s->username); - auth_end(data); - return SCP_SERVER_STATE_END; - } - - e = scp_v1s_mng_allow_connection(atrans, s); - - end = 1; - - while (end) - { - switch (e) - { - case SCP_SERVER_STATE_MNG_ACTION: - LOG(LOG_LEVEL_INFO, "Connection cancelled after session listing"); - break; - - case SCP_SERVER_STATE_MNG_LISTREQ: - /* list disconnected sessions */ - slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); - LOG_DEVEL(LOG_LEVEL_DEBUG, "sessions on TS: %d (slist: %p)", scount, slist); - if (0 == slist) - { - LOG(LOG_LEVEL_INFO, "No sessions on Terminal Server"); - } - - e = scp_v1s_mng_list_sessions(atrans, s, scount, slist); - g_free(slist); - break; - default: - /* we check the other errors */ - parseCommonStates(e, "scp_v1s_mng_list_sessions()"); - end = 0; - break; - } - } - - /* cleanup */ - auth_end(data); - return SCP_SERVER_STATE_END; -} - -static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f) -{ - switch (e) - { - case SCP_SERVER_STATE_VERSION_ERR: - LOG(LOG_LEVEL_WARNING, "version error"); - case SCP_SERVER_STATE_SIZE_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - LOG(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - LOG(LOG_LEVEL_WARNING, "libscp network error."); - break; - case SCP_SERVER_STATE_SEQUENCE_ERR: - LOG(LOG_LEVEL_WARNING, "libscp sequence error."); - break; - case SCP_SERVER_STATE_INTERNAL_ERR: - /* internal error occurred (eg. malloc() error, ecc.) */ - LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); - break; - default: - /* dummy: scp_v1s_request_password won't generate any other */ - /* error other than the ones before */ - LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f); - break; - } -} diff --git a/sesman/scp_v1_mng.h b/sesman/scp_v1_mng.h deleted file mode 100644 index b738de2f..00000000 --- a/sesman/scp_v1_mng.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * 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 scp_v1.h - * @brief scp version 1 declarations - management - * @author Simone Fedele - * - */ - -#ifndef SCP_V1_MNG_H -#define SCP_V1_MNG_H - -/** - * - * @brief processes the stream using scp version 1 - * @param atrans incoming transport - * @param s incoming session details - * - */ -enum SCP_SERVER_STATES_E -scp_v1_mng_process_msg(struct trans *atrans, struct SCP_SESSION *s); - -#endif diff --git a/sesman/sesman.c b/sesman/sesman.c index 3d15a83b..54a2267e 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -33,6 +33,9 @@ #include "sesman.h" #include "xrdp_configure_options.h" #include "string_calls.h" +#include "trans.h" + +#include "scp_process.h" /** * Maximum number of short-lived connections to sesman @@ -64,7 +67,6 @@ tintptr g_reload_event = 0; struct sesman_con { struct trans *t; - struct SCP_SESSION *s; }; static struct trans *g_list_trans; @@ -108,22 +110,10 @@ static struct sesman_con * alloc_connection(struct trans *t) { struct sesman_con *result; - struct SCP_SESSION *s; if ((result = g_new(struct sesman_con, 1)) != NULL) { - if ((s = scp_session_create()) != NULL) - { - result->t = t; - result->s = s; - /* Ensure we can find the connection easily from a callback */ - t->callback_data = (void *)result; - } - else - { - g_free(result); - result = NULL; - } + result->t = t; } return result; @@ -141,7 +131,6 @@ static void delete_connection(struct sesman_con *sc) { trans_delete(sc->t); - scp_session_destroy(sc->s); g_free(sc); } @@ -232,7 +221,7 @@ static int sesman_listen_test(struct config_sesman *cfg) LOG(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.", cfg->listen_address, cfg->listen_port); g_tcp_set_non_blocking(sck); - error = scp_tcp_bind(sck, cfg->listen_address, cfg->listen_port); + error = g_tcp_bind_address(sck, cfg->listen_port, cfg->listen_address); if (error == 0) { /* try to listen */ @@ -277,39 +266,21 @@ sesman_close_all(void) static int sesman_data_in(struct trans *self) { -#define HEADER_SIZE 8 - int version; - int size; + int rv; + int available; - if (self->extra_flags == 0) - { - in_uint32_be(self->in_s, version); - in_uint32_be(self->in_s, size); - if (size < HEADER_SIZE || size > self->in_s->size) - { - LOG(LOG_LEVEL_ERROR, "sesman_data_in: bad message size %d", size); - return 1; - } - self->header_size = size; - self->extra_flags = 1; - } - else + rv = scp_msg_in_check_available(self, &available); + + if (rv == 0 && available) { - /* process message */ - struct sesman_con *sc = (struct sesman_con *)self->callback_data; - self->in_s->p = self->in_s->data; - if (scp_process(self, sc->s) != SCP_SERVER_STATE_OK) + if ((rv = scp_process(self)) != 0) { LOG(LOG_LEVEL_ERROR, "sesman_data_in: scp_process_msg failed"); - return 1; } - /* reset for next message */ - self->header_size = HEADER_SIZE; - self->extra_flags = 0; - init_stream(self->in_s, 0); /* Reset input stream pointers */ + scp_msg_in_reset(self); } - return 0; -#undef HEADER_SIZE + + return rv; } /******************************************************************************/ @@ -323,7 +294,8 @@ sesman_listen_conn_in(struct trans *self, struct trans *new_self) "connections, rejecting"); trans_delete(new_self); } - else if ((sc = alloc_connection(new_self)) == NULL) + else if ((sc = alloc_connection(new_self)) == NULL || + scp_init_trans(new_self) != 0) { LOG(LOG_LEVEL_ERROR, "sesman_data_in: No memory to allocate " "new connection"); @@ -331,10 +303,8 @@ sesman_listen_conn_in(struct trans *self, struct trans *new_self) } else { - new_self->header_size = 8; + new_self->callback_data = (void *)sc; new_self->trans_data_in = sesman_data_in; - new_self->no_stream_init_on_data_in = 1; - new_self->extra_flags = 0; list_add_item(g_con_list, (intptr_t) sc); } @@ -775,10 +745,6 @@ main(int argc, char **argv) } } - /* libscp initialization */ - scp_init(); - - if (daemon) { /* start of daemonizing code */ diff --git a/sesman/sesman.h b/sesman/sesman.h index e7e7fe63..785810d6 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -39,8 +39,6 @@ #include "access.h" #include "scp.h" -#include "libscp.h" - /* Globals */ extern struct config_sesman *g_cfg; extern unsigned char g_fixedkey[8]; diff --git a/sesman/session.c b/sesman/session.c index 8be3855a..0eae928e 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -38,7 +38,6 @@ #endif #include "sesman.h" -#include "libscp_types.h" #include "xauth.h" #include "xrdp_sockets.h" #include "string_calls.h" @@ -87,58 +86,38 @@ 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) +session_get_bydata(const struct session_parameters *sp) { struct session_chain *tmp; enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy; char ip[64]; - - tmp = g_sessions; - - /* convert from SCP_SESSION_TYPE namespace to SESMAN_SESSION_TYPE namespace */ - switch (type) - { - case SCP_SESSION_TYPE_XVNC: /* 0 */ - type = SESMAN_SESSION_TYPE_XVNC; /* 2 */ - break; - case SCP_SESSION_TYPE_XRDP: /* 1 */ - type = SESMAN_SESSION_TYPE_XRDP; /* 1 */ - break; - case SCP_SESSION_TYPE_XORG: - type = SESMAN_SESSION_TYPE_XORG; - break; - default: - return 0; - } + char tmp_ip[64]; if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0) { /* We'll need to compare on IP addresses */ - g_get_ip_from_description(connection_description, ip, sizeof(ip)); + g_get_ip_from_description(sp->connection_description, + ip, sizeof(ip)); } else { ip[0] = '\0'; + tmp_ip[0] = '\0'; } 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); + policy, sp->username, sp->width, sp->height, sp->bpp, + sp->type, sp->connection_description); - while (tmp != 0) + for (tmp = g_sessions ; tmp != 0 ; tmp = tmp->next) { - char tmp_ip[64]; if ((policy & SESMAN_CFG_SESS_POLICY_I) != 0) { g_get_ip_from_description(tmp->item->connection_description, tmp_ip, sizeof (tmp_ip)); } - else - { - tmp_ip[0] = '\0'; - } LOG(LOG_LEVEL_DEBUG, "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s", @@ -148,20 +127,39 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, tmp->item->bpp, tmp->item->type, tmp->item->connection_description); - if (g_strncmp(name, tmp->item->name, 255) == 0 && - (!(policy & SESMAN_CFG_SESS_POLICY_D) || - (tmp->item->width == width && tmp->item->height == height)) && - (!(policy & SESMAN_CFG_SESS_POLICY_I) || - (g_strcmp(ip, tmp_ip) == 0)) && - (!(policy & SESMAN_CFG_SESS_POLICY_C) || - (g_strncmp(connection_description, tmp->item->connection_description, 255) == 0)) && - tmp->item->bpp == bpp && - tmp->item->type == type) + if (g_strncmp(sp->username, tmp->item->name, 255) != 0 || + tmp->item->bpp != sp->bpp || + tmp->item->type != sp->type) { - return tmp->item; + LOG(LOG_LEVEL_DEBUG, + "session_get_bydata: Basic parameters don't match"); + continue; } - tmp = tmp->next; + if ((policy & SESMAN_CFG_SESS_POLICY_D) && + (tmp->item->width != sp->width || tmp->item->height != sp->height)) + { + LOG(LOG_LEVEL_DEBUG, + "session_get_bydata: Dimensions don't match for 'D' policy"); + continue; + } + + if ((policy & SESMAN_CFG_SESS_POLICY_I) && g_strcmp(ip, tmp_ip) != 0) + { + LOG(LOG_LEVEL_DEBUG, + "session_get_bydata: IPs don't match for 'I' policy"); + continue; + } + + if ((policy & SESMAN_CFG_SESS_POLICY_C) && + g_strncmp(sp->connection_description, tmp->item->connection_description, 255) != 0) + { + LOG(LOG_LEVEL_DEBUG, + "session_get_bydata: connections don't match for 'C' policy"); + } + + LOG(LOG_LEVEL_DEBUG, "session_get_bydata: Got match"); + return tmp->item; } return 0; @@ -390,7 +388,7 @@ wait_for_xserver(int display) /******************************************************************************/ static int -session_start_chansrv(char *username, int display) +session_start_chansrv(const char *username, int display) { struct list *chansrv_params; char exe_path[262]; @@ -427,9 +425,11 @@ session_start_chansrv(char *username, int display) } /******************************************************************************/ -/* called with the main thread */ -static int -session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) + +int +session_start(long data, + const struct session_parameters *s, + struct guid *guid) { int display = 0; int pid = 0; @@ -443,16 +443,12 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) char **pp1 = (char **)NULL; struct session_chain *temp = (struct session_chain *)NULL; struct list *xserver_params = (struct list *)NULL; - struct tm stime; - time_t ltime; char authfile[256]; /* The filename for storing xauth informations */ int chansrv_pid; int display_pid; int window_manager_pid; /* initialize (zero out) local variables: */ - g_memset(<ime, 0, sizeof(time_t)); - g_memset(&stime, 0, sizeof(struct tm)); g_memset(geometry, 0, sizeof(char) * 32); g_memset(depth, 0, sizeof(char) * 32); g_memset(screen, 0, sizeof(char) * 32); @@ -496,6 +492,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) return 0; } + /* Create a GUID for the new session before we work */ + *guid = guid_new(); + pid = g_fork(); /* parent is fork from tcp accept, child forks X and wm, then becomes scp */ @@ -514,7 +513,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) /* Clone the session object, as the passed-in copy will be * deleted by sesman_close_all() */ - if ((s = scp_session_clone(s)) == NULL) + if ((s = clone_session_params(s)) == NULL) { LOG(LOG_LEVEL_ERROR, "Failed to clone the session data - out of memory"); @@ -603,23 +602,23 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) g_set_current_dir(s->directory); } } - if (s->program != 0 && s->program[0] != 0) + if (s->shell != 0 && s->shell[0] != 0) { - if (g_strchr(s->program, ' ') != 0 || g_strchr(s->program, '\t') != 0) + if (g_strchr(s->shell, ' ') != 0 || g_strchr(s->shell, '\t') != 0) { LOG(LOG_LEVEL_INFO, "Starting user requested window manager on " "display %d with embeded arguments using a shell: %s", - display, s->program); - const char *params[] = {"sh", "-c", s->program, NULL}; - g_execvp("/bin/sh", (char **)params); + display, s->shell); + const char *argv[] = {"sh", "-c", s->shell, NULL}; + g_execvp("/bin/sh", (char **)argv); } else { LOG(LOG_LEVEL_INFO, "Starting user requested window manager on " - "display %d: %s", display, s->program); - g_execlp3(s->program, s->program, 0); + "display %d: %s", display, s->shell); + g_execlp3(s->shell, s->shell, 0); } } else @@ -684,7 +683,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) } else if (display_pid == 0) /* child */ { - if (type == SESMAN_SESSION_TYPE_XVNC) + if (s->type == SCP_SESSION_TYPE_XVNC) { env_set_user(s->username, &passwd_file, @@ -733,7 +732,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) g_exit(1); } - if (type == SESMAN_SESSION_TYPE_XORG) + if (s->type == SCP_SESSION_TYPE_XORG) { #ifdef HAVE_SYS_PRCTL_H /* @@ -778,10 +777,10 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) g_sprintf(geometry, "%d", s->height); g_setenv("XRDP_START_HEIGHT", geometry, 1); } - else if (type == SESMAN_SESSION_TYPE_XVNC) + else if (s->type == SCP_SESSION_TYPE_XVNC) { char guid_str[GUID_STR_SIZE]; - guid_to_str(&s->guid, guid_str); + guid_to_str(guid, guid_str); env_check_password_file(passwd_file, guid_str); xserver_params = list_create(); xserver_params->auto_free = 1; @@ -804,7 +803,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) g_free(passwd_file); /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC, + //config_read_xserver_params(SCP_SESSION_TYPE_XVNC, // xserver_params); list_append_list_strdup(g_cfg->vnc_params, xserver_params, 1); @@ -812,7 +811,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) list_add_item(xserver_params, 0); pp1 = (char **)xserver_params->items; } - else if (type == SESMAN_SESSION_TYPE_XRDP) + else if (s->type == SCP_SESSION_TYPE_XRDP) { xserver_params = list_create(); xserver_params->auto_free = 1; @@ -831,7 +830,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) list_add_item(xserver_params, (tintptr)g_strdup(depth)); /* additional parameters from sesman.ini file */ - //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP, + //config_read_xserver_params(SCP_SESSION_TYPE_XRDP, // xserver_params); list_append_list_strdup(g_cfg->rdp_params, xserver_params, 1); @@ -841,7 +840,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) } else { - LOG(LOG_LEVEL_ERROR, "Unknown session type: %d", type); + LOG(LOG_LEVEL_ERROR, "Unknown session type: %d", + s->type); LOG(LOG_LEVEL_ERROR, "A fatal error has occured attempting " "to start the X server on display %d, aborting connection", display); @@ -958,19 +958,11 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) temp->item->data = data; g_strncpy(temp->item->connection_description, s->connection_description, 255); /* store client ip data */ g_strncpy(temp->item->name, s->username, 255); - temp->item->guid = s->guid; - - ltime = g_time1(); - localtime_r(<ime, &stime); - temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); - temp->item->connect_time.month = (tui8)(stime.tm_mon + 1); - temp->item->connect_time.day = (tui8)stime.tm_mday; - temp->item->connect_time.hour = (tui8)stime.tm_hour; - temp->item->connect_time.minute = (tui8)stime.tm_min; - zero_time(&(temp->item->disconnect_time)); - zero_time(&(temp->item->idle_time)); - - temp->item->type = type; + temp->item->guid = *guid; + + temp->item->start_time = g_time1(); + + temp->item->type = s->type; temp->item->status = SESMAN_SESSION_STATUS_ACTIVE; temp->next = g_sessions; @@ -986,9 +978,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_SESSION *s) } /******************************************************************************/ -/* called with the main thread */ -static int -session_reconnect_fork(int display, char *username, long data) +int +session_reconnect(int display, const char *username, long data) { int pid; @@ -1035,25 +1026,7 @@ session_reconnect_fork(int display, char *username, long data) } /******************************************************************************/ -/* called by a worker thread, ask the main thread to call session_sync_start - and wait till done */ -int -session_start(long data, tui8 type, struct SCP_SESSION *s) -{ - return session_start_fork(data, type, s); -} - -/******************************************************************************/ -/* called by a worker thread, ask the main thread to call session_sync_start - and wait till done */ -int -session_reconnect(int display, char *username, long data) -{ - return session_reconnect_fork(display, username, data); -} - -/******************************************************************************/ -int +enum session_kill_status session_kill(int pid) { struct session_chain *tmp; @@ -1180,11 +1153,11 @@ session_get_bypid(int pid) } /******************************************************************************/ -struct SCP_DISCONNECTED_SESSION * -session_get_byuser(const char *user, int *cnt, unsigned char flags) +struct scp_session_info * +session_get_byuser(const char *user, unsigned int *cnt, unsigned char flags) { struct session_chain *tmp; - struct SCP_DISCONNECTED_SESSION *sess; + struct scp_session_info *sess; int count; int index; @@ -1218,7 +1191,7 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags) } /* malloc() an array of disconnected sessions */ - sess = g_new0(struct SCP_DISCONNECTED_SESSION, count); + sess = g_new0(struct scp_session_info, count); if (sess == 0) { @@ -1229,43 +1202,31 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags) tmp = g_sessions; index = 0; - while (tmp != 0) + while (tmp != 0 && index < count) { /* #warning FIXME: we should get only disconnected sessions! */ if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { if ((tmp->item->status) & flags) { - (sess[index]).SID = tmp->item->pid; + (sess[index]).sid = tmp->item->pid; + (sess[index]).display = tmp->item->display; (sess[index]).type = tmp->item->type; (sess[index]).height = tmp->item->height; (sess[index]).width = tmp->item->width; (sess[index]).bpp = tmp->item->bpp; - /* #warning FIXME: setting idle times and such */ - /*(sess[index]).connect_time.year = tmp->item->connect_time.year; - (sess[index]).connect_time.month = tmp->item->connect_time.month; - (sess[index]).connect_time.day = tmp->item->connect_time.day; - (sess[index]).connect_time.hour = tmp->item->connect_time.hour; - (sess[index]).connect_time.minute = tmp->item->connect_time.minute; - (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; - (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; - (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; - (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; - (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; - (sess[index]).idle_time.year = tmp->item->idle_time.year; - (sess[index]).idle_time.month = tmp->item->idle_time.month; - (sess[index]).idle_time.day = tmp->item->idle_time.day; - (sess[index]).idle_time.hour = tmp->item->idle_time.hour; - (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ - (sess[index]).conn_year = tmp->item->connect_time.year; - (sess[index]).conn_month = tmp->item->connect_time.month; - (sess[index]).conn_day = tmp->item->connect_time.day; - (sess[index]).conn_hour = tmp->item->connect_time.hour; - (sess[index]).conn_minute = tmp->item->connect_time.minute; - (sess[index]).idle_days = tmp->item->idle_time.day; - (sess[index]).idle_hours = tmp->item->idle_time.hour; - (sess[index]).idle_minutes = tmp->item->idle_time.minute; + (sess[index]).start_time = tmp->item->start_time; + (sess[index]).username = g_strdup(tmp->item->name); + (sess[index]).connection_description = + g_strdup(tmp->item->connection_description); + if ((sess[index]).username == NULL || + (sess[index]).connection_description == NULL) + { + free_session_info_list(sess, *cnt); + (*cnt) = 0; + return 0; + } index++; } } @@ -1279,6 +1240,23 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags) } /******************************************************************************/ +void +free_session_info_list(struct scp_session_info *sesslist, unsigned int cnt) +{ + if (sesslist != NULL && cnt > 0) + { + unsigned int i; + for (i = 0 ; i < cnt ; ++i) + { + g_free(sesslist[i].username); + g_free(sesslist[i].connection_description); + } + } + + g_free(sesslist); +} + +/******************************************************************************/ int cleanup_sockets(int display) { @@ -1372,3 +1350,45 @@ cleanup_sockets(int display) return error; } + +/******************************************************************************/ +struct session_parameters * +clone_session_params(const struct session_parameters *sp) +{ + struct session_parameters *result; + char *strptr; + + /* Allocate a single block of memory big enough for the structure and + * all the strings it points to */ + unsigned int len = sizeof(*result); + len += g_strlen(sp->username) + 1; + len += g_strlen(sp->shell) + 1; + len += g_strlen(sp->directory) + 1; + len += g_strlen(sp->connection_description) + 1; + + if ((result = (struct session_parameters *)g_malloc(len, 0)) != NULL) + { + *result = *sp; /* Copy all the scalar parameters */ + + /* Initialise the string pointers in the result */ + strptr = (char *)result + sizeof(*result); + +#define COPY_STRING_MEMBER(src,dest)\ + {\ + unsigned int len = g_strlen(src) + 1;\ + g_memcpy(strptr, (src), len);\ + (dest) = strptr;\ + strptr += len;\ + } + + COPY_STRING_MEMBER(sp->username, result->username); + COPY_STRING_MEMBER(sp->shell, result->shell); + COPY_STRING_MEMBER(sp->directory, result->directory); + COPY_STRING_MEMBER(sp->connection_description, + result->connection_description); + +#undef COPY_STRING_MEMBER + } + + return result; +} diff --git a/sesman/session.h b/sesman/session.h index d2521bdb..d8a9fb82 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -28,12 +28,10 @@ #ifndef SESSION_H #define SESSION_H -#include "libscp_types.h" -#include "guid.h" +#include <time.h> -#define SESMAN_SESSION_TYPE_XRDP 1 -#define SESMAN_SESSION_TYPE_XVNC 2 -#define SESMAN_SESSION_TYPE_XORG 3 +#include "guid.h" +#include "scp_application_types.h" #define SESMAN_SESSION_STATUS_ACTIVE 0x01 #define SESMAN_SESSION_STATUS_IDLE 0x02 @@ -43,20 +41,14 @@ */ #define SESMAN_SESSION_STATUS_ALL 0xFF -#define SESMAN_SESSION_KILL_OK 0 -#define SESMAN_SESSION_KILL_NULLITEM 1 -#define SESMAN_SESSION_KILL_NOTFOUND 2 - -struct session_date +enum session_kill_status { - tui16 year; - tui8 month; - tui8 day; - tui8 hour; - tui8 minute; + SESMAN_SESSION_KILL_OK = 0, + SESMAN_SESSION_KILL_NULLITEM, + SESMAN_SESSION_KILL_NOTFOUND }; -#define zero_time(s) { (s)->year=0; (s)->month=0; (s)->day=0; (s)->hour=0; (s)->minute=0; } +struct scp_session_info; struct session_item { @@ -70,12 +62,12 @@ struct session_item /* status info */ unsigned char status; - unsigned char type; + enum scp_session_type type; /* time data */ - struct session_date connect_time; - struct session_date disconnect_time; - struct session_date idle_time; + time_t start_time; + // struct session_date disconnect_time; // Currently unused + // struct session_date idle_time; // Currently unused char connection_description[256]; struct guid guid; }; @@ -86,6 +78,22 @@ struct session_chain struct session_item *item; }; + +/** + * Information used to start or find a session + */ +struct session_parameters +{ + enum scp_session_type type; + unsigned short height; + unsigned short width; + unsigned char bpp; + const char *username; + const char *shell; + const char *directory; + const char *connection_description; +}; + /** * * @brief finds a session matching the supplied parameters @@ -93,10 +101,9 @@ struct session_chain * */ struct session_item * -session_get_bydata(const char *name, int width, int height, int bpp, int type, - const char *connection_description); +session_get_bydata(const struct session_parameters *params); #ifndef session_find_item -#define session_find_item(a, b, c, d, e, f) session_get_bydata(a, b, c, d, e, f); +#define session_find_item(a) session_get_bydata(a) #endif /** @@ -106,10 +113,12 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type, * */ int -session_start(long data, tui8 type, struct SCP_SESSION *s); +session_start(long authdata, + const struct session_parameters *params, + struct guid *guid); int -session_reconnect(int display, char *username, long data); +session_reconnect(int display, const char *username, long data); /** * @@ -118,7 +127,7 @@ session_reconnect(int display, char *username, long data); * @return * */ -int +enum session_kill_status session_kill(int pid); /** @@ -142,13 +151,24 @@ session_get_bypid(int pid); /** * - * @brief retrieves a session's descriptor - * @param pid the session pid - * @return a pointer to the session descriptor on success, NULL otherwise + * @brief retrieves session descriptions + * @param user the user for the sessions + * @return A block of session descriptions + * + * Pass the return result to free_session_info_list() after use + * + */ +struct scp_session_info * +session_get_byuser(const char *user, unsigned int *cnt, unsigned char flags); + +/** * + * @brief Frees the result of session_get_byuser() + * @param sesslist Resuit of session_get_byuser() + * @param cnt Number of entries in sess */ -struct SCP_DISCONNECTED_SESSION * -session_get_byuser(const char *user, int *cnt, unsigned char flags); +void +free_session_info_list(struct scp_session_info *sesslist, unsigned int cnt); /** * @@ -157,4 +177,15 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags); * @return non-zero value (number of errors) if failed */ int cleanup_sockets(int display); + +/** + * Clone a session_parameters structure + * + * @param sp Parameters to clone + * @return Cloned parameters, or NULL if no memory + * + * The cloned structure can be free'd with a single call to g_free() + */ +struct session_parameters * +clone_session_params(const struct session_parameters *sp); #endif |