Hi,

Here is a patch for xinetd to use the Labeled IPsec hooks recently
added to Linux 2.6.16.  It enables xinetd to use the IPsec labels for
setting security contexts and has no effect when no IPsec contexts
are used.

Please let me know if you have comments.

Regards,
Trent.

----------------------------------------------

Documentation:

This patch enables xinetd to extract the security context (security
label in SELinux terms) of a peer client based on the Labeled IPsec
patch for Linux (available in 2.6.16).  We have added a new option for
xinetd configuration, called 'secsock_adopt.'  By setting this option
(setting its value to 'yes'), xinetd automatically sets the security
context of all service processes that it launches to that of the IPsec
security association used to connect to xinetd, if any.  By default,
this is set option is set to 'no'.

Design:

xinetd gets the security context from the connected socket
that received the request using the following system call.

getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buffer, buflen);

SO_PEERSEC has been added to enable to retrieval of the security label
of a peer socket.  For a socket connected to a remote client, the
client's security context is determined by the security context of the
IPsec security association.  The Linux kernel extensions added in
version 2.6.16 enable retrieval of this security label using
getsockopt.  This approach will not work for kernels older than
2.6.16.

The patch then has xinetd use the SELinux command setexeccon to assign
the security context for the next execute command performed by xinetd.
As a result, the service process launched for this client request will
be assigned the security context of the IPsec security association.
If there is no security association or the security association has no 
label, the child will be given the default security label.  

Note that this only works with the SELinux module.  If SELinux is not
loaded, then things work normally.

Signed-off by: Dave King ([EMAIL PROTECTED])
Signed-off by: Trent Jaeger ([EMAIL PROTECTED])

---

 Makefile.in        |    6 ++---
 xinetd/Makefile.in |    2 -
 xinetd/attr.h      |    1 
 xinetd/child.c     |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 xinetd/child.h     |    2 +
 xinetd/parse.c     |    1 
 xinetd/parsers.c   |   18 +++++++++++++++
 xinetd/parsers.h   |    1 
 xinetd/sconf.h     |    3 ++
 9 files changed, 90 insertions(+), 4 deletions(-)

diff -puN xinetd/child.h~xinetd-fork-context xinetd/child.h
--- xinetd-2.3.14/xinetd/child.h~xinetd-fork-context    2006-03-20 
16:44:09.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/child.h   2006-03-20 16:44:31.000000000 -0500
@@ -17,3 +17,5 @@ void child_exit(void);
 __attribute__ ((noreturn))
 #endif
 void exec_server( const struct server *serp );
+int set_exec_context_from_socket( int fd );
+int get_context_from_socket(int fd, char* buffer, unsigned int* buflen);

 #endif
diff -puN xinetd/child.c~xinetd-fork-context xinetd/child.c
--- xinetd-2.3.14/xinetd/child.c~xinetd-fork-context    2006-03-20 
16:44:09.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/child.c   2006-03-21 10:04:10.000000000 -0500
@@ -31,3 +31,4 @@
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
 #endif
+#include <selinux/selinux.h>

 #include "str.h"
 #include "child.h"
@@ -143,2 +144,2 @@ void exec_server( const struct server *s
    }
 #endif

+   /* 
+      only take on the security context if the configuration option has been 
set as such
+   */
+
+   if (SC_ADOPTS_SECSOCK(scp))
+   {
+      set_exec_context_from_socket( descriptor );
+   }
+
    (void) Sclose( descriptor ) ;

 #ifndef solaris
@@ -461,2 +471,2 @@ void child_exit(void)
    }
 }

