Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/sesman
diff options
context:
space:
mode:
authormatt335672 <30179339+matt335672@users.noreply.github.com>2022-02-14 12:16:42 +0300
committermatt335672 <30179339+matt335672@users.noreply.github.com>2022-03-15 13:45:00 +0300
commitc0cb03801c365664f936b81c52a9d0a79f702835 (patch)
treea8419149259a0a4e6c4f9767a17588d1f0c83f55 /sesman
parent6cf053c9df27179190541c126a57c8a8ceb6bf9d (diff)
Move sesman to new SCP interface
Diffstat (limited to 'sesman')
-rw-r--r--sesman/Makefile.am15
-rw-r--r--sesman/notes.txt59
-rw-r--r--sesman/scp.c88
-rw-r--r--sesman/scp.h45
-rw-r--r--sesman/scp_process.c277
-rw-r--r--sesman/scp_process.h (renamed from sesman/scp_v0.h)20
-rw-r--r--sesman/scp_v0.c174
-rw-r--r--sesman/scp_v1.c307
-rw-r--r--sesman/scp_v1.h41
-rw-r--r--sesman/scp_v1_mng.c134
-rw-r--r--sesman/scp_v1_mng.h40
-rw-r--r--sesman/sesman.c68
-rw-r--r--sesman/sesman.h2
-rw-r--r--sesman/session.c278
-rw-r--r--sesman/session.h93
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(&ltime, 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(&ltime, &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