From 7c7929861246310d48789748cc150c9a4a492e09 Mon Sep 17 00:00:00 2001 From: ilsimo Date: Thu, 11 Sep 2008 20:23:15 +0000 Subject: [PATCH] added first management code added a rough management tool fixes in session.c --- sesman/Makefile | 2 +- sesman/Makefile.am | 1 + sesman/libscp/Makefile | 2 +- sesman/libscp/Makefile.am | 2 + sesman/libscp/libscp.h | 6 +- sesman/libscp/libscp_commands.h | 36 +++ sesman/libscp/libscp_commands_mng.h | 39 ++++ sesman/libscp/libscp_session.c | 21 +- sesman/libscp/libscp_types.h | 7 +- sesman/libscp/libscp_types_mng.h | 48 ++++ sesman/libscp/libscp_v1s.c | 21 +- sesman/libscp/libscp_v1s_mng.c | 340 ++++++++++++++++++++++++++++ sesman/libscp/libscp_v1s_mng.h | 79 +++++++ sesman/scp.c | 2 +- sesman/scp.h | 4 +- sesman/scp_v1.c | 13 +- sesman/scp_v1_mng.c | 145 ++++++++++++ sesman/scp_v1_mng.h | 42 ++++ sesman/session.c | 130 +++++------ sesman/session.h | 11 +- sesman/tools/Makefile | 3 +- sesman/tools/Makefile.am | 11 +- sesman/tools/sesadmin.c | 195 ++++++++++++++++ 23 files changed, 1055 insertions(+), 105 deletions(-) create mode 100644 sesman/libscp/libscp_commands.h create mode 100644 sesman/libscp/libscp_commands_mng.h create mode 100644 sesman/libscp/libscp_types_mng.h create mode 100644 sesman/libscp/libscp_v1s_mng.c create mode 100644 sesman/libscp/libscp_v1s_mng.h create mode 100644 sesman/scp_v1_mng.c create mode 100644 sesman/scp_v1_mng.h create mode 100644 sesman/tools/sesadmin.c diff --git a/sesman/Makefile b/sesman/Makefile index 4483142d..f059fbe7 100644 --- a/sesman/Makefile +++ b/sesman/Makefile @@ -2,7 +2,7 @@ SESMANOBJ = sesman.o config.o sig.o session.o env.o \ os_calls.o d3des.o list.o file.o log.o access.o \ - scp.o scp_v0.o scp_v1.o thread.o lock.o + scp.o scp_v0.o scp_v1.o scp_v1_mng.o thread.o lock.o SESSVCOBJ = sessvc.o os_calls.o log.o diff --git a/sesman/Makefile.am b/sesman/Makefile.am index 22736e61..ab388ed0 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -28,6 +28,7 @@ xrdp_sesman_SOURCES = \ scp.c \ scp_v0.c \ scp_v1.c \ + scp_v1_mng.c \ sesman.c \ session.c \ sig.c \ diff --git a/sesman/libscp/Makefile b/sesman/libscp/Makefile index 03779f92..62702afc 100644 --- a/sesman/libscp/Makefile +++ b/sesman/libscp/Makefile @@ -4,7 +4,7 @@ LIBSCPOBJ = libscp_vX.o libscp_v0.o \ libscp_init.o libscp_lock.o libscp_tcp.o \ libscp_session.o libscp_connection.o \ os_calls.o \ -# libscp_v1s_mng.o libscp_v1c_mng.o + libscp_v1s_mng.o libscp_v1c_mng.o CFGDIR = /etc/xrdp PIDDIR = /var/run diff --git a/sesman/libscp/Makefile.am b/sesman/libscp/Makefile.am index 5450f41a..f0b87a7b 100644 --- a/sesman/libscp/Makefile.am +++ b/sesman/libscp/Makefile.am @@ -13,6 +13,8 @@ libscp_la_SOURCES = \ libscp_v0.c \ libscp_v1c.c \ libscp_v1s.c \ + libscp_v1c_mng.c \ + libscp_v1s_mng.c \ libscp_vX.c libscp_la_LIBADD = \ diff --git a/sesman/libscp/libscp.h b/sesman/libscp/libscp.h index b8f9dea9..c0dbf944 100644 --- a/sesman/libscp/libscp.h +++ b/sesman/libscp/libscp.h @@ -22,7 +22,7 @@ * @file libscp.h * @brief libscp main header * @author Simone Fedele - * + * */ #ifndef LIBSCP_H @@ -33,6 +33,7 @@ #endif #include "libscp_types.h" +#include "libscp_commands.h" #include "libscp_connection.h" #include "libscp_session.h" @@ -44,6 +45,7 @@ #include "libscp_v0.h" #include "libscp_v1s.h" #include "libscp_v1c.h" -#include "file_loc.h" +#include "libscp_v1s_mng.h" +#include "libscp_v1c_mng.h" #endif diff --git a/sesman/libscp/libscp_commands.h b/sesman/libscp/libscp_commands.h new file mode 100644 index 00000000..96488f76 --- /dev/null +++ b/sesman/libscp/libscp_commands.h @@ -0,0 +1,36 @@ +/* + 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-2008 +*/ + +/** + * + * @file libscp_commands.h + * @brief libscp data types definitions + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_COMMANDS_H +#define LIBSCP_COMMANDS_H + +#include "libscp_commands_mng.h" + +#define SCP_CMD_LOGIN 0x0001 +#define SCP_CMD_CONN_ERROR 0xFFFF + +#endif diff --git a/sesman/libscp/libscp_commands_mng.h b/sesman/libscp/libscp_commands_mng.h new file mode 100644 index 00000000..e9f2a2a6 --- /dev/null +++ b/sesman/libscp/libscp_commands_mng.h @@ -0,0 +1,39 @@ +/* + 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-2008 +*/ + +/** + * + * @file libscp_commands_mng.h + * @brief libscp data types definitions + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_COMMANDS_MNG_H +#define LIBSCP_COMMANDS_MNG_H + +#define SCP_CMD_MNG_LOGIN 0x0001 +#define SCP_CMD_MNG_LOGIN_ALLOW 0x0002 +#define SCP_CMD_MNG_LOGIN_DENY 0x0003 +#define SCP_CMD_MNG_CMD_ERROR 0x0004 +#define SCP_CMD_MNG_LIST_REQ 0x0005 +#define SCP_CMD_MNG_LIST 0x0006 +#define SCP_CMD_MNG_ACTION 0x0007 + +#endif diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 6f86e208..13d0b13a 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -50,6 +50,7 @@ scp_session_create() s->password = 0; s->hostname = 0; s->errstr = 0; + s->mng = 0; s->locale[0]='\0'; return s; @@ -69,6 +70,12 @@ scp_session_set_type(struct SCP_SESSION* s, tui8 type) break; case SCP_SESSION_TYPE_MANAGE: s->type = SCP_SESSION_TYPE_MANAGE; + s->mng = g_malloc(sizeof(struct SCP_MNG_DATA),1); + if (NULL == s->mng) + { + log_message(s_log, LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); + return 1; + } break; default: log_message(s_log, LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); @@ -311,25 +318,31 @@ scp_session_destroy(struct SCP_SESSION* s) if (s->username) { g_free(s->username); - s->username=0; + s->username = 0; } if (s->password) { g_free(s->password); - s->password=0; + s->password = 0; } if (s->hostname) { g_free(s->hostname); - s->hostname=0; + s->hostname = 0; } if (s->errstr) { g_free(s->errstr); - s->errstr=0; + s->errstr = 0; + } + + if (s->mng) + { + g_free(s->mng); + s->mng = 0; } g_free(s); diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index b8b5d6bd..e4cbd0ff 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -56,7 +56,7 @@ #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);} +#include "libscp_types_mng.h" struct SCP_CONNECTION { @@ -80,8 +80,9 @@ struct SCP_SESSION tui8 addr_type; tui32 ipv4addr; tui8 ipv6addr[16]; - tui16 display; + SCP_DISPLAY display; char* errstr; + struct SCP_MNG_DATA* mng; }; struct SCP_DISCONNECTED_SESSION @@ -135,6 +136,8 @@ enum SCP_SERVER_STATES_E SCP_SERVER_STATE_SELECTION_CANCEL, /*SCP_SERVER_STATE_FORCE_NEW,*/ SCP_SERVER_STATE_START_MANAGE, + SCP_SERVER_STATE_MNG_LISTREQ, + SCP_SERVER_STATE_MNG_ACTION, SCP_SERVER_STATE_END }; diff --git a/sesman/libscp/libscp_types_mng.h b/sesman/libscp/libscp_types_mng.h new file mode 100644 index 00000000..04bda283 --- /dev/null +++ b/sesman/libscp/libscp_types_mng.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-2008 +*/ + +/** + * + * @file libscp_types_mng.h + * @brief libscp data types definitions + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_TYPES_MNG_H +#define LIBSCP_TYPES_MNG_H + +#include "os_calls.h" +#include "parse.h" +#include "arch.h" +#include "log.h" + +enum SCP_MNG_COMMAND +{ + SCP_MNG_CMD_KILL, + SCP_MNG_CMD_DISCONNECT +}; + +struct SCP_MNG_DATA +{ + enum SCP_MNG_COMMAND cmd; + SCP_SID sid; +}; + +#endif diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c index 74ce187d..93c42fa8 100644 --- a/sesman/libscp/libscp_v1s.c +++ b/sesman/libscp/libscp_v1s.c @@ -87,7 +87,8 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION* c, struct SCP_SES if (cmdset == SCP_COMMAND_SET_MANAGE) { log_message(s_log, LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); - return SCP_SERVER_STATE_START_MANAGE; + /* should return SCP_SERVER_STATE_START_MANAGE */ + return scp_v1s_mng_accept(c, s); } /* if we started with resource sharing... */ @@ -372,7 +373,23 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION* c, SCP_DISPLAY d) enum SCP_SERVER_STATES_E scp_v1s_connection_error(struct SCP_CONNECTION* c, char* error) { - return SCP_SERVER_STATE_INTERNAL_ERR; + tui16 len; + + len = g_strlen(error); + init_stream(c->out_s,c->out_s->size); + + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 + len */ + /* version + size + cmdset + cmd */ + out_uint32_be(c->out_s, (12 + len)); + out_uint16_be(c->out_s, SCP_COMMAND_SET_DEFAULT); + out_uint16_be(c->out_s, SCP_CMD_CONN_ERROR); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, (12 + len))) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } + return SCP_SERVER_STATE_END; } diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c new file mode 100644 index 00000000..4acb6570 --- /dev/null +++ b/sesman/libscp/libscp_v1s_mng.c @@ -0,0 +1,340 @@ +/* + 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-2008 +*/ + +/** + * + * @file libscp_v1s_mng.c + * @brief libscp version 1 server api code - session management + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_V1S_MNG_C +#define LIBSCP_V1S_MNG_C + +#include "libscp_v1s_mng.h" + +extern struct log_config* s_log; + +static enum SCP_SERVER_STATES_E +_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s); + +/* server API */ +enum SCP_SERVER_STATES_E scp_v1s_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s) +{ + struct SCP_SESSION* session; + tui32 ipaddr; + tui16 cmd; + tui8 sz; + char buf[257]; + + /* reading command */ + in_uint16_be(c->in_s, cmd); + if (cmd != 1) /* manager login */ + { + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + session = scp_session_create(); + if (0 == session) + { + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, 1); + scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); + + /* reading username */ + in_uint8(c->in_s, sz); + buf[sz]='\0'; + in_uint8a(c->in_s, buf, sz); + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint8(c->in_s, sz); + buf[sz]='\0'; + in_uint8a(c->in_s, buf, sz); + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading remote address */ + in_uint8(c->in_s, sz); + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->in_s, ipaddr); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV4_BIN, &ipaddr); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, SCP_ADDRESS_TYPE_IPV6_BIN, buf); + } + + /* reading hostname */ + in_uint8(c->in_s, sz); + buf[sz]='\0'; + in_uint8a(c->in_s, buf, sz); + if (0 != scp_session_set_hostname(session, buf)) + { + scp_session_destroy(session); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* returning the struct */ + (*s)=session; + + return SCP_SERVER_STATE_START_MANAGE; +} + +/* 002 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_allow_connection(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +{ + init_stream(c->out_s,c->out_s->size); + + out_uint32_be(c->out_s, 1); + /* packet size: 4 + 4 + 2 + 2 */ + /* version + size + cmdset + cmd */ + out_uint32_be(c->out_s, 12); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_ALLOW); + + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 12)) + { + return SCP_SERVER_STATE_NETWORK_ERR; + } + + return _scp_v1s_mng_check_response(c, s); +} + +/* 003 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_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_MANAGE); + out_uint16_be(c->out_s, SCP_CMD_MNG_LOGIN_DENY); + 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; +} + +/* 006 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_list_sessions(struct SCP_CONNECTION* c, struct SCP_SESSION* s, + int sescnt, struct SCP_DISCONNECTED_SESSION* ds) +{ + tui32 version = 1; + tui32 size = 12; + tui16 cmd = SCP_CMD_MNG_LIST; + int pktcnt; + int idx; + int sidx; + int pidx; + struct SCP_DISCONNECTED_SESSION* cds; + + /* 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; idxout_s, c->out_s->size); + + /* size: ver+size+cmdset+cmd+sescnt+continue+count */ + size=4+4+2+2+4+1+1; + + /* header */ + s_push_layer(c->out_s, channel_hdr, 8); + out_uint16_be(c->out_s, SCP_COMMAND_SET_MANAGE); + 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; sidxout_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 += 13; + + out_uint16_be(c->out_s, cds->conn_year); + out_uint8(c->out_s, cds->conn_month); + out_uint8(c->out_s, cds->conn_day); + out_uint8(c->out_s, cds->conn_hour); + out_uint8(c->out_s, cds->conn_minute); + out_uint8(c->out_s, cds->addr_type); + size += 7; + + if (cds->addr_type == SCP_ADDRESS_TYPE_IPV4) + { + in_uint32_be(c->out_s, cds->ipv4addr); + size += 4; + } + else if (cds->addr_type == SCP_ADDRESS_TYPE_IPV6) + { + in_uint8a(c->out_s, cds->ipv6addr, 16); + size += 16; + } + } + + 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)) + { + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + } + + return _scp_v1s_mng_check_response(c, s); +} + +static enum SCP_SERVER_STATES_E +_scp_v1s_mng_check_response(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +{ + tui32 version; + tui32 size; + tui16 cmd; +// tui8 dim; +// char buf[257]; + + init_stream(c->in_s, c->in_s->size); + if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint32_be(c->in_s, version); + if (version != 1) + { + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); + return SCP_SERVER_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)) + { + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + return SCP_SERVER_STATE_NETWORK_ERR; + } + + in_uint16_be(c->in_s, cmd); + if (cmd != SCP_COMMAND_SET_MANAGE) + { + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; + } + + in_uint16_be(c->in_s, cmd) + if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ + { + log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); + return SCP_SERVER_STATE_MNG_LISTREQ; + } + else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ + { + /*in_uint8(c->in_s, dim); + buf[dim]='\0'; + in_uint8a(c->in_s, buf, dim); + scp_session_set_errstr(s, buf);*/ + + log_message(s_log, LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); + return SCP_SERVER_STATE_MNG_ACTION; + } + /* else if (cmd == 20) / * password change * / + { + in_uint16_be(c->in_s, s->display); + + return SCP_SERVER_STATE_OK; + } + else if (cmd == 40) / * session list * / + { + return SCP_SERVER_STATE_SESSION_LIST; + }*/ + + log_message(s_log, LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + return SCP_SERVER_STATE_SEQUENCE_ERR; +} + +#endif diff --git a/sesman/libscp/libscp_v1s_mng.h b/sesman/libscp/libscp_v1s_mng.h new file mode 100644 index 00000000..59145771 --- /dev/null +++ b/sesman/libscp/libscp_v1s_mng.h @@ -0,0 +1,79 @@ +/* + 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-2008 +*/ + +/** + * + * @file libscp_v1s_mng.h + * @brief libscp version 1 server api declarations - session management + * @author Simone Fedele + * + */ + +#ifndef LIBSCP_V1S_MNG_H +#define LIBSCP_V1S_MNG_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 + * + * 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_mng_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s); + +/** + * + * @brief allows connection to sesman + * @param c connection descriptor + * + */ +/* 002 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_allow_connection(struct SCP_CONNECTION* c, struct SCP_SESSION* s); + +/** + * + * @brief denies connection to sesman + * @param c connection descriptor + * @param reason pointer to a string containinge the reason for denying connection + * + */ +/* 003 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_deny_connection(struct SCP_CONNECTION* c, char* reason); + +/** + * + * @brief sends session list + * @param c connection descriptor + * + */ +/* 006 */ +enum SCP_SERVER_STATES_E +scp_v1s_mng_list_sessions(struct SCP_CONNECTION* c, struct SCP_SESSION* s, + int sescnt, struct SCP_DISCONNECTED_SESSION* ds); +// SCP_SID* sid); + +#endif diff --git a/sesman/scp.c b/sesman/scp.c index ea5a8ec0..6a920720 100644 --- a/sesman/scp.c +++ b/sesman/scp.c @@ -74,7 +74,7 @@ scp_process_start(void* sck) /* starting a management session */ log_message(&(g_cfg.log), LOG_LEVEL_WARNING, "starting a sesman management session..."); -// scp_v1s_mng_process(&scon, sdata); + scp_v1_mng_process(&scon, sdata); break; case SCP_SERVER_STATE_VERSION_ERR: /* an unknown scp version was requested, so we shut down the */ diff --git a/sesman/scp.h b/sesman/scp.h index 236620c6..b3433f4e 100644 --- a/sesman/scp.h +++ b/sesman/scp.h @@ -22,15 +22,15 @@ * @file scp.h * @brief scp (sesman control protocol) common definitions * @author Simone Fedele - * + * */ #ifndef SCP_H #define SCP_H -//#include "libscp.h" #include "scp_v0.h" #include "scp_v1.h" +#include "scp_v1_mng.h" /** * diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index c5ff2d4c..49a23af8 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -74,7 +74,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) default: /* we check the other errors */ parseCommonStates(e, "scp_v1s_list_sessions()"); - free_session(s); + scp_session_destroy(s); return; //break; } @@ -85,7 +85,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) scp_v1s_deny_connection(c, "Login failed"); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Login failed for user %s. Connection terminated", s->username); - free_session(s); + scp_session_destroy(s); return; } @@ -95,14 +95,14 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "User %s not allowed on TS. Connection terminated", s->username); - free_session(s); + scp_session_destroy(s); return; } //check if we need password change /* list disconnected sessions */ - slist = session_get_byuser(s->username, &scount); + slist = session_get_byuser(s->username, &scount, SESMAN_SESSION_STATUS_DISCONNECTED); if (scount == 0) { @@ -135,8 +135,6 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) } else { -#warning FIXME session_get_by*() should return a malloc()ated struct -#warning FIXME or at least lock the chain /* one or more disconnected sessions - listing */ e = scp_v1s_list_sessions(c, scount, slist, &sid); @@ -162,6 +160,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) e=scp_v1s_reconnect_session(c, display); log_message(&(g_cfg->log), LOG_LEVEL_INFO, "User %s reconnected to session %d on port %d", \ s->username, sitem->pid, display); + g_free(sitem); } break; default: @@ -179,7 +178,7 @@ scp_v1_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) } /* cleanup */ - free_session(s); + scp_session_destroy(s); auth_end(data); } diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c new file mode 100644 index 00000000..36ff8507 --- /dev/null +++ b/sesman/scp_v1_mng.c @@ -0,0 +1,145 @@ +/* + 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-2008 +*/ + +/** + * + * @file scp_v1_mng.c + * @brief scp version 1 implementation - management + * @author Jay Sorg, Simone Fedele + * + */ + +#include "sesman.h" + +#include "libscp.h" + +extern struct config_sesman* g_cfg; + +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f); + +/******************************************************************************/ +void DEFAULT_CC +scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +{ + long data; + int retries; + int current_try; + enum SCP_SERVER_STATES_E e; + struct SCP_DISCONNECTED_SESSION* slist = 0; + int scount; + int end = 0; + + retries = g_cfg->sec.login_retry; + current_try = retries; + + data = auth_userpass(s->username, s->password); + /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + + if (!data) + { + scp_v1s_mng_deny_connection(c, "Login failed"); + log_message(&(g_cfg->log), LOG_LEVEL_INFO, + "[MNG] Login failed for user %s. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } + + /* testing if login is allowed */ + if (0 == access_login_mng_allowed(s->username)) + { + scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); + log_message(&(g_cfg->log), LOG_LEVEL_INFO, + "[MNG] User %s not allowed on TS. Connection terminated", s->username); + scp_session_destroy(s); + auth_end(data); + return; + } + + e = scp_v1s_mng_allow_connection(c, s); + + end = 1; + while (end) + { + switch (e) + { + case SCP_SERVER_STATE_MNG_ACTION: + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "Connection cancelled after session listing"); + break; + + case SCP_SERVER_STATE_MNG_LISTREQ: + /* list disconnected sessions */ + slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL); + LOG_DBG(&(g_cfg->log), "sessions on TS: %d (slist: %x)", scount, slist); + + if (0 == slist) + { +// e=scp_v1s_connection_error(c, "Internal error"); + log_message(&(g_cfg->log), LOG_LEVEL_INFO, "No sessions on Terminal Server"); + end = 0; + } + else + { + e = scp_v1s_mng_list_sessions(c, s, scount, slist); + g_free(slist); + } + + break; + default: + /* we check the other errors */ + parseCommonStates(e, "scp_v1s_mng_list_sessions()"); + end = 0; + break; + } + } + + /* cleanup */ + scp_session_destroy(s); + auth_end(data); +} + +static void parseCommonStates(enum SCP_SERVER_STATES_E e, char* f) +{ + switch (e) + { + case SCP_SERVER_STATE_VERSION_ERR: + LOG_DBG(&(g_cfg->log), "version error") + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, so we shut down the */ + /* connection (and log the fact) */ + log_message(&(g_cfg->log), LOG_LEVEL_WARNING, + "protocol violation. connection closed."); + break; + case SCP_SERVER_STATE_NETWORK_ERR: + log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp network error."); + break; + case SCP_SERVER_STATE_SEQUENCE_ERR: + log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "libscp sequence error."); + break; + case SCP_SERVER_STATE_INTERNAL_ERR: + /* internal error occurred (eg. malloc() error, ecc.) */ + log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "libscp internal error occurred."); + break; + default: + /* dummy: scp_v1s_request_password won't generate any other */ + /* error other than the ones before */ + log_message(&(g_cfg->log), LOG_LEVEL_ALWAYS, "unknown return from %s", f); + break; + } +} diff --git a/sesman/scp_v1_mng.h b/sesman/scp_v1_mng.h new file mode 100644 index 00000000..d4ef88ae --- /dev/null +++ b/sesman/scp_v1_mng.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-2008 +*/ + +/** + * + * @file scp_v1.h + * @brief scp version 1 declarations - management + * @author Simone Fedele + * + */ + +#ifndef SCP_V1_MNG_H +#define SCP_V1_MNG_H + +/** + * + * @brief processes the stream using scp version 1 + * @param in_sck connection socket + * @param in_s input stream + * @param out_s output stream + * + */ +void DEFAULT_CC +scp_v1_mng_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s); + +#endif diff --git a/sesman/session.c b/sesman/session.c index 54e02ad6..8249f7fa 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -412,8 +412,8 @@ for user %s denied", username); g_strncpy(temp->item->name, username, 255); ltime = g_time1(); - gmtime_r(<ime, &stime); - temp->item->connect_time.year = (tui16)stime.tm_year; + localtime_r(<ime, &stime); + temp->item->connect_time.year = (tui16)(stime.tm_year + 1900); temp->item->connect_time.month = (tui8)stime.tm_mon; temp->item->connect_time.day = (tui8)stime.tm_mday; temp->item->connect_time.hour = (tui8)stime.tm_hour; @@ -437,43 +437,6 @@ for user %s denied", username); return display; } -/* -SESMAN_SESSION_TYPE_XRDP 1 -SESMAN_SESSION_TYPE_XVNC 2 - -SESMAN_SESSION_STATUS_ACTIVE 1 -SESMAN_SESSION_STATUS_IDLE 2 -SESMAN_SESSION_STATUS_DISCONNECTED 3 - -struct session_item -{ - char name[256]; - int pid; - int display; - int width; - int height; - int bpp; - long data; - - / * - unsigned char status; - unsigned char type; - * / - - / * - time_t connect_time; - time_t disconnect_time; - time_t idle_time; - * / -}; - -struct session_chain -{ - struct session_chain* next; - struct session_item* item; -}; -*/ - /******************************************************************************/ int DEFAULT_CC session_kill(int pid) @@ -576,6 +539,14 @@ struct session_item* DEFAULT_CC session_get_bypid(int pid) { struct session_chain* tmp; + struct session_item* dummy; + + dummy = g_malloc(sizeof(struct session_item), 1); + if (0 == dummy) + { + log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "internal error", pid); + return 0; + } /*THREAD-FIX require chain lock */ lock_chain_acquire(); @@ -595,8 +566,10 @@ session_get_bypid(int pid) if (tmp->item->pid == pid) { /*THREAD-FIX release chain lock */ + g_memcpy(dummy, tmp->item, sizeof(struct session_item)); lock_chain_release(); - return tmp->item; + /*return tmp->item;*/ + return dummy; } /* go on */ @@ -610,7 +583,7 @@ session_get_bypid(int pid) /******************************************************************************/ struct SCP_DISCONNECTED_SESSION* -session_get_byuser(char* user, int* cnt) +session_get_byuser(char* user, int* cnt, unsigned char flags) { struct session_chain* tmp; struct SCP_DISCONNECTED_SESSION* sess; @@ -625,10 +598,14 @@ session_get_byuser(char* user, int* cnt) tmp = g_sessions; while (tmp != 0) { -#warning FIXME: we should get only disconnected sessions! - if (!g_strncasecmp(user, tmp->item->name, 256)) + LOG_DBG(&(g_cfg->log), "user: %s", user); + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { - count++; + LOG_DBG(&(g_cfg->log), "session_get_byuser: status=%d, flags=%d, result=%d", (tmp->item->status), flags, ((tmp->item->status) & flags)); + if ((tmp->item->status) & flags) + { + count++; + } } /* go on */ @@ -658,39 +635,42 @@ session_get_byuser(char* user, int* cnt) while (tmp != 0) { #warning FIXME: we should get only disconnected sessions! - if (!g_strncasecmp(user, tmp->item->name, 256)) + if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { - (sess[index]).SID=tmp->item->pid; - (sess[index]).type=tmp->item->type; - (sess[index]).height=tmp->item->height; - (sess[index]).width=tmp->item->width; - (sess[index]).bpp=tmp->item->bpp; + if ((tmp->item->status) & flags) + { + (sess[index]).SID=tmp->item->pid; + (sess[index]).type=tmp->item->type; + (sess[index]).height=tmp->item->height; + (sess[index]).width=tmp->item->width; + (sess[index]).bpp=tmp->item->bpp; #warning FIXME: setting idle times and such - /*(sess[index]).connect_time.year = tmp->item->connect_time.year; - (sess[index]).connect_time.month = tmp->item->connect_time.month; - (sess[index]).connect_time.day = tmp->item->connect_time.day; - (sess[index]).connect_time.hour = tmp->item->connect_time.hour; - (sess[index]).connect_time.minute = tmp->item->connect_time.minute; - (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; - (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; - (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; - (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; - (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; - (sess[index]).idle_time.year = tmp->item->idle_time.year; - (sess[index]).idle_time.month = tmp->item->idle_time.month; - (sess[index]).idle_time.day = tmp->item->idle_time.day; - (sess[index]).idle_time.hour = tmp->item->idle_time.hour; - (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ - (sess[index]).conn_year = tmp->item->connect_time.year; - (sess[index]).conn_month = tmp->item->connect_time.month; - (sess[index]).conn_day = tmp->item->connect_time.day; - (sess[index]).conn_hour = tmp->item->connect_time.hour; - (sess[index]).conn_minute = tmp->item->connect_time.minute; - (sess[index]).idle_days = tmp->item->idle_time.day; - (sess[index]).idle_hours = tmp->item->idle_time.hour; - (sess[index]).idle_minutes = tmp->item->idle_time.minute; - - index++; + /*(sess[index]).connect_time.year = tmp->item->connect_time.year; + (sess[index]).connect_time.month = tmp->item->connect_time.month; + (sess[index]).connect_time.day = tmp->item->connect_time.day; + (sess[index]).connect_time.hour = tmp->item->connect_time.hour; + (sess[index]).connect_time.minute = tmp->item->connect_time.minute; + (sess[index]).disconnect_time.year = tmp->item->disconnect_time.year; + (sess[index]).disconnect_time.month = tmp->item->disconnect_time.month; + (sess[index]).disconnect_time.day = tmp->item->disconnect_time.day; + (sess[index]).disconnect_time.hour = tmp->item->disconnect_time.hour; + (sess[index]).disconnect_time.minute = tmp->item->disconnect_time.minute; + (sess[index]).idle_time.year = tmp->item->idle_time.year; + (sess[index]).idle_time.month = tmp->item->idle_time.month; + (sess[index]).idle_time.day = tmp->item->idle_time.day; + (sess[index]).idle_time.hour = tmp->item->idle_time.hour; + (sess[index]).idle_time.minute = tmp->item->idle_time.minute;*/ + (sess[index]).conn_year = tmp->item->connect_time.year; + (sess[index]).conn_month = tmp->item->connect_time.month; + (sess[index]).conn_day = tmp->item->connect_time.day; + (sess[index]).conn_hour = tmp->item->connect_time.hour; + (sess[index]).conn_minute = tmp->item->connect_time.minute; + (sess[index]).idle_days = tmp->item->idle_time.day; + (sess[index]).idle_hours = tmp->item->idle_time.hour; + (sess[index]).idle_minutes = tmp->item->idle_time.minute; + + index++; + } } /* go on */ diff --git a/sesman/session.h b/sesman/session.h index e6c6563b..41acea2a 100644 --- a/sesman/session.h +++ b/sesman/session.h @@ -34,12 +34,13 @@ #define SESMAN_SESSION_TYPE_XRDP 1 #define SESMAN_SESSION_TYPE_XVNC 2 -#define SESMAN_SESSION_STATUS_ACTIVE 1 -#define SESMAN_SESSION_STATUS_IDLE 2 -#define SESMAN_SESSION_STATUS_DISCONNECTED 3 +#define SESMAN_SESSION_STATUS_ACTIVE 0x01 +#define SESMAN_SESSION_STATUS_IDLE 0x02 +#define SESMAN_SESSION_STATUS_DISCONNECTED 0x04 /* future expansion -#define SESMAN_SESSION_STATUS_REMCONTROL 4 +#define SESMAN_SESSION_STATUS_REMCONTROL 0x08 */ +#define SESMAN_SESSION_STATUS_ALL 0xFF #define SESMAN_SESSION_KILL_OK 0 #define SESMAN_SESSION_KILL_NULLITEM 1 @@ -141,7 +142,7 @@ session_get_bypid(int pid); * */ struct SCP_DISCONNECTED_SESSION* -session_get_byuser(char* user, int* cnt); +session_get_byuser(char* user, int* cnt, unsigned char flags); #endif diff --git a/sesman/tools/Makefile b/sesman/tools/Makefile index bde00374..65705fc6 100644 --- a/sesman/tools/Makefile +++ b/sesman/tools/Makefile @@ -25,8 +25,7 @@ LDFLAGS = -L/usr/gnu/lib -L/usr/lib/nptl -L../libscp -lpthread -ldl -lscp -Wl,-r C_OS_FLAGS = $(CFLAGS) -c -g CC = gcc -all: xrdp-sestest xrdp-sesrun -# xrdp-sesadmin +all: xrdp-sestest xrdp-sesrun xrdp-sesadmin xrdp-sestest: $(SESTESTOBJ) $(CC) $(LDFLAGS) -o xrdp-sestest $(SESTESTOBJ) diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am index 2d46cbe1..d7102fe7 100644 --- a/sesman/tools/Makefile.am +++ b/sesman/tools/Makefile.am @@ -5,7 +5,8 @@ INCLUDES = \ bin_PROGRAMS = \ xrdp-sesrun \ - xrdp-sestest + xrdp-sestest \ + xrdp-sesadmin xrdp_sesrun_SOURCES = \ sesrun.c \ @@ -15,9 +16,17 @@ xrdp_sesrun_SOURCES = \ xrdp_sestest_SOURCES = \ sestest.c +xrdp_sesadmin_SOURCES = \ + sesadmin.c + xrdp_sesrun_LDADD = \ $(top_srcdir)/common/libcommon.la xrdp_sestest_LDADD = \ $(top_srcdir)/common/libcommon.la \ $(top_srcdir)/sesman/libscp/libscp.la + +xrdp_sesadmin_LDADD = \ + $(top_srcdir)/common/libcommon.la \ + $(top_srcdir)/sesman/libscp/libscp.la + diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c new file mode 100644 index 00000000..4c612316 --- /dev/null +++ b/sesman/tools/sesadmin.c @@ -0,0 +1,195 @@ +/* + * sesadmin.c - an sesman administration tool + * (c) 2008 Simone Fedele + * + */ + +#include "arch.h" +#include "tcp.h" +#include "libscp.h" +#include "parse.h" +#include "log.h" +#include "libscp.h" + +#include +#include + +char user[257]; +char pass[257]; +char cmnd[257]; +char serv[257]; +char port[257]; + +struct log_config logging; + +void cmndList(struct SCP_CONNECTION* c); +void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s); +void cmndHelp(); + +int inputSession(struct SCP_SESSION* s); +unsigned int menuSelect(unsigned int choices); + +int main(int argc, char** argv) +{ + struct SCP_SESSION* s; + struct SCP_CONNECTION* c; + enum SCP_CLIENT_STATES_E e; + //int end; + int idx; + //int sel; + int sock; + char* pwd; + + user[0]='\0'; + pass[0]='\0'; + cmnd[0]='\0'; + serv[0]='\0'; + port[0]='\0'; + + logging.program_name = g_strdup("sesadmin"); + logging.log_file = g_strdup("xrdp-sesadmin.log"); + logging.log_level = LOG_LEVEL_DEBUG; + logging.enable_syslog = 0; + log_start(&logging); + + for (idx = 0; idx < argc; idx++) + { + if (0 == g_strncmp(argv[idx], "-u=", 3)) + { + g_strncpy(user, (argv[idx])+3, 256); + } + else if (0 == g_strncmp(argv[idx], "-p=", 3)) + { + g_strncpy(pass, (argv[idx])+3, 256); + } + else if (0 == g_strncmp(argv[idx], "-s=", 3)) + { + g_strncpy(serv, (argv[idx])+3, 256); + } + else if (0 == g_strncmp(argv[idx], "-i=", 3)) + { + g_strncpy(port, (argv[idx])+3, 256); + } + else if (0 == g_strncmp(argv[idx], "-c=", 3)) + { + g_strncpy(cmnd, (argv[idx])+3, 256); + } + } + + if (0 == g_strncmp(serv, "", 1)) + { + g_strncpy(serv, "localhost", 256); + } + + if (0 == g_strncmp(port, "", 1)) + { + g_strncpy(port, "3350", 256); + } + + if (0 == g_strncmp(user, "", 1)) + { + g_strncpy(user, "root", 256); + } + + if (0 == g_strncmp(pass, "", 1)) + { + pwd = getpass("password:"); + g_strncpy(pass, pwd, 256); + + /* zeroing the password */ + while ((*pwd) != '\0') + { + (*pwd) = 0x00; + pwd++; + } + } + + scp_init(&logging); + + sock = g_tcp_socket(); + s = scp_session_create(); + c = scp_connection_create(sock); + + LOG_DBG(&logging, "Connecting to %s:%s with user %s (%s)\n", serv, port, user, pass); + + if (0 != g_tcp_connect(sock, serv, port)) + { + LOG_DBG(&logging, "g_tcp_connect() error\n"); + return 1; + } + + scp_session_set_type(s, SCP_SESSION_TYPE_MANAGE); + scp_session_set_version(s, 1); + scp_session_set_username(s, user); + scp_session_set_password(s, pass); + + e = scp_v1c_mng_connect(c,s); + + if (SCP_CLIENT_STATE_OK != e) + { + LOG_DBG(&logging, "libscp error connecting: %s %d\n", s->errstr, (int)e); + } + + if (0 == g_strncmp(cmnd, "list", 5)) + { + cmndList(c); + } + else if (0 == g_strncmp(cmnd, "kill:", 5)) + { + cmndKill(c,s); + } + + g_tcp_close(sock); + scp_session_destroy(s); + scp_connection_destroy(c); + log_end(&logging); + + return 0; +} + +void cmndHelp() +{ + fprintf(stderr, "sesadmin - a console sesman adminitration tool\n"); + fprintf(stderr, "sysntax: sesadmin [] COMMAND [OPTIONS]\n\n"); + fprintf(stderr, "-u=: username to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-p=: password to connect to sesman [MANDATORY]\n"); + fprintf(stderr, "-s=: sesman host (default is localhost)\n"); + fprintf(stderr, "-i= : sesman port (default 3350)\n"); + fprintf(stderr, "-c= : command to execute on the server [MANDATORY]\n"); + fprintf(stderr, " it can be one of those:\n"); + fprintf(stderr, " LIST\n"); + fprintf(stderr, " KILL:\n"); +} + +void cmndList(struct SCP_CONNECTION* c) +{ + struct SCP_DISCONNECTED_SESSION* dsl; + enum SCP_CLIENT_STATES_E e; + int scnt; + int idx; + + e = scp_v1c_mng_get_session_list(c, &scnt, &dsl); + if ((SCP_CLIENT_STATE_LIST_OK == e) && (scnt > 0)) + { + for (idx = 0; idx < scnt; idx++) + { + printf("%d\t%d\t%dx%dx%d\t%d-%d-%d\t%04d/%02d/%02d@%02d:%02d\n", \ + (dsl[idx]).SID, (dsl[idx]).type, (dsl[idx]).width, (dsl[idx]).height, (dsl[idx]).bpp, \ + (dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \ + (dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute); + } + if (0 != dsl) + { + g_free(dsl); + } + } + else + { + printf("No sessions.\n"); + } +} + +void cmndKill(struct SCP_CONNECTION* c, struct SCP_SESSION* s) +{ + +}