+int set_exec_context_from_socket( int fd )
+{
+   const char *func = "set_exec_context_from_socket" ;
+
+   char buffer[255];
+   unsigned int buflen = 255;
+
+   get_context_from_socket(fd, buffer, &buflen);
+
+   int retval = setexeccon(buffer);
+
+   if (debug.on)
+   {
+      security_context_t current_exec_context;
+      getexeccon( &current_exec_context );
+
+      msg( LOG_DEBUG, func, 
+          "current security exec context now: %s", 
+          current_exec_context);
+
+      freecon( current_exec_context );
+   }
+
+   return retval;
+}
+
+int get_context_from_socket(int fd, char* buffer, unsigned int* buflen)
+{
+   const char *func = "get_context_from_socket" ;
+
+   int retval = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, buffer, buflen);
+   
+   if ( debug.on )
+   {
+     if (retval)
+     {
+       msg( LOG_DEBUG, func, 
+            "error getting context for socket %d: %s (%d)", 
+            fd, strerror(errno), errno);
+     }
+     else
+     {
+       msg( LOG_DEBUG, func, 
+            "got context for socket %d: %s", 
+            fd, buffer);
+     }
+   }
+     
+   return retval;
+}
diff -puN Makefile.in~xinetd-fork-context Makefile.in
--- xinetd-2.3.14/Makefile.in~xinetd-fork-context       2006-03-20 
16:44:09.000000000 -0500
+++ xinetd-2.3.14-root/Makefile.in      2006-03-20 16:44:31.000000000 -0500
@@ -12,2 +12,2 @@ DAEMONDIR = @sbindir@
 MANDIR = @mandir@
 topdir = @top_srcdir@

-LIBS = -lsio -lstr -lmisc -lxlog -lportable -lpset @LIBS@
+LIBS = -lsio -lstr -lmisc -lxlog -lportable -lpset -lselinux @LIBS@

 CFLAGS += @CFLAGS@ 
 DCFLAGS = -Wall -Wredundant-decls -W -Wfloat-equal -Wundef -Wcast-qual 
-Wwrite-strings -Wconversion -Wmissing-noreturn -Wmissing-format-attribute 
-Wshadow -Wpointer-arith -g
@@ -30,2 +30,2 @@ PROGMAKEDEFS = CC='$(CC)' CFLAGS='$(CFLA
 DEBUGLIBMAKEDEFS = CC='$(CC)' CFLAGS='$(DCFLAGS) -I../../include'
 DEBUGMAKEDEFS = CC='$(CC)' CFLAGS='$(DCFLAGS) -I../libs/include' 
LDFLAGS='$(LDFLAGS) -L../libs/lib'

-MANDATORY_LIBS = portable sio str misc xlog pset 
-ALL_LIBS       = portable sio str misc xlog pset 
+MANDATORY_LIBS = portable sio str misc xlog pset selinux
+ALL_LIBS       = portable sio str misc xlog pset selinux

 build: makelibs makeprog

diff -puN xinetd/Makefile.in~xinetd-fork-context xinetd/Makefile.in
--- xinetd-2.3.14/xinetd/Makefile.in~xinetd-fork-context        2006-03-20 
16:44:09.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/Makefile.in       2006-03-20 16:44:31.000000000 
-0500
@@ -40,0 +40,0 @@ PREFIX      = @prefix@

 INSTALL_CMD = @INSTALL@

-LIBS        = -lsio -lmisc -lxlog -lportable -lstr -lpset @LIBS@
+LIBS        = -lsio -lmisc -lxlog -lportable -lstr -lpset -lselinux @LIBS@

 INCLUDEDIR  = -I../libs/include
 LIBDIR      = -L../libs/lib
diff -puN xinetd/parse.c~xinetd-fork-context xinetd/parse.c
--- xinetd-2.3.14/xinetd/parse.c~xinetd-fork-context    2006-03-20 
16:52:30.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/parse.c   2006-03-20 17:44:33.000000000 -0500
@@ -107,5 +107,6 @@ static const struct attribute service_at
 #ifdef LIBWRAP
    { "libwrap",        A_LIBWRAP,        1, libwrap_parser          },
 #endif
+   { "secsock_adopt",  A_SECSOCK_ADOPT,  1, secsock_adopt_parser    },
    { NULL,             A_NONE,          -1,  NULL                   }
 } ;

