[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#308555: ssh: Pleas apply this SELinux support patch



Package: ssh
Version: 1:3.9p1-3.1
Severity: wishlist

Hi,

        Please apply the patch file below. This adds SELinux
 capability, and turns it on be default. It adds restorecon calls to
 the preinst and postinst (should not matter if the machine is not
 SELinux aware). By and large, the changes made should have no effect
 unless the rules file calls --with-selinux; and even then there
 should be no performance hit for machines not actively running
 SELinux.

        It also adds a comment to /etc/pam.d/ssh to indicate that a
 selinux system may want to also include pam_selinux.so

 	Some more details should be on
 http://www.golden-gryphon.com/software/security/selinux.xhtml
 
        manoj

--- orig/ChangeLog
+++ mod/ChangeLog
@@ -1,3 +1,27 @@
+20050510
+ - (srivasta) [selinux.c] if selinux is enabled, then provide funtions to
+    initialize the pty and execution context for ssh.
+ - (srivasta) [selinux.h] if SELinux is defined, add function prototypes for
+    functions, or make them null ops.
+ - (srivasta) [sshpty.c] include selinuh.h
+   pty_setowner: set up the selinux pty correcty.
+ - (srivasta) [session.c] include selinuh.h
+   do_setusercontext: set up proper execution context for SELinux.
+ - (srivasta) [monitor_wrap.h] Add function prototype for new function to
+    inform the privileged process about role.
+ - (srivasta) [monitor_wrap.c]  (mm_inform_authrole) Inform the privileged
+    process about role.
+ - (srivasta) [monitor.h] Add a new monitor request type for auth roles.
+ - (srivasta) [monitor.c] (mm_answer_authrole) Add nre function to deal withe
+   the new authorization role, and add a new monitor request type.
+ - (srivasta) [contrib/redhat/sshd.init]  (PID_FILE)restore the proper security
+   file context of the generated public keys.
+ - (srivasta) [configure.ac]  (HAVE_HEADER_AD)Add an SELinux option
+ - (srivasta) [auth2.c]  (input_userauth_request)Handle the new role member
+ - (srivasta) [auth1.c]  (do_authentication)Handle the new role member
+ - (srivasta) [auth.h] Added a role member in struct Authctxt
+ - (srivasta) [Makefile.in (SSHDOBJS)] Add selinux.o
+
 20040817
  - (dtucker) [regress/README.regress] Note compatibility issues with GNU head.
  - (djm) OpenBSD CVS Sync


--- orig/Makefile.in
+++ mod/Makefile.in
@@ -76,7 +76,7 @@
 	sshconnect.o sshconnect1.o sshconnect2.o
 
 SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
-	sshpty.o sshlogin.o servconf.o serverloop.o \
+	sshpty.o sshlogin.o servconf.o serverloop.o selinux.o \
 	auth.o auth1.o auth2.o auth-options.o session.o \
 	auth-chall.o auth2-chall.o groupaccess.o \
 	auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \


--- orig/auth.h
+++ mod/auth.h
@@ -57,6 +57,7 @@
 	char		*service;
 	struct passwd	*pw;		/* set if 'valid' */
 	char		*style;
+	char		*role;
 	void		*kbdintctxt;
 #ifdef BSD_AUTH
 	auth_session_t	*as;


--- orig/auth1.c
+++ mod/auth1.c
@@ -283,7 +283,7 @@
 do_authentication(Authctxt *authctxt)
 {
 	u_int ulen;
-	char *user, *style = NULL;
+	char *user, *style = NULL, *role=NULL;
 
 	/* Get the name of the user that we wish to log in as. */
 	packet_read_expect(SSH_CMSG_USER);
@@ -292,11 +292,19 @@
 	user = packet_get_string(&ulen);
 	packet_check_eom();
 
+	if ((role = strchr(user, '/')) != NULL)
+		*role++ = '\0';
+
 	if ((style = strchr(user, ':')) != NULL)
 		*style++ = '\0';
+	else
+		if (role && (style = strchr(role, ':')) != NULL)
+			*style++ = '\0';
+			
 
 	authctxt->user = user;
 	authctxt->style = style;
+	authctxt->role = role;
 
 	/* Verify that the user is a valid user. */
 	if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)


--- orig/auth2.c
+++ mod/auth2.c
@@ -132,7 +132,7 @@
 {
 	Authctxt *authctxt = ctxt;
 	Authmethod *m = NULL;
-	char *user, *service, *method, *style = NULL;
+	char *user, *service, *method, *style = NULL, *role = NULL;
 	int authenticated = 0;
 
 	if (authctxt == NULL)
@@ -144,6 +144,9 @@
 	debug("userauth-request for user %s service %s method %s", user, service, method);
 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
 
+	if ((role = strchr(user, '/')) != NULL)
+		*role++ = 0;
+
 	if ((style = strchr(user, ':')) != NULL)
 		*style++ = 0;
 
@@ -170,8 +173,11 @@
 		    use_privsep ? " [net]" : "");
 		authctxt->service = xstrdup(service);
 		authctxt->style = style ? xstrdup(style) : NULL;
-		if (use_privsep)
+		authctxt->role = role ? xstrdup(role) : NULL;
+		if (use_privsep) {
 			mm_inform_authserv(service, style);
+			mm_inform_authrole(role);
+		}
 	} else if (strcmp(user, authctxt->user) != 0 ||
 	    strcmp(service, authctxt->service) != 0) {
 		packet_disconnect("Change of username or service not allowed: "


--- orig/config.h.in
+++ mod/config.h.in
@@ -783,6 +783,9 @@
 /* Define to 1 if you have the <security/pam_appl.h> header file. */
 #undef HAVE_SECURITY_PAM_APPL_H
 
+/* Define to 1 if you have the <selinux.h> header file. */
+#undef HAVE_SELINUX_H
+
 /* Define to 1 if you have the `sendmsg' function. */
 #undef HAVE_SENDMSG
 
@@ -1086,6 +1089,9 @@
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* Define if you want SELinux support. */
+#undef WITH_SELINUX
+
 /* Define to 1 if your processor stores words with the most significant byte
    first (like Motorola and SPARC, unlike Intel and VAX). */
 #undef WORDS_BIGENDIAN


--- orig/configure
+++ mod/configure
@@ -880,6 +880,7 @@
   --with-privsep-user=user Specify non-privileged user for privilege separation
   --with-sectok           Enable smartcard support using libsectok
   --with-opensc=PFX       Enable smartcard support using OpenSC
+  --with-selinux   Enable SELinux support
   --with-kerberos5=PATH   Enable Kerberos 5 support
   --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
   --with-xauth=PATH       Specify path to xauth program
@@ -20951,6 +20763,173 @@
 fi
 
 
+# Check whether user wants SELinux support
+SELINUX_MSG="no"
+
+# Check whether --with-selinux or --without-selinux was given.
+if test "${with_selinux+set}" = set; then
+  withval="$with_selinux"
+   if test "x$withval" != "xno" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SELINUX 1
+_ACEOF
+
+		SELINUX_MSG="yes"
+
+for ac_header in selinux.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+		LIBS="$LIBS -lselinux"
+	fi
+
+fi;
+
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no"
 
@@ -24746,11 +24701,6 @@
   *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
   esac
 
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
   # Let's still pretend it is `configure' which instantiates (i.e., don't
   # use $as_me), people would be surprised to read:
   #    /* config.h.  Generated by config.status.  */
@@ -24789,6 +24739,12 @@
 	 fi;;
       esac
     done` || { (exit 1); exit 1; }
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
   sed "$ac_vpsub
@@ -25111,6 +25067,7 @@
 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"


--- orig/configure.ac
+++ mod/configure.ac
@@ -2218,6 +2218,18 @@
 			[#include <arpa/nameser.h>])
 	])
 
+# Check whether user wants SELinux support
+SELINUX_MSG="no"
+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_HEADERS(selinux.h)
+		LIBS="$LIBS -lselinux"
+	fi
+	])
+
 # Check whether user wants Kerberos 5 support
 KRB5_MSG="no"
 AC_ARG_WITH(kerberos5,
@@ -2973,6 +2985,7 @@
 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"


--- orig/contrib/redhat/sshd.init
+++ mod/contrib/redhat/sshd.init
@@ -35,6 +35,9 @@
 		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 @@
 		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 @@
 		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


--- orig/debian/changelog
+++ mod/debian/changelog
@@ -1,3 +1,19 @@
+openssh (1:3.9p1-3.1) experimental; urgency=low
+
+  * NMU to add SELinux awareness.
+  * Added SELinux capability, and turned it on be default. Added
+    restorecon calls in preinst and postinst (should not matter if the
+    machine is not SELinux aware). By and large, the changes made should
+    have no effect unless the rules file calls --with-selinux; and even
+    then there should be no performance hit for machines not actively
+    running SELinux.
+  * modified the preinst and postinst to call restorecon to set the
+    security context for the generated public key files.
+  * Added a comment to /etc/pam.d/ssh to indicate that a selinux system
+    may want to also include pam_selinux.so
+
+ -- Manoj Srivastava <srivasta@debian.org>  Tue, 10 May 2005 20:07:00 -0500
+
 openssh (1:3.9p1-3) experimental; urgency=low
 
   * Explain how to run sshd from inittab in README.Debian (closes: #147360).

--- orig/debian/control
+++ mod/debian/control
@@ -2,7 +2,7 @@
 Section: net
 Priority: standard
 Maintainer: Matthew Vernon <matthew@debian.org>
-Build-Depends: libwrap0-dev | libwrap-dev, zlib1g-dev | libz-dev, libssl-dev, libpam0g-dev | libpam-dev, libgnomeui-dev (>= 2.0.0) | libgnome-dev, groff, debhelper (>= 2), sharutils
+Build-Depends: libwrap0-dev | libwrap-dev, zlib1g-dev | libz-dev, libssl-dev, libpam0g-dev | libpam-dev, libgnomeui-dev (>= 2.0.0) | libgnome-dev, groff, debhelper (>= 2), sharutils, libselinux1-dev
 Standards-Version: 3.6.1
 Uploaders: Colin Watson <cjwatson@debian.org>
 


--- orig/debian/openssh-server.postinst
+++ mod/debian/openssh-server.postinst
@@ -91,6 +91,10 @@
 		echo -n $msg
 		ssh-keygen -q -f "$file" -N '' "$@"
 		echo
+                if [ -x /sbin/restorecon ]; then
+                    /sbin/restorecon "$file.pub"
+                fi
+                
 	fi
 }
 


--- orig/debian/openssh-server.preinst
+++ mod/debian/openssh-server.preinst
@@ -72,6 +72,10 @@
       # case the key is encrypted, which we need to fix
       chmod 600 $key
       ssh-keygen -u -f $key >/dev/null
+      if [ -x /sbin/restorecon ]; then
+          /sbin/restorecon $key.pub
+      fi
+      
     }
   fi
 fi


--- orig/debian/openssh-server.ssh.pam
+++ mod/debian/openssh-server.ssh.pam
@@ -22,5 +22,8 @@
 # Set up user limits from /etc/security/limits.conf.
 session    required     pam_limits.so
 
+# Set up SELinux capabilities (need modified pam)
+# session  required     pam_selinux.so multiple
+
 # Standard Un*x password updating.
 @include common-password

--- orig/debian/rules
+++ mod/debian/rules
@@ -58,7 +58,7 @@
 build-deb-stamp:
 	dh_testdir
 	mkdir -p build-deb
-	cd build-deb && $(FORCE_LIBS) ../configure --prefix=/usr --sysconfdir=/etc/ssh --libexecdir=/usr/lib --mandir=/usr/share/man --with-tcp-wrappers --with-xauth=/usr/bin/X11/xauth --with-default-path=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin --with-superuser-path=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin --with-pam --with-4in6 --with-privsep-path=/var/run/sshd  --without-rand-helper
+	cd build-deb && $(FORCE_LIBS) ../configure --prefix=/usr --sysconfdir=/etc/ssh --libexecdir=/usr/lib --mandir=/usr/share/man --with-tcp-wrappers --with-xauth=/usr/bin/X11/xauth --with-default-path=/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin --with-superuser-path=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin --with-pam --with-4in6 --with-privsep-path=/var/run/sshd  --without-rand-helper --with-selinux 
 
 	# Some 2.2 kernels have trouble with setres[ug]id() (bug #239999).
 	perl -pi -e 's/.*#undef (BROKEN_SETRES[UG]ID).*/#define $$1 1/' build-deb/config.h
@@ -79,7 +79,7 @@
 build-udeb-stamp:
 	dh_testdir
 	mkdir -p build-udeb
-	cd build-udeb && $(FORCE_LIBS) ../configure --prefix=/usr --sysconfdir=/etc/ssh --without-xauth --with-default-path=/usr/local/bin:/bin:/usr/bin --with-superuser-path=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin --with-4in6 --with-privsep-path=/var/run/sshd --without-rand-helper
+	cd build-udeb && $(FORCE_LIBS) ../configure --prefix=/usr --sysconfdir=/etc/ssh --without-xauth --with-default-path=/usr/local/bin:/bin:/usr/bin --with-superuser-path=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin --with-4in6 --with-privsep-path=/var/run/sshd --without-rand-helper --with-selinux 
 	# Avoid libnsl linkage. Ugh.
 	perl -pi -e 's/ +-lnsl//' build-udeb/config.status
 	cd build-udeb && ./config.status


--- orig/monitor.c
+++ mod/monitor.c
@@ -111,6 +111,7 @@
 int mm_answer_pwnamallow(int, Buffer *);
 int mm_answer_auth2_read_banner(int, Buffer *);
 int mm_answer_authserv(int, Buffer *);
+int mm_answer_authrole(int, Buffer *);
 int mm_answer_authpassword(int, Buffer *);
 int mm_answer_bsdauthquery(int, Buffer *);
 int mm_answer_bsdauthrespond(int, Buffer *);
@@ -176,6 +177,7 @@
     {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
     {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
     {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
+    {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
     {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
     {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
 #ifdef USE_PAM
@@ -602,6 +604,7 @@
 	else {
 		/* Allow service/style information on the auth context */
 		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
+		monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
 		monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
 	}
 
@@ -647,6 +650,23 @@
 }
 
 int
+mm_answer_authrole(int sock, Buffer *m)
+{
+	monitor_permit_authentications(1);
+
+	authctxt->role = buffer_get_string(m, NULL);
+	debug3("%s: role=%s",
+	    __func__, authctxt->role);
+
+	if (strlen(authctxt->role) == 0) {
+		xfree(authctxt->role);
+		authctxt->role = NULL;
+	}
+
+	return (0);
+}
+
+int
 mm_answer_authpassword(int sock, Buffer *m)
 {
 	static int call_count;


--- orig/monitor.h
+++ mod/monitor.h
@@ -30,7 +30,7 @@
 
 enum monitor_reqtype {
 	MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
-	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
+	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,MONITOR_REQ_AUTHROLE,
 	MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
 	MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
 	MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,


--- orig/monitor_wrap.c
+++ mod/monitor_wrap.c
@@ -274,6 +274,23 @@
 	buffer_free(&m);
 }
 
+/* Inform the privileged process about role */
+
+void
+mm_inform_authrole(char *role)
+{
+	Buffer m;
+
+	debug3("%s entering", __func__);
+
+	buffer_init(&m);
+	buffer_put_cstring(&m, role ? role : "");
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
+
+	buffer_free(&m);
+}
+
 /* Do the password authentication */
 int
 mm_auth_password(Authctxt *authctxt, char *password)


--- orig/monitor_wrap.h
+++ mod/monitor_wrap.h
@@ -44,6 +44,7 @@
 DH *mm_choose_dh(int, int, int);
 int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
 void mm_inform_authserv(char *, char *);
+void mm_inform_authrole(char *);
 struct passwd *mm_getpwnamallow(const char *);
 char *mm_auth2_read_banner(void);
 int mm_auth_password(struct Authctxt *, char *);


--- orig/session.c
+++ mod/session.c
@@ -58,6 +58,8 @@
 #include "session.h"
 #include "monitor_wrap.h"
 
+#include "selinux.h"
+
 #if defined(KRB5) && defined(USE_AFS)
 #include <kafs.h>
 #endif
@@ -1304,6 +1306,8 @@
 #endif
 	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
 		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
+
+	setup_selinux_exec_context(pw->pw_name);
 }
 
 static void


--- orig/sshpty.c
+++ mod/sshpty.c
@@ -22,6 +22,8 @@
 #include "log.h"
 #include "misc.h"
 
+#include "selinux.h"
+
 #ifdef HAVE_PTY_H
 # include <pty.h>
 #endif
@@ -200,6 +202,8 @@
 		fatal("stat(%.100s) failed: %.100s", tty,
 		    strerror(errno));
 
+	setup_selinux_pty(pw->pw_name, tty);
+
 	if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
 		if (chown(tty, pw->pw_uid, gid) < 0) {
 			if (errno == EROFS &&



--- /dev/null
+++ new-files-archive/selinux.c
@@ -0,0 +1,77 @@
+#include "includes.h"
+#include "auth.h"
+#include "log.h"
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/context.h>
+#include <selinux/get_context_list.h>
+#include <selinux/get_default_type.h>
+extern Authctxt *the_authctxt;
+
+static const security_context_t selinux_get_user_context(const char *name) {
+	security_context_t user_context=NULL;
+	char *role=NULL;
+	int ret=0;
+	if (the_authctxt) 
+		role=the_authctxt->role;
+	if (role != NULL && role[0]) 
+		ret=get_default_context_with_role(name,role,NULL,&user_context);
+	else
+		ret=get_default_context(name,NULL,&user_context);
+	if ( ret < 0 ) {
+		if (security_getenforce() > 0) 
+			fatal("Failed to get default security context for %s.", name);
+		else 
+			error("Failed to get default security context for %s. Continuing in permissve mode", name);
+	} 
+	return user_context;
+}
+
+void setup_selinux_pty(const char *name, const char *tty) {
+	if (is_selinux_enabled() > 0) {
+		security_context_t new_tty_context=NULL, user_context=NULL, old_tty_context=NULL; 
+
+		user_context=selinux_get_user_context(name);
+
+		if (getfilecon(tty, &old_tty_context) < 0) {
+			error("getfilecon(%.100s) failed: %.100s", tty, strerror(errno));
+		} else {
+			if (security_compute_relabel(user_context,old_tty_context,
+						     SECCLASS_CHR_FILE,
+						     &new_tty_context) != 0) {
+				error("security_compute_relabel(%.100s) failed: %.100s", tty,
+				      strerror(errno));
+			} else {
+				if (setfilecon (tty, new_tty_context) != 0) 
+					error("setfilecon(%.100s, %s) failed: %.100s",
+					      tty, new_tty_context, 
+					      strerror(errno));
+				freecon(new_tty_context);
+			}
+			freecon(old_tty_context);
+		}
+		if (user_context) {
+			freecon(user_context);
+		}
+	}
+}
+
+void setup_selinux_exec_context(char *name) {
+
+	if (is_selinux_enabled() > 0) {
+		security_context_t user_context=selinux_get_user_context(name);
+		if (setexeccon(user_context)) {
+			if (security_getenforce() > 0) 
+				fatal("Failed to set exec security context %s for %s.", user_context, name);
+			else 
+				error("Failed to set exec security context %s for %s. Continuing in permissive mode", user_context, name);
+		}
+		if (user_context) {
+			freecon(user_context);
+		}
+	}
+}
+
+#endif /* WITH_SELINUX */
--- /dev/null
+++ new-files-archive/selinux.h
@@ -0,0 +1,10 @@
+#ifndef __SELINUX_H_
+#define __SELINUX_H_
+#ifdef WITH_SELINUX
+extern void setup_selinux_pty(const char *name, const char *tty);
+extern void setup_selinux_exec_context(const char *name);
+#else
+inline void setup_selinux_pty(const char *name, const char *tty) {}
+inline void setup_selinux_exec_context(const char *name) {} 
+#endif /* WITH_SELINUX */
+#endif /* __SELINUX_H_ */

-- System Information:
Debian Release: 3.1
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.6.11.2-skas3-v8-rc2
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)

Versions of packages ssh depends on:
ii  openssh-client               1:3.9p1-3.1 Secure shell client, an rlogin/rsh
ii  openssh-server               1:3.9p1-3.1 Secure shell server, an rshd repla

-- debconf information:
  ssh/insecure_rshd:
* ssh/user_environment_tell:
* ssh/forward_warning:
  ssh/encrypted_host_key_but_no_keygen:
* ssh/run_sshd: true
  ssh/privsep_ask: true
  ssh/insecure_telnetd:
  ssh/new_config: true
* ssh/use_old_init_script: true
* ssh/SUID_client: true
  ssh/disable_cr_auth: false
* ssh/privsep_tell:
  ssh/ssh2_keys_merged:
* ssh/protocol2_only: false

-- 
Xerox never comes up with anything original.
Manoj Srivastava     <srivasta@acm.org>    <http://www.golden-gryphon.com/>
1024D/BF24424C print 4966 F272 D093 B493 410B  924B 21BA DABB BF24 424C

Reply to: