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/libscp | |
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/libscp')
-rw-r--r-- | sesman/libscp/Makefile | 54 | ||||
-rw-r--r-- | sesman/libscp/libscp.h | 42 | ||||
-rw-r--r-- | sesman/libscp/libscp_init.c | 59 | ||||
-rw-r--r-- | sesman/libscp/libscp_init.c~ | 59 | ||||
-rw-r--r-- | sesman/libscp/libscp_init.h | 55 | ||||
-rw-r--r-- | sesman/libscp/libscp_lock.c | 146 | ||||
-rw-r--r-- | sesman/libscp/libscp_lock.h | 75 | ||||
-rw-r--r-- | sesman/libscp/libscp_tcp.c | 130 | ||||
-rw-r--r-- | sesman/libscp/libscp_tcp.h | 69 | ||||
-rw-r--r-- | sesman/libscp/libscp_types.h | 127 | ||||
-rw-r--r-- | sesman/libscp/libscp_v0.c | 247 | ||||
-rw-r--r-- | sesman/libscp/libscp_v0.h | 77 | ||||
-rw-r--r-- | sesman/libscp/libscp_v1c.c | 448 | ||||
-rw-r--r-- | sesman/libscp/libscp_v1c.h | 64 | ||||
-rw-r--r-- | sesman/libscp/libscp_v1s.c | 599 | ||||
-rw-r--r-- | sesman/libscp/libscp_v1s.h | 87 | ||||
-rw-r--r-- | sesman/libscp/libscp_vX.c | 53 | ||||
-rw-r--r-- | sesman/libscp/libscp_vX.h | 48 |
18 files changed, 2439 insertions, 0 deletions
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 |