tools: Moved to new SCP interface

This commit is contained in:
matt335672 2022-02-14 20:13:03 +00:00
parent a952ff8542
commit bb820cca87
5 changed files with 274 additions and 173 deletions

View File

@ -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)

View File

@ -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 <stdio.h>
#include <unistd.h>
@ -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;
}

View File

@ -33,13 +33,14 @@
#include <ctype.h>
#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 <password> TESTING ONLY - DO NOT USE IN PRODUCTION\n"
" -F <file-descriptor> Read password from this file descriptor\n"
" -c <sesman_ini> 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);
}

View File

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

View File

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