diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am index 9789388b..a113a4f4 100644 --- a/sesman/tools/Makefile.am +++ b/sesman/tools/Makefile.am @@ -5,7 +5,7 @@ AM_CPPFLAGS = \ -DXRDP_PID_PATH=\"${localstatedir}/run\" \ -DXRDP_SOCKET_PATH=\"${socketdir}\" \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/sesman/libscp \ + -I$(top_srcdir)/libipm \ -I$(top_srcdir)/sesman AM_CFLAGS = $(X_CFLAGS) @@ -19,11 +19,15 @@ noinst_PROGRAMS = \ xrdp-xcon xrdp_sesrun_SOURCES = \ + sesrun.c \ config.c \ - sesrun.c + tools_common.h \ + tools_common.c xrdp_sesadmin_SOURCES = \ - sesadmin.c + sesadmin.c \ + tools_common.h \ + tools_common.c xrdp_dis_SOURCES = \ dis.c @@ -36,11 +40,11 @@ xrdp_xcon_SOURCES = \ xrdp_sesrun_LDADD = \ $(top_builddir)/common/libcommon.la \ - $(top_builddir)/sesman/libscp/libscp.la + $(top_builddir)/libipm/libipm.la xrdp_sesadmin_LDADD = \ $(top_builddir)/common/libcommon.la \ - $(top_builddir)/sesman/libscp/libscp.la + $(top_builddir)/libipm/libipm.la xrdp_xcon_LDFLAGS = \ $(X_LIBS) diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index e0d20da1..e04e4ef2 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -22,11 +22,11 @@ #endif #include "arch.h" -#include "libscp.h" -#include "parse.h" +#include "trans.h" #include "log.h" -#include "libscp.h" +#include "os_calls.h" #include "string_calls.h" +#include "tools_common.h" #include #include @@ -37,23 +37,20 @@ char cmnd[257]; char serv[257]; char port[257]; -void cmndList(struct trans *t); -void cmndKill(struct trans *t, struct SCP_SESSION *s); -void cmndHelp(void); +static int cmndList(struct trans *t); +static int cmndKill(struct trans *t); +static void cmndHelp(void); -int inputSession(struct SCP_SESSION *s); -unsigned int menuSelect(unsigned int choices); int main(int argc, char **argv) { - struct SCP_SESSION *s; struct trans *t; - enum SCP_CLIENT_STATES_E e; //int end; int idx; //int sel; char *pwd; struct log_config *logging; + int rv = 1; user[0] = '\0'; pass[0] = '\0'; @@ -116,56 +113,34 @@ int main(int argc, char **argv) pwd = getpass("password:"); g_strncpy(pass, pwd, 256); - /* zeroing the password */ - while ((*pwd) != '\0') - { - (*pwd) = 0x00; - pwd++; - } } - scp_init(); - - s = scp_session_create(); - LOG_DEVEL(LOG_LEVEL_DEBUG, "Connecting to %s:%s)", serv, port); - t = scp_connect(serv, port, NULL, NULL, NULL); + t = scp_connect(serv, port, NULL); if (t == NULL) { LOG(LOG_LEVEL_ERROR, "scp_connect() error"); - 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(t, s); - - if (SCP_CLIENT_STATE_OK != e) + else if (0 == g_strncmp(cmnd, "list", 5)) { - LOG_DEVEL(LOG_LEVEL_DEBUG, "libscp error connecting: %s %d", s->errstr, (int)e); - } - - if (0 == g_strncmp(cmnd, "list", 5)) - { - cmndList(t); + rv = cmndList(t); } else if (0 == g_strncmp(cmnd, "kill:", 5)) { - cmndKill(t, s); + rv = cmndKill(t); } - scp_session_destroy(s); + g_memset(pass, '\0', sizeof(pass)); + trans_delete(t); log_end(); - return 0; + return rv; } -void cmndHelp(void) +static void +cmndHelp(void) { fprintf(stderr, "sesadmin - a console sesman administration tool\n"); fprintf(stderr, "syntax: sesadmin [] COMMAND [OPTIONS]\n\n"); @@ -180,50 +155,93 @@ void cmndHelp(void) } static void -print_session(const struct SCP_DISCONNECTED_SESSION *s) +print_session(const struct scp_session_info *s) { - printf("Session ID: %d\n", s->SID); - printf("\tSession type: %d\n", s->type); + printf("Session ID: %d\n", s->sid); + printf("\tDisplay: :%u\n", s->display); + printf("\tUser: %s\n", s->username); + printf("\tSession type: %s\n", SCP_SESSION_TYPE_TO_STR(s->type)); printf("\tScreen size: %dx%d, color depth %d\n", s->width, s->height, s->bpp); - printf("\tIdle time: %d day(s) %d hour(s) %d minute(s)\n", - s->idle_days, s->idle_hours, s->idle_minutes); - printf("\tConnected: %04d/%02d/%02d %02d:%02d\n", - s->conn_year, s->conn_month, s->conn_day, s->conn_hour, - s->conn_minute); + printf("\tStarted: %s", ctime(&s->start_time)); + if (s->connection_description[0] != '\0') + { + printf("\tConnection Description: %s\n", s->connection_description); + } } -void cmndList(struct trans *t) +static int +cmndList(struct trans *t) { - struct SCP_DISCONNECTED_SESSION *dsl; - enum SCP_CLIENT_STATES_E e; - int scnt; - int idx; + struct list *sessions = list_create(); + int end_of_list = 0; - e = scp_v1c_mng_get_session_list(t, &scnt, &dsl); + enum scp_list_sessions_status status; + struct scp_session_info *p; - if (e != SCP_CLIENT_STATE_LIST_OK) + int rv = scp_send_list_sessions_request(t, user, pass); + + sessions->auto_free = 1; + + while (rv == 0 && !end_of_list) { - printf("Error getting session list.\n"); - return; + rv = wait_for_sesman_reply(t, E_SCP_LIST_SESSIONS_RESPONSE); + if (rv != 0) + { + break; + } + + rv = scp_get_list_sessions_response(t, &status, &p); + if (rv != 0) + { + break; + } + + switch (status) + { + case E_SCP_LS_AUTHENTICATION_FAIL: + printf("Connection denied (authentication error)\n"); + rv = 1; + break; + + case E_SCP_LS_SESSION_INFO: + list_add_item(sessions, (tintptr)p); + break; + + case E_SCP_LS_END_OF_LIST: + end_of_list = 1; + break; + + default: + printf("Unexpected return code %d\n", status); + rv = 1; + } + scp_msg_in_reset(t); } - if (scnt > 0) + if (rv == 0) { - for (idx = 0; idx < scnt; idx++) + if (sessions->count == 0) { - print_session(&dsl[idx]); + printf("No sessions.\n"); + } + else + { + int i; + for (i = 0 ; i < sessions->count; ++i) + { + print_session((struct scp_session_info *)sessions->items[i]); + } } } - else - { - printf("No sessions.\n"); - } - g_free(dsl); + list_delete(sessions); + return rv; } -void cmndKill(struct trans *t, struct SCP_SESSION *s) +static int +cmndKill(struct trans *t) { - + fprintf(stderr, "not yet implemented\n"); + return 1; } diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index 84257f77..cbdc7a46 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -33,13 +33,14 @@ #include #include "parse.h" +#include "trans.h" #include "os_calls.h" #include "config.h" #include "log.h" #include "string_calls.h" #include "guid.h" -#include "libscp_connection.h" +#include "tools_common.h" #if !defined(PACKAGE_VERSION) #define PACKAGE_VERSION "???" @@ -71,18 +72,18 @@ #endif /** - * Maps session type strings to internal code numbers + * Maps session type strings session type codes */ static struct { const char *name; - int code; + enum scp_session_type type; } type_map[] = { - { "Xvnc", 0}, - { "X11rdp", 10}, - { "Xorg", 20}, - { NULL, -1} + { "Xvnc", SCP_SESSION_TYPE_XVNC}, + { "X11rdp", SCP_SESSION_TYPE_XRDP}, + { "Xorg", SCP_SESSION_TYPE_XORG}, + { NULL, (enum scp_session_type) - 1} }; /** @@ -93,37 +94,38 @@ struct session_params int width; int height; int bpp; - int session_code; + enum scp_session_type session_type; const char *server; - const char *domain; /* Currently unused by sesman */ const char *directory; const char *shell; - const char *client_ip; + const char *connection_description; const char *username; char password[MAX_PASSWORD_LEN + 1]; }; /**************************************************************************//** - * Maps a string to a session code + * Maps a string to a session type value * - * @param t session type - * @return session code, or -1 if not found + * @param string session type string + * @param[out] value session type value + * @return 0 for success or != 0 if not found */ static -int get_session_type_code(const char *t) +int string_to_session_type(const char *t, enum scp_session_type *value) { unsigned int i; for (i = 0 ; type_map[i].name != NULL; ++i) { if (g_strcasecmp(type_map[i].name, t) == 0) { - return type_map[i].code; + *value = type_map[i].type; + return 0; } } - return -1; + return 1; } /**************************************************************************//** @@ -182,7 +184,7 @@ usage(void) " -p TESTING ONLY - DO NOT USE IN PRODUCTION\n" " -F Read password from this file descriptor\n" " -c Alternative sesman.ini file\n"); - g_printf("Supported types are %s or use int for internal code\n", + g_printf("Supported types are %s\n", sesstype_list); g_printf("Password is prompted if -p or -F are not specified\n"); } @@ -288,13 +290,12 @@ parse_program_args(int argc, char *argv[], struct session_params *sp, sp->width = DEFAULT_WIDTH; sp->height = DEFAULT_HEIGHT; sp->bpp = DEFAULT_BPP; - sp->session_code = get_session_type_code(DEFAULT_TYPE); + (void)string_to_session_type(DEFAULT_TYPE, &sp->session_type); sp->server = DEFAULT_SERVER; - sp->domain = ""; sp->directory = ""; sp->shell = ""; - sp->client_ip = ""; + sp->connection_description = ""; sp->username = NULL; sp->password[0] = '\0'; @@ -320,19 +321,11 @@ parse_program_args(int argc, char *argv[], struct session_params *sp, break; case 't': - if (isdigit(optarg[0])) + if (string_to_session_type(optarg, &sp->session_type) != 0) { - sp->session_code = atoi(optarg); - } - else - { - sp->session_code = get_session_type_code(optarg); - if (sp->session_code < 0) - { - LOG(LOG_LEVEL_ERROR, "Unrecognised session type '%s'", - optarg); - params_ok = 0; - } + LOG(LOG_LEVEL_ERROR, "Unrecognised session type '%s'", + optarg); + params_ok = 0; } break; @@ -416,89 +409,61 @@ parse_program_args(int argc, char *argv[], struct session_params *sp, } /**************************************************************************//** - * Sends an SCP V0 authorization request + * Sends an SCP create session request * - * @param sck file descriptor to send request on + * @param t SCP connection * @param sp Data for request - * - * @todo This code duplicates functionality in the XRDP function - * xrdp_mm_send_login(). When SCP is reworked, a common library - * function should be used */ -static enum SCP_CLIENT_STATES_E -send_scpv0_auth_request(struct trans *t, const struct session_params *sp) +static int +send_create_session_request(struct trans *t, const struct session_params *sp) { LOG(LOG_LEVEL_DEBUG, "width:%d height:%d bpp:%d code:%d\n" - "server:\"%s\" domain:\"%s\" directory:\"%s\"\n" - "shell:\"%s\" client_ip:\"%s\"", - sp->width, sp->height, sp->bpp, sp->session_code, - sp->server, sp->domain, sp->directory, - sp->shell, sp->client_ip); + "server:\"%s\" directory:\"%s\"\n" + "shell:\"%s\" connection_description:\"%s\"", + sp->width, sp->height, sp->bpp, sp->session_type, + sp->server, sp->directory, + sp->shell, sp->connection_description); /* Only log the password in development builds */ LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password); - return scp_v0c_create_session_request( - t, sp->username, sp->password, sp->session_code, sp->width, sp->height, - sp->bpp, sp->domain, sp->shell, sp->directory, sp->client_ip); + return scp_send_create_session_request( + t, sp->username, sp->password, sp->session_type, + sp->width, sp->height, sp->bpp, sp->shell, sp->directory, + sp->connection_description); } /**************************************************************************//** - * Receives an SCP V0 authorization reply + * Receives an SCP create session response * * @param t SCP transport to receive reply on * @return 0 for success */ static int -handle_scpv0_auth_reply(struct trans *t) +handle_create_session_response(struct trans *t) { - tbus wobj[1]; - int ocnt = 0; + int auth_result; + int display; + struct guid guid; - int rv = 1; + int rv = wait_for_sesman_reply(t, E_SCP_CREATE_SESSION_RESPONSE); + if (rv == 0) + { + rv = scp_get_create_session_response(t, &auth_result, + &display, &guid); - if (trans_get_wait_objs(t, wobj, &ocnt) != 0) - { - LOG(LOG_LEVEL_ERROR, "Can't get wait object for sesman transport"); - } - else - { - while (t->status == TRANS_STATUS_UP) + if (rv == 0) { - g_obj_wait(wobj, ocnt, NULL, 0, -1); - if (trans_check_wait_objs(t) != 0) + if (auth_result != 0) { - LOG(LOG_LEVEL_ERROR, "sesman transport down"); - break; + g_printf("Connection denied (authentication error)\n"); } - - if (scp_v0c_reply_available(t)) + else { - struct scp_v0_reply_type msg; - enum SCP_CLIENT_STATES_E e = scp_v0c_get_reply(t, &msg); - if (e != SCP_CLIENT_STATE_OK) - { - LOG(LOG_LEVEL_ERROR, - "Error reading response from sesman [%s]", - scp_client_state_to_str(e)); - } - else - { - if (msg.auth_result == 0) - { - g_printf("Connection denied (authentication error)\n"); - } - else - { - char guid_str[GUID_STR_SIZE]; - g_printf("ok data=%d display=:%d GUID=%s\n", - msg.auth_result, - msg.display, - guid_to_str(&msg.guid, guid_str)); - } - rv = 0; - } - break; + char guid_str[GUID_STR_SIZE]; + g_printf("ok display=:%d GUID=%s\n", + display, + guid_to_str(&guid, guid_str)); } } } @@ -514,7 +479,6 @@ main(int argc, char **argv) struct config_sesman *cfg = NULL; struct trans *t = NULL; - enum SCP_CLIENT_STATES_E e; struct session_params sp; struct log_config *logging; @@ -534,23 +498,20 @@ main(int argc, char **argv) LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s", sesman_ini, g_get_strerror()); } - else if (!(t = scp_connect(sp.server, cfg->listen_port, NULL, NULL, NULL))) + else if (!(t = scp_connect(sp.server, cfg->listen_port, NULL))) { LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror()); } else { - e = send_scpv0_auth_request(t, &sp); - if (e != SCP_CLIENT_STATE_OK) + rv = send_create_session_request(t, &sp); + if (rv != 0) { - LOG(LOG_LEVEL_ERROR, - "Error sending create session to sesman [%s]", - scp_client_state_to_str(e)); - rv = 1; + LOG(LOG_LEVEL_ERROR, "Error sending create session to sesman"); } else { - rv = handle_scpv0_auth_reply(t); + rv = handle_create_session_response(t); } trans_delete(t); } diff --git a/sesman/tools/tools_common.c b/sesman/tools/tools_common.c new file mode 100644 index 00000000..442a79a9 --- /dev/null +++ b/sesman/tools/tools_common.c @@ -0,0 +1,70 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * + * @file tools_common.c + * @brief Common definitions for the tools utilities + * @author Matt Burt + * + */ + + +#if defined(HAVE_CONFIG_H) +#include "config_ac.h" +#endif + +#include "trans.h" +#include "os_calls.h" +#include "scp.h" + + +/*****************************************************************************/ +int +wait_for_sesman_reply(struct trans *t, enum scp_msg_code wait_msgno) +{ + + int rv = 0; + int available = 0; + + while (rv == 0 && !available) + { + if ((rv = scp_msg_in_wait_available(t)) != 0) + { + LOG(LOG_LEVEL_ERROR, "Error waiting on sesman transport"); + } + else + { + enum scp_msg_code reply_msgno = scp_msg_in_start(t); + + available = 1; + if (reply_msgno != wait_msgno) + { + char buff[64]; + scp_msgno_to_str(reply_msgno, buff, sizeof(buff)); + + LOG(LOG_LEVEL_WARNING, + "Ignoring unexpected message %s", buff); + scp_msg_in_reset(t); + available = 0; + } + } + } + + return rv; +} diff --git a/sesman/tools/tools_common.h b/sesman/tools/tools_common.h new file mode 100644 index 00000000..bc32af17 --- /dev/null +++ b/sesman/tools/tools_common.h @@ -0,0 +1,48 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2022 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * + * @file tools_common.c + * @brief Common definitions for the tools utilities + * @author Matt Burt + * + */ + +#if !defined(TOOLS_COMMON_H) +#define TOOLS_COMMON_H + +#include "scp.h" + +struct trans; + +/**************************************************************************//** + * Waits for an expected reply from sesman + * + * Any other incoming messages are ignored. + * + * Following this call, the mesage can be parsed in the usual way. + * + * @param t SCP transport + * @param wait_msgno Code of the message we're waiting for. + * @result 0 for success + */ +int +wait_for_sesman_reply(struct trans *t, enum scp_msg_code wait_msgno); + +#endif /* TOOLS_COMMON_H */