diff -urp ipsec-tools-0.6.5.orig/configure.ac ipsec-tools-0.6.5/configure.ac --- ipsec-tools-0.6.5.orig/configure.ac 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/configure.ac 2007-04-20 08:26:52.000000000 -0400 @@ -624,6 +624,27 @@ if test "$enable_security_context" = "ye fi fi +AC_MSG_CHECKING(whether to support Auditing) +AC_ARG_ENABLE(audit, + [ --enable-audit build audit daemon support for SELinux], + enable_audit=$enableval,enable_audit=auto) + +AC_MSG_RESULT($enable_audit) + +# libaudit detection +if test x$enable_audit = xno ; then + have_libaudit=no; +else + AC_CHECK_LIB(audit, audit_log_user_avc_message, + have_libaudit=yes, have_libaudit=no) +fi +AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes) +if test x$have_libaudit = xyes ; then + AUDIT_LIBS="-laudit" + AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support]) +fi +AC_SUBST(AUDIT_LIBS) + CFLAGS="$CFLAGS $CFLAGS_ADD" CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD" diff -urp ipsec-tools-0.6.5.orig/src/racoon/handler.h ipsec-tools-0.6.5/src/racoon/handler.h --- ipsec-tools-0.6.5.orig/src/racoon/handler.h 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/src/racoon/handler.h 2007-04-20 08:26:52.000000000 -0400 @@ -280,6 +280,7 @@ struct ph2handle { u_int32_t msgid; /* msgid for phase 2 */ u_int32_t sa_count; /* num of SAs sent in SADB_ADD */ + u_int8_t loopback; struct sainfo *sainfo; /* place holder of sainfo */ struct saprop *proposal; /* SA(s) proposal. */ @@ -422,7 +423,7 @@ struct policyindex; extern struct ph1handle *getph1byindex __P((isakmp_index *)); extern struct ph1handle *getph1byindex0 __P((isakmp_index *)); extern struct ph1handle *getph1byaddr __P((struct sockaddr *, - struct sockaddr *)); + struct sockaddr *)); extern struct ph1handle *getph1byaddrwop __P((struct sockaddr *, struct sockaddr *)); extern struct ph1handle *getph1bydstaddrwop __P((struct sockaddr *)); diff -urp ipsec-tools-0.6.5.orig/src/racoon/main.c ipsec-tools-0.6.5/src/racoon/main.c --- ipsec-tools-0.6.5.orig/src/racoon/main.c 2005-11-06 12:18:26.000000000 -0500 +++ ipsec-tools-0.6.5/src/racoon/main.c 2007-04-20 08:26:52.000000000 -0400 @@ -73,6 +73,7 @@ #include "session.h" #include "oakley.h" #include "pfkey.h" +#include "policy.h" #include "crypto_openssl.h" #include "backupsa.h" #include "vendorid.h" @@ -163,7 +164,12 @@ main(ac, av) #ifdef DEBUG_RECORD_MALLOCATION DRM_init(); #endif - +#ifdef HAVE_SECCTX + init_avc(); +#endif +#ifdef HAVE_LIBAUDIT + audit_init(); +#endif eay_init(); initlcconf(); initrmconf(); diff -urp ipsec-tools-0.6.5.orig/src/racoon/Makefile.am ipsec-tools-0.6.5/src/racoon/Makefile.am --- ipsec-tools-0.6.5.orig/src/racoon/Makefile.am 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/src/racoon/Makefile.am 2007-04-19 13:17:22.000000000 -0400 @@ -34,7 +34,7 @@ EXTRA_racoon_SOURCES = isakmp_xauth.c is isakmp_frag.c nattraversal.c security.c $(MISSING_ALGOS) racoon_LDFLAGS = ../libipsec/libipsec.la racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) \ - $(SECCTX_OBJS) $(LEXLIB) vmbuf.o sockmisc.o misc.o + $(SECCTX_OBJS) $(LEXLIB) vmbuf.o sockmisc.o misc.o @AUDIT_LIBS@ racoon_DEPENDENCIES = ../libipsec/libipsec.la \ $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(SECCTX_OBJS) \ vmbuf.o sockmisc.o misc.o diff -urp ipsec-tools-0.6.5.orig/src/racoon/pfkey.c ipsec-tools-0.6.5/src/racoon/pfkey.c --- ipsec-tools-0.6.5.orig/src/racoon/pfkey.c 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/src/racoon/pfkey.c 2007-04-20 08:26:52.000000000 -0400 @@ -99,6 +99,7 @@ #include "nattraversal.h" #include "crypto_openssl.h" #include "grabmyaddr.h" +#include "sockmisc.h" #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC) #define SADB_X_EALG_AESCBC SADB_X_EALG_RIJNDAELCBC @@ -959,6 +960,45 @@ pk_recvgetspi(mhp) return -1; } +#ifdef HAVE_SECCTX + if (iph2->loopback == 1) { + u_int satype, reqid; + struct sockaddr *src; + + src = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_DST]); + if (cmpsaddrstrict(src, dst) == 0) { + /* yep, this is loopback. install SA */ + satype = ipsecdoi2pfkey_proto(iph2->proposal->head->proto_id); + if (satype == ~0) { + plog(LLV_ERROR, LOCATION, NULL, + "invalid proto_id %d\n", + iph2->proposal->head->proto_id); + return -1; + } + + reqid = iph2->proposal->head->reqid_in; + + iph2->status = PHASE2ST_ADDSA; + if (pfkey_send_update(lcconf->sock_pfkey, satype, + IPSEC_MODE_TRANSPORT, src, dst, sa->sadb_sa_spi, + reqid, 0, NULL, SADB_EALG_NULL, 0, SADB_AALG_NONE, + 0, 0, 0, 0, iph2->proposal->lifetime, 0, + iph2->seq, iph2->proposal->sctx.ctx_doi, + iph2->proposal->sctx.ctx_alg, + iph2->proposal->sctx.ctx_str, + iph2->proposal->sctx.ctx_strlen) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to update loopback SA: %s\n", + ipsec_strerror()); + remph2(iph2); + delph2(iph2); + return -1; + } + } + return 0; + } +#endif /* HAVE SECCTX */ + /* set SPI, and check to get all spi whether or not */ allspiok = 1; notfound = 1; @@ -1244,6 +1284,26 @@ pk_recvupdate(mhp) return -1; } +#ifdef HAVE_SECCTX + /* get update for loopback here */ + if (iph2->loopback == 1 && (cmpsaddrstrict(src, dst) == 0)) { + plog(LLV_INFO, LOCATION, NULL, + "IPsec-SA established without ISAKMP: %s\n", + sadbsecas2str(iph2->dst, iph2->src, + msg->sadb_msg_satype, sa->sadb_sa_spi, + IPSEC_MODE_TRANSPORT)); + + /* turn off the timer for calling pfkey_timeover() */ + SCHED_KILL(iph2->sce); + + iph2->sce = sched_new(iph2->proposal->lifetime, + isakmp_ph2expire_stub, iph2); + + iph2->status = PHASE2ST_ESTABLISHED; + return 0; + } +#endif + /* check to complete all keys ? */ for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { proto_id = pfkey2ipsecdoi_proto(msg->sadb_msg_satype); @@ -1286,11 +1346,6 @@ pk_recvupdate(mhp) /* turn off the timer for calling pfkey_timeover() */ SCHED_KILL(iph2->sce); - /* update status */ - /* Do this in pk_recvadd - * iph2->status = PHASE2ST_ESTABLISHED; - */ - #ifdef ENABLE_STATS gettimeofday(&iph2->end, NULL); syslog(LOG_NOTICE, "%s(%s): %8.6f", @@ -1705,6 +1761,7 @@ pk_recvacquire(mhp) struct sadb_x_sec_ctx *m_sec_ctx; #endif /* HAVE_SECCTX */ struct policyindex spidx; + int do_listen = 0; /* ignore this message because of local test mode. */ if (f_local) @@ -1728,6 +1785,12 @@ pk_recvacquire(mhp) m_sec_ctx = (struct sadb_x_sec_ctx *)mhp[SADB_X_EXT_SEC_CTX]; if (m_sec_ctx != NULL) { + if (m_sec_ctx->sadb_x_ctx_len > MAX_CTXSTR_SIZE) { + plog(LLV_ERROR, LOCATION, NULL, + "ignoring ACQUIRE: security context is greater than MAX, %d.\n", + MAX_CTXSTR_SIZE); + return -1; + } plog(LLV_INFO, LOCATION, NULL, "security context doi: %u\n", m_sec_ctx->sadb_x_ctx_doi); @@ -1779,7 +1842,6 @@ pk_recvacquire(mhp) */ struct sockaddr *sa = PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]); struct myaddrs *p; - int do_listen = 0; for (p = lcconf->myaddrs; p; p = p->next) { if (!cmpsaddrwop(p->addr, sa)) { do_listen = 1; @@ -1903,6 +1965,73 @@ pk_recvacquire(mhp) plog(LLV_DEBUG, LOCATION, NULL, "new acquire %s\n", spidx2str(&sp_out->spidx)); +#ifdef HAVE_SECCTX + /* + * If the src address in the ACQUIRE is one we listen on and + * the src and dst addresses are the same, then assume this + * packet arrived over loopback and just get an SPI and + * install the SA. + */ + if (do_listen && m_sec_ctx && (cmpsaddrstrict(src, dst) == 0)) { + struct saprop *newpp; + struct saproto *newpr; + iph2[n]->loopback = 1; + newpp = newsaprop(); + if (newpp == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saprop.\n"); + delph2(iph2[n]); + return -1; + } + /* allocate to hold reqid */ + newpr = newsaproto(); + if (newpr == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "failed to allocate saproto.\n"); + delph2(iph2[n]); + return -1; + } + + newpr->reqid_out = sp_out->req->saidx.reqid; + newpr->reqid_in = sp_in->req->saidx.reqid; + newpr->proto_id = ipproto2doi(sp_out->req->saidx.proto); + + inssaprotorev(newpp, newpr); + iph2[n]->proposal = newpp; + printsaprop0(LLV_DEBUG, newpp); + + set_secctx_in_proposal(iph2[n], spidx); + iph2[n]->proposal->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT; + + insph2(iph2[n]); + + iph2[n]->status = PHASE2ST_GETSPISENT; + plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_getspi\n"); + if (pfkey_send_getspi( + lcconf->sock_pfkey, + iph2[n]->satype, + IPSEC_MODE_TRANSPORT, + dst, /* src of SA */ + src, /* dst of SA */ + 0, 0, + newpr->reqid_in, iph2[n]->seq) < 0) { + plog(LLV_ERROR, LOCATION, NULL, + "ipseclib failed send getspi (%s)\n", + ipsec_strerror()); + delph2(iph2[n]); + return -1; + } + iph2[n]->sce = sched_new(lcconf->wait_ph2complete, + pfkey_timeover_stub, iph2[n]); + + plog(LLV_DEBUG, LOCATION, NULL, + "pfkey GETSPI sent: %s\n", + sadbsecas2str(dst, src, iph2[n]->satype, 0, + IPSEC_MODE_TRANSPORT)); + return 0; + } +#endif /* HAVE_SECCTX */ + /* get sainfo */ { vchar_t *idsrc, *iddst; diff -urp ipsec-tools-0.6.5.orig/src/racoon/policy.h ipsec-tools-0.6.5/src/racoon/policy.h --- ipsec-tools-0.6.5.orig/src/racoon/policy.h 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/src/racoon/policy.h 2007-04-19 13:17:22.000000000 -0400 @@ -36,7 +36,11 @@ #ifdef HAVE_SECCTX -#define MAX_CTXSTR_SIZE 50 +/* Current LSPP policy is 1024 compartments, 5 chars each 'c1024'. SE Linux + * will attempt to combine so, worst case is all odd or even numbers. The + * context size of SE Linux types is max'ed around 256. We allow 16 for + * sensitivity */ +#define MAX_CTXSTR_SIZE 3344 /* (6 * 512) + 256 + 16 */ struct security_ctx { u_int8_t ctx_doi; /* Security Context DOI */ u_int8_t ctx_alg; /* Security Context Algorithm */ @@ -147,9 +151,13 @@ extern void initsp __P((void)); extern struct ipsecrequest *newipsecreq __P((void)); extern const char *spidx2str __P((const struct policyindex *)); +#ifdef HAVE_LIBAUDIT +extern void audit_init __P((void)); +#endif #ifdef HAVE_SECCTX #include extern int get_security_context __P((vchar_t *, struct policyindex *)); +extern void init_avc __P((void)); extern int within_range __P((security_context_t, security_context_t)); extern void set_secctx_in_proposal __P((struct ph2handle *, struct policyindex)); #endif diff -urp ipsec-tools-0.6.5.orig/src/racoon/security.c ipsec-tools-0.6.5/src/racoon/security.c --- ipsec-tools-0.6.5.orig/src/racoon/security.c 2007-04-19 13:16:42.000000000 -0400 +++ ipsec-tools-0.6.5/src/racoon/security.c 2007-04-19 13:17:22.000000000 -0400 @@ -55,6 +55,60 @@ #include "proposal.h" #include "strnames.h" #include "handler.h" +#ifdef HAVE_LIBAUDIT +#include +#include "libaudit.h" +#endif + +static void log_callback (const char *fmt, ...); + +static const struct avc_log_callback log_cb = +{ + .func_log = log_callback, + .func_audit = NULL +}; + +#ifdef HAVE_LIBAUDIT +static int audit_fd = -1; +void +audit_init(void) +{ + audit_fd = audit_open(); + if (audit_fd < 0) { + /* If kernel doesn't support audit, bail out */ + if (errno == EINVAL || errno == EPROTONOSUPPORT || + errno == EAFNOSUPPORT) + return; + /* If unprivileged, bail out */ + if (errno == EPERM && getuid() != 0) + return; + plog (LLV_ERROR, LOCATION, NULL, + "Failed opening connection to the audit subsystem"); + } +} +#endif /* HAVE_LIBAUDIT */ + +static void +log_callback (const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); +#ifdef HAVE_LIBAUDIT + if (audit_fd >= 0) { + char buf[PATH_MAX*2]; + + /* FIXME: need to change this to show real user */ + vsnprintf(buf, sizeof(buf), fmt, ap); + audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, + buf, NULL, NULL, NULL, -1); + return; + } else +#endif /* HAVE_LIBAUDIT */ + { + vsyslog (LOG_INFO, fmt, ap); + va_end(ap); + } +} /* * Get the security context information from SA. @@ -181,24 +235,21 @@ set_secctx_in_proposal(iph2, spidx) * return: 0 if avc was successfully initialized * 1 if the avc could not be initialized */ - -static int +static int mls_ready = 0; +void init_avc(void) { - int rtn = 0; - if (!is_selinux_mls_enabled()) { plog(LLV_ERROR, LOCATION, NULL, "racoon: MLS support is not" " enabled.\n"); - return 1; + return; } - rtn = avc_init("racoon", NULL, NULL, NULL, NULL); - if (rtn != 0) { - plog(LLV_ERROR, LOCATION, NULL, "racoon: could not initialize avc.\n"); - rtn = 1; - } - return rtn; + if (avc_init("racoon", NULL, &log_cb, NULL, NULL) == 0) + mls_ready = 1; + else + plog(LLV_ERROR, LOCATION, NULL, + "racoon: could not initialize avc.\n"); } /* @@ -225,12 +276,8 @@ within_range(security_context_t sl, secu if (!*range) /* This policy doesn't have security context */ return 1; - rtn = init_avc(); - if (rtn != 0) { - plog(LLV_ERROR, LOCATION, NULL, - "within_range: couldn't initialize the AVC\n"); + if (!mls_ready) /* mls may not be enabled */ return 0; - } /* * Get the sids for the sl and range contexts