mirror of https://github.com/neutrinolabs/xrdp
Update sesman tools for new interfaces
The sesman tools sesrun and sesadmin now use the separate authentication/authorization (AA) interface introduced to sesman by the previous comment. sesrun can use either password or UDS authentication. With some limitations, this can allow for automatic creation of sessions for local users without a password being needed. sesadmin now operates using UDS logins only and so a username and password are not required. To use sesadmin for another user, use su/sudo/doas to authenticate as the other user.
This commit is contained in:
parent
fd99653957
commit
851bed680c
|
@ -18,13 +18,11 @@ command.
|
|||
A summary of options is included below.
|
||||
.TP
|
||||
.BI \-u= username
|
||||
\fIUsername\fP for authentication on the server.
|
||||
Defaults to \fBroot\fP.
|
||||
Retained for compatibility, but ignored.
|
||||
|
||||
.TP
|
||||
.BI \-p= password
|
||||
The \fIpassword\fP to authenticate with.
|
||||
The default is to ask for the password interactively.
|
||||
Retained for compatibility, but ignored.
|
||||
|
||||
.TP
|
||||
.BI \-i= port
|
||||
|
@ -39,7 +37,7 @@ Valid commands are:
|
|||
.RS 4
|
||||
.TP
|
||||
.B list
|
||||
List currently active sessions.
|
||||
List active sessions for the current user.
|
||||
.TP
|
||||
.BI kill: sid
|
||||
Kills the session specified the given \fIsession id\fP.
|
||||
|
|
|
@ -4,18 +4,28 @@
|
|||
|
||||
.SH "SYNTAX"
|
||||
.B xrdp\-sesrun
|
||||
.I [ options ] username
|
||||
.I --help
|
||||
.br
|
||||
|
||||
.B xrdp\-sesrun
|
||||
.I [ options ] [ username ]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
\fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
|
||||
.br
|
||||
This is a tool useful for testing, it simply behaves like xrdp when some
|
||||
This is a tool useful for testing. It simply behaves like xrdp when some
|
||||
user logs in a new session and authenticates, thus starting a new session.
|
||||
|
||||
Default values for the options are set at compile-time. Run the utility without
|
||||
a username to see what the defaults are for your installation.
|
||||
Default values for the options are set at compile-time. Run the utility with
|
||||
the '--help' option to see what the defaults are for your installation.
|
||||
|
||||
The utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
|
||||
If no username is used, the current username is used, and no password
|
||||
needs to be provided. In this instance, it is important that any necessary
|
||||
authentication tokens for a GUI session (e.g. a Kerberos ticket) have
|
||||
already been acquired.
|
||||
|
||||
If a username is provided, a password must also be provided. In this instance
|
||||
the utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
|
@ -60,6 +70,10 @@ Override the default logging level. One of "error", "warn", "info",
|
|||
.SH "EXAMPLES"
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun
|
||||
Create a default session for the current user.
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun -F 0 user1 <passwd.txt
|
||||
Create a default session for user \fBuser1\fR with a password from
|
||||
a file
|
||||
|
|
|
@ -31,8 +31,6 @@
|
|||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char user[257];
|
||||
char pass[257];
|
||||
char cmnd[257];
|
||||
char port[257];
|
||||
|
||||
|
@ -47,12 +45,9 @@ int main(int argc, char **argv)
|
|||
//int end;
|
||||
int idx;
|
||||
//int sel;
|
||||
char *pwd;
|
||||
struct log_config *logging;
|
||||
int rv = 1;
|
||||
|
||||
user[0] = '\0';
|
||||
pass[0] = '\0';
|
||||
cmnd[0] = '\0';
|
||||
port[0] = '\0';
|
||||
|
||||
|
@ -64,11 +59,11 @@ int main(int argc, char **argv)
|
|||
{
|
||||
if (0 == g_strncmp(argv[idx], "-u=", 3))
|
||||
{
|
||||
g_strncpy(user, (argv[idx]) + 3, 256);
|
||||
g_printf("** Ignoring unused argument '-u'");
|
||||
}
|
||||
else if (0 == g_strncmp(argv[idx], "-p=", 3))
|
||||
{
|
||||
g_strncpy(pass, (argv[idx]) + 3, 256);
|
||||
g_printf("** Ignoring unused argument '-p'");
|
||||
}
|
||||
else if (0 == g_strncmp(argv[idx], "-i=", 3))
|
||||
{
|
||||
|
@ -80,48 +75,57 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (0 == g_strncmp(port, "", 1))
|
||||
{
|
||||
g_strncpy(port, "3350", 256);
|
||||
}
|
||||
|
||||
if (0 == g_strncmp(user, "", 1))
|
||||
{
|
||||
cmndHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == g_strncmp(cmnd, "", 1))
|
||||
{
|
||||
cmndHelp();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == g_strncmp(pass, "", 1))
|
||||
{
|
||||
pwd = getpass("password:");
|
||||
g_strncpy(pass, pwd, 256);
|
||||
|
||||
}
|
||||
|
||||
t = scp_connect(port, NULL);
|
||||
|
||||
t = scp_connect(port, "xrdp-sesadmin", NULL);
|
||||
|
||||
if (t == NULL)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "scp_connect() error");
|
||||
}
|
||||
else if (0 == g_strncmp(cmnd, "list", 5))
|
||||
else
|
||||
{
|
||||
rv = cmndList(t);
|
||||
}
|
||||
else if (0 == g_strncmp(cmnd, "kill:", 5))
|
||||
{
|
||||
rv = cmndKill(t);
|
||||
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);
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
g_memset(pass, '\0', sizeof(pass));
|
||||
if (rv == 0)
|
||||
{
|
||||
if (0 == g_strncmp(cmnd, "list", 5))
|
||||
{
|
||||
rv = cmndList(t);
|
||||
}
|
||||
else if (0 == g_strncmp(cmnd, "kill:", 5))
|
||||
{
|
||||
rv = cmndKill(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
rv = scp_send_close_connection_request(t);
|
||||
}
|
||||
trans_delete(t);
|
||||
log_end();
|
||||
|
||||
|
@ -133,10 +137,7 @@ cmndHelp(void)
|
|||
{
|
||||
fprintf(stderr, "sesadmin - a console sesman administration tool\n");
|
||||
fprintf(stderr, "syntax: sesadmin [] COMMAND [OPTIONS]\n\n");
|
||||
fprintf(stderr, "-u=<username>: username to connect to sesman [MANDATORY]\n");
|
||||
fprintf(stderr, "-p=<password>: password to connect to sesman (asked if not given)\n");
|
||||
fprintf(stderr, "-s=<hostname>: sesman host (default is localhost)\n");
|
||||
fprintf(stderr, "-i=<port> : sesman port (default 3350)\n");
|
||||
fprintf(stderr, "-i=<port> : sesman port (can be defaulted)\n");
|
||||
fprintf(stderr, "-c=<command> : command to execute on the server [MANDATORY]\n");
|
||||
fprintf(stderr, " it can be one of those:\n");
|
||||
fprintf(stderr, " list\n");
|
||||
|
@ -146,9 +147,14 @@ cmndHelp(void)
|
|||
static void
|
||||
print_session(const struct scp_session_info *s)
|
||||
{
|
||||
char *username;
|
||||
const char *uptr;
|
||||
g_getuser_info_by_uid(s->uid, &username, NULL, NULL, NULL, NULL);
|
||||
uptr = (username == NULL) ? "<unknown>" : username;
|
||||
|
||||
printf("Session ID: %d\n", s->sid);
|
||||
printf("\tDisplay: :%u\n", s->display);
|
||||
printf("\tUser: %s\n", s->username);
|
||||
printf("\tUser: %s\n", uptr);
|
||||
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);
|
||||
|
@ -157,6 +163,7 @@ print_session(const struct scp_session_info *s)
|
|||
{
|
||||
printf("\tStart IP address: %s\n", s->start_ip_addr);
|
||||
}
|
||||
g_free(username);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -168,7 +175,7 @@ cmndList(struct trans *t)
|
|||
enum scp_list_sessions_status status;
|
||||
struct scp_session_info *p;
|
||||
|
||||
int rv = scp_send_list_sessions_request(t, user, pass);
|
||||
int rv = scp_send_list_sessions_request(t);
|
||||
|
||||
sessions->auto_free = 1;
|
||||
|
||||
|
@ -188,11 +195,6 @@ cmndList(struct trans *t)
|
|||
|
||||
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;
|
||||
|
|
|
@ -94,7 +94,7 @@ struct session_params
|
|||
|
||||
const char *directory;
|
||||
const char *shell;
|
||||
const char *connection_description;
|
||||
const char *ip_addr;
|
||||
|
||||
const char *username;
|
||||
char password[MAX_PASSWORD_LEN + 1];
|
||||
|
@ -165,7 +165,9 @@ usage(void)
|
|||
|
||||
g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
|
||||
g_printf("\nusage:\n");
|
||||
g_printf("sesrun [options] username\n\n");
|
||||
g_printf("sesrun --help\n"
|
||||
"\nor\n"
|
||||
"sesrun [options] [username]\n\n");
|
||||
g_printf("options:\n");
|
||||
g_printf(" -g <geometry> Default:%dx%d\n",
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
|
@ -176,9 +178,11 @@ 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\n",
|
||||
g_printf("\nSupported types are %s\n",
|
||||
sesstype_list);
|
||||
g_printf("Password is prompted if -p or -F are not specified\n");
|
||||
g_printf("\nIf username is omitted, the current user is used.\n"
|
||||
"If username is provided, password is needed.\n"
|
||||
" Password is prompted for if -p or -F are not specified\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -286,7 +290,7 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
|
|||
|
||||
sp->directory = "";
|
||||
sp->shell = "";
|
||||
sp->connection_description = "";
|
||||
sp->ip_addr = "";
|
||||
|
||||
sp->username = NULL;
|
||||
sp->password[0] = '\0';
|
||||
|
@ -367,33 +371,109 @@ parse_program_args(int argc, char *argv[], struct session_params *sp,
|
|||
}
|
||||
}
|
||||
|
||||
if (argc <= optind)
|
||||
if (argc == optind)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "No user name specified");
|
||||
params_ok = 0;
|
||||
// No username was specified
|
||||
if (password_set)
|
||||
{
|
||||
LOG(LOG_LEVEL_WARNING, "No username - ignoring specified password");
|
||||
sp->password[0] = '\0';
|
||||
}
|
||||
sp->username = NULL;
|
||||
}
|
||||
else if ((argc - optind) > 1)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Unexpected arguments after username");
|
||||
params_ok = 0;
|
||||
}
|
||||
else
|
||||
else if (params_ok)
|
||||
{
|
||||
// A username is specified
|
||||
sp->username = argv[optind];
|
||||
}
|
||||
|
||||
if (params_ok && !password_set)
|
||||
{
|
||||
const char *p = getpass("Password: ");
|
||||
if (p != NULL)
|
||||
if (!password_set)
|
||||
{
|
||||
g_strcpy(sp->password, p);
|
||||
const char *p = getpass("Password: ");
|
||||
if (p == NULL)
|
||||
{
|
||||
params_ok = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_snprintf(sp->password, sizeof(sp->password), "%s", p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return params_ok;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Sends an SCP login request
|
||||
*
|
||||
* A sys login request (i.e. username / password) is used if a username
|
||||
* is specified. Otherwise we use a uds login request for the current user.
|
||||
*
|
||||
* @param t SCP connection
|
||||
* @param sp Data for request
|
||||
*/
|
||||
static int
|
||||
send_login_request(struct trans *t, const struct session_params *sp)
|
||||
{
|
||||
int rv;
|
||||
LOG(LOG_LEVEL_DEBUG, "ip_addr:\"%s\"", sp->ip_addr);
|
||||
if (sp->username != NULL)
|
||||
{
|
||||
/* Only log the password in development builds */
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
|
||||
|
||||
rv = scp_send_sys_login_request(t, sp->username,
|
||||
sp->password, sp->ip_addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = scp_send_uds_login_request(t);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* Receives an SCP login response
|
||||
*
|
||||
* @param t SCP transport to receive reply on
|
||||
* @param[out] server_closed != 0 if server has gone away
|
||||
* @return 0 for successful authentication
|
||||
*/
|
||||
static int
|
||||
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);
|
||||
if (rv != 0)
|
||||
{
|
||||
*server_closed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = scp_get_login_response(t, &login_result, server_closed);
|
||||
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
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* Sends an SCP create session request
|
||||
*
|
||||
|
@ -405,18 +485,13 @@ 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"
|
||||
"directory:\"%s\"\n"
|
||||
"shell:\"%s\" connection_description:\"%s\"",
|
||||
"directory:\"%s\" shell:\"%s\"",
|
||||
sp->width, sp->height, sp->bpp, sp->session_type,
|
||||
sp->directory,
|
||||
sp->shell, sp->connection_description);
|
||||
/* Only log the password in development builds */
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
|
||||
sp->directory, sp->shell);
|
||||
|
||||
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);
|
||||
t, sp->session_type,
|
||||
sp->width, sp->height, sp->bpp, sp->shell, sp->directory);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
|
@ -428,21 +503,24 @@ send_create_session_request(struct trans *t, const struct session_params *sp)
|
|||
static int
|
||||
handle_create_session_response(struct trans *t)
|
||||
{
|
||||
int auth_result;
|
||||
enum scp_screate_status status;
|
||||
int display;
|
||||
struct guid guid;
|
||||
|
||||
int rv = wait_for_sesman_reply(t, E_SCP_CREATE_SESSION_RESPONSE);
|
||||
if (rv == 0)
|
||||
{
|
||||
rv = scp_get_create_session_response(t, &auth_result,
|
||||
rv = scp_get_create_session_response(t, &status,
|
||||
&display, &guid);
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
if (auth_result != 0)
|
||||
if (status != E_SCP_SCREATE_OK)
|
||||
{
|
||||
g_printf("Connection denied (authentication error)\n");
|
||||
char msg[256];
|
||||
scp_screate_status_to_str(status, msg, sizeof(msg));
|
||||
g_printf("Connection failed; %s\n", msg);
|
||||
rv = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -452,6 +530,7 @@ handle_create_session_response(struct trans *t)
|
|||
guid_to_str(&guid, guid_str));
|
||||
}
|
||||
}
|
||||
scp_msg_in_reset(t); // Done with this message
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -475,7 +554,12 @@ main(int argc, char **argv)
|
|||
log_start_from_param(logging);
|
||||
log_config_free(logging);
|
||||
|
||||
if (!parse_program_args(argc, argv, &sp, &sesman_ini))
|
||||
if (argc == 2 && g_strcmp(argv[1], "--help") == 0)
|
||||
{
|
||||
usage();
|
||||
rv = 0;
|
||||
}
|
||||
else if (!parse_program_args(argc, argv, &sp, &sesman_ini))
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
@ -484,20 +568,44 @@ 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(cfg->listen_port, NULL)))
|
||||
else if (!(t = scp_connect(cfg->listen_port, "xrdp-sesrun", NULL)))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror());
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = send_create_session_request(t, &sp);
|
||||
if (rv != 0)
|
||||
int server_closed = 0;
|
||||
while (!server_closed)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Error sending create session to sesman");
|
||||
rv = send_login_request(t, &sp);
|
||||
if (rv != 0)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "Error sending login request to sesman");
|
||||
break;
|
||||
}
|
||||
|
||||
rv = handle_login_response(t, &server_closed);
|
||||
if (rv == 0)
|
||||
{
|
||||
break; /* Successful authentication */
|
||||
}
|
||||
if (!server_closed)
|
||||
{
|
||||
const char *p = getpass("Password: ");
|
||||
if (p == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_snprintf(sp.password, sizeof(sp.password), "%s", p);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
rv = handle_create_session_response(t);
|
||||
if ((rv = send_create_session_request(t, &sp)) == 0)
|
||||
{
|
||||
rv = handle_create_session_response(t);
|
||||
}
|
||||
}
|
||||
trans_delete(t);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue