]> andersk Git - openssh.git/commitdiff
- (djm) [Makefile.in configure.ac session.c sshpty.c]
authordjm <djm>
Sat, 22 Apr 2006 11:26:08 +0000 (11:26 +0000)
committerdjm <djm>
Sat, 22 Apr 2006 11:26:08 +0000 (11:26 +0000)
   [contrib/redhat/sshd.init openbsd-compat/Makefile.in]
   [openbsd-compat/openbsd-compat.h openbsd-compat/port-linux.c]
   [openbsd-compat/port-linux.h] Add support for SELinux, setting
   the execution and TTY contexts. based on patch from Daniel Walsh,
   bz #880; ok dtucker@

ChangeLog
Makefile.in
configure.ac
contrib/redhat/sshd.init
openbsd-compat/Makefile.in
openbsd-compat/openbsd-compat.h
openbsd-compat/port-linux.c [new file with mode: 0644]
openbsd-compat/port-linux.h [new file with mode: 0644]
session.c
sshpty.c

index 8c78a50220716f1780d06bd24f8e86b67ddbebe1..069bca1b2f27bb4b66f1953371ea7c1ea4da63bf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,14 @@
+20060421
+ - (djm) [Makefile.in configure.ac session.c sshpty.c]
+   [contrib/redhat/sshd.init openbsd-compat/Makefile.in]
+   [openbsd-compat/openbsd-compat.h openbsd-compat/port-linux.c]
+   [openbsd-compat/port-linux.h] Add support for SELinux, setting 
+   the execution and TTY contexts. based on patch from Daniel Walsh,
+   bz #880; ok dtucker@
+
 20060418
- - (djm) Reorder IP options check so that it isn't broken by 
-   mapped addresses; bz #1179 reported by markw wtech-llc.com;
+ - (djm) [canohost.c] Reorder IP options check so that it isn't broken
+   by mapped addresses; bz #1179 reported by markw wtech-llc.com;
    ok dtucker@
 
 20060331
index d256d58fa188ac7e056bde41c2530ed23cba7ec5..ae8108dfa15834cb18e7745991ae68dd6780c92b 100644 (file)
@@ -43,6 +43,7 @@ LD=@LD@
 CFLAGS=@CFLAGS@
 CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
 LIBS=@LIBS@
+LIBSELINUX=@LIBSELINUX@
 LIBEDIT=@LIBEDIT@
 LIBPAM=@LIBPAM@
 LIBWRAP=@LIBWRAP@
@@ -136,7 +137,7 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
        $(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 sshd$(EXEEXT): libssh.a        $(LIBCOMPAT) $(SSHDOBJS)
-       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS)
+       $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBSELINUX) $(LIBS)
 
 scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
        $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
index 62dd8d79cfdde0ea2a0139831c141e70c2a6407c..577253699d3f30b777f0217de053e04b618c9258 100644 (file)
@@ -3000,6 +3000,23 @@ int main()
                        [#include <arpa/nameser.h>])
        ])
 
