From 71e7fc734d6160ae6c19e440db1266b30bdb667e Mon Sep 17 00:00:00 2001 From: ilsimo Date: Sun, 15 Oct 2006 13:08:08 +0000 Subject: [PATCH] first try for a scp protocol layer (aka libscp) --- sesman/Makefile | 5 +- sesman/libscp.h | 37 +++++++ sesman/libscp_types.h | 117 ++++++++++++++++++++++ sesman/libscp_v0.c | 188 ++++++++++++++++++++++++++++++++++ sesman/libscp_v0.h | 72 ++++++++++++++ sesman/libscp_v1c.h | 31 ++++++ sesman/libscp_v1s.c | 227 ++++++++++++++++++++++++++++++++++++++++++ sesman/libscp_v1s.h | 20 ++++ sesman/libscp_vX.c | 53 ++++++++++ sesman/libscp_vX.h | 48 +++++++++ sesman/scp.c | 72 ++++++++------ sesman/scp.h | 2 +- sesman/scp_v0.c | 103 ++++++++----------- sesman/scp_v0.h | 4 +- sesman/sesman.h | 2 + sesman/sig.c | 2 +- 16 files changed, 885 insertions(+), 98 deletions(-) create mode 100644 sesman/libscp.h create mode 100644 sesman/libscp_types.h create mode 100644 sesman/libscp_v0.c create mode 100644 sesman/libscp_v0.h create mode 100644 sesman/libscp_v1c.h create mode 100644 sesman/libscp_v1s.c create mode 100644 sesman/libscp_v1s.h create mode 100644 sesman/libscp_vX.c create mode 100644 sesman/libscp_vX.h diff --git a/sesman/Makefile b/sesman/Makefile index 4e2251c4..9dd94c45 100644 --- a/sesman/Makefile +++ b/sesman/Makefile @@ -1,7 +1,10 @@ # 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 \ os_calls.o d3des.o list.o file.o log.o access.o \ - scp.o scp_v0.o thread.o lock.o + scp.o scp_v0.o thread.o lock.o \ + $(LIBSCPOBJ) SESRUNOBJ = sesrun.o config.o tcp.o lock.o \ os_calls.o d3des.o list.o file.o log.o diff --git a/sesman/libscp.h b/sesman/libscp.h new file mode 100644 index 00000000..d4b412ba --- /dev/null +++ b/sesman/libscp.h @@ -0,0 +1,37 @@ +/* + 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-2006 +*/ + +/** + * + * @file libscp.h + * @brief libscp main header + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_H +#define LIBSCP_H + +#include "libscp_types.h" +#include "libscp_vX.h" +#include "libscp_v0.h" +#include "libscp_v1s.h" +//#include "libscp_v1c.h" + +#endif diff --git a/sesman/libscp_types.h b/sesman/libscp_types.h new file mode 100644 index 00000000..27ff9751 --- /dev/null +++ b/sesman/libscp_types.h @@ -0,0 +1,117 @@ +/* + 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-2006 +*/ + +/** + * + * @file libscp_types.h + * @brief libscp data types definitions + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_TYPES_H +#define LIBSCP_TYPES_H + +#include +#include + +#include "os_calls.h" +#include "parse.h" +#include "arch.h" + +//#warning sesman requires its own tcp streaming functions for threading safety +#include "tcp.h" + +#define SCP_SID uint32_t +#define SCP_DISPLAY uint16_t + +//#warning this should be an INT16 on every platform... +//typedef unsigned int SCP_DISPLAY_PORT; --> uint16_t is it portable? + +#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 + +struct SCP_CONNECTION +{ + int in_sck; + struct stream* in_s; + struct stream* out_s; +}; + +struct SCP_SESSION +{ + unsigned char type; + uint32_t version; + uint16_t height; + uint16_t width; + unsigned char bpp; + unsigned char rsr; + char locale[18]; + char* username; + char* password; + char* hostname; + unsigned char addr_type; + uint32_t ipv4addr; //htons + uint32_t ipv6addr; //should be 128bit + uint16_t display; + char* errstr; +}; + +struct SCP_DISCONNECTED_SESSION +{ + uint32_t SID; + unsigned char type; + uint16_t height; + uint16_t width; + unsigned char bpp; + unsigned char idle_days; + unsigned char idle_hours; + unsigned char idle_minutes; +}; + +enum SCP_CLIENT_STATES_E +{ + SCP_CLIENT_STATE_OK, + SCP_CLIENT_STATE_NETWORK_ERR +}; + +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_START_MANAGE, + SCP_SERVER_STATE_END +}; + +#endif diff --git a/sesman/libscp_v0.c b/sesman/libscp_v0.c new file mode 100644 index 00000000..363b2550 --- /dev/null +++ b/sesman/libscp_v0.c @@ -0,0 +1,188 @@ +/* + 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-2006 +*/ + +/** + * + * @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, SCP_DISPLAY* d) +{ + uint16_t 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); + + out_uint16_be(c->out_s, 10); // code + 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!=tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + return SCP_CLIENT_STATE_NETWORK_ERR; + } + + return SCP_CLIENT_STATE_OK; +} + +/* server API */ +/******************************************************************************/ +enum SCP_SERVER_STATES_E scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) +{ + uint32_t version=0; + uint32_t size; + struct SCP_SESSION* session=0; + uint16_t sz; + uint32_t code=0; + + if (!skipVchk) + { + if (0==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!=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; + + g_printf("session %x\n",session); + + 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) 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) 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; + } + + //reset_stream(c->in_s); + //reset_stream(c->out_s); + (*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!=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!=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_v0.h b/sesman/libscp_v0.h new file mode 100644 index 00000000..47789885 --- /dev/null +++ b/sesman/libscp_v0.h @@ -0,0 +1,72 @@ +/* + 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-2006 +*/ + +/** + * + * @file libscp_v0.h + * @brief libscp version 0 declarations + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_V0_H +#define LIBSCP_V0_H + +#include "libscp_types.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, SCP_DISPLAY* d); + +/* 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_v1c.h b/sesman/libscp_v1c.h new file mode 100644 index 00000000..0d7d299f --- /dev/null +++ b/sesman/libscp_v1c.h @@ -0,0 +1,31 @@ +#include "scp.h" + +#ifndef SCP_V1C_H +#define SCP_V1C_H + +enum SCP_CLIENY_STATES_E +{ + SCP_CLIENT_STATE_NO, + SCP_CLIENT_STATE_WRONGPWD, + SCP_CLIENT_STATE_PWDCHG_REQ, + SCP_CLIENT_STATE_PWDCHG_CANCEL, + SCP_CLIENT_STATE_, + +}; + +/* client API */ +/** + * + * + */ +/* 001 */ SCP_CLIENT_STATES_E scp_v1c_connect(struct SCP_CONNECTION* c, struct SCP_SESSION* s); + ritorna errore: o il display + +/* 021 */ SCP_CLIENT_STATES_E scp_v1c_pwd_change(struct SCP_CONNECTION* c, char* newpass); +/* 022 */ SCP_CLIENT_STATES_E scp_v1c_pwd_change_cancel(struct SCP_CONNECTION* c); + +/* ... */ SCP_CLIENT_STATES_E scp_v1c_get_session_list(struct SCP_CONNECTION* c, int* scount, struct SCP_DISCONNECTED_SESSION** s); +/* 041 */ SCP_CLIENT_STATES_E scp_v1c_select_session(struct SCP_CONNECTION* c, SCP_SID sid); +/* 042 */ SCP_CLIENT_STATES_E scp_v1c_select_session_cancel(struct SCP_CONNECTION* c); + +#endif diff --git a/sesman/libscp_v1s.c b/sesman/libscp_v1s.c new file mode 100644 index 00000000..0ff6e8ec --- /dev/null +++ b/sesman/libscp_v1s.c @@ -0,0 +1,227 @@ + +#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; + uint32_t version; + uint32_t size; + uint16_t cmdset; + uint16_t cmd; + unsigned char sz; + + if (!skipVchk) + { + + if (0==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; + } + } + + in_uint32_be(c->in_s, size); + if (size<12) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (0!=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 != 0) + { + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + session = g_malloc(sizeof(struct SCP_SESSION),1); + if (0 == session) return SCP_SERVER_STATE_INTERNAL_ERR; + + in_uint8(c->in_s, session->type); + if ((session->type != SCP_SESSION_TYPE_XVNC) && (session->type != SCP_SESSION_TYPE_XRDP)) + { + 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) 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) 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) return SCP_SERVER_STATE_INTERNAL_ERR; + session->password[sz]='\0'; + in_uint8a(c->in_s, session->password, sz); + + //leggo lo stream e ritorno la struttura + *s=session; + + return SCP_SERVER_STATE_OK; +} + +enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, char* reason) +{ + int rlen; + + /* 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!=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, char** pwd, char** user) +{ + unsigned char sz; + uint32_t version; + uint32_t size; + uint16_t cmdset; + uint16_t cmd; + + version=1; + size=12; + cmdset=0; + cmd=3; + + /* send password request */ + out_uint32_be(c->out_s, 1); /* version */ + out_uint32_be(c->out_s, 12); /* size */ + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); /* cmdset */ + out_uint16_be(c->out_s, 3); /* cmd */ + + if (0!=tcp_force_send(c->in_sck, c->out_s->data, 12)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } + + /* receive password & username */ +#warning check cmd seq +/* tcp_force_recv() + in_uint32_be() + in_uint32_be + in_uint16_be + in_uint16_be*/ + + /* reading username */ + in_uint8(c->in_s, sz); + (*user)=g_malloc(sz+1,1); + if (0==(*user)) return SCP_SERVER_STATE_INTERNAL_ERR; + (*user)[sz]='\0'; + in_uint8a(c->in_s, (*user), sz); + + /* reading password */ + in_uint8(c->in_s, sz); + (*pwd)=g_malloc(sz+1,1); + if (0==(*pwd)) return SCP_SERVER_STATE_INTERNAL_ERR; + (*pwd)[sz]='\0'; + in_uint8a(c->in_s, (*pwd), sz); + + return SCP_SERVER_STATE_INTERNAL_ERR; +} + +/* 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* s, 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* s, SCP_DISPLAY d) +{ + return SCP_SERVER_STATE_INTERNAL_ERR; +} +/* 031 */ +enum SCP_SERVER_STATES_E scp_v1s_reconnect_session(struct SCP_CONNECTION* s, SCP_DISPLAY d) +{ + return SCP_SERVER_STATE_INTERNAL_ERR; +} +/* 032 */ +enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* s, char* error) +{ + return SCP_SERVER_STATE_INTERNAL_ERR; +} +/* 040 */ +enum SCP_SERVER_STATES_E scp_v1s_list_sessions(struct SCP_CONNECTION* s, int sescnt, struct SCP_DISCONNECTED_SESSION** ds, SCP_SID* sid) +{ + return SCP_SERVER_STATE_INTERNAL_ERR; +} + +#endif diff --git a/sesman/libscp_v1s.h b/sesman/libscp_v1s.h new file mode 100644 index 00000000..241afba7 --- /dev/null +++ b/sesman/libscp_v1s.h @@ -0,0 +1,20 @@ + +#ifndef LIBSCP_V1S_H +#define LIBSCP_V1S_H + +#include "libscp_types.h" +//#include "os_calls.h" +//#include "tcp.h" + +/* server API */ +/* ... */ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk); +/* 002 */ enum SCP_SERVER_STATES_E scp_v1s_deny_connection(struct SCP_CONNECTION* c, 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* s, char* error, int retry, char* npw); +/* 030 */ enum SCP_SERVER_STATES_E scp_v1s_connect_new_session(struct SCP_CONNECTION* s, SCP_DISPLAY d); +/* 031 */ enum SCP_SERVER_STATES_E scp_v1s_reconnect_session(struct SCP_CONNECTION* s, SCP_DISPLAY d); +/* 032 */ enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* s, char* error); +/* 040 */ enum SCP_SERVER_STATES_E scp_v1s_list_sessions(struct SCP_CONNECTION* s, int sescnt, struct SCP_DISCONNECTED_SESSION** ds, SCP_SID* sid); + +#endif diff --git a/sesman/libscp_vX.c b/sesman/libscp_vX.c new file mode 100644 index 00000000..45520f1e --- /dev/null +++ b/sesman/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-2006 +*/ + +/** + * + * @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) +{ + uint32_t version; + + /* reading version and packet size */ + if (0!=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_vX.h b/sesman/libscp_vX.h new file mode 100644 index 00000000..1124322c --- /dev/null +++ b/sesman/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-2006 +*/ + +/** + * + * @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/scp.c b/sesman/scp.c index 45ca8ee4..8be9e090 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -35,55 +35,61 @@ extern int thread_sck; void* DEFAULT_CC scp_process_start(void* sck) { - int socket; - int version; - int size; - struct stream* in_s; - struct stream* out_s; + struct SCP_CONNECTION scon; + struct SCP_SESSION* sdata; /* making a local copy of the socket (it's on the stack) */ /* probably this is just paranoia */ - //socket = *((int*) sck); - socket = thread_sck; - LOG_DBG("started scp thread on socket %d", socket); + scon.in_sck = thread_sck; + LOG_DBG("started scp thread on socket %d", scon.in_sck); /* unlocking thread_sck */ lock_socket_release(); - make_stream(in_s); - make_stream(out_s); + make_stream(scon.in_s); + make_stream(scon.out_s); - init_stream(in_s, 8192); - if (tcp_force_recv(socket, in_s->data, 8) == 0) + init_stream(scon.in_s, 8192); + init_stream(scon.out_s, 8192); + + switch (scp_vXs_accept(&scon, &(sdata))) { - in_uint32_be(in_s, version); - in_uint32_be(in_s, size); - init_stream(in_s, 8192); - if (tcp_force_recv(socket, in_s->data, size - 8) == 0) - { - if (version == 0) + case SCP_SERVER_STATE_OK: + if (sdata->version == 0) { /* starts processing an scp v0 connection */ - scp_v0_process(socket, in_s, out_s); + scp_v0_process(&scon, sdata); } -#warning scp v1 is disabled - /* this is temporarily disabled... - else if (version == 1) - { - / * starts processing an scp v0 connection * / - //scp_v1_process(); - }*/ else { - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING,"unknown protocol version specified. connection refused."); + //scp_v1_process(); } - } + + case SCP_SERVER_STATE_VERSION_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(LOG_LEVEL_WARNING,"unknown protocol version specified. connection refused."); + break; + + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(LOG_LEVEL_WARNING,"libscp network error."); + break; + + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(LOG_LEVEL_WARNING,"libscp sequence error."); + break; + + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); } - g_tcp_close(socket); - free_stream(in_s); - free_stream(out_s); + + g_tcp_close(scon.in_sck); + free_stream(scon.in_s); + free_stream(scon.out_s); return 0; } diff --git a/sesman/scp.h b/sesman/scp.h index 713c7836..8da78b86 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -29,7 +29,7 @@ #define SCP_H #include "scp_v0.h" -//#include "scp_v1.h" +#include "libscp.h" /** * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index f31cd4ff..37d8a2cd 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -29,81 +29,62 @@ /******************************************************************************/ void DEFAULT_CC -scp_v0_process(int in_sck, struct stream* in_s, struct stream* out_s) +scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { - int code; - int i; - int width; - int height; - int bpp; - int display; - char user[256]; - char pass[256]; + int code=0; + int display=0; long data; struct session_item* s_item; - in_uint16_be(in_s, code); - if (code == 0 || code == 10) /* check username - password, */ - { /* start session */ - in_uint16_be(in_s, i); - in_uint8a(in_s, user, i); - user[i] = 0; - in_uint16_be(in_s, i); - in_uint8a(in_s, pass, i); - pass[i] = 0; - in_uint16_be(in_s, width); - in_uint16_be(in_s, height); - in_uint16_be(in_s, bpp); - data = auth_userpass(user, pass); - display = 0; - if (data) + data = auth_userpass(s->username, s->password); + + if (data) + { + s_item = session_get_bydata(s->username, s->width, s->height, s->bpp); + if (s_item != 0) { - s_item = session_get_bydata(user, width, height, bpp); - if (s_item != 0) - { - display = s_item->display; - auth_end(data); - /* don't set data to null here */ - } - else + display = s_item->display; + auth_end(data); + /* don't set data to null here */ + } + else + { + g_printf("pre auth"); + if (1 == access_login_allowed(s->username)) { - g_printf("pre auth"); - if (1 == access_login_allowed(user)) + log_message(LOG_LEVEL_INFO, "granted TS access to user %s", s->username); + if (0 == code) { - log_message(LOG_LEVEL_INFO, - "granted TS access to user %s", user); - if (0 == code) - { - log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); - display = session_start(width, height, bpp, user, pass, - data, SESMAN_SESSION_TYPE_XVNC); - } - else - { - log_message(LOG_LEVEL_INFO, "starting Xrdp session..."); - display = session_start(width, height, bpp, user, pass, - data, SESMAN_SESSION_TYPE_XRDP); - } + log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); + display = session_start(s->width, s->height, s->bpp, s->username, s->password, + data, SESMAN_SESSION_TYPE_XVNC); } else { - display = 0; + log_message(LOG_LEVEL_INFO, "starting Xrdp session..."); + display = session_start(s->width, s->height, s->bpp, s->username, s->password, + data, SESMAN_SESSION_TYPE_XRDP); } } - if (display == 0) + else { - auth_end(data); - data = 0; + display = 0; } } - init_stream(out_s, 8192); - out_uint32_be(out_s, 0); /* version */ - out_uint32_be(out_s, 14); /* size */ - out_uint16_be(out_s, 3); /* cmd */ - out_uint16_be(out_s, data != 0); /* data */ - out_uint16_be(out_s, display); /* data */ - s_mark_end(out_s); - tcp_force_send(in_sck, out_s->data, - out_s->end - out_s->data); + if (display == 0) + { + auth_end(data); + data = 0; + scp_v0s_deny_connection(c); + } + else + { + scp_v0s_allow_connection(c, display); + } + } + else + { + scp_v0s_deny_connection(c); } } + diff --git a/sesman/scp_v0.h b/sesman/scp_v0.h index 652348e4..08eae801 100644 --- a/sesman/scp_v0.h +++ b/sesman/scp_v0.h @@ -28,6 +28,8 @@ #ifndef SCP_V0_H #define SCP_V0_H +#include "libscp.h" + /** * * @brief processes the stream using scp version 0 @@ -37,6 +39,6 @@ * */ void DEFAULT_CC -scp_v0_process(int in_sck, struct stream* in_s, struct stream* out_s); +scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); #endif diff --git a/sesman/sesman.h b/sesman/sesman.h index 057044d8..3ee0c1c9 100644 --- a/sesman/sesman.h +++ b/sesman/sesman.h @@ -44,6 +44,8 @@ #include "thread.h" #include "lock.h" +#include "libscp.h" + #ifndef SESMAN_PID_FILE #define SESMAN_PID_FILE "./sesman.pid" #endif diff --git a/sesman/sig.c b/sesman/sig.c index 8527f60a..501a1050 100644 --- a/sesman/sig.c +++ b/sesman/sig.c @@ -135,7 +135,7 @@ sig_handler_thread(void* arg) sig_sesman_session_end(SIGCHLD); break; /*case SIGKILL; - /* we die * / + / * we die * / LOG_DBG("sesman received SIGKILL",0); sig_sesman_shutdown(recv_signal); break;*/