summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
authorilsimo <ilsimo>2007-05-06 21:02:25 +0000
committerilsimo <ilsimo>2007-05-06 21:02:25 +0000
commitf22b5b42a74314af8c4232c86ccce968c6a37ce5 (patch)
tree83da9d21acb9b9c8bb04414228a85153ec972259 /sesman
parentd0e066ee8b0d428f6876bc32a97ce1e70420a65e (diff)
downloadxrdp-proprietary-f22b5b42a74314af8c4232c86ccce968c6a37ce5.tar.gz
xrdp-proprietary-f22b5b42a74314af8c4232c86ccce968c6a37ce5.zip
making libscp a real library
some fixes in configuration options
Diffstat (limited to 'sesman')
-rw-r--r--sesman/Makefile21
-rw-r--r--sesman/config.c85
-rw-r--r--sesman/config.h46
-rw-r--r--sesman/env.c15
-rw-r--r--sesman/libscp/Makefile54
-rw-r--r--sesman/libscp/libscp.h42
-rw-r--r--sesman/libscp/libscp_init.c59
-rw-r--r--sesman/libscp/libscp_init.c~59
-rw-r--r--sesman/libscp/libscp_init.h55
-rw-r--r--sesman/libscp/libscp_lock.c146
-rw-r--r--sesman/libscp/libscp_lock.h75
-rw-r--r--sesman/libscp/libscp_tcp.c130
-rw-r--r--sesman/libscp/libscp_tcp.h69
-rw-r--r--sesman/libscp/libscp_types.h127
-rw-r--r--sesman/libscp/libscp_v0.c247
-rw-r--r--sesman/libscp/libscp_v0.h77
-rw-r--r--sesman/libscp/libscp_v1c.c448
-rw-r--r--sesman/libscp/libscp_v1c.h64
-rw-r--r--sesman/libscp/libscp_v1s.c599
-rw-r--r--sesman/libscp/libscp_v1s.h87
-rw-r--r--sesman/libscp/libscp_vX.c53
-rw-r--r--sesman/libscp/libscp_vX.h48
-rw-r--r--sesman/lock.c113
-rw-r--r--sesman/lock.h42
-rw-r--r--sesman/sesman.c5
-rw-r--r--sesman/sesman.h2
-rw-r--r--sesman/session.c35
-rw-r--r--sesman/tools/Makefile27
-rw-r--r--sesman/tools/sesrun.c1
29 files changed, 2603 insertions, 228 deletions
diff --git a/sesman/Makefile b/sesman/Makefile
index 07d9efd3..8a8915c2 100644
--- a/sesman/Makefile
+++ b/sesman/Makefile
@@ -1,10 +1,9 @@
# sesman makefile
LIBSCPOBJ = libscp_vX.o libscp_v0.o libscp_v1s.o
-SESMANOBJ = sesman.o config.o tcp.o sig.o session.o env.o \
+SESMANOBJ = sesman.o config.o sig.o session.o env.o \
os_calls.o d3des.o list.o file.o log.o access.o \
- scp.o scp_v0.o scp_v1.o thread.o lock.o \
- $(LIBSCPOBJ)
+ scp.o scp_v0.o scp_v1.o thread.o lock.o
SESSVCOBJ = sessvc.o os_calls.o
@@ -19,18 +18,19 @@ DEFINES = -DSESMAN_CFG_FILE=\"$(CFGDIR)/sesman.ini\" \
-DSESMAN_SESSVC_FILE=\"$(DESTDIR)/sessvc\" \
-DDEBUG
-CFLAGS = -Wall -O2 -I../common -I/usr/include/nptl $(DEFINES)
-LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES)
+CFLAGS = -Wall -O2 -I../common -I/usr/include/nptl -I./libscp $(DEFINES)
+LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl -Wl,-rpath,./libscp -L./libscp -lscp $(DEFINES)
C_OS_FLAGS = $(CFLAGS) -c
CC = gcc
-all: pam tools
+all: libscp pam tools
-nopam: no-pam tools
+nopam: libscp no-pam tools
-kerberos: kerberos-base tools
+kerberos: libscp kerberos-base tools
no-pam: $(SESMANOBJ) verify_user.o
+ make -C libscp
$(CC) $(LDFLAGS) -o sesman $(SESMANOBJ) verify_user.o -lcrypt
pam: $(SESMANOBJ) verify_user_pam.o
@@ -48,9 +48,13 @@ sessvc: $(SESSVCOBJ)
tools: sessvc
make -C tools
+libscp:
+ make -C libscp
+
clean:
rm -f $(SESMANOBJ) verify_user.o verify_user_pam.o verify_user_pam_userpass.o sesman sesrun.o sesrun sessvc.o sessvc
make -C tools clean
+ make -C libscp clean
install:
install sesman $(DESTDIR)/sesman
@@ -58,6 +62,7 @@ install:
install sesman.ini $(CFGDIR)/sesman.ini
install sessvc $(DESTDIR)/sessvc
make -C tools install
+ make -C libscp install
installdeb:
install sesman $(DESTDIRDEB)/usr/lib/xrdp/sesman
diff --git a/sesman/config.c b/sesman/config.c
index 1b3bc4ab..5cb7c7ef 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -78,6 +78,10 @@ config_read", SESMAN_CFG_FILE);
/* read global config */
config_read_globals(fd, cfg, param_n, param_v);
+ /* read Xvnc/X11rdp parameter list */
+ config_read_vnc_params(fd, cfg, param_n, param_v);
+ config_read_rdp_params(fd, cfg, param_n, param_v);
+
/* read logging config */
config_read_logging(fd, &(cfg->log), param_n, param_v);
@@ -112,6 +116,7 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n,
cf->enable_user_wm = 0;
cf->user_wm[0] = '\0';
cf->default_wm[0] = '\0';
+ cf->auth_file_path = 0;
file_read_section(file, SESMAN_CFG_GLOBALS, param_n, param_v);
for (i = 0; i < param_n->count; i++)
@@ -137,6 +142,10 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n,
{
g_strncpy(cf->listen_address, (char*)list_get_item(param_v, i), 31);
}
+ else if (0 == g_strcasecmp(buf, SESMAN_CFG_AUTH_FILE_PATH))
+ {
+ cf->auth_file_path = g_strdup((char*)list_get_item(param_v, i));
+ }
}
/* checking for missing required parameters */
@@ -164,6 +173,7 @@ config_read_globals(int file, struct config_sesman* cf, struct list* param_n,
g_printf("\tEnableUserWindowManager: %i\r\n", cf->enable_user_wm);
g_printf("\tUserWindowManager: %s\r\n", cf->user_wm);
g_printf("\tDefaultWindowManager: %s\r\n", cf->default_wm);
+ g_printf("\tAuthFilePath: %s\r\n", ((cf->auth_file_path) ? (cf->auth_file_path) : ("disabled")));
return 0;
}
@@ -346,49 +356,58 @@ config_read_sessions(int file, struct config_sessions* se, struct list* param_n,
}
/******************************************************************************/
-/* returns in params a list of parameters that need to be freed */
-/* returns error */
int DEFAULT_CC
-config_read_xserver_params(int server_type, struct list* param_array)
+config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n,
+ struct list* param_v)
{
- struct list* names;
- struct list* params;
- int fd;
- char section_name[16];
+ int i;
- if (server_type == SESMAN_SESSION_TYPE_XRDP)
- {
- g_strncpy(section_name, "X11rdp", 15);
- }
- else if (server_type == SESMAN_SESSION_TYPE_XVNC)
+ list_clear(param_v);
+ list_clear(param_n);
+
+ cs->rdp_params=list_create();
+
+ file_read_section(file, SESMAN_CFG_RDP_PARAMS, param_n, param_v);
+ for (i = 0; i < param_n->count; i++)
{
- g_strncpy(section_name, "Xvnc", 15);
+ list_add_item(cs->rdp_params, (long)g_strdup((char*)list_get_item(param_v, i)));
}
- else
+
+ /* printing security config */
+ g_printf("X11rdp parameters:\r\n");
+ for (i = 0; i < cs->rdp_params->count; i++)
{
- /* error */
- log_message(LOG_LEVEL_ALWAYS, "error unknown type in \
-config_read_xserver_params");
- return 1;
+ g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->rdp_params, i));
}
- fd = g_file_open(SESMAN_CFG_FILE);
- if (-1 == fd)
+
+ return 0;
+}
+
+/******************************************************************************/
+int DEFAULT_CC
+config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n,
+ struct list* param_v)
+{
+ int i;
+
+ list_clear(param_v);
+ list_clear(param_n);
+
+ cs->vnc_params=list_create();
+
+ file_read_section(file, SESMAN_CFG_VNC_PARAMS, param_n, param_v);
+ for (i = 0; i < param_n->count; i++)
{
- /* error */
- log_message(LOG_LEVEL_ALWAYS, "error opening %s in \
-config_read_xserver_params %s", SESMAN_CFG_FILE, g_get_strerror());
- return 1;
+ list_add_item(cs->vnc_params, (long)g_strdup((char*)list_get_item(param_v, i)));
}
- names = list_create();
- names->auto_free = 1;
- params = list_create();
- params->auto_free = 1;
- if (file_read_section(fd, section_name, names, params) == 0)
+
+ /* printing security config */
+ g_printf("Xvnc parameters:\r\n");
+ for (i = 0; i < cs->vnc_params->count; i++)
{
- list_append_list_strdup(params, param_array, 0);
+ g_printf("\tParameter %02d %s\r\n", i, (char*)list_get_item(cs->vnc_params, i));
}
- g_file_close(fd);
- list_delete(names);
- list_delete(params);
+
return 0;
}
+
diff --git a/sesman/config.h b/sesman/config.h
index 3ecc345a..023c1f2d 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -49,6 +49,10 @@
#define SESMAN_CFG_ENABLE_USERWM "EnableUserWindowManager"
#define SESMAN_CFG_USERWM "UserWindowManager"
#define SESMAN_CFG_MAX_SESSION "MaxSessions"
+#define SESMAN_CFG_AUTH_FILE_PATH "AuthFilePath"
+
+#define SESMAN_CFG_RDP_PARAMS "X11rdp"
+#define SESMAN_CFG_VNC_PARAMS "Xvnc"
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
@@ -168,6 +172,21 @@ struct config_sesman
*/
char user_wm[32];
/**
+ * @var auth_file_path
+ * @brief Auth file path
+ */
+ char* auth_file_path;
+ /**
+ * @var vnc_params
+ * @brief Xvnc additional parameter list
+ */
+struct list* vnc_params;
+ /**
+ * @var rdp_params
+ * @brief X11rdp additional parameter list
+ */
+struct list* rdp_params;
+ /**
* @var log
* @brief Log configuration struct
*/
@@ -252,13 +271,32 @@ config_read_sessions(int file, struct config_sessions* ss,
/**
*
- * @brief Reads sesman [X11rdp, Xvnc, ...] configuration section
- * @param server_type integer representing server type
- * @param param_array pointer to list to add strings to
+ * @brief Reads sesman [X11rdp] configuration section
+ * @param file configuration file descriptor
+ * @param cs pointer to a config_sesman struct
+ * @param param_n parameter name list
+ * @param param_v parameter value list
+ * @return 0 on success, 1 on failure
+ *
+ */
+int DEFAULT_CC
+config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n,
+ struct list* param_v);
+
+
+/**
+ *
+ * @brief Reads sesman [Xvnc] configuration section
+ * @param file configuration file descriptor
+ * @param cs pointer to a config_sesman struct
+ * @param param_n parameter name list
+ * @param param_v parameter value list
* @return 0 on success, 1 on failure
*
*/
int DEFAULT_CC
-config_read_xserver_params(int server_type, struct list* param_array);
+config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n,
+ struct list* param_v);
#endif
+
diff --git a/sesman/env.c b/sesman/env.c
index 32984b50..53849e3a 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -31,6 +31,7 @@
#include "grp.h"
extern unsigned char g_fixedkey[8]; /* in sesman.c */
+extern struct config_sesman g_cfg;
/******************************************************************************/
int DEFAULT_CC
@@ -97,8 +98,18 @@ env_set_user(char* username, char* passwd_file, int display)
g_setenv("DISPLAY", text, 1);
if (passwd_file != 0)
{
- g_mkdir(".vnc");
- g_sprintf(passwd_file, "%s/.vnc/sesman_passwd", pw_dir);
+ if (0==g_cfg.auth_file_path)
+ {
+ /* if no auth_file_path is set, then we go for $HOME/.vnc/sesman_passwd */
+ g_mkdir(".vnc");
+ g_sprintf(passwd_file, "%s/.vnc/sesman_passwd", pw_dir);
+ }
+ else
+ {
+ /* we use auth_file_path as requested */
+ g_sprintf(passwd_file, g_cfg.auth_file_path, username);
+ }
+ LOG_DBG("pass file: %s", passwd_file);
}
}
}
diff --git a/sesman/libscp/Makefile b/sesman/libscp/Makefile
new file mode 100644
index 00000000..fde62d35
--- /dev/null
+++ b/sesman/libscp/Makefile
@@ -0,0 +1,54 @@
+# sesman makefile
+LIBSCPOBJ = libscp_vX.o libscp_v0.o \
+ libscp_v1s.o libscp_v1c.o \
+ libscp_init.o libscp_lock.o libscp_tcp.o \
+ os_calls.o
+
+DESTDIR = /usr/local/xrdp
+CFGDIR = /etc/xrdp
+PIDDIR = /var/run
+MANDIR = /usr/local/man
+DOCDIR = /usr/doc/xrdp
+LIBDIR = /usr/lib
+
+DESTDIRDEB = /tmp
+
+LIBSCPLNAME=libscp.so
+LIBSCPSONAME=$(LIBSCPLNAME).1
+LIBSCPFNAME=$(LIBSCPSONAME).0.0
+
+DEFINES = -DSESMAN_CFG_FILE=\"$(CFGDIR)/sesman.ini\" \
+ -DSESMAN_PID_FILE=\"$(PIDDIR)/sesman.pid\" \
+ -DSESMAN_SESSVC_FILE=\"$(DESTDIR)/sessvc\" \
+ -DDEBUG
+
+CFLAGS = -Wall -O2 -I../../common -I/usr/include/nptl -fPIC -g $(DEFINES)
+LDFLAGS = -shared -Wl,-soname,$(LIBSCPSONAME) -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread $(DEFINES)
+C_OS_FLAGS = $(CFLAGS) -c
+CC = gcc
+
+all: $(LIBSCPOBJ)
+ $(CC) $(LDFLAGS) -o $(LIBSCPFNAME) $(LIBSCPOBJ)
+ ln -s $(LIBSCPFNAME) $(LIBSCPLNAME)
+
+clean:
+ rm -f $(LIBSCPOBJ) $(LIBSCPFNAME) $(LIBSCPLNAME)
+
+install:
+ install $(LIBSCPFNAME) $(LIBDIR)/$(LIBSCPFNAME)
+ echo "cd $(LIBDIR) && ln -s $(LIBSCPSONAME) $(LIBSCPLNAME)" | /bin/sh
+ ldconfig
+
+installdeb:
+ install $(LIBSCPFNAME) $(DESTDIRDEB)/$(LIBDIR)/$(LIBSCPFNAME)
+ echo "cd $(DESTDIRDEB)/$(LIBDIR) && ln -s $(LIBSCPSONAME) $(LIBSCPLNAME)" | /bin/sh
+
+os_calls.o: ../../common/os_calls.c
+ $(CC) $(C_OS_FLAGS) ../../common/os_calls.c
+
+list.o: ../common/list.c
+ $(CC) $(C_OS_FLAGS) ../common/list.c
+
+log.o: ../common/log.c
+ $(CC) $(C_OS_FLAGS) -DLOG_ENABLE_THREAD ../common/log.c
+
diff --git a/sesman/libscp/libscp.h b/sesman/libscp/libscp.h
new file mode 100644
index 00000000..31aa367f
--- /dev/null
+++ b/sesman/libscp/libscp.h
@@ -0,0 +1,42 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp.h
+ * @brief libscp main header
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_H
+#define LIBSCP_H
+
+#include "libscp_types.h"
+
+#include "libscp_init.h"
+#include "libscp_tcp.h"
+#include "libscp_lock.h"
+
+#include "libscp_vX.h"
+#include "libscp_v0.h"
+#include "libscp_v1s.h"
+#include "libscp_v1c.h"
+
+#endif
diff --git a/sesman/libscp/libscp_init.c b/sesman/libscp/libscp_init.c
new file mode 100644
index 00000000..48c6b2c3
--- /dev/null
+++ b/sesman/libscp/libscp_init.c
@@ -0,0 +1,59 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_init.c
+ * @brief libscp initialization code
+ * @author Simone Fedele
+ *
+ */
+
+#include "libscp_init.h"
+
+/* server API */
+int DEFAULT_CC
+scp_init(void)
+{
+ scp_lock_init();
+
+ return 0;
+}
+
+struct SCP_CONNECTION*
+scp_make_connection(int sck)
+{
+ struct SCP_CONNECTION* conn;
+
+ conn = g_malloc(sizeof(struct SCP_CONNECTION), 0);
+
+ if (0 == conn)
+ {
+ return 0;
+ }
+
+ conn->in_sck=sck;
+ make_stream(conn->in_s);
+ init_stream(conn->in_s, 8196);
+ make_stream(conn->out_s);
+ init_stream(conn->out_s, 8196);
+
+ return conn;
+}
+
diff --git a/sesman/libscp/libscp_init.c~ b/sesman/libscp/libscp_init.c~
new file mode 100644
index 00000000..fe4f205f
--- /dev/null
+++ b/sesman/libscp/libscp_init.c~
@@ -0,0 +1,59 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_init.c
+ * @brief libscp initialization code
+ * @author Simone Fedele
+ *
+ */
+
+#include "libscp_init.h"
+
+/* server API */
+int DEFAULT_CC
+scp_init(void)
+{
+ scp_lock_init();
+
+ return 0;
+}
+
+struct SCP_CONNECTION*
+scp_make_connection(int sck)
+{
+ struct SCP_CONNECTION* conn;
+
+ conn = g_malloc(sizeof(struct SCP_CONNECTION), 0);
+
+ if (0 == conn)
+ {
+ return 0;
+ }
+
+ conn->in_sck=sck;
+ make_stream(conn->in_s);
+ init_stream(conn->in_s, 8196);
+ make_stream(conn->out_s);
+ init_stream(conn->out_s, 8196);
+
+ return conn;
+}
+
diff --git a/sesman/libscp/libscp_init.h b/sesman/libscp/libscp_init.h
new file mode 100644
index 00000000..0ff3a449
--- /dev/null
+++ b/sesman/libscp/libscp_init.h
@@ -0,0 +1,55 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_init.h
+ * @brief libscp initialization code header
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_INIT_H
+#define LIBSCP_INIT_H
+
+#include "libscp.h"
+
+/**
+ *
+ * @brief version neutral server accept function
+ * @param c connection descriptor
+ * @param s session descriptor pointer address.
+ * it will return a newely allocated descriptor.
+ * It this memory needs to be g_free()d
+ *
+ */
+int DEFAULT_CC
+scp_init(void);
+
+/**
+ *
+ * @brief mmm
+ * @param sck
+ *
+ */
+struct SCP_CONNECTION*
+scp_make_connection(int sck);
+
+#endif
+
diff --git a/sesman/libscp/libscp_lock.c b/sesman/libscp/libscp_lock.c
new file mode 100644
index 00000000..abc110d6
--- /dev/null
+++ b/sesman/libscp/libscp_lock.c
@@ -0,0 +1,146 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+
+ session manager
+ linux only
+
+*/
+
+#include "libscp_lock.h"
+
+#include <semaphore.h>
+#include <pthread.h>
+
+pthread_mutex_t lock_fork; /* this lock protects the counters */
+pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
+sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
+sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */
+int lock_fork_forkers_count; /* threads that want to fork */
+int lock_fork_blockers_count; /* threads thar are blocking fork */
+int lock_fork_waiting_count; /* threads suspended until the fork finishes */
+
+void DEFAULT_CC
+scp_lock_init(void)
+{
+ /* initializing fork lock */
+ pthread_mutexattr_init(&lock_fork_attr);
+ pthread_mutex_init(&lock_fork, &lock_fork_attr);
+ sem_init(&lock_fork_req, 0, 0);
+ sem_init(&lock_fork_wait, 0, 0);
+
+ /* here we don't use locking because lock_init() should be called BEFORE */
+ /* any thread is created */
+ lock_fork_blockers_count=0;
+ lock_fork_waiting_count=0;
+ lock_fork_forkers_count=0;
+}
+
+/******************************************************************************/
+void DEFAULT_CC
+scp_lock_fork_request(void)
+{
+ /* lock mutex */
+ pthread_mutex_lock(&lock_fork);
+ if (lock_fork_blockers_count == 0)
+ {
+ /* if noone is blocking fork(), then we're allowed to fork */
+ sem_post(&lock_fork_req);
+ }
+ lock_fork_forkers_count++;
+ pthread_mutex_unlock(&lock_fork);
+
+ /* we wait to be allowed to fork() */
+ sem_wait(&lock_fork_req);
+}
+
+/******************************************************************************/
+void DEFAULT_CC
+scp_lock_fork_release(void)
+{
+ pthread_mutex_lock(&lock_fork);
+ lock_fork_forkers_count--;
+
+ /* if there's someone else that want to fork, we let him fork() */
+ if (lock_fork_forkers_count > 0)
+ {
+ sem_post(&lock_fork_req);
+ }
+
+ for (;lock_fork_waiting_count > 0; lock_fork_waiting_count--)
+ {
+ /* waking up the other processes */
+ sem_post(&lock_fork_wait);
+ }
+ pthread_mutex_unlock(&lock_fork);
+}
+
+/******************************************************************************/
+void DEFAULT_CC
+scp_lock_fork_critical_section_end(int blocking)
+{
+ //LOG_DBG("lock_fork_critical_secection_end()",0);
+ /* lock mutex */
+ pthread_mutex_lock(&lock_fork);
+
+ if (blocking == LIBSCP_LOCK_FORK_BLOCKER)
+ {
+ lock_fork_blockers_count--;
+ }
+
+ /* if there's someone who wants to fork and we're the last blocking */
+ /* then we let him go */
+ if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count>0))
+ {
+ sem_post(&lock_fork_req);
+ }
+ pthread_mutex_unlock(&lock_fork);
+}
+
+/******************************************************************************/
+int DEFAULT_CC
+scp_lock_fork_critical_section_start(void)
+{
+ //LOG_DBG("lock_fork_critical_secection_start()",0);
+ do
+ {
+ pthread_mutex_lock(&lock_fork);
+
+ /* someone requested to fork */
+ if (lock_fork_forkers_count > 0)
+ {
+ lock_fork_waiting_count++;
+ pthread_mutex_unlock(&lock_fork);
+
+ /* we wait until the fork finishes */
+ sem_wait(&lock_fork_wait);
+
+ }
+ else
+ {
+ /* no fork, so we can go on... */
+ lock_fork_blockers_count++;
+ pthread_mutex_unlock(&lock_fork);
+
+ return LIBSCP_LOCK_FORK_BLOCKER;
+ }
+ } while (1);
+
+ /* we'll never get here */
+ return LIBSCP_LOCK_FORK_WAITING;
+}
+
diff --git a/sesman/libscp/libscp_lock.h b/sesman/libscp/libscp_lock.h
new file mode 100644
index 00000000..5e29c302
--- /dev/null
+++ b/sesman/libscp/libscp_lock.h
@@ -0,0 +1,75 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+#ifndef LIBSCP_LOCK_H
+#define LIBSCP_LOCK_H
+
+#include "libscp_types.h"
+
+#define LIBSCP_LOCK_FORK_BLOCKER 1
+#define LIBSCP_LOCK_FORK_WAITING 0
+
+/**
+ *
+ * @brief initializes all the locks
+ *
+ */
+void DEFAULT_CC
+scp_lock_init(void);
+
+/**
+ *
+ * @brief requires to fork a new child process
+ *
+ */
+void DEFAULT_CC
+scp_lock_fork_request(void);
+
+/**
+ *
+ * @brief releases a fork() request
+ *
+ */
+void DEFAULT_CC
+scp_lock_fork_release(void);
+
+/**
+ *
+ * @brief starts a section that is critical for forking
+ *
+ * starts a section that is critical for forking, that is noone can fork()
+ * while i'm in a critical section. But if someone wanted to fork we have
+ * to wait until he finishes with lock_fork_release()
+ *
+ * @return
+ *
+ */
+int DEFAULT_CC
+scp_lock_fork_critical_section_start(void);
+
+/**
+ *
+ * @brief closes the critical section
+ *
+ */
+void DEFAULT_CC
+scp_lock_fork_critical_section_end(int blocking);
+
+#endif
+
diff --git a/sesman/libscp/libscp_tcp.c b/sesman/libscp/libscp_tcp.c
new file mode 100644
index 00000000..25693099
--- /dev/null
+++ b/sesman/libscp/libscp_tcp.c
@@ -0,0 +1,130 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file tcp.c
+ * @brief Tcp stream funcions
+ * @author Jay Sorg, Simone Fedele
+ *
+ */
+
+#include "libscp_tcp.h"
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*****************************************************************************/
+int DEFAULT_CC
+scp_tcp_force_recv(int sck, char* data, int len)
+{
+ int rcvd;
+ int block;
+
+ block = scp_lock_fork_critical_section_start();
+
+ while (len > 0)
+ {
+ rcvd = g_tcp_recv(sck, data, len, 0);
+ if (rcvd == -1)
+ {
+ if (g_tcp_last_error_would_block(sck))
+ {
+ g_sleep(1);
+ }
+ else
+ {
+ scp_lock_fork_critical_section_end(block);
+ return 1;
+ }
+ }
+ else if (rcvd == 0)
+ {
+ scp_lock_fork_critical_section_end(block);
+ return 1;
+ }
+ else
+ {
+ data += rcvd;
+ len -= rcvd;
+ }
+ }
+
+ scp_lock_fork_critical_section_end(block);
+
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+scp_tcp_force_send(int sck, char* data, int len)
+{
+ int sent;
+ int block;
+
+ block = scp_lock_fork_critical_section_start();
+
+ while (len > 0)
+ {
+ sent = g_tcp_send(sck, data, len, 0);
+ if (sent == -1)
+ {
+ if (g_tcp_last_error_would_block(sck))
+ {
+ g_sleep(1);
+ }
+ else
+ {
+ scp_lock_fork_critical_section_end(block);
+ return 1;
+ }
+ }
+ else if (sent == 0)
+ {
+ scp_lock_fork_critical_section_end(block);
+ return 1;
+ }
+ else
+ {
+ data += sent;
+ len -= sent;
+ }
+ }
+
+ scp_lock_fork_critical_section_end(block);
+
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+scp_tcp_bind(int sck, char* addr, char* port)
+{
+ struct sockaddr_in s;
+
+ memset(&s, 0, sizeof(struct sockaddr_in));
+ s.sin_family = AF_INET;
+ s.sin_port = htons(atoi(port));
+ s.sin_addr.s_addr = inet_addr(addr);
+ return bind(sck, (struct sockaddr*)&s, sizeof(struct sockaddr_in));
+}
+
diff --git a/sesman/libscp/libscp_tcp.h b/sesman/libscp/libscp_tcp.h
new file mode 100644
index 00000000..aa21c607
--- /dev/null
+++ b/sesman/libscp/libscp_tcp.h
@@ -0,0 +1,69 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_tcp.h
+ * @brief Tcp stream functions declarations
+ * @author Jay Sorg, Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_TCP_H
+#define LIBSCP_TCP_H
+
+#include "libscp.h"
+
+/**
+ *
+ * @brief Force receiving data from tcp stream
+ * @param sck The socket to read from
+ * @param data Data buffer
+ * @param len Data buffer size
+ * @return 0 on success, 1 on error
+ *
+ */
+int DEFAULT_CC
+scp_tcp_force_recv(int sck, char* data, int len);
+
+/**
+ *
+ * @brief Force sending data to tcp stream
+ * @param sck the socket to write to
+ * @param data Data buffer
+ * @param len Data buffer size
+ * @return 0 on success, 1 on error
+ *
+ */
+int DEFAULT_CC
+scp_tcp_force_send(int sck, char* data, int len);
+
+/**
+ *
+ * @brief Binds the listening socket
+ * @param sck Listening socket
+ * @param addr Listening address
+ * @param port Listening port
+ * @return 0 on success, -1 on error
+ *
+ */
+int DEFAULT_CC
+scp_tcp_bind(int sck, char* addr, char* port);
+
+#endif
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
new file mode 100644
index 00000000..d4cea660
--- /dev/null
+++ b/sesman/libscp/libscp_types.h
@@ -0,0 +1,127 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_types.h
+ * @brief libscp data types definitions
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_TYPES_H
+#define LIBSCP_TYPES_H
+
+#include "os_calls.h"
+#include "parse.h"
+#include "arch.h"
+//#include "log.h"
+
+#define SCP_SID tui32
+#define SCP_DISPLAY tui16
+
+#define SCP_RESOURCE_SHARING_REQUEST_YES 0x01
+#define SCP_RESOURCE_SHARING_REQUEST_NO 0x00
+
+#define SCP_SESSION_TYPE_XVNC 0x00
+#define SCP_SESSION_TYPE_XRDP 0x01
+
+#define SCP_ADDRESS_TYPE_IPV4 0x00
+#define SCP_ADDRESS_TYPE_IPV6 0x01
+
+#define SCP_COMMAND_SET_DEFAULT 0x0000
+#define SCP_COMMAND_SET_MANAGE 0x0001
+#define SCP_COMMAND_SET_RSR 0x0002
+
+#define SCP_SERVER_MAX_LIST_SIZE 100
+
+#define free_session(s) {g_free((s)->username); g_free((s)->password); g_free((s)->hostname); g_free(s);}
+
+struct SCP_CONNECTION
+{
+ int in_sck;
+ struct stream* in_s;
+ struct stream* out_s;
+};
+
+struct SCP_SESSION
+{
+ tui8 type;
+ tui32 version;
+ tui16 height;
+ tui16 width;
+ tui8 bpp;
+ tui8 rsr;
+ char locale[18];
+ char* username;
+ char* password;
+ char* hostname;
+ tui8 addr_type;
+ tui32 ipv4addr; //htons
+ tui32 ipv6addr; //should be 128bit
+ tui16 display;
+ char* errstr;
+};
+
+struct SCP_DISCONNECTED_SESSION
+{
+ tui32 SID;
+ tui8 type;
+ tui16 height;
+ tui16 width;
+ tui8 bpp;
+ tui8 idle_days;
+ tui8 idle_hours;
+ tui8 idle_minutes;
+};
+
+enum SCP_CLIENT_STATES_E
+{
+ SCP_CLIENT_STATE_OK,
+ SCP_CLIENT_STATE_NETWORK_ERR,
+ SCP_CLIENT_STATE_VERSION_ERR,
+ SCP_CLIENT_STATE_SEQUENCE_ERR,
+ SCP_CLIENT_STATE_SIZE_ERR,
+ SCP_CLIENT_STATE_INTERNAL_ERR,
+ SCP_CLIENT_STATE_SESSION_LIST,
+ SCP_CLIENT_STATE_LIST_OK,
+ SCP_CLIENT_STATE_RESEND_CREDENTIALS,
+ SCP_CLIENT_STATE_CONNECTION_DENIED,
+ SCP_CLIENT_STATE_PWD_CHANGE_REQ,
+ SCP_CLIENT_STATE_RECONNECT_SINGLE,
+ SCP_CLIENT_STATE_SELECTION_CANCEL,
+ SCP_CLIENT_STATE_END
+};
+
+enum SCP_SERVER_STATES_E
+{
+ SCP_SERVER_STATE_OK,
+ SCP_SERVER_STATE_VERSION_ERR,
+ SCP_SERVER_STATE_NETWORK_ERR,
+ SCP_SERVER_STATE_SEQUENCE_ERR,
+ SCP_SERVER_STATE_INTERNAL_ERR,
+ SCP_SERVER_STATE_SESSION_TYPE_ERR,
+ SCP_SERVER_STATE_SIZE_ERR,
+ SCP_SERVER_STATE_SELECTION_CANCEL,
+ /*SCP_SERVER_STATE_FORCE_NEW,*/
+ SCP_SERVER_STATE_START_MANAGE,
+ SCP_SERVER_STATE_END
+};
+
+#endif
diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c
new file mode 100644
index 00000000..e2cd206b
--- /dev/null
+++ b/sesman/libscp/libscp_v0.c
@@ -0,0 +1,247 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v0.c
+ * @brief libscp version 0 code
+ * @author Simone Fedele
+ *
+ */
+
+#include "libscp_v0.h"
+
+#include "os_calls.h"
+/* client API */
+/******************************************************************************/
+enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
+{
+ tui32 version;
+ tui32 size;
+ tui16 sz;
+
+ init_stream(c->in_s, c->in_s->size);
+ init_stream(c->out_s, c->in_s->size);
+
+ g_tcp_set_non_blocking(c->in_sck);
+ g_tcp_set_no_delay(c->in_sck);
+ s_push_layer(c->out_s, channel_hdr, 8);
+
+ if (s->type==SCP_SESSION_TYPE_XVNC)
+ {
+ out_uint16_be(c->out_s, 0); // code
+ }
+ else if (s->type==SCP_SESSION_TYPE_XRDP)
+ {
+ out_uint16_be(c->out_s, 10); // code
+ }
+ else
+ {
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ sz = g_strlen(s->username);
+ out_uint16_be(c->out_s, sz);
+ out_uint8a(c->out_s, s->username, sz);
+
+ sz = g_strlen(s->password);
+ out_uint16_be(c->out_s,sz);
+ out_uint8a(c->out_s, s->password, sz);
+ out_uint16_be(c->out_s, s->width);
+ out_uint16_be(c->out_s, s->height);
+ out_uint16_be(c->out_s, s->bpp);
+
+ s_mark_end(c->out_s);
+ s_pop_layer(c->out_s, channel_hdr);
+
+ out_uint32_be(c->out_s, 0); // version
+ out_uint32_be(c->out_s, c->out_s->end - c->out_s->data); // size
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (0 != version)
+ {
+ return SCP_CLIENT_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size < 14)
+ {
+ return SCP_CLIENT_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, sz);
+ if (3!=sz)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, sz);
+ if (1!=sz)
+ {
+ return SCP_CLIENT_STATE_CONNECTION_DENIED;
+ }
+
+ in_uint16_be(c->in_s, sz);
+ s->display=sz;
+
+ return SCP_CLIENT_STATE_END;
+}
+
+/* server API */
+/******************************************************************************/
+enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
+{
+ tui32 version=0;
+ tui32 size;
+ struct SCP_SESSION* session=0;
+ tui16 sz;
+ tui32 code=0;
+
+ if (!skipVchk)
+ {
+ if (0==scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ in_uint32_be(c->in_s, version);
+ if (version != 0)
+ {
+ return SCP_SERVER_STATE_VERSION_ERR;
+ }
+ }
+ else
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+ }
+
+ in_uint32_be(c->in_s, size);
+
+ init_stream(c->in_s, 8196);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size-8))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, code);
+
+ if (code == 0 || code == 10)
+ {
+ session = g_malloc(sizeof(struct SCP_SESSION),1);
+ if (0 == session)
+ {
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+
+ session->version=version;
+
+ if (code == 0)
+ {
+ session->type=SCP_SESSION_TYPE_XVNC;
+ }
+ else
+ {
+ session->type=SCP_SESSION_TYPE_XRDP;
+ }
+
+ /* reading username */
+ in_uint16_be(c->in_s, sz);
+ session->username=g_malloc(sz+1,0);
+ if (0==session->username)
+ {
+ g_free(session);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->username[sz]='\0';
+ in_uint8a(c->in_s, session->username, sz);
+
+ /* reading password */
+ in_uint16_be(c->in_s, sz);
+ session->password=g_malloc(sz+1,0);
+ if (0==session->password)
+ {
+ g_free(session->username);
+ g_free(session);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->password[sz]='\0';
+ in_uint8a(c->in_s, session->password, sz);
+
+ in_uint16_be(c->in_s, session->width);
+ in_uint16_be(c->in_s, session->height);
+ in_uint16_be(c->in_s, sz);
+ session->bpp=(unsigned char)sz;
+ }
+ else
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ (*s)=session;
+ return SCP_SERVER_STATE_OK;
+}
+
+/******************************************************************************/
+enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d)
+{
+ out_uint32_be(c->out_s, 0); /* version */
+ out_uint32_be(c->out_s, 14); /* size */
+ out_uint16_be(c->out_s, 3); /* cmd */
+ out_uint16_be(c->out_s, 1); /* data */
+ out_uint16_be(c->out_s, d); /* data */
+ s_mark_end(c->out_s);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ return SCP_SERVER_STATE_OK;
+}
+
+/******************************************************************************/
+enum SCP_SERVER_STATES_E scp_v0s_deny_connection(struct SCP_CONNECTION* c)
+{
+ out_uint32_be(c->out_s, 0); /* version */
+ out_uint32_be(c->out_s, 14); /* size */
+ out_uint16_be(c->out_s, 3); /* cmd */
+ out_uint16_be(c->out_s, 0); /* data */
+ out_uint16_be(c->out_s, 0); /* data */
+ s_mark_end(c->out_s);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ return SCP_SERVER_STATE_OK;
+}
diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h
new file mode 100644
index 00000000..567b10f9
--- /dev/null
+++ b/sesman/libscp/libscp_v0.h
@@ -0,0 +1,77 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v0.h
+ * @brief libscp version 0 declarations
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_V0_H
+#define LIBSCP_V0_H
+
+#include "libscp.h"
+
+/* client API */
+/**
+ *
+ * @brief connects to sesman using scp v0
+ * @param c connection descriptor
+ * @param s session descriptor
+ * @param d display
+ *
+ */
+enum SCP_CLIENT_STATES_E
+scp_v0c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
+
+/* server API */
+/**
+ *
+ * @brief processes the stream using scp version 0
+ * @param c connection descriptor
+ * @param s session descriptor
+ * @param skipVchk if set to !0 skips the version control (to be used after
+ * scp_vXs_accept() )
+ *
+ */
+enum SCP_SERVER_STATES_E
+scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
+
+/**
+ *
+ * @brief allows the connection to TS, returning the display port
+ * @param c connection descriptor
+ *
+ */
+enum SCP_SERVER_STATES_E
+scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d);
+
+/**
+ *
+ * @brief denies the connection to TS
+ * @param c connection descriptor
+ *
+ */
+enum SCP_SERVER_STATES_E
+scp_v0s_deny_connection(struct SCP_CONNECTION* c);
+
+#endif
+
diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c
new file mode 100644
index 00000000..a103649e
--- /dev/null
+++ b/sesman/libscp/libscp_v1c.c
@@ -0,0 +1,448 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v1c.c
+ * @brief libscp version 1 client api code
+ * @author Simone Fedele
+ *
+ */
+
+#include "libscp_v1c.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
+
+/* client API */
+/* 001 */
+enum SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
+{
+ tui8 sz;
+ tui32 size;
+
+ init_stream(c->out_s, c->out_s->size);
+ init_stream(c->in_s, c->in_s->size);
+
+ size=19+17+4+ g_strlen(s->hostname) + g_strlen(s->username) + g_strlen(s->password);
+ if (s->addr_type==SCP_ADDRESS_TYPE_IPV4)
+ {
+ size=size+4;
+ }
+ else
+ {
+ size=size+16;
+ }
+
+ /* sending request */
+
+ /* header */
+ out_uint32_be(c->out_s, 1); /* version */
+ out_uint32_be(c->out_s, size);
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
+ out_uint16_be(c->out_s, 1);
+
+ /* body */
+ out_uint8(c->out_s, s->type);
+ out_uint16_be(c->out_s, s->height);
+ out_uint16_be(c->out_s, s->width);
+ out_uint8(c->out_s, s->bpp);
+ out_uint8(c->out_s, s->rsr);
+ out_uint8p(c->out_s, s->locale, 17);
+ out_uint8(c->out_s, s->addr_type);
+
+ if (s->addr_type==SCP_ADDRESS_TYPE_IPV4)
+ {
+ out_uint32_be(c->out_s, s->ipv4addr);
+ }
+ else
+ {
+ #warning ipv6 address needed
+ }
+
+ sz=g_strlen(s->hostname);
+ out_uint8(c->out_s, sz);
+ out_uint8p(c->out_s, s->hostname, sz);
+ sz=g_strlen(s->username);
+ out_uint8(c->out_s, sz);
+ out_uint8p(c->out_s, s->username, sz);
+ sz=g_strlen(s->password);
+ out_uint8(c->out_s, sz);
+ out_uint8p(c->out_s, s->password, sz);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ /* wait for response */
+ return _scp_v1c_check_response(c, s);
+}
+
+/* 004 */
+enum SCP_CLIENT_STATES_E scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
+{
+ tui8 sz;
+ tui32 size;
+
+ init_stream(c->out_s, c->out_s->size);
+ init_stream(c->in_s, c->in_s->size);
+
+ size=12+2+g_strlen(s->username)+g_strlen(s->password);
+
+ /* sending request */
+ /* header */
+ out_uint32_be(c->out_s, 1); /* version */
+ out_uint32_be(c->out_s, size);
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
+ out_uint16_be(c->out_s, 4);
+
+ /* body */
+ sz=g_strlen(s->username);
+ out_uint8(c->out_s, sz);
+ out_uint8p(c->out_s, s->username, sz);
+ sz=g_strlen(s->password);
+ out_uint8(c->out_s, sz);
+ out_uint8p(c->out_s, s->password, sz);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ /* wait for response */
+ return _scp_v1c_check_response(c, s);
+}
+
+/* 021 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
+/* 022 */ enum SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
+
+/* 041 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s)
+{
+ tui32 version=1;
+ tui32 size=12;
+ tui16 cmd=41;
+ tui32 sescnt=0; /* total session number */
+ tui32 sestmp=0; /* additional total session number */
+ tui8 pktcnt=0; /* packet session count */
+ tui32 totalcnt=0; /* session counter */
+ tui8 continued=0; /* continue flag */
+ int firstpkt=1; /* "first packet" flag */
+ int idx;
+ struct SCP_DISCONNECTED_SESSION* ds=0;
+
+ init_stream(c->out_s, c->out_s->size);
+
+ /* we request session list */
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, size); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ do
+ {
+ /* then we wait for server response */
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_CLIENT_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_CLIENT_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size-8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd!=SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd!=42)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ if (firstpkt)
+ {
+ firstpkt = 0;
+ in_uint32_be(c->in_s, sescnt);
+ sestmp = sescnt;
+
+ ds = g_malloc(sizeof(struct SCP_DISCONNECTED_SESSION)*sescnt, 0);
+ if (ds == 0)
+ {
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ }
+ else
+ {
+ in_uint32_be(c->in_s, sestmp);
+ }
+ in_uint8(c->in_s, continued);
+ in_uint8(c->in_s, pktcnt);
+
+ for (idx=0; idx<pktcnt; idx++)
+ {
+ in_uint32_be(c->in_s, (ds[totalcnt]).SID); /* session id */
+ in_uint8(c->in_s, (ds[totalcnt]).type);
+ in_uint16_be(c->in_s, (ds[totalcnt]).height);
+ in_uint16_be(c->in_s, (ds[totalcnt]).width);
+ in_uint8(c->in_s, (ds[totalcnt]).bpp);
+ in_uint8(c->in_s, (ds[totalcnt]).idle_days);
+ in_uint8(c->in_s, (ds[totalcnt]).idle_hours);
+ in_uint8(c->in_s, (ds[totalcnt]).idle_minutes);
+ totalcnt++;
+ }
+ }
+ while (continued);
+
+ printf("fine\n");
+ /* return data... */
+ (*scount) = sescnt;
+ (*s) = ds;
+
+ return SCP_CLIENT_STATE_LIST_OK;
+}
+
+/* 043 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_select_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s, SCP_SID sid)
+{
+ tui32 version = 1;
+ tui32 size = 16;
+ tui16 cmd = 43;
+
+ init_stream(c->out_s, c->out_s->size);
+
+ /* sending our selection */
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, size); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ out_uint32_be(c->out_s, sid);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ /* waiting for response.... */
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_CLIENT_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_CLIENT_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ /* read the rest of the packet */
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size-8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != 46)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ /* session display */
+ in_uint16_be(c->in_s, (s->display));
+ /*we don't need to return any data other than the display */
+ /*because we already sent that */
+
+ return SCP_CLIENT_STATE_OK;
+}
+
+/* 044 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_select_session_cancel(struct SCP_CONNECTION* c)
+{
+ tui32 version = 1;
+ tui32 size = 12;
+ tui16 cmd = 44;
+
+ init_stream(c->out_s, c->out_s->size);
+
+ /* sending our selection */
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, size); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ return SCP_CLIENT_STATE_END;
+}
+
+static enum SCP_CLIENT_STATES_E _scp_v1c_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s)
+{
+ tui32 version;
+ tui32 size;
+ tui16 cmd;
+ tui16 dim;
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_CLIENT_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+
+ init_stream(c->in_s, c->in_s->size);
+ /* read the rest of the packet */
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, size-8))
+ {
+ return SCP_CLIENT_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd!=SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd)
+ if (cmd==2) /* connection denied */
+ {
+ in_uint16_be(c->in_s, dim);
+ if (s->errstr!=0)
+ {
+ g_free(s->errstr);
+ }
+ s->errstr=g_malloc(dim+1,0);
+ if (s->errstr==0)
+ {
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ in_uint8a(c->in_s, s->errstr, dim);
+ (s->errstr)[dim]='\0';
+
+ return SCP_CLIENT_STATE_CONNECTION_DENIED;
+ }
+ else if (cmd==3) /* resend usr/pwd */
+ {
+ in_uint16_be(c->in_s, dim);
+ if (s->errstr!=0)
+ {
+ g_free(s->errstr);
+ }
+ s->errstr=g_malloc(dim+1,0);
+ if (s->errstr==0)
+ {
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ in_uint8a(c->in_s, s->errstr, dim);
+ (s->errstr)[dim]='\0';
+
+ return SCP_CLIENT_STATE_RESEND_CREDENTIALS;
+ }
+ else if (cmd==20) /* password change */
+ {
+ in_uint16_be(c->in_s, dim);
+ if (s->errstr!=0)
+ {
+ g_free(s->errstr);
+ }
+ s->errstr=g_malloc(dim+1,0);
+ if (s->errstr==0)
+ {
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ in_uint8a(c->in_s, s->errstr, dim);
+ (s->errstr)[dim]='\0';
+
+ return SCP_CLIENT_STATE_PWD_CHANGE_REQ;
+ }
+ else if (cmd==30) /* display */
+ {
+ in_uint16_be(c->in_s, s->display);
+
+ return SCP_CLIENT_STATE_OK;
+ }
+ //else if (cmd==31) /* there's a disconnected session */
+ //{
+ // return SCP_CLIENT_STATE_RECONNECT_SINGLE;
+ //}
+ //else if (cmd==33) /* display of a disconnected session */
+ //{
+ // return SCP_CLIENT_STATE_RECONNECT;
+ //}
+ else if (cmd==40) /* session list */
+ {
+ return SCP_CLIENT_STATE_SESSION_LIST;
+ }
+
+ return SCP_CLIENT_STATE_SEQUENCE_ERR;
+}
+
diff --git a/sesman/libscp/libscp_v1c.h b/sesman/libscp/libscp_v1c.h
new file mode 100644
index 00000000..7b5b6fae
--- /dev/null
+++ b/sesman/libscp/libscp_v1c.h
@@ -0,0 +1,64 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v1c.h
+ * @brief libscp version 1 client api declarations
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_V1C_H
+#define LIBSCP_V1C_H
+
+#include "libscp.h"
+
+/* client API */
+/* 001 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
+
+/* 004 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_resend_credentials(struct SCP_CONNECTION* c, struct SCP_SESSION* s);
+
+/* 021 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass);
+
+/* 022 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c);
+
+/* 041 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount,
+ struct SCP_DISCONNECTED_SESSION** s);
+
+/* 043 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_select_session(struct SCP_CONNECTION* c, struct SCP_SESSION* s,
+ SCP_SID sid);
+
+/* 044 */
+enum SCP_CLIENT_STATES_E
+scp_v1c_select_session_cancel(struct SCP_CONNECTION* c);
+
+#endif
diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c
new file mode 100644
index 00000000..95ca1f56
--- /dev/null
+++ b/sesman/libscp/libscp_v1s.c
@@ -0,0 +1,599 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v1s.c
+ * @brief libscp version 1 server api code
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_V1S_C
+#define LIBSCP_V1S_C
+
+#include "libscp_v1s.h"
+
+/* server API */
+enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk)
+{
+ struct SCP_SESSION* session;
+ tui32 version;
+ tui32 size;
+ tui16 cmdset;
+ tui16 cmd;
+ tui8 sz;
+
+ if (!skipVchk)
+ {
+
+ if (0==scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ in_uint32_be(c->in_s, version);
+ if (version != 1)
+ {
+ return SCP_SERVER_STATE_VERSION_ERR;
+ }
+ }
+ else
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+ }
+ else
+ {
+ version=1;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_SERVER_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ /* reading command set */
+ in_uint16_be(c->in_s, cmdset);
+
+ /* if we are starting a management session */
+ if (cmdset==SCP_COMMAND_SET_MANAGE)
+ {
+ return SCP_SERVER_STATE_START_MANAGE;
+ }
+
+ /* if we started with resource sharing... */
+ if (cmdset==SCP_COMMAND_SET_RSR)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ /* reading command */
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != 1)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ session = g_malloc(sizeof(struct SCP_SESSION),1);
+ if (0 == session)
+ {
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->version=1;
+
+ in_uint8(c->in_s, session->type);
+ if ((session->type != SCP_SESSION_TYPE_XVNC) && (session->type != SCP_SESSION_TYPE_XRDP))
+ {
+ g_free(session);
+ return SCP_SERVER_STATE_SESSION_TYPE_ERR;
+ }
+
+ in_uint16_be(c->in_s,session->height);
+ in_uint16_be(c->in_s, session->width);
+ in_uint8(c->in_s, session->bpp);
+ in_uint8(c->in_s, session->rsr);
+ in_uint8a(c->in_s, session->locale, 17);
+ session->locale[17]='\0';
+
+ in_uint8(c->in_s, session->addr_type);
+ if (session->addr_type==SCP_ADDRESS_TYPE_IPV4)
+ {
+ in_uint32_be(c->in_s, session->ipv4addr);
+ }
+ else if (session->addr_type==SCP_ADDRESS_TYPE_IPV6)
+ {
+ #warning how to handle ipv6 addresses?
+ }
+
+ /* reading hostname */
+ in_uint8(c->in_s, sz);
+ session->hostname=g_malloc(sz+1,1);
+ if (0==session->hostname)
+ {
+ g_free(session);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->hostname[sz]='\0';
+ in_uint8a(c->in_s, session->hostname, sz);
+
+ /* reading username */
+ in_uint8(c->in_s, sz);
+ session->username=g_malloc(sz+1,1);
+ if (0==session->username)
+ {
+ g_free(session->hostname);
+ g_free(session);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->username[sz]='\0';
+ in_uint8a(c->in_s, session->username, sz);
+
+ /* reading password */
+ in_uint8(c->in_s, sz);
+ session->password=g_malloc(sz+1,1);
+ if (0==session->password)
+ {
+ g_free(session->username);
+ g_free(session->hostname);
+ g_free(session);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ session->password[sz]='\0';
+ in_uint8a(c->in_s, session->password, sz);
+
+ /* returning the struct */
+ (*s)=session;
+
+ return SCP_SERVER_STATE_OK;
+}
+
+enum SCP_SERVER_STATES_E
+scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason)
+{
+ int rlen;
+
+ init_stream(c->out_s,c->out_s->size);
+
+ /* forcing message not to exceed 64k */
+ rlen = g_strlen(reason);
+ if (rlen > 65535)
+ {
+ rlen = 65535;
+ }
+
+ out_uint32_be(c->out_s, 1);
+ /* packet size: 4 + 4 + 2 + 2 + 2 + strlen(reason)*/
+ /* version + size + cmdset + cmd + msglen + msg */
+ out_uint32_be(c->out_s, rlen+14);
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
+ out_uint16_be(c->out_s, 2);
+ out_uint16_be(c->out_s, rlen)
+ out_uint8p(c->out_s, reason, rlen);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, rlen+14))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ return SCP_SERVER_STATE_END;
+}
+
+enum SCP_SERVER_STATES_E
+scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason)
+{
+ tui8 sz;
+ char *ubuf;
+ char *pbuf;
+ tui32 version;
+ tui32 size;
+ tui16 cmdset;
+ tui16 cmd;
+ int rlen;
+
+ init_stream(c->in_s, c->in_s->size);
+ init_stream(c->out_s, c->out_s->size);
+
+ /* forcing message not to exceed 64k */
+ rlen = g_strlen(reason);
+ if (rlen > 65535)
+ {
+ rlen = 65535;
+ }
+
+ /* send password request */
+ version=1;
+ size=12;
+ cmdset=0;
+ cmd=3;
+
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, 14+rlen); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ out_uint16_be(c->out_s, rlen);
+ out_uint8p(c->out_s, reason, rlen);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14+rlen))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ /* receive password & username */
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_SERVER_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_SERVER_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmdset);
+ if (cmdset != SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != 4)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ /* reading username */
+ in_uint8(c->in_s, sz);
+ ubuf=g_malloc(sz+1,1);
+ if (0==ubuf)
+ {
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ ubuf[sz]='\0';
+ in_uint8a(c->in_s, ubuf, sz);
+
+ /* reading password */
+ in_uint8(c->in_s, sz);
+ pbuf=g_malloc(sz+1,1);
+ if (0==pbuf)
+ {
+ g_free(ubuf);
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ }
+ pbuf[sz]='\0';
+ in_uint8a(c->in_s, pbuf, sz);
+
+ /* replacing username and password */
+ g_free(s->username);
+ g_free(s->password);
+ s->username=ubuf;
+ s->password=pbuf;
+
+ return SCP_SERVER_STATE_OK;
+}
+
+/* 020 */
+enum SCP_SERVER_STATES_E
+scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw)
+{
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+}
+
+/* 023 */
+enum SCP_SERVER_STATES_E
+scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char* npw)
+{
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+}
+
+/* 030 */
+enum SCP_SERVER_STATES_E
+scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
+{
+ /* send password request */
+ tui32 version=1;
+ tui32 size=14;
+ tui16 cmd=30;
+
+ init_stream(c->out_s, c->out_s->size);
+
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, size); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ out_uint16_be(c->out_s, d); /* display */
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, 14))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ return SCP_SERVER_STATE_OK;
+}
+
+/* 032 */
+enum SCP_SERVER_STATES_E
+scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error)
+{
+ return SCP_SERVER_STATE_INTERNAL_ERR;
+ return SCP_SERVER_STATE_END;
+}
+
+/* 040 */
+enum SCP_SERVER_STATES_E
+scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt, struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid)
+{
+ tui32 version=1;
+ tui32 size=12;
+ tui16 cmd=40;
+ int pktcnt;
+ int idx;
+ int sidx;
+ int pidx;
+ struct SCP_DISCONNECTED_SESSION* cds;
+
+ /* first we send a notice that we have some disconnected sessions */
+ init_stream(c->out_s, c->out_s->size);
+
+ out_uint32_be(c->out_s, version); /* version */
+ out_uint32_be(c->out_s, size); /* size */
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */
+ out_uint16_be(c->out_s, cmd); /* cmd */
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ /* then we wait for client ack */
+#warning maybe this message could say if the session should be resized on
+#warning server side or client side
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_SERVER_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_SERVER_STATE_SIZE_ERR;
+ }
+
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != 41)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ /* calculating the number of packets to send */
+ pktcnt=sescnt/SCP_SERVER_MAX_LIST_SIZE;
+ if ((sescnt%SCP_SERVER_MAX_LIST_SIZE)!=0)
+ {
+ pktcnt++;
+ }
+
+ for (idx=0; idx<pktcnt; idx++)
+ {
+ /* ok, we send session session list */
+ init_stream(c->out_s, c->out_s->size);
+
+ /* size: ver+size+cmdset+cmd+sescnt+continue+count */
+ size=4+4+2+2+4+1+1;
+
+ /* header */
+ cmd=42;
+ s_push_layer(c->out_s, channel_hdr, 8);
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
+ out_uint16_be(c->out_s, cmd);
+
+ /* session count */
+ out_uint32_be(c->out_s, sescnt);
+
+ /* setting the continue flag */
+ if ((idx+1)*SCP_SERVER_MAX_LIST_SIZE >= sescnt)
+ {
+ out_uint8(c->out_s, 0);
+ /* setting session count for this packet */
+ pidx=sescnt-(idx*SCP_SERVER_MAX_LIST_SIZE);
+ out_uint8(c->out_s, pidx);
+ }
+ else
+ {
+ out_uint8(c->out_s, 1);
+ /* setting session count for this packet */
+ pidx=SCP_SERVER_MAX_LIST_SIZE;
+ out_uint8(c->out_s, pidx);
+ }
+
+ /* adding session descriptors */
+ for (sidx=0; sidx<pidx; sidx++)
+ {
+ /* shortcut to the current session to send */
+ cds=ds+((idx)*SCP_SERVER_MAX_LIST_SIZE)+sidx;
+
+ /* session data */
+ out_uint32_be(c->out_s, cds->SID); /* session id */
+ out_uint8(c->out_s, cds->type);
+ out_uint16_be(c->out_s, cds->height);
+ out_uint16_be(c->out_s, cds->width);
+ out_uint8(c->out_s, cds->bpp);
+ out_uint8(c->out_s, cds->idle_days);
+ out_uint8(c->out_s, cds->idle_hours);
+ out_uint8(c->out_s, cds->idle_minutes);
+
+ size = size + 13;
+ }
+
+ s_pop_layer(c->out_s, channel_hdr);
+ out_uint32_be(c->out_s, version);
+ out_uint32_be(c->out_s, size);
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+ }
+
+ /* we get the response */
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (8)))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+ if (version!=1)
+ {
+ return SCP_SERVER_STATE_VERSION_ERR;
+ }
+
+ in_uint32_be(c->in_s, size);
+ if (size<12)
+ {
+ return SCP_SERVER_STATE_SIZE_ERR;
+ }
+
+ /* rest of the packet */
+ init_stream(c->in_s, c->in_s->size);
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, (size-8)))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd != SCP_COMMAND_SET_DEFAULT)
+ {
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ in_uint16_be(c->in_s, cmd);
+ if (cmd == 43)
+ {
+ /* select session */
+ in_uint32_be(c->in_s, (*sid));
+
+ /* checking sid value */
+ for (idx=0; idx<sescnt; idx++)
+ {
+ /* the sid is valid */
+ if (ds[idx].SID==(*sid))
+ {
+ /* ok, session selected */
+ return SCP_SERVER_STATE_OK;
+ }
+ }
+
+ /* if we got here, the requested sid wasn't one from the list we sent */
+ /* we should kill the connection */
+ return SCP_CLIENT_STATE_INTERNAL_ERR;
+ }
+ else if (cmd == 44)
+ {
+ /* cancel connection */
+ return SCP_SERVER_STATE_SELECTION_CANCEL;
+ }
+// else if (cmd == 45)
+// {
+// /* force new connection */
+// return SCP_SERVER_STATE_FORCE_NEW;
+// }
+ else
+ {
+ /* wrong response */
+ return SCP_SERVER_STATE_SEQUENCE_ERR;
+ }
+
+ return SCP_SERVER_STATE_OK;
+}
+
+/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
+enum SCP_SERVER_STATES_E
+scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d)
+{
+ tui32 version = 1;
+ tui32 size = 14;
+ tui16 cmd = 46;
+
+ /* ok, we send session data and display */
+ init_stream(c->out_s, c->out_s->size);
+
+ /* header */
+ out_uint32_be(c->out_s, version);
+ out_uint32_be(c->out_s, size);
+ out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT);
+ out_uint16_be(c->out_s, cmd);
+
+ /* session data */
+ out_uint16_be(c->out_s, d); /* session display */
+ /*out_uint8(c->out_s, ds->type);
+ out_uint16_be(c->out_s, ds->height);
+ out_uint16_be(c->out_s, ds->width);
+ out_uint8(c->out_s, ds->bpp);
+ out_uint8(c->out_s, ds->idle_days);
+ out_uint8(c->out_s, ds->idle_hours);
+ out_uint8(c->out_s, ds->idle_minutes);*/
+ /* these last three are not really needed... */
+
+ if (0!=scp_tcp_force_send(c->in_sck, c->out_s->data, size))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ return SCP_SERVER_STATE_OK;
+}
+
+#endif
diff --git a/sesman/libscp/libscp_v1s.h b/sesman/libscp/libscp_v1s.h
new file mode 100644
index 00000000..6aeb4091
--- /dev/null
+++ b/sesman/libscp/libscp_v1s.h
@@ -0,0 +1,87 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_v1s.h
+ * @brief libscp version 1 server api declarations
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_V1S_H
+#define LIBSCP_V1S_H
+
+#include "libscp.h"
+
+/* server API */
+/**
+ *
+ * @brief processes the stream using scp version 1
+ * @param c connection descriptor
+ * @param s pointer to session descriptor pointer
+ * @param skipVchk if set to !0 skips the version control (to be used after
+ * scp_vXs_accept() )
+ *
+ * this function places in *s the address of a newely allocated SCP_SESSION structure
+ * that should be free()d
+ */
+enum SCP_SERVER_STATES_E
+scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk);
+
+/**
+ *
+ * @brief denies connection to sesman
+ * @param c connection descriptor
+ * @param reason pointer to a string containinge the reason for denying connection
+ *
+ */
+/* 002 */
+enum SCP_SERVER_STATES_E
+scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason);
+
+enum SCP_SERVER_STATES_E
+scp_v1s_request_password(struct SCP_CONNECTION* c, struct SCP_SESSION* s, char* reason);
+
+/* 020 */
+enum SCP_SERVER_STATES_E
+scp_v1s_request_pwd_change(struct SCP_CONNECTION* c, char* reason, char* npw);
+
+/* 023 */
+enum SCP_SERVER_STATES_E
+scp_v1s_pwd_change_error(struct SCP_CONNECTION* c, char* error, int retry, char* npw);
+
+/* 030 */
+enum SCP_SERVER_STATES_E
+scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
+
+/* 032 */
+enum SCP_SERVER_STATES_E
+scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error);
+
+/* 040 */
+enum SCP_SERVER_STATES_E
+scp_v1s_list_sessions(struct SCP_CONNECTION* c, int sescnt,
+ struct SCP_DISCONNECTED_SESSION* ds, SCP_SID* sid);
+
+/* 046 was: 031 struct SCP_DISCONNECTED_SESSION* ds, */
+enum SCP_SERVER_STATES_E
+scp_v1s_reconnect_session(struct SCP_CONNECTION* c, SCP_DISPLAY d);
+
+#endif
diff --git a/sesman/libscp/libscp_vX.c b/sesman/libscp/libscp_vX.c
new file mode 100644
index 00000000..791f8ba9
--- /dev/null
+++ b/sesman/libscp/libscp_vX.c
@@ -0,0 +1,53 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_vX.c
+ * @brief libscp version neutral code
+ * @author Simone Fedele
+ *
+ */
+
+#include "libscp_vX.h"
+
+/* server API */
+enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s)
+{
+ tui32 version;
+
+ /* reading version and packet size */
+ if (0!=scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
+ {
+ return SCP_SERVER_STATE_NETWORK_ERR;
+ }
+
+ in_uint32_be(c->in_s, version);
+
+ if (version == 0)
+ {
+ return scp_v0s_accept(c, s, 1);
+ }
+ else if (version == 1)
+ {
+ return scp_v1s_accept(c, s, 1);
+ }
+
+ return SCP_SERVER_STATE_VERSION_ERR;
+}
diff --git a/sesman/libscp/libscp_vX.h b/sesman/libscp/libscp_vX.h
new file mode 100644
index 00000000..af54cd8d
--- /dev/null
+++ b/sesman/libscp/libscp_vX.h
@@ -0,0 +1,48 @@
+/*
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ xrdp: A Remote Desktop Protocol server.
+ Copyright (C) Jay Sorg 2005-2007
+*/
+
+/**
+ *
+ * @file libscp_vX.h
+ * @brief libscp version neutral code header
+ * @author Simone Fedele
+ *
+ */
+
+#ifndef LIBSCP_VX_H
+#define LIBSCP_VX_H
+
+#include "libscp_types.h"
+
+#include "libscp_v0.h"
+#include "libscp_v1s.h"
+
+/* server API */
+/**
+ *
+ * @brief version neutral server accept function
+ * @param c connection descriptor
+ * @param s session descriptor pointer address.
+ * it will return a newely allocated descriptor.
+ * It this memory needs to be g_free()d
+ *
+ */
+enum SCP_SERVER_STATES_E scp_vXs_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s);
+
+#endif
diff --git a/sesman/lock.c b/sesman/lock.c
index 9aa3e621..d63f57ec 100644
--- a/sesman/lock.c
+++ b/sesman/lock.c
@@ -32,14 +32,6 @@ pthread_mutexattr_t lock_chain_attr; /* mutex attributes */
pthread_mutex_t lock_config; /* configuration access lock */
pthread_mutexattr_t lock_config_attr; /* mutex attributes */
-pthread_mutex_t lock_fork; /* this lock protects the counters */
-pthread_mutexattr_t lock_fork_attr; /* mutex attributes */
-sem_t lock_fork_req; /* semaphore on which the process that are going to fork suspend on */
-sem_t lock_fork_wait; /* semaphore on which the suspended process wait on */
-int lock_fork_forkers_count; /* threads that want to fork */
-int lock_fork_blockers_count; /* threads thar are blocking fork */
-int lock_fork_waiting_count; /* threads suspended until the fork finishes */
-
sem_t lock_socket;
void DEFAULT_CC
@@ -55,18 +47,6 @@ lock_init(void)
/* initializing config lock */
pthread_mutexattr_init(&lock_config_attr);
pthread_mutex_init(&lock_config, &lock_config_attr);
-
- /* initializing fork lock */
- pthread_mutexattr_init(&lock_fork_attr);
- pthread_mutex_init(&lock_chain, &lock_fork_attr);
- sem_init(&lock_fork_req, 0, 0);
- sem_init(&lock_fork_wait, 0, 0);
-
- /* here we don't use locking because lock_init() should be called BEFORE */
- /* any thread is created */
- lock_fork_blockers_count=0;
- lock_fork_waiting_count=0;
- lock_fork_forkers_count=0;
}
/******************************************************************************/
@@ -105,96 +85,3 @@ lock_socket_release(void)
sem_post(&lock_socket);
}
-/******************************************************************************/
-void DEFAULT_CC
-lock_fork_request(void)
-{
- /* lock mutex */
- pthread_mutex_lock(&lock_fork);
- if (lock_fork_blockers_count == 0)
- {
- /* if noone is blocking fork(), then we're allowed to fork */
- sem_post(&lock_fork_req);
- }
- lock_fork_forkers_count++;
- pthread_mutex_unlock(&lock_fork);
-
- /* we wait to be allowed to fork() */
- sem_wait(&lock_fork_req);
-}
-
-/******************************************************************************/
-void DEFAULT_CC
-lock_fork_release(void)
-{
- pthread_mutex_lock(&lock_fork);
- lock_fork_forkers_count--;
-
- /* if there's someone else that want to fork, we let him fork() */
- if (lock_fork_forkers_count > 0)
- {
- sem_post(&lock_fork_req);
- }
-
- for (;lock_fork_waiting_count > 0; lock_fork_waiting_count--)
- {
- /* waking up the other processes */
- sem_post(&lock_fork_wait);
- }
- pthread_mutex_unlock(&lock_fork);
-}
-
-/******************************************************************************/
-void DEFAULT_CC
-lock_fork_critical_section_end(int blocking)
-{
- LOG_DBG("lock_fork_critical_secection_end()",0);
- /* lock mutex */
- pthread_mutex_lock(&lock_fork);
-
- if (blocking == SESMAN_LOCK_FORK_BLOCKER)
- {
- lock_fork_blockers_count--;
- }
-
- /* if there's someone who wants to fork and we're the last blocking */
- /* then we let him go */
- if ((lock_fork_blockers_count == 0) && (lock_fork_forkers_count>0))
- {
- sem_post(&lock_fork_req);
- }
- pthread_mutex_unlock(&lock_fork);
-}
-
-/******************************************************************************/
-int DEFAULT_CC
-lock_fork_critical_section_start(void)
-{
- LOG_DBG("lock_fork_critical_secection_start()",0);
- do
- {
- pthread_mutex_lock(&lock_fork);
-
- /* someone requested to fork */
- if (lock_fork_forkers_count > 0)
- {
- lock_fork_waiting_count++;
- pthread_mutex_unlock(&lock_fork);
-
- /* we wait until the fork finishes */
- sem_wait(&lock_fork_wait);
-
- }
- else
- {
- /* no fork, so we can go on... */
- lock_fork_blockers_count++;
- pthread_mutex_unlock(&lock_fork);
-
- return SESMAN_LOCK_FORK_BLOCKER;
- }
- } while (1);
-
- /* we'll never get here */
- return SESMAN_LOCK_FORK_WAITING;
-}
diff --git a/sesman/lock.h b/sesman/lock.h
index 312bb045..045a8ffa 100644
--- a/sesman/lock.h
+++ b/sesman/lock.h
@@ -22,9 +22,6 @@
#include "sesman.h"
-#define SESMAN_LOCK_FORK_BLOCKER 1
-#define SESMAN_LOCK_FORK_WAITING 0
-
/**
*
* @brief initializes all the locks
@@ -81,42 +78,5 @@ lock_socket_acquire(void);
void DEFAULT_CC
lock_socket_release(void);
-/**
- *
- * @brief requires to fork a new child process
- *
- */
-void DEFAULT_CC
-lock_fork_request(void);
-
-/**
- *
- * @brief releases a fork() request
- *
- */
-void DEFAULT_CC
-lock_fork_release(void);
-
-/**
- *
- * @brief starts a section that is critical for forking
- *
- * starts a section that is critical for forking, that is noone can fork()
- * while i'm in a critical section. But if someone wanted to fork we have
- * to wait until he finishes with lock_fork_release()
- *
- * @return
- *
- */
-int DEFAULT_CC
-lock_fork_critical_section_start(void);
-
-/**
- *
- * @brief closes the critical section
- *
- */
-void DEFAULT_CC
-lock_fork_critical_section_end(int blocking);
-
#endif
+
diff --git a/sesman/sesman.c b/sesman/sesman.c
index b760a727..e3d7565e 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -50,7 +50,7 @@ sesman_main_loop(void)
log_message(LOG_LEVEL_INFO, "listening...");
g_sck = g_tcp_socket();
g_tcp_set_non_blocking(g_sck);
- error = tcp_bind(g_sck, g_cfg.listen_address, g_cfg.listen_port);
+ error = scp_tcp_bind(g_sck, g_cfg.listen_address, g_cfg.listen_port);
if (error == 0)
{
error = g_tcp_listen(g_sck);
@@ -213,6 +213,9 @@ main(int argc, char** argv)
g_exit(1);
}
+ /* libscp initialization */
+ scp_init();
+
if (daemon)
{
/* start of daemonizing code */
diff --git a/sesman/sesman.h b/sesman/sesman.h
index 774e2aad..349e78e3 100644
--- a/sesman/sesman.h
+++ b/sesman/sesman.h
@@ -36,7 +36,7 @@
#include "env.h"
#include "auth.h"
#include "config.h"
-#include "tcp.h"
+//#include "tcp.h"
#include "sig.h"
#include "session.h"
#include "access.h"
diff --git a/sesman/session.c b/sesman/session.c
index 95ab8488..868d82cc 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -217,7 +217,7 @@ for user %s denied", username);
/* we should need no more displays than this */
/* block all the threads running to enable forking */
- lock_fork_request();
+ scp_lock_fork_request();
while (x_server_running(display))
{
display++;
@@ -285,13 +285,18 @@ for user %s denied", username);
/* still a problem starting window manager just start xterm */
g_execlp3("xterm", "xterm", 0);
+
+ /* should not get here */
+ log_message(LOG_LEVEL_ALWAYS,"error starting xterm for user %s - pid %d",
+ username, g_getpid());
+ /* logging parameters */
+ /* no problem calling strerror for thread safety: other threads are blocked */
+ log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", errno, g_get_strerror());
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "another Xserver is already active on display %d", display);
}
- /* should not get here */
- log_message(LOG_LEVEL_ALWAYS,"error starting xterm for user %s - pid %d",
- username, g_getpid());
- /* logging parameters */
- /* no problem calling strerror for thread safety: other threads are blocked */
- log_message(LOG_LEVEL_DEBUG, "errno: %d, description: %s", errno, g_get_strerror());
log_message(LOG_LEVEL_DEBUG,"aborting connection...");
g_exit(0);
}
@@ -318,9 +323,12 @@ for user %s denied", username);
list_add_item(xserver_params, (long)g_strdup(depth));
list_add_item(xserver_params, (long)g_strdup("-rfbauth"));
list_add_item(xserver_params, (long)g_strdup(passwd_file));
+
/* additional parameters from sesman.ini file */
- config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
- xserver_params);
+ //config_read_xserver_params(SESMAN_SESSION_TYPE_XVNC,
+ // xserver_params);
+ list_append_list_strdup(g_cfg.vnc_params, xserver_params, 0);
+
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char**)xserver_params->items;
@@ -337,9 +345,12 @@ for user %s denied", username);
list_add_item(xserver_params, (long)g_strdup(geometry));
list_add_item(xserver_params, (long)g_strdup("-depth"));
list_add_item(xserver_params, (long)g_strdup(depth));
+
/* additional parameters from sesman.ini file */
- config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,
- xserver_params);
+ //config_read_xserver_params(SESMAN_SESSION_TYPE_XRDP,
+ // xserver_params);
+ list_append_list_strdup(g_cfg.rdp_params, xserver_params, 0);
+
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char**)xserver_params->items;
@@ -378,7 +389,7 @@ for user %s denied", username);
else /* parent sesman process */
{
/* let the other threads go on */
- lock_fork_release();
+ scp_lock_fork_release();
temp->item->pid = pid;
temp->item->display = display;
diff --git a/sesman/tools/Makefile b/sesman/tools/Makefile
index 585327d2..46ec9e50 100644
--- a/sesman/tools/Makefile
+++ b/sesman/tools/Makefile
@@ -1,15 +1,16 @@
# sesman tools makefile
-SESTESTOBJ = sestest.o tcp.o \
- os_calls.o d3des.o list.o file.o \
- libscp_v1c.o
+SESTESTOBJ = sestest.o \
+ os_calls.o
+# d3des.o list.o file.o \
+# libscp_v1c.o tcp.o
SESRUNOBJ = sesrun.o config.o tcp.o \
os_calls.o d3des.o list.o file.o log.o
DEFINES = -DLIBSCP_CLIENT
-CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl $(DEFINES)
-LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -lpthread -ldl $(DEFINES)
+CFLAGS = -Wall -O2 -I../../common -I../ -I/usr/include/nptl -I../libscp $(DEFINES)
+LDFLAGS = -L /usr/gnu/lib -I/usr/include/nptl -L/usr/lib/nptl -L../libscp -lpthread -ldl -lscp -Wl,-rpath,../libscp $(DEFINES)
#LDFLAGS = -L /usr/gnu/lib -ldl $(DEFINES)
C_OS_FLAGS = $(CFLAGS) -c -g
CC = gcc
@@ -25,26 +26,26 @@ srun: $(SESRUNOBJ)
os_calls.o: ../../common/os_calls.c
$(CC) $(C_OS_FLAGS) ../../common/os_calls.c
-d3des.o: ../../common/d3des.c
+#d3des.o: ../../common/d3des.c
$(CC) $(C_OS_FLAGS) ../../common/d3des.c
-list.o: ../../common/list.c
+#list.o: ../../common/list.c
$(CC) $(C_OS_FLAGS) ../../common/list.c
-file.o: ../../common/file.c
+#file.o: ../../common/file.c
$(CC) $(C_OS_FLAGS) ../../common/file.c
-log.o: ../../common/file.c
+log.o: ../../common/log.c
$(CC) $(C_OS_FLAGS) ../../common/log.c
-tcp.o: ../tcp.c
- $(CC) $(C_OS_FLAGS) ../tcp.c
+#tcp.o: tcp.c
+# $(CC) $(C_OS_FLAGS) ../tcp.c
config.o: ../config.c
$(CC) $(C_OS_FLAGS) ../config.c
-libscp_v1c.o: ../libscp_v1c.c
- $(CC) $(C_OS_FLAGS) ../libscp_v1c.c
+#libscp_v1c.o: ../libscp_v1c.c
+# $(CC) $(C_OS_FLAGS) ../libscp_v1c.c
clean:
rm -f *.o sestest sesrun
diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c
index 22ccf138..7db3b670 100644
--- a/sesman/tools/sesrun.c
+++ b/sesman/tools/sesrun.c
@@ -26,6 +26,7 @@
*/
#include "sesman.h"
+#include "tcp.h"
int g_sck;
int g_pid;