From 5741653900a497c01e36f5e19ba6332d6305a295 Mon Sep 17 00:00:00 2001 From: Lennart Sauerbeck Date: Fri, 14 Apr 2023 20:22:42 +0200 Subject: [PATCH] sesman: Prevent the use of 'alternate shell' By setting the new config value 'AllowAlternateShell' to 'no' it is now possible to prevent the use of an alternate shell, which can be set by the connecting user. The default remains unchanged and any shell is allowed if the config value is not specified. It can also be set explicitly to 'yes' to achieve the same outcome. Fixes: #850 --- docs/man/sesman.ini.5.in | 4 +++ sesman/libsesman/sesman_config.c | 8 ++++++ sesman/libsesman/sesman_config.h | 9 +++++++ sesman/sesman.ini.in | 2 ++ sesman/session.c | 44 +++++++++++++++++++++++--------- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/docs/man/sesman.ini.5.in b/docs/man/sesman.ini.5.in index e632c13882..45c256f97f 100644 --- a/docs/man/sesman.ini.5.in +++ b/docs/man/sesman.ini.5.in @@ -292,6 +292,10 @@ To keep compatibility, the following aliases are also available. If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even if the group specified in \fBTerminalServerUsers\fR doesn't exist. +.TP +\fBAllowAlternateShell\fR=\fI[true|false]\fR +If set to \fB0\fR, \fBfalse\fR or \fBno\fR, prevent usage of alternate shells by users. + .SH "X11 SERVER" Following parameters can be used in the \fB[Xvnc]\fR and \fB[Xorg]\fR sections. diff --git a/sesman/libsesman/sesman_config.c b/sesman/libsesman/sesman_config.c index aa9bf0ae31..1513a53d51 100644 --- a/sesman/libsesman/sesman_config.c +++ b/sesman/libsesman/sesman_config.c @@ -69,6 +69,7 @@ #define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck" #define SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD "RestrictOutboundClipboard" #define SESMAN_CFG_SEC_RESTRICT_INBOUND_CLIPBOARD "RestrictInboundClipboard" +#define SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL "AllowAlternateShell" #define SESMAN_CFG_SESSIONS "Sessions" #define SESMAN_CFG_SESS_MAX "MaxSessions" @@ -306,6 +307,7 @@ config_read_security(int file, struct config_security *sc, sc->ts_admins_enable = 0; sc->restrict_outbound_clipboard = 0; sc->restrict_inbound_clipboard = 0; + sc->allow_alternate_shell = 1; file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v); @@ -373,6 +375,11 @@ config_read_security(int file, struct config_security *sc, unrecognised); } } + if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_ALLOW_ALTERNATE_SHELL)) + { + sc->allow_alternate_shell = + g_text2bool((char *)list_get_item(param_v, i)); + } } @@ -641,6 +648,7 @@ config_dump(struct config_sesman *config) g_writeln(" AllowRootLogin: %d", sc->allow_root); g_writeln(" MaxLoginRetry: %d", sc->login_retry); g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check); + g_writeln(" AllowAlternateShell: %d", sc->allow_alternate_shell); sesman_clip_restrict_mask_to_string(sc->restrict_outbound_clipboard, restrict_s, sizeof(restrict_s)); g_writeln(" RestrictOutboundClipboard: %s", restrict_s); diff --git a/sesman/libsesman/sesman_config.h b/sesman/libsesman/sesman_config.h index a4cc125108..c671935ca8 100644 --- a/sesman/libsesman/sesman_config.h +++ b/sesman/libsesman/sesman_config.h @@ -89,6 +89,15 @@ struct config_security * @brief if the clipboard should be enforced restricted. If true only allow server -> client, not vice versa. */ int restrict_inbound_clipboard; + + /** + * @var allow_alternate_shell + * @brief allow an user-supplied alternate shell. + * @details 'YES' for all programs allowed, 'NO' for disabling of alternate + * shells. + * If not specified, 'YES' is assumed. + */ + int allow_alternate_shell; }; /** diff --git a/sesman/sesman.ini.in b/sesman/sesman.ini.in index e14ff02b89..f2ce82c133 100644 --- a/sesman/sesman.ini.in +++ b/sesman/sesman.ini.in @@ -37,6 +37,8 @@ RestrictOutboundClipboard=none ; false: an alias of none ; yes: an alias of all RestrictInboundClipboard=none +; Set to 'no' to prevent users from logging in with alternate shells +#AllowAlternateShell=true [Sessions] ;; X11DisplayOffset - x11 display number offset diff --git a/sesman/session.c b/sesman/session.c index a9d02a739a..f69c5d67eb 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -275,26 +275,46 @@ start_window_manager(struct auth_info *auth_info, auth_set_env(auth_info); if (s->directory[0] != '\0') { - g_set_current_dir(s->directory); + if (g_cfg->sec.allow_alternate_shell) + { + g_set_current_dir(s->directory); + } + else + { + LOG(LOG_LEVEL_WARNING, + "Directory change to %s requested, but not " + "allowed by AllowAlternateShell config value.", + s->directory); + } } if (s->shell[0] != '\0') { - if (g_strchr(s->shell, ' ') != 0 || g_strchr(s->shell, '\t') != 0) + if (g_cfg->sec.allow_alternate_shell) { - LOG(LOG_LEVEL_INFO, - "Using user requested window manager on " - "display %u with embedded arguments using a shell: %s", - s->display, s->shell); - const char *argv[] = {"sh", "-c", s->shell, NULL}; - g_execvp("/bin/sh", (char **)argv); + if (g_strchr(s->shell, ' ') != 0 || g_strchr(s->shell, '\t') != 0) + { + LOG(LOG_LEVEL_INFO, + "Using user requested window manager on " + "display %u with embedded arguments using a shell: %s", + s->display, s->shell); + const char *argv[] = {"sh", "-c", s->shell, NULL}; + g_execvp("/bin/sh", (char **)argv); + } + else + { + LOG(LOG_LEVEL_INFO, + "Using user requested window manager on " + "display %d: %s", s->display, s->shell); + g_execlp3(s->shell, s->shell, 0); + } } else { - LOG(LOG_LEVEL_INFO, - "Using user requested window manager on " - "display %d: %s", s->display, s->shell); - g_execlp3(s->shell, s->shell, 0); + LOG(LOG_LEVEL_WARNING, + "Shell %s requested by user, but not allowed by " + "AllowAlternateShell config value.", + s->shell); } } else