+# Check whether user wants SELinux support
+SELINUX_MSG="no"
+LIBSELINUX=""
+AC_ARG_WITH(selinux,
+       [  --with-selinux   Enable SELinux support],
+       [ if test "x$withval" != "xno" ; then
+               AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
+               SELINUX_MSG="yes"
+               AC_CHECK_HEADER([selinux/selinux.h], ,
+                   AC_MSG_ERROR(SELinux support requires selinux.h header))
+               AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
+                   AC_MSG_ERROR(SELinux support requires libselinux library))
+               AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
+       fi ]
+)
+AC_SUBST(LIBSELINUX)
+
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no"
 AC_ARG_WITH(kerberos5,
@@ -3818,6 +3835,7 @@ fi
 echo "                    Manpage format: $MANTYPE"
 echo "                       PAM support: $PAM_MSG"
 echo "                 KerberosV support: $KRB5_MSG"
+echo "                   SELinux support: $SELINUX_MSG"
 echo "                 Smartcard support: $SCARD_MSG"
 echo "                     S/KEY support: $SKEY_MSG"
 echo "              TCP Wrappers support: $TCPW_MSG"
index 4ee8630c3954eb1711d5f4c03a7ece5f2678f116..e5d837cbc10422025f4abf71f9f8b8694b17d794 100755 (executable)
@@ -35,6 +35,9 @@ do_rsa1_keygen() {
                if $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
                        chmod 600 $RSA1_KEY
                        chmod 644 $RSA1_KEY.pub
+                       if [ -x /sbin/restorecon ]; then
+                           /sbin/restorecon $RSA1_KEY.pub
+                       fi
                        success $"RSA1 key generation"
                        echo
                else
@@ -51,6 +54,9 @@ do_rsa_keygen() {
                if $KEYGEN -q -t rsa -f $RSA_KEY -C '' -N '' >&/dev/null; then
                        chmod 600 $RSA_KEY
                        chmod 644 $RSA_KEY.pub
+                       if [ -x /sbin/restorecon ]; then
+                           /sbin/restorecon $RSA_KEY.pub
+                       fi
                        success $"RSA key generation"
                        echo
                else
@@ -67,6 +73,9 @@ do_dsa_keygen() {
                if $KEYGEN -q -t dsa -f $DSA_KEY -C '' -N '' >&/dev/null; then
                        chmod 600 $DSA_KEY
                        chmod 644 $DSA_KEY.pub
+                       if [ -x /sbin/restorecon ]; then
+                           /sbin/restorecon $DSA_KEY.pub
+                       fi
                        success $"DSA key generation"
                        echo
                else
index ee5ac8269ed79090968019488474b7e45fa72f9c..cb9ea362c9b3037df41b987104a96e78c9ae3570 100644 (file)
@@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgroupl
 
 COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
 
-PORTS=port-irix.o port-aix.o port-uw.o port-tun.o
+PORTS=port-irix.o port-linux.o port-aix.o port-uw.o port-tun.o
 
 .c.o:
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
index 9827f0fd49aba30e3dafc55ddc5a99bb9662fa04..91ec536dba1d22724f5ee2ab5dce397f679ffd20 100644 (file)
@@ -185,6 +185,7 @@ char *shadow_pw(struct passwd *pw);
 #include "bsd-cray.h"
 #include "bsd-cygwin_util.h"
 #include "port-irix.h"
+#include "port-linux.h"
 #include "port-aix.h"
 #include "port-uw.h"
 #include "port-tun.h"
diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c
new file mode 100644 (file)
index 0000000..ecff797
--- /dev/null
@@ -0,0 +1,165 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
+ * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Linux-specific portability code - just SELinux support at present
+ */
+
+#include "includes.h"
+
+#ifdef WITH_SELINUX
+#include "log.h"
+#include "port-linux.h"
+
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/get_context_list.h>
+
+/* Wrapper around is_selinux_enabled() to log its return value once only */
+static int
+ssh_selinux_enabled(void)
+{
+       static int enabled = -1;
+
+       if (enabled == -1) {
+               enabled = is_selinux_enabled();
+               debug("SELinux support %s", enabled ? "enabled" : "disabled");
+       }
+
+       return (enabled);
+}
+
+/* Return the default security context for the given username */
+static security_context_t
+ssh_selinux_getctxbyname(char *pwname)
+{
+       security_context_t sc;
+       char *sename = NULL, *lvl = NULL;
+       int r;
+
+#ifdef HAVE_GETSEUSERBYNAME
+       if (getseuserbyname(pwname, &sename, &lvl) != 0)
+               return NULL;
+#else
+       sename = pwname;
+       lvl = NULL;
+#endif
+
+#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
+       r = get_default_context_with_level(sename, lvl, NULL, &sc);
+#else
+       r = get_default_context(sename, NULL, &sc);
+#endif
+
+       if (r != 0) {
+               switch (security_getenforce()) {
+               case -1:
+                       fatal("%s: ssh_selinux_getctxbyname: "
+                           "security_getenforce() failed", __func__);
+               case 0:
+                       error("%s: Failed to get default SELinux security "
+                           "context for %s", __func__, pwname);
+               default:
+                       fatal("%s: Failed to get default SELinux security "
+                           "context for %s (in enforcing mode)",
+                           __func__, pwname);
+               }
+       }
+
+#ifdef HAVE_GETSEUSERBYNAME
+       if (sename != NULL)
+               xfree(sename);
+       if (lvl != NULL)
+               xfree(lvl);
+#endif
+
+       return (sc);
+}
+
+/* Set the execution context to the default for the specified user */
+void
+ssh_selinux_setup_exec_context(char *pwname)
+{
+       security_context_t user_ctx = NULL;
+
+       if (!ssh_selinux_enabled())
+               return;
+
+       debug3("%s: setting execution context", __func__);
+
+       user_ctx = ssh_selinux_getctxbyname(pwname);
+       if (setexeccon(user_ctx) != 0) {
+               switch (security_getenforce()) {
+               case -1:
+                       fatal("%s: security_getenforce() failed", __func__);
+               case 0:
+                       error("%s: Failed to set SELinux execution "
+                           "context for %s", __func__, pwname);
+               default:
+                       fatal("%s: Failed to set SELinux execution context "
+                           "for %s (in enforcing mode)", __func__, pwname);
+               }
+       }
+       if (user_ctx != NULL)
+               freecon(user_ctx);
+
+       debug3("%s: done", __func__);
+}
+
+/* Set the TTY context for the specified user */
+void
+ssh_selinux_setup_pty(char *pwname, const char *tty)
+{
+       security_context_t new_tty_ctx = NULL;
+       security_context_t user_ctx = NULL;
+       security_context_t old_tty_ctx = NULL;
+
+       if (!ssh_selinux_enabled())
+               return;
+
+       debug3("%s: setting TTY context on %s", __func__, tty);
+
+       user_ctx = ssh_selinux_getctxbyname(pwname);
+
+       /* XXX: should these calls fatal() upon failure in enforcing mode? */
+
+       if (getfilecon(tty, &old_tty_ctx) == -1) {
+               error("%s: getfilecon: %s", __func__, strerror(errno));
+               goto out;
+       }
+
+       if (security_compute_relabel(user_ctx, old_tty_ctx,
+           SECCLASS_CHR_FILE, &new_tty_ctx) != 0) {
+               error("%s: security_compute_relabel: %s",
+                   __func__, strerror(errno));
+               goto out;
+       }
+
+       if (setfilecon(tty, new_tty_ctx) != 0)
+               error("%s: setfilecon: %s", __func__, strerror(errno));
+ out:
+       if (new_tty_ctx != NULL)
+               freecon(new_tty_ctx);
+       if (old_tty_ctx != NULL)
+               freecon(old_tty_ctx);
+       if (user_ctx != NULL)
+               freecon(user_ctx);
+       debug3("%s: done", __func__);
+}
+#endif /* WITH_SELINUX */
diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h
new file mode 100644 (file)
index 0000000..ccb42df
--- /dev/null
@@ -0,0 +1,27 @@
+/* $Id$ */
+
+/*
+ * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _PORT_LINUX_H
+#define _PORT_LINUX_H
+
+#ifdef WITH_SELINUX
+void ssh_selinux_setup_pty(char *, const char *);
+void ssh_selinux_setup_exec_context(char *);
+#endif
+
+#endif /* ! _PORT_LINUX_H */
index 8b837d07db0be9d60e655efca3ee448932f5b07d..bba3fa21f71d2ed5f98c7cc42925ec2a12e57f48 100644 (file)
--- a/session.c
+++ b/session.c
@@ -1352,6 +1352,10 @@ do_setusercontext(struct passwd *pw)
 #endif
        if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
+
+#ifdef WITH_SELINUX
+       ssh_selinux_setup_exec_context(pw->pw_name);
+#endif
 }
 
 static void
index a15df041421008d06d0e4ecd9836c418814ad568..0e49e9a1696337b0e1a3f2b96fbc702cfba7d23f 100644 (file)
--- a/sshpty.c
+++ b/sshpty.c
@@ -210,6 +210,10 @@ pty_setowner(struct passwd *pw, const char *tty)
                fatal("stat(%.100s) failed: %.100s", tty,
                    strerror(errno));
 
+#ifdef WITH_SELINUX
+       ssh_selinux_setup_pty(pw->pw_name, tty);
+#endif
+
        if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
                if (chown(tty, pw->pw_uid, gid) < 0) {
                        if (errno == EROFS &&
This page took 0.066673 seconds and 5 git commands to generate.