Move SCP synch calls from sesman tools to library

The sesman tools have some private functions to make syncronous calls
to sesman over SCP. This commit moves these calls to a new module
scp_sync in libipm so that they can be utilised by other parts of
xrdp (i.e. chansrv)
This commit is contained in:
matt335672 2024-09-13 11:57:15 +01:00
parent dd1dc7c630
commit 4d80cf6d77
8 changed files with 275 additions and 190 deletions

View File

@ -19,6 +19,8 @@ libipm_la_SOURCES = \
ercp.c \ ercp.c \
scp.h \ scp.h \
scp.c \ scp.c \
scp_sync.h \
scp_sync.c \
scp_application_types.h \ scp_application_types.h \
scp_application_types.c scp_application_types.c

168
libipm/scp_sync.c Normal file
View File

@ -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;
}

89
libipm/scp_sync.h Normal file
View File

@ -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 <scp.h>
/**
* 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 */

View File

@ -17,14 +17,10 @@ noinst_PROGRAMS = \
xrdp-xcon xrdp-xcon
xrdp_sesrun_SOURCES = \ xrdp_sesrun_SOURCES = \
sesrun.c \ sesrun.c
tools_common.h \
tools_common.c
xrdp_sesadmin_SOURCES = \ xrdp_sesadmin_SOURCES = \
sesadmin.c \ sesadmin.c
tools_common.h \
tools_common.c
xrdp_dis_SOURCES = \ xrdp_dis_SOURCES = \
dis.c dis.c

View File

@ -26,11 +26,14 @@
#include "log.h" #include "log.h"
#include "os_calls.h" #include "os_calls.h"
#include "string_calls.h" #include "string_calls.h"
#include "tools_common.h"
#include "scp.h"
#include "scp_sync.h"
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
char cmnd[257]; char cmnd[257];
char port[257]; char port[257];
@ -89,25 +92,8 @@ int main(int argc, char **argv)
} }
else else
{ {
enum scp_login_status login_result;
/* Log in as the current user */ /* Log in as the current user */
if ((rv = scp_send_uds_login_request(t)) == 0 && rv = scp_sync_uds_login_request(t);
(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
}
} }
if (rv == 0) if (rv == 0)
@ -169,48 +155,9 @@ print_session(const struct scp_session_info *s)
static int static int
cmndList(struct trans *t) cmndList(struct trans *t)
{ {
struct list *sessions = list_create(); int rv = 1;
int end_of_list = 0; struct list *sessions = scp_sync_list_sessions_request(t);
if (sessions != NULL)
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)
{ {
if (sessions->count == 0) if (sessions->count == 0)
{ {
@ -224,9 +171,10 @@ cmndList(struct trans *t)
print_session((struct scp_session_info *)sessions->items[i]); print_session((struct scp_session_info *)sessions->items[i]);
} }
} }
(void)scp_send_close_connection_request(t);
list_delete(sessions);
} }
list_delete(sessions);
return rv; return rv;
} }

View File

@ -40,7 +40,8 @@
#include "string_calls.h" #include "string_calls.h"
#include "guid.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 // cppcheck doesn't always set this macro to something in double-quotes
#if defined(__cppcheck__) #if defined(__cppcheck__)
@ -453,7 +454,7 @@ handle_login_response(struct trans *t, int *server_closed)
{ {
enum scp_login_status login_result; 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) if (rv != 0)
{ {
*server_closed = 1; *server_closed = 1;
@ -511,7 +512,7 @@ handle_create_session_response(struct trans *t)
int display; int display;
struct guid guid; 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) if (rv == 0)
{ {
rv = scp_get_create_session_response(t, &status, rv = scp_get_create_session_response(t, &status,

View File

@ -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;
}

View File

@ -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 */