diff options
author | ilsimo <ilsimo> | 2007-05-06 21:02:25 +0000 |
---|---|---|
committer | ilsimo <ilsimo> | 2007-05-06 21:02:25 +0000 |
commit | f22b5b42a74314af8c4232c86ccce968c6a37ce5 (patch) | |
tree | 83da9d21acb9b9c8bb04414228a85153ec972259 /sesman | |
parent | d0e066ee8b0d428f6876bc32a97ce1e70420a65e (diff) | |
download | xrdp-proprietary-f22b5b42a74314af8c4232c86ccce968c6a37ce5.tar.gz xrdp-proprietary-f22b5b42a74314af8c4232c86ccce968c6a37ce5.zip |
making libscp a real library
some fixes in configuration options
Diffstat (limited to 'sesman')
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; |