diff --git a/libipm/Makefile.am b/libipm/Makefile.am index a1a6edcd..8da084bc 100644 --- a/libipm/Makefile.am +++ b/libipm/Makefile.am @@ -19,6 +19,8 @@ libipm_la_SOURCES = \ ercp.c \ scp.h \ scp.c \ + scp_sync.h \ + scp_sync.c \ scp_application_types.h \ scp_application_types.c diff --git a/libipm/scp_sync.c b/libipm/scp_sync.c new file mode 100644 index 00000000..8312e9cb --- /dev/null +++ b/libipm/scp_sync.c @@ -0,0 +1,168 @@ +/** + * 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 scp_sync.c + * @brief scp definitions (synchronous calls) + * @author Matt Burt + * + */ + +#if defined(HAVE_CONFIG_H) +#include "config_ac.h" +#endif + +//nclude "tools_common.h" +//nclude "trans.h" +#include "os_calls.h" +#include "log.h" +#include "scp.h" +#include "scp_sync.h" + +/*****************************************************************************/ +int +scp_sync_wait_specific(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_get_msgno(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; +} + +/*****************************************************************************/ +int +scp_sync_uds_login_request(struct trans *t) +{ + int rv = scp_send_uds_login_request(t); + if (rv == 0) + { + if ((rv = scp_sync_wait_specific(t, E_SCP_LOGIN_RESPONSE)) == 0) + { + enum scp_login_status login_result; + int server_closed; + rv = scp_get_login_response(t, &login_result, &server_closed, NULL); + if (rv == 0 && login_result != E_SCP_LOGIN_OK) + { + char msg[256]; + scp_login_status_to_str(login_result, msg, sizeof(msg)); + g_printf("Login failed; %s\n", msg); + rv = 1; + if (!server_closed) + { + (void)scp_send_close_connection_request(t); + } + } + scp_msg_in_reset(t); // Done with this message + } + + } + return rv; +} + +/*****************************************************************************/ +struct list * +scp_sync_list_sessions_request(struct trans *t) +{ + struct list *sessions = list_create(); + if (sessions == NULL) + { + LOG(LOG_LEVEL_ERROR, "Out of memory for sessions list"); + } + else + { + int end_of_list = 0; + + enum scp_list_sessions_status status; + struct scp_session_info *p; + + int rv = scp_send_list_sessions_request(t); + + sessions->auto_free = 1; + + while (rv == 0 && !end_of_list) + { + rv = scp_sync_wait_specific(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_SESSION_INFO: + if (!list_add_item(sessions, (tintptr)p)) + { + g_free(p); + LOG(LOG_LEVEL_ERROR, "Out of memory for session item"); + rv = 1; + } + break; + + case E_SCP_LS_END_OF_LIST: + end_of_list = 1; + break; + + default: + LOG(LOG_LEVEL_ERROR, + "Unexpected return code %d for session item", status); + rv = 1; + } + scp_msg_in_reset(t); + } + + if (rv != 0) + { + list_delete(sessions); + sessions = NULL; + } + } + + return sessions; +} diff --git a/libipm/scp_sync.h b/libipm/scp_sync.h new file mode 100644 index 00000000..b99d3b99 --- /dev/null +++ b/libipm/scp_sync.h @@ -0,0 +1,89 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2022, all xrdp contributors + * + * 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 libipm/scp_sync.h + * @brief scp declarations (synchronous calls) + * @author Simone Fedele/ Matt Burt + * + * This module places a synchronous wrapper on top of some of the + * calls in scp.h. It is intended to be used for simple SCP applications + * which do not need to handle SCP messages along with other messages + * using the xrdp transport mechanism. + * + */ + +#ifndef SCP_SYNC_H +#define SCP_SYNC_H + +#include + +/** + * Waits on a single transport for a specific SCP message to be available for + * parsing + * + * @param trans libipm transport + * @param wait_msgno Message number to wait for + * @return != 0 for error + * + * This is a convenience function, used to implement synchronous calls. + * + * While the call is active, data-in callbacks for the transport are + * disabled. + * + * Unexpected messages are ignored and logged. + * + * Only use this call if you have nothing to do until a message + * arrives on the transport. + * - If you have other transports to service, use + * scp_msg_in_check_available() + * - If you can process any incoming message, use + * scp_msg_in_wait_available() + */ +int +scp_sync_wait_specific(struct trans *t, enum scp_msg_code wait_msgno); + +/** + * Send UDS login request to sesman and wait for answer + * + * @param t SCP transport + * @return 0 for successful login + * + * If non-zero is returned, the scp_connection has been closed (if + * appropriate) and simply remains to be deleted. + */ +int +scp_sync_uds_login_request(struct trans *t); + +/** + * Send list sessions request to sesman and wait for answer(s) + * + * @param t SCP transport + * @return list of sessions + * + * If NULL is returned, the scp_connection has been closed (if + * appropriate) and simply remains to be deleted. + * + * If NULL is not returned, the caller must call list_delete() to + * free it. + */ +struct list * +scp_sync_list_sessions_request(struct trans *t); + +#endif /* SCP_SYNC_H */ diff --git a/sesman/tools/Makefile.am b/sesman/tools/Makefile.am index 73f1a3b9..ce5171b1 100644 --- a/sesman/tools/Makefile.am +++ b/sesman/tools/Makefile.am @@ -17,14 +17,10 @@ noinst_PROGRAMS = \ xrdp-xcon xrdp_sesrun_SOURCES = \ - sesrun.c \ - tools_common.h \ - tools_common.c + sesrun.c xrdp_sesadmin_SOURCES = \ - sesadmin.c \ - tools_common.h \ - tools_common.c + sesadmin.c xrdp_dis_SOURCES = \ dis.c diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c index e41c8fed..e5c5e58e 100644 --- a/sesman/tools/sesadmin.c +++ b/sesman/tools/sesadmin.c @@ -26,11 +26,14 @@ #include "log.h" #include "os_calls.h" #include "string_calls.h" -#include "tools_common.h" + +#include "scp.h" +#include "scp_sync.h" #include #include + char cmnd[257]; char port[257]; @@ -89,25 +92,8 @@ int main(int argc, char **argv) } else { - enum scp_login_status login_result; - /* Log in as the current user */ - if ((rv = scp_send_uds_login_request(t)) == 0 && - (rv = wait_for_sesman_reply(t, E_SCP_LOGIN_RESPONSE)) == 0) - { - rv = scp_get_login_response(t, &login_result, NULL, NULL); - if (rv == 0) - { - if (login_result != E_SCP_LOGIN_OK) - { - char msg[256]; - scp_login_status_to_str(login_result, msg, sizeof(msg)); - g_printf("Login failed; %s\n", msg); - rv = 1; - } - } - scp_msg_in_reset(t); // Done with this message - } + rv = scp_sync_uds_login_request(t); } if (rv == 0) @@ -169,48 +155,9 @@ print_session(const struct scp_session_info *s) static int cmndList(struct trans *t) { - struct list *sessions = list_create(); - int end_of_list = 0; - - enum scp_list_sessions_status status; - struct scp_session_info *p; - - int rv = scp_send_list_sessions_request(t); - - sessions->auto_free = 1; - - while (rv == 0 && !end_of_list) - { - 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_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 (rv == 0) + int rv = 1; + struct list *sessions = scp_sync_list_sessions_request(t); + if (sessions != NULL) { if (sessions->count == 0) { @@ -224,9 +171,10 @@ cmndList(struct trans *t) print_session((struct scp_session_info *)sessions->items[i]); } } + (void)scp_send_close_connection_request(t); + list_delete(sessions); } - list_delete(sessions); return rv; } diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c index b727da35..89e20c36 100644 --- a/sesman/tools/sesrun.c +++ b/sesman/tools/sesrun.c @@ -40,7 +40,8 @@ #include "string_calls.h" #include "guid.h" -#include "tools_common.h" +#include "scp.h" +#include "scp_sync.h" // cppcheck doesn't always set this macro to something in double-quotes #if defined(__cppcheck__) @@ -453,7 +454,7 @@ handle_login_response(struct trans *t, int *server_closed) { enum scp_login_status login_result; - int rv = wait_for_sesman_reply(t, E_SCP_LOGIN_RESPONSE); + int rv = scp_sync_wait_specific(t, E_SCP_LOGIN_RESPONSE); if (rv != 0) { *server_closed = 1; @@ -511,7 +512,7 @@ handle_create_session_response(struct trans *t) int display; struct guid guid; - int rv = wait_for_sesman_reply(t, E_SCP_CREATE_SESSION_RESPONSE); + int rv = scp_sync_wait_specific(t, E_SCP_CREATE_SESSION_RESPONSE); if (rv == 0) { rv = scp_get_create_session_response(t, &status, diff --git a/sesman/tools/tools_common.c b/sesman/tools/tools_common.c deleted file mode 100644 index 674ba69e..00000000 --- a/sesman/tools/tools_common.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * 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 "tools_common.h" -#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_get_msgno(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 deleted file mode 100644 index 2e357965..00000000 --- a/sesman/tools/tools_common.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * 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 message 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 */