diff -puN xinetd/attr.h~xinetd-fork-context xinetd/attr.h
--- xinetd-2.3.14/xinetd/attr.h~xinetd-fork-context     2006-03-20 
16:52:30.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/attr.h    2006-03-20 17:02:32.000000000 -0500
@@ -61,3 +61,4 @@
 #define A_DISABLED         43
 #define A_MDNS             44
 #define A_LIBWRAP          45
+#define A_SECSOCK_ADOPT    46

 /*
  * SERVICE_ATTRIBUTES is the number of service attributes and also
diff -puN xinetd/parsers.h~xinetd-fork-context xinetd/parsers.h
--- xinetd-2.3.14/xinetd/parsers.h~xinetd-fork-context  2006-03-20 
17:09:07.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/parsers.h 2006-03-20 17:44:01.000000000 -0500
@@ -70,3 +70,4 @@ status_e mdns_parser(pset_h, struct serv
 #ifdef LIBWRAP
 status_e libwrap_parser(pset_h, struct service_config *, enum assign_op) ;
 #endif
+status_e secsock_adopt_parser(pset_h, struct service_config *, enum assign_op) 
;

 #endif
diff -puN xinetd/parsers.c~xinetd-fork-context xinetd/parsers.c
--- xinetd-2.3.14/xinetd/parsers.c~xinetd-fork-context  2006-03-20 
17:09:08.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/parsers.c 2006-03-20 17:20:59.000000000 -0500
@@ -1513,2 +1513,2 @@ status_e libwrap_parser( pset_h values,
 }
 #endif

+status_e secsock_adopt_parser( pset_h values, 
+                              struct service_config *scp, 
+                              enum assign_op op )
+{
+   char *val = (char *) pset_pointer( values, 0 ) ;
+   const char *func = "secsock_adopt_parser" ;
+
+   if ( EQ( val, "yes" ) )
+      SC_SECSOCK_ADOPT(scp) = YES ;
+   else if ( EQ( val, "no" ) )
+      SC_SECSOCK_ADOPT(scp) = NO ;
+   else
+   {
+      parsemsg( LOG_ERR, func, "Bad value for secsock_adopt: %s", val ) ;
+      return( FAILED );
+   }
+   return( OK ) ;
+}
diff -puN xinetd/sconf.h~xinetd-fork-context xinetd/sconf.h
--- xinetd-2.3.14/xinetd/sconf.h~xinetd-fork-context    2006-03-20 
17:18:50.000000000 -0500
+++ xinetd-2.3.14-root/xinetd/sconf.h   2006-03-20 17:42:48.000000000 -0500
@@ -157,4 +157,5 @@ struct service_config
 #ifdef LIBWRAP
    char                *sc_libwrap;
 #endif
+   boolean_e            sc_secsock_adopt ;            /* if YES, take on 
security context before launching child */
 } ;

 #define SCP( p ) ((struct service_config *)(p))
@@ -218,6 +219,7 @@ struct service_config
 #define SC_MDNS( scp )           (scp)->sc_mdns
 #define SC_PER_SOURCE( scp )     (scp)->sc_per_source
 #define SC_LIBWRAP( scp )        (scp)->sc_libwrap
+#define SC_SECSOCK_ADOPT( scp )  (scp)->sc_secsock_adopt
 /*
  * Field set macros
  */
@@ -253,3 +255,4 @@ struct service_config
 #define SC_IS_TCPMUX( scp )     ( (scp)->sc_builtin &&                     \
                                    (BUILTIN_HANDLER( (scp)->sc_builtin ) == \
                                   (void *)tcpmux_handler ) )
+#define SC_ADOPTS_SECSOCK( scp ) ( (scp)->sc_secsock_adopt == YES )

 #define LOGS_USERID( scp, flags ) \
    ( M_IS_SET( (scp)->flags, LO_USERID ) && SC_ACCEPTS_CONNECTIONS( scp ) )



--
redhat-lspp mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-lspp

Reply via email to