Skip to content

Commit

Permalink
added selinu support
Browse files Browse the repository at this point in the history
Commit adds SELinux support to dropbear by:

- adding a new '--enable-selinux' option to configure; by default, it
  is disabled.  This option defines an ENABLE_SELINUX preprocessor
  macro.

- mapping the unix username to the SELinux user which is stored in a
  new 'user_sid' attribute in the AuthState object

- relabeling the controlling pty

- setting the context for the next execve() call to the user_sid


Operations above will not be done when SELinux is disabled.  Failures will
generate LOG_ERR messages and in enforcing SELinux mode, dropbear_exit()
will be called.


Signed-off-by: Enrico Scholz <[email protected]>
  • Loading branch information
ensc committed Nov 11, 2018
1 parent 7e03e4d commit 24e456a
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions svr-chansession.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
#include "runopts.h"
#include "auth.h"

#ifdef ENABLE_SELINUX
# include <selinux/selinux.h>
#endif

/* Handles sessions (either shells or programs) requested by the client */

static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
Expand Down Expand Up @@ -556,6 +560,48 @@ static void get_termmodes(const struct ChanSess *chansess) {
TRACE(("leave get_termmodes"))
}

static void relabelpty(const char *tty)
{
#ifdef ENABLE_SELINUX
char *old_sid = NULL;
char *new_sid = NULL;
security_class_t class;
int rc;

if (!is_selinux_enabled())
return;

rc = getfilecon(tty, &old_sid);
if (rc < 0) {
dropbear_log(LOG_ERR, "failed to get context of tty '%s'", tty);
goto out;
}

class = string_to_security_class("chr_file");

rc = security_compute_relabel(ses.authstate.user_sid, old_sid, class, &new_sid);
if (rc < 0) {
dropbear_log(LOG_ERR, "failed to compute tty relabel");
goto out;
}

rc = setfilecon(tty, new_sid);
if (rc < 0) {
dropbear_log(LOG_ERR, "failed to set file context for '%s'", tty);
goto out;
}

rc = 0;

out:
freecon(new_sid);
freecon(old_sid);

if (rc < 0 && security_getenforce() > 0)
dropbear_exit("SELinux: failed to relabel PTY");
#endif
}

/* Set up a session pty which will be used to execute the shell or program.
* The pty is allocated now, and kept for when the shell/program executes.
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
Expand Down Expand Up @@ -604,6 +650,8 @@ static int sessionpty(struct ChanSess * chansess) {
/* Read the terminal modes */
get_termmodes(chansess);

relabelpty(chansess->tty);

TRACE(("leave sessionpty"))
return DROPBEAR_SUCCESS;
}
Expand Down Expand Up @@ -726,6 +774,31 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
return ret;
}

static void init_selinux_session(void)
{
#ifdef ENABLE_SELINUX
char *ctx = ses.authstate.user_sid;
int rc;
unsigned int i;
security_class_t class;

if (!is_selinux_enabled())
return;

rc = setexeccon(ctx);
if (rc < 0) {
dropbear_log(LOG_ERR, "setexeccon() failed");
goto out;
}

rc = 0;

out:
if (rc < 0 && security_getenforce() > 0)
dropbear_exit("SELinux: failed to initialize session");
#endif
}

/* Execute a command and set up redirection of stdin/stdout/stderr without a
* pty.
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
Expand Down Expand Up @@ -932,6 +1005,8 @@ static void execchild(const void *user_data) {
#endif /* HAVE_CLEARENV */
#endif /* DEBUG_VALGRIND */

init_selinux_session();

/* We can only change uid/gid as root ... */
if (getuid() == 0) {

Expand Down

0 comments on commit 24e456a

Please sign in to comment.