diff options
author | ilsimo <ilsimo> | 2008-09-11 20:23:15 +0000 |
---|---|---|
committer | ilsimo <ilsimo> | 2008-09-11 20:23:15 +0000 |
commit | 7c7929861246310d48789748cc150c9a4a492e09 (patch) | |
tree | 6b71e5c47fdc95451df2c7d23437ca4adfd227f6 /sesman/libscp/libscp_v1s_mng.c | |
parent | 1e33ad14c3c2e82b9ba74a5f8d1210b5ae643054 (diff) | |
download | xrdp-proprietary-7c7929861246310d48789748cc150c9a4a492e09.tar.gz xrdp-proprietary-7c7929861246310d48789748cc150c9a4a492e09.zip |
added first management code
added a rough management tool
fixes in session.c
Diffstat (limited to 'sesman/libscp/libscp_v1s_mng.c')
-rw-r--r-- | sesman/libscp/libscp_v1s_mng.c | 340 |
1 files changed, 340 insertions, 0 deletions
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; 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 */ + 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; 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 += 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 |