From: Quentin Swain <qsw...@tresys.com>

Implement IPSec labeling on Android. Modified pfkey to support setting labels
within SPD policies. The labels are only applied to locally to IPsec traffic 
andare not sent to the remote IKE during connectioin setup.

Change-Id: I8b38d2a70f7632036d76cbfcbac459c71935a32c
---
 Android.mk            | 20 ++++++++++++++++++++
 src/libipsec/pfkey.c  | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
 src/racoon/proposal.h |  1 +
 src/racoon/security.c | 11 +++++++++--
 4 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/Android.mk b/Android.mk
index c7ac4d7..6a29095 100644
--- a/Android.mk
+++ b/Android.mk
@@ -66,6 +66,18 @@ LOCAL_CFLAGS := -DANDROID_CHANGES -DHAVE_CONFIG_H 
-DHAVE_OPENSSL_ENGINE_H
 
 LOCAL_CFLAGS += -Wno-sign-compare -Wno-missing-field-initializers
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_SRC_FILES += src/racoon/security.c
+
+LOCAL_C_INCLUDES += external/libselinux/include
+
+LOCAL_SHARED_LIBRARIES += libselinux
+
+LOCAL_LD_LIBS := -lselinux
+
+LOCAL_CFLAGS += -DHAVE_SECCTX
+endif
+
 LOCAL_MODULE := racoon
 
 include $(BUILD_EXECUTABLE)
@@ -87,6 +99,14 @@ LOCAL_C_INCLUDES += \
        $(LOCAL_PATH)/src/include-glibc \
        $(LOCAL_PATH)/src/libipsec
 
+ifeq ($(HAVE_SELINUX),true)
+LOCAL_C_INCLUDES += external/libselinux/include
+
+LOCAL_SHARED_LIBRARIES := libselinux
+
+LOCAL_CFLAGS += -DHAVE_SECCTX
+endif
+
 LOCAL_MODULE := libipsec
 
 LOCAL_MODULE_TAGS := optional
diff --git a/src/libipsec/pfkey.c b/src/libipsec/pfkey.c
index fae0415..3791cc4 100644
--- a/src/libipsec/pfkey.c
+++ b/src/libipsec/pfkey.c
@@ -42,6 +42,7 @@
 #include <netinet/in.h>
 #include PATH_IPSEC_H
 
+#include <selinux/selinux.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
@@ -1630,9 +1631,14 @@ pfkey_send_x3(so, type, satype)
                return -1;
 
        __ipsec_errcode = EIPSEC_NO_ERROR;
-       return len;
+        return len;
 }
-
+//policy structure defined in setup.c
+struct policy {
+  struct sadb_x_policy p;
+  struct sadb_x_ipsecrequest q;
+  char addresses[sizeof(struct sockaddr_storage) * 2];
+};
 /* sending SADB_X_SPDADD message to the kernel */
 static int
 pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
@@ -1676,7 +1682,24 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
                __ipsec_errcode = EIPSEC_INVAL_PREFIXLEN;
                return -1;
        }
-
+#ifdef HAVE_SECCTX
+        struct policy *pol = (struct policy *)policy;
+        char address[INET_ADDRSTRLEN];
+        int doi=1,alg=1;
+        int direction = pol-> p.sadb_x_policy_dir;
+       if(direction == IPSEC_DIR_INBOUND){
+            inet_ntop(AF_INET,&((((struct sockaddr_in 
*)pol->addresses))->sin_addr)
+                             ,address,INET_ADDRSTRLEN);
+        }
+
+        else if(direction == IPSEC_DIR_OUTBOUND){
+            inet_ntop(AF_INET,&((((struct sockaddr_in 
*)pol->addresses)+1)->sin_addr)
+                             ,address,INET_ADDRSTRLEN);
+        }
+        char*  sec_label = getvpnctx(direction,address);
+       if(sec_label== NULL)
+           return -1;
+#endif
        /* create new sadb_msg to reply. */
        len = sizeof(struct sadb_msg)
                + sizeof(struct sadb_address)
@@ -1684,6 +1707,10 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
                + sizeof(struct sadb_address)
                + PFKEY_ALIGN8(sysdep_sa_len(src))
                + sizeof(struct sadb_lifetime)
+#ifdef HAVE_SECCTX
+               + sizeof(struct sadb_x_sec_ctx)
+               + strlen(sec_label) + 1
+#endif
                + policylen;
 
        if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
@@ -1710,10 +1737,26 @@ pfkey_send_x4(so, type, src, prefs, dst, prefd, proto,
        }
        p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
                        0, 0, (u_int)ltime, (u_int)vtime);
-       if (!p || p + policylen != ep) {
+#ifndef HAVE_SECCTX
+       if(!p || p + policylen != ep) {
                free(newmsg);
                return -1;
        }
+
+#else
+        if(!p){
+
+               free(newmsg);
+               return -1 ;
+       }
+        p = pfkey_setsecctx(p,ep, 
SADB_X_EXT_SEC_CTX,doi,alg,sec_label,strlen(sec_label));
+       if(!p || p + policylen  != ep){
+               free(newmsg);
+               return -1;
+       }
+
+#endif
+
        memcpy(p, policy, (size_t)policylen);
 
        /* send message */
diff --git a/src/racoon/proposal.h b/src/racoon/proposal.h
index 60fc531..a292f1f 100644
--- a/src/racoon/proposal.h
+++ b/src/racoon/proposal.h
@@ -35,6 +35,7 @@
 #define _PROPOSAL_H
 
 #include <sys/queue.h>
+#include "policy.h"
 
 /*
  *   A. chained list of transform, only for single proto_id
diff --git a/src/racoon/security.c b/src/racoon/security.c
index e4b5a0d..3b48cef 100644
--- a/src/racoon/security.c
+++ b/src/racoon/security.c
@@ -38,8 +38,6 @@
 #include <string.h>
 
 #include <selinux/selinux.h>
-#include <selinux/flask.h>
-#include <selinux/av_permissions.h>
 #include <selinux/avc.h>
 #include <selinux/context.h>
 
@@ -56,6 +54,15 @@
 #include "strnames.h"
 #include "handler.h"
 
+/*
+ * Defined for use with labeled IPSec. Constants not contained in selinux for
+ * Android but needed by ipsec-tools.
+ */
+#ifdef HAVE_SECCTX
+#define SECCLASS_ASSOCIATION 54
+#define ASSOCIATION__POLMATCH 0x00000008UL
+#endif
+
 /* 
  * Get the security context information from SA.
  */
-- 
1.7.11.7


--
This message was distributed to subscribers of the seandroid-list mailing list.
If you no longer wish to subscribe, send mail to majord...@tycho.nsa.gov with
the words "unsubscribe seandroid-list" without quotes as the message.

Reply via email to