From 886926c087c10c05fed266ba16e5f571352de3b4 Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Thu, 22 Sep 2016 17:57:34 +0000
Subject: [PATCH] ipsec-305.tar.gz

---
 entitlements.plist                        |   2 +
 ipsec-tools/Common/pfkey.c                |  85 +++++++++----
 ipsec-tools/racoon/com.apple.racoon.plist | Bin 357 -> 387 bytes
 ipsec-tools/racoon/crypto_cssm.c          |  27 +++-
 ipsec-tools/racoon/main.c                 |  19 ++-
 ipsec-tools/racoon/session.c              |  11 +-
 ipsec-tools/racoon/session.h              |   3 +
 ipsec-tools/racoon/vpn.c                  |  13 +-
 ipsec-tools/racoon/vpn_control.c          | 103 +++++++++++++++-
 ipsec-tools/racoon/vpn_control_var.h      |   2 +-
 racoon.sb                                 | 142 ++++++----------------
 11 files changed, 258 insertions(+), 149 deletions(-)

diff --git a/entitlements.plist b/entitlements.plist
index bb6a89a..a630f63 100644
--- a/entitlements.plist
+++ b/entitlements.plist
@@ -18,5 +18,7 @@
 	</array>
 	<key>com.apple.private.nehelper.privileged</key>
 	<true/>
+	<key>com.apple.private.system-keychain</key>
+	<true/>
 </dict>
 </plist>
diff --git a/ipsec-tools/Common/pfkey.c b/ipsec-tools/Common/pfkey.c
index 2a8a765..3330ec7 100644
--- a/ipsec-tools/Common/pfkey.c
+++ b/ipsec-tools/Common/pfkey.c
@@ -51,6 +51,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 
 #include "var.h"
 #include "ipsec_strerror.h"
@@ -1110,8 +1111,11 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
               u_int32_t l_alloc, u_int32_t l_bytes, u_int32_t l_addtime, u_int32_t l_usetime, u_int32_t seq, u_int16_t port,
               u_int always_expire)
 {
-	struct sadb_msg *newmsg;
+	struct sadb_msg *newmsg = NULL;
+	struct ifaddrs *ifap = NULL;
+	struct ifaddrs *ifa = NULL;
 	int len;
+	int ret = -1;
 	caddr_t p;
 	int plen;
 	caddr_t ep;
@@ -1181,6 +1185,25 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
 		return -1;
 	}
 
+	if (getifaddrs(&ifap) < 0) {
+		return -1;
+	}
+
+	for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != src->ss_family)
+			continue;
+
+		if (src->ss_family == AF_INET) {
+			if (memcmp(&((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr, &((struct sockaddr_in *)src)->sin_addr, sizeof(struct in_addr)) != 0)
+				continue;
+		} else if (src->ss_family == AF_INET6) {
+			if (memcmp(&((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr, &((struct sockaddr_in6 *)src)->sin6_addr, sizeof(struct in6_addr)) != 0)
+				continue;
+		}
+
+		break;
+	}
+
 	/* create new sadb_msg to reply. */
 	len = sizeof(struct sadb_msg)
 		+ sizeof(struct sadb_sa_2)
@@ -1190,7 +1213,8 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
 		+ sizeof(struct sadb_address)
 		+ PFKEY_ALIGN8(sysdep_sa_len((struct sockaddr *)dst))
 		+ sizeof(struct sadb_lifetime)
-		+ sizeof(struct sadb_lifetime);
+		+ sizeof(struct sadb_lifetime)
+		+ ((ifa != NULL && ifa->ifa_name != NULL) ? sizeof(struct sadb_x_ipsecif) : 0);
 		
 	if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP)
 		len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen));
@@ -1199,7 +1223,7 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
 
 	if ((newmsg = CALLOC((size_t)len, struct sadb_msg *)) == NULL) {
 		__ipsec_set_strerror(strerror(errno));
-		return -1;
+		goto err;
 	}
 	ep = ((caddr_t)(void *)newmsg) + len;
 
@@ -1207,45 +1231,47 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
 	                     satype, seq, getpid());
 	if (!p) {
 		free(newmsg);
+		freeifaddrs(ifap);
 		return -1;
 	}
 	p = pfkey_setsadbsa(p, ep, spi, wsize, a_type, e_type, flags, port);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 	p = pfkey_setsadbxsa2(p, ep, mode, reqid, always_expire);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, (u_int)plen,
 	    IPSEC_ULPROTO_ANY);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 	p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_DST, dst, (u_int)plen,
 	    IPSEC_ULPROTO_ANY);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
+	}
+
+	if (ifa != NULL && ifa->ifa_name != NULL) {
+		p = pfkey_setsadbipsecif(p, ep, NULL, ifa->ifa_name, NULL, 0);
+		if (!p) {
+			goto err;
+		}
 	}
 
 	if (e_type != SADB_EALG_NONE && satype != SADB_X_SATYPE_IPCOMP) {
 		p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_ENCRYPT,
 		                   keymat, e_keylen);
 		if (!p) {
-			free(newmsg);
-			return -1;
+			goto err;
 		}
 	}
 	if (a_type != SADB_AALG_NONE) {
 		p = pfkey_setsadbkey(p, ep, SADB_EXT_KEY_AUTH,
 		                   keymat + e_keylen, a_keylen);
 		if (!p) {
-			free(newmsg);
-			return -1;
+			goto err;
 		}
 	}
 
@@ -1253,30 +1279,37 @@ pfkey_send_x1(int so, u_int type, u_int satype, u_int mode, struct sockaddr_stor
 	p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_HARD,
 			l_alloc, l_bytes, l_addtime, l_usetime);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 	p = pfkey_setsadblifetime(p, ep, SADB_EXT_LIFETIME_SOFT,
 			l_alloc, l_bytes, l_addtime, l_usetime);
 	if (!p) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 	
 	if (p != ep) {
-		free(newmsg);
-		return -1;
+		goto err;
 	}
 
 	/* send message */
 	len = pfkey_send(so, newmsg, len);
-	free(newmsg);
-
-	if (len < 0)
-		return -1;
+	if (len < 0) {
+		goto err;
+	}
 
 	__ipsec_errcode = EIPSEC_NO_ERROR;
-	return len;
+	ret = len;
+	
+err:
+	if (ifap != NULL) {
+		freeifaddrs(ifap);
+	}
+
+	if (newmsg != NULL) {
+		free(newmsg);
+	}
+
+	return ret;
 }
 
 
diff --git a/ipsec-tools/racoon/com.apple.racoon.plist b/ipsec-tools/racoon/com.apple.racoon.plist
index f0c233ba9bc42df47b1dd9f286017460c0771f16..c5f03e74b440392ef39510b2989cd2479873272e 100644
GIT binary patch
delta 293
zcmaFL)XZF;RFIQdTw-8woso%|g_Vt+gOf*8f?Fy&peR2%wYWH>vLH3aH!(RQIJKxO
z6DSfMoS&SXT2dS@AOKX7UX+;YSd?Cxo0?Zr92r!a=UC#CpO_LaAmo~tn3R(mQk0li
zoS0manV(l2>XVq1niK7rSCU!;5-Ll*$i+SJt%}G+UcN{lpd(WAQj3Z&^9u+H35!hZ
z_o!baCJwYkzqGhWzc?u~Pami&KR+)>*M)-<D4v|3tCv_%kdvwh5oh3F5NA+kFkrA?
z@MZ{Q$YLm9s9~sQSj4cHVHv{)hV2Z87|t`?VR*>!gyBCU6Qd}j1fwLQ6ayGAF+ykt
NX($b%Sb>;P7XaSjQvd(}

delta 234
zcmZo>e#+#ORFIQdTw-8wjgg6&g_Vt+OISo)EM7n$peR4RC^6TuD7`c{HLs*NJUBl&
zJGG=Z)F&}1H7CY5F*zeRwWusJId!6!g6<*?PM{wB(&8fh;-t(x{i4L={QSHiU6+g8
zJdr*?3sUn^i;6Gv^6?7@3QgSZ0kR=EKUXiYpdcqz52E^_sMy4Ml@Jb21`Y;M1`P%S
z1~Ud{2499GhE#?MhH8d7h7N{)hFJ{D8MZL&WZ1)So#7S3TSfs!K}I14FkoVY&<v7L
J8cHz=0|0g!JXQbz

diff --git a/ipsec-tools/racoon/crypto_cssm.c b/ipsec-tools/racoon/crypto_cssm.c
index 1b28547..e8fdc98 100644
--- a/ipsec-tools/racoon/crypto_cssm.c
+++ b/ipsec-tools/racoon/crypto_cssm.c
@@ -34,6 +34,7 @@
 #include <Security/SecIdentity.h>
 #include <Security/SecItem.h>
 #include <TargetConditionals.h>
+#include <Security/SecItemPriv.h>
 #if TARGET_OS_EMBEDDED
 #include <Security/SecTrustPriv.h>
 #include <Security/SecPolicyPriv.h>
@@ -310,8 +311,16 @@ vchar_t* crypto_cssm_getsign(CFDataRef persistentCertRef, vchar_t* hash)
 
 
 	CFDictionaryRef		persistFind = NULL;
-	const void			*keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass};
-	const void			*values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity};
+	const void			*keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+							    kSecUseSystemKeychain,
+#endif
+							  };
+	const void			*values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+							      kCFBooleanTrue,
+#endif
+							    };
     
 #define SIG_BUF_SIZE 1024
 	
@@ -378,8 +387,16 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef,
 	size_t                  dataLen;
 	CFDataRef               certData = NULL;
 	SecIdentityRef 			identityRef = NULL;
-	const void              *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass };
-	const void              *values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity };
+	const void              *keys_persist[] = { kSecReturnRef, kSecValuePersistentRef, kSecClass,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+						    kSecUseSystemKeychain,
+#endif
+						  };
+	const void              *values_persist[] = { kCFBooleanTrue, persistentCertRef, kSecClassIdentity,
+#if TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
+						      kCFBooleanTrue,
+#endif
+						    };
 	
 	/* find identity by persistent ref */
 	persistFind = CFDictionaryCreate(NULL, keys_persist, values_persist,
@@ -387,7 +404,7 @@ vchar_t* crypto_cssm_get_x509cert(CFDataRef persistentCertRef,
 	if (persistFind == NULL)
 		goto end;
     
-    status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
+	status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
 	if (status != noErr)
 		goto end;
 
diff --git a/ipsec-tools/racoon/main.c b/ipsec-tools/racoon/main.c
index 631b86c..4d654cb 100644
--- a/ipsec-tools/racoon/main.c
+++ b/ipsec-tools/racoon/main.c
@@ -81,6 +81,11 @@
 #include "crypto_openssl.h"
 #include "vendorid.h"
 
+#if !TARGET_OS_EMBEDDED
+#include <sandbox.h>
+#endif // !TARGET_OS_EMBEDDED
+
+
 #include <CoreFoundation/CoreFoundation.h>
 #include "power_mgmt.h"
 #include "preferences.h"
@@ -150,17 +155,21 @@ main(ac, av)
 {
 	int error;
 
+#if !TARGET_OS_EMBEDDED
+	char *errorbuf;
+	if (sandbox_init("racoon", SANDBOX_NAMED, &errorbuf) == -1) {
+		plog(ASL_LEVEL_ERR, "initializing sandbox failed %s", errorbuf);
+		sandbox_free_error(errorbuf);
+		return -1;
+	}
+#endif // !TARGET_OS_EMBEDDED
+
 	/*
 	 * Check IPSec plist
 	 */
 	prefsinit();
 	ploginit();
 
-	/* 
-	 * racoon is not sandboxed on Mac OS.
-	 * On embedded, racoon is sandboxed with a seatbelt-profiles entitlement.
-	 */
-
 	if (geteuid() != 0) {
 		errx(1, "must be root to invoke this program.");
 		/* NOTREACHED*/
diff --git a/ipsec-tools/racoon/session.c b/ipsec-tools/racoon/session.c
index 11915b2..1f9dee4 100644
--- a/ipsec-tools/racoon/session.c
+++ b/ipsec-tools/racoon/session.c
@@ -115,7 +115,6 @@ extern int launchdlaunched;
 static void close_session (int);
 static int init_signal (void);
 static int set_signal (int sig, RETSIGTYPE (*func) (int, siginfo_t *, void *));
-static void check_sigreq (void);
 static void check_flushsa_stub (void *);
 static void check_flushsa (void);
 static void auto_exit_do (void *);
@@ -123,6 +122,7 @@ static int close_sockets (void);
 
 static volatile sig_atomic_t sigreq[NSIG + 1];
 int terminated = 0;
+int pending_signal_handle = 0;
 
 static int64_t racoon_keepalive = -1;
 
@@ -482,7 +482,7 @@ static int signals[] = {
 };
 
 
-static void
+void
 check_sigreq()
 {
 	int sig;
@@ -603,9 +603,14 @@ signal_handler(int sig, siginfo_t *sigi, void *ctx)
     if ( sig == SIGTERM ){
         terminated = 1;
     }
+
+	pending_signal_handle = 1;
     dispatch_async(main_queue, 
                    ^{
-                        check_sigreq(); 
+						if (pending_signal_handle) {
+							check_sigreq();
+							pending_signal_handle = 0;
+						}
                    });
 }
 
diff --git a/ipsec-tools/racoon/session.h b/ipsec-tools/racoon/session.h
index b17ca70..78424e1 100644
--- a/ipsec-tools/racoon/session.h
+++ b/ipsec-tools/racoon/session.h
@@ -34,7 +34,10 @@
 
 #include "handler.h"
 
+extern int pending_signal_handle;
+
 extern void session (void);
+extern void check_sigreq(void);
 extern RETSIGTYPE signal_handler (int, siginfo_t *, void *);
 extern void check_auto_exit (void);
 extern void dying (void);
diff --git a/ipsec-tools/racoon/vpn.c b/ipsec-tools/racoon/vpn.c
index 0548429..393e4d3 100644
--- a/ipsec-tools/racoon/vpn.c
+++ b/ipsec-tools/racoon/vpn.c
@@ -245,7 +245,7 @@ vpn_disconnect(struct bound_addr *srv, const char *reason)
 }
 
 int
-vpn_start_ph2(struct bound_addr *addr, struct vpnctl_cmd_start_ph2 *pkt)
+vpn_start_ph2(struct bound_addr *addr, struct vpnctl_cmd_start_ph2 *pkt, size_t pkt_len)
 {
 	struct vpnctl_sa_selector *selector_ptr;
 	struct vpnctl_algo *algo_ptr, *next_algo;
@@ -283,7 +283,18 @@ vpn_start_ph2(struct bound_addr *addr, struct vpnctl_cmd_start_ph2 *pkt)
 	}
 
 	selector_ptr = (struct vpnctl_sa_selector *)(pkt + 1);
+	size_t total_selector_len = (sizeof(struct vpnctl_sa_selector) * ntohs(pkt->selector_count));
+	if (pkt_len < (sizeof(struct vpnctl_cmd_start_ph2) + total_selector_len)) {
+		plog(ASL_LEVEL_ERR, "invalid length for vpn ph2 selector - len=%ld - expected %ld\n", pkt_len, (sizeof(struct vpnctl_cmd_start_ph2) + total_selector_len));
+		return -1;
+	}
+
 	algo_ptr = (struct vpnctl_algo *)(selector_ptr + ntohs(pkt->selector_count));
+	size_t total_algo_len = (sizeof(struct vpnctl_algo) * ntohs(pkt->algo_count));
+	if (pkt_len < (sizeof(struct vpnctl_cmd_start_ph2) + total_selector_len + total_algo_len)) {
+		plog(ASL_LEVEL_ERR, "invalid length for vpn ph2 algo - len=%ld - expected %ld\n", pkt_len, (sizeof(struct vpnctl_cmd_start_ph2) + total_selector_len + total_algo_len));
+		return -1;
+	}
 
 	for (i = 0; i < ntohs(pkt->selector_count); i++, selector_ptr++) {
 		new_sainfo = create_sainfo();
diff --git a/ipsec-tools/racoon/vpn_control.c b/ipsec-tools/racoon/vpn_control.c
index 35be491..1b70dd2 100644
--- a/ipsec-tools/racoon/vpn_control.c
+++ b/ipsec-tools/racoon/vpn_control.c
@@ -119,7 +119,7 @@ gid_t vpncontrolsock_group = 0;
 mode_t vpncontrolsock_mode = 0600;
 
 static struct sockaddr_un sunaddr;
-static int vpncontrol_process (struct vpnctl_socket_elem *, char *);
+static int vpncontrol_process (struct vpnctl_socket_elem *, char *, size_t);
 static int vpncontrol_reply (int, char *);
 static void vpncontrol_close_comm (struct vpnctl_socket_elem *);
 static int checklaunchd (void);
@@ -316,7 +316,13 @@ vpncontrol_comm_handler(struct vpnctl_socket_elem *elem)
 		goto end;
 	}
 
-	(void)vpncontrol_process(elem, combuf);
+	if (len < (sizeof(hdr) + ntohs(hdr.len))) {
+		plog(ASL_LEVEL_ERR,
+			 "invalid length of vpn_control command - len=%ld - expected %ld\n", len, (sizeof(hdr) + ntohs(hdr.len)));
+		goto end;
+	}
+
+	(void)vpncontrol_process(elem, combuf, len);
 
 end:
 	if (combuf)
@@ -325,7 +331,7 @@ end:
 }
 
 static int
-vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
+vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf, size_t combuf_len)
 {
 	u_int16_t	error = 0;
 	struct vpnctl_hdr *hdr = ALIGNED_CAST(struct vpnctl_hdr *)combuf;
@@ -334,8 +340,20 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 	
 		case VPNCTL_CMD_BIND:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_bind)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl bind cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_bind));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_bind *pkt = ALIGNED_CAST(struct vpnctl_cmd_bind *)combuf;
 				struct bound_addr *addr;
+
+				if (combuf_len < (sizeof(struct vpnctl_cmd_bind) + ntohs(pkt->vers_len))) {
+					plog(ASL_LEVEL_ERR, "invalid length for vpnctl bind cmd - len=%ld - expected %ld\n", combuf_len, (sizeof(struct vpnctl_cmd_bind) + ntohs(pkt->vers_len)));
+					error = -1;
+					break;
+				}
 			
 				plog(ASL_LEVEL_DEBUG, 
 					"received bind command on vpn control socket.\n");
@@ -364,6 +382,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 			
 		case VPNCTL_CMD_UNBIND:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_unbind)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl unbind cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_unbind));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_unbind *pkt = ALIGNED_CAST(struct vpnctl_cmd_unbind *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
@@ -385,6 +409,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_REDIRECT:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_redirect)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl redirect cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_redirect));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_redirect *redirect_msg = ALIGNED_CAST(struct vpnctl_cmd_redirect *)combuf;
 				struct redirect *raddr;
 				struct redirect *t_raddr;
@@ -428,12 +458,24 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_XAUTH_INFO:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_xauth_info)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl xauth info cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_xauth_info));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_xauth_info *pkt = ALIGNED_CAST(struct vpnctl_cmd_xauth_info *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
 				void *attr_list;
 
-				plog(ASL_LEVEL_DEBUG, 
+				if (combuf_len < (sizeof(struct vpnctl_cmd_xauth_info) + ntohs(pkt->hdr.len) - sizeof(u_int32_t))) {
+					plog(ASL_LEVEL_ERR, "invalid length for vpnctl xauth info cmd - len=%ld - expected %ld\n", combuf_len, (sizeof(struct vpnctl_cmd_xauth_info) + ntohs(pkt->hdr.len) - sizeof(u_int32_t)));
+					error = -1;
+					break;
+				}
+
+				plog(ASL_LEVEL_DEBUG,
 					"received xauth info command vpn control socket.\n");
 				LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
 					if (pkt->address == addr->address) {
@@ -448,6 +490,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_SET_NAT64_PREFIX:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_set_nat64_prefix)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl nat64 prefix cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_set_nat64_prefix));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_set_nat64_prefix *pkt = ALIGNED_CAST(struct vpnctl_cmd_set_nat64_prefix *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
@@ -462,10 +510,25 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_CONNECT:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_connect)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl connect cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_connect));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_connect *pkt = ALIGNED_CAST(struct vpnctl_cmd_connect *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
 
+				if (pending_signal_handle) {
+					/*
+					 * This check is done to ensure that a SIGUSR1 signal to re-read the configuration file
+					 * is completed before calling a connect. This is to fix the issue seen in (rdar://problem/25641686)
+					 */
+					check_sigreq();
+					pending_signal_handle = 0;
+				}
+
 				plog(ASL_LEVEL_DEBUG, 
 					"received connect command on vpn control socket.\n");
 				LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
@@ -480,6 +543,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 			
 		case VPNCTL_CMD_DISCONNECT:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_connect)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl disconnect cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_connect));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_connect *pkt = ALIGNED_CAST(struct vpnctl_cmd_connect *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
@@ -498,6 +567,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 			
 		case VPNCTL_CMD_START_PH2:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_start_ph2)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl start ph2 cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_start_ph2));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_start_ph2 *pkt = ALIGNED_CAST(struct vpnctl_cmd_start_ph2 *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
@@ -506,7 +581,7 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 				LIST_FOREACH_SAFE(addr, &elem->bound_addresses, chain, t_addr) {
 					if (pkt->address == addr->address) {
 						/* start the connection */
-						error = vpn_start_ph2(addr, pkt);
+						error = vpn_start_ph2(addr, pkt, combuf_len);
 						break;
 					}
 				}
@@ -515,6 +590,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_START_DPD:
             {
+				if (combuf_len < sizeof(struct vpnctl_cmd_start_dpd)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl start dpd cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_start_dpd));
+					error = -1;
+					break;
+				}
+
                 struct vpnctl_cmd_start_dpd *pkt = ALIGNED_CAST(struct vpnctl_cmd_start_dpd *)combuf;
                 struct bound_addr *srv;
                 struct bound_addr *t_addr;
@@ -544,6 +625,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_ASSERT:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_assert)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl assert cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_assert));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_assert *pkt = ALIGNED_CAST(struct vpnctl_cmd_assert *)combuf;
 //				struct bound_addr *addr;
 //				struct bound_addr *t_addr;
@@ -573,6 +660,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
 		case VPNCTL_CMD_RECONNECT:
 			{
+				if (combuf_len < sizeof(struct vpnctl_cmd_connect)) {
+					plog(ASL_LEVEL_ERR, "invalid header length for vpnctl reconnect cmd - len=%ld - expected %ld\n", combuf_len, sizeof(struct vpnctl_cmd_connect));
+					error = -1;
+					break;
+				}
+
 				struct vpnctl_cmd_connect *pkt = ALIGNED_CAST(struct vpnctl_cmd_connect *)combuf;
 				struct bound_addr *addr;
 				struct bound_addr *t_addr;
diff --git a/ipsec-tools/racoon/vpn_control_var.h b/ipsec-tools/racoon/vpn_control_var.h
index ee9b47f..bd52157 100644
--- a/ipsec-tools/racoon/vpn_control_var.h
+++ b/ipsec-tools/racoon/vpn_control_var.h
@@ -74,7 +74,7 @@ extern int vpn_control_connected (void);
 extern int vpn_connect (struct bound_addr *, int);
 extern int vpn_disconnect (struct bound_addr *, const char *);
 extern void vpncontrol_disconnect_all (struct vpnctl_socket_elem *, const char *);
-extern int vpn_start_ph2 (struct bound_addr *, struct vpnctl_cmd_start_ph2 *);
+extern int vpn_start_ph2 (struct bound_addr *, struct vpnctl_cmd_start_ph2 *, size_t);
 extern int vpncontrol_notify_need_authinfo (phase1_handle_t *, void*, size_t);
 extern int vpncontrol_notify_peer_resp_ph1 (u_int16_t, phase1_handle_t*);
 extern int vpncontrol_notify_peer_resp_ph2 (u_int16_t, phase2_handle_t*);
diff --git a/racoon.sb b/racoon.sb
index ec52313..34e2459 100644
--- a/racoon.sb
+++ b/racoon.sb
@@ -8,120 +8,56 @@
 
 (allow system-info (info-type "net.link.addr"))
 
-(allow ipc-posix* (ipc-posix-name "com.apple.securityd"))
-(allow ipc-posix-shm
-    (ipc-posix-name "apple.shm.notification_center")
-    (ipc-posix-name "com.apple.AppleDatabaseChanged"))
-
-(allow file-read* file-ioctl
-    (subpath "/private/etc/master.passwd")
-    (subpath "/private/var/run/racoon")
-    (literal "/private/var/preferences/SystemConfiguration/com.apple.ipsec.plist")
-    (subpath "/private/etc/racoon"))
-
-(allow file-read*
-    (subpath "/Library/Managed\ Preferences")
-    (subpath "/Library/Preferences")
-    (subpath "/private/var/root")
-    (literal "/private/var/mobile/Library/Caches/com.apple.MobileGestalt.plist")
-    (literal "/private/var/db/mds/messages/se_SecurityMessages")
-    (literal "/private/var/db/icu"))
-
-(allow file-write*
-    (literal "/private/var/run/racoon.sock")
-    (literal "/private/var/run/racoon.pid"))
+(allow file-read*)
 
-(allow file*
-    (literal "/var/log/racoon.log")
-    (literal "/private/var/log/racoon.log"))
+(allow file-write*)
 
-(allow iokit-open (iokit-user-client-class "RootDomainUserClient"))
-
-(allow network-outbound (subpath "/private/var/tmp/launchd"))
-(allow network*
-    (local udp "*:500" "*:4500")
-    (remote udp "*:*")
-    (literal "/private/var/run/racoon.sock"))
+(allow ipc-posix* (ipc-posix-name "com.apple.securityd"))
 
-(allow file*
-    (literal "/Library/Keychains/System.keychain")
-    (literal "/private/var/db/mds/system/mdsObject.db")
-    (literal "/private/var/db/mds/system/mds.lock")
-    (literal "/private/var/db/mds/system/mdsDirectory.db"))
+(allow ipc-posix-shm
+	(ipc-posix-name "apple.shm.notification_center")
+	(ipc-posix-name "com.apple.AppleDatabaseChanged"))
 
-(allow mach-lookup
-    (global-name "com.apple.SecurityServer")
-    (global-name "com.apple.SystemConfiguration.configd")
-    (global-name "com.apple.ocspd")
-    (global-name "com.apple.commcenter.xpc")
-    (global-name "com.apple.aggregated")
-    (global-name "com.apple.cfprefsd.daemon")
-    (global-name "com.apple.cfprefsd.agent")
-    (local-name "com.apple.cfprefsd.agent")
-    (global-name "com.apple.nehelper"))
-	
 (allow ipc-posix-shm-read*
-    (ipc-posix-name-regex #"^apple\.shm\.cfprefsd\."))
+	(ipc-posix-name-regex #"^apple\.shm\.cfprefsd\."))
 
-;;;;;; Common system sandbox rules
-;;;;;;
-;;;;;; Copyright (c) 2008-2010 Apple Inc.  All Rights reserved.
-;;;;;;
-;;;;;; WARNING: The sandbox rules in this file currently constitute
-;;;;;; Apple System Private Interface and are subject to change at any time and
-;;;;;; without notice. The contents of this file are also auto-generated and
-;;;;;; not user editable; it may be overwritten at any time.
+(allow iokit-open
+	(iokit-user-client-class "RootDomainUserClient"))
 
-;;; Allow read access to standard system paths.
-
-(allow file-read*
-       (require-all (file-mode #o0004)
-                    (require-any (subpath "/System")
-                                 (subpath "/usr/lib")
-                                 (subpath "/usr/sbin")
-                                 (subpath "/usr/share"))))
-
-(allow file-read-metadata
-       (literal "/etc")
-       (literal "/tmp")
-       (literal "/var"))
-
-;;; Allow access to standard special files.
-
-(allow file-read*
-       (subpath "/usr/share")
-       (subpath "/private/var/db/timezone")
-       (literal "/dev/random")
-       (literal "/dev/urandom"))
+(allow mach-lookup
+	(global-name "com.apple.PowerManagement.control")
+	(global-name "com.apple.SecurityServer")
+	(global-name "com.apple.SystemConfiguration.configd")
+	(global-name "com.apple.nehelper")
+	(global-name "com.apple.securityd.xpc")
+	(global-name "com.apple.ocspd")
+	(global-name "com.apple.aggregated")
+	(global-name "com.apple.cfprefsd.daemon")
+	(global-name "com.apple.cfprefsd.agent")
+	(local-name "com.apple.cfprefsd.agent")
+	(global-name "com.apple.securityd")
+	(global-name "com.apple.bsd.dirhelper")
+	(global-name "com.apple.system.logger")
+	(global-name "com.apple.system.notification_center")
+	(global-name "com.apple.system.libinfo.muser"))
 
-(allow file-read*
-       file-write-data
-       (literal "/dev/null")
-       (literal "/dev/zero"))
+(allow network*
+	(local udp "*:500" "*:4500")
+	(remote udp "*:*"))
 
-(allow file-read*
-       file-write-data
-       file-ioctl
-       (literal "/dev/aes_0")
-       (literal "/dev/sha1_0")
-       (literal "/dev/dtracehelper"))
+(allow network-inbound
+	(path "/private/var/run/vpncontrol.sock"))
 
+;;; Allow read access to standard system paths.
 (allow network-outbound
-       (literal "/private/var/run/asl_input")
-       (literal "/private/var/run/syslog"))
+	(literal "/private/var/run/asl_input")
+	(literal "/private/var/run/syslog")
+	(subpath "/private/var/tmp/launchd"))
 
-;;; Allow IPC to standard system agents.
-
-(allow mach-lookup
-       (global-name "com.apple.securityd")
-       (global-name "com.apple.bsd.dirhelper")
-       (global-name "com.apple.system.logger")
-       (global-name "com.apple.system.notification_center"))
-       
-;;; Allow creating an ipsec interface
-       (allow network-outbound
-       (control-name "com.apple.net.ipsec_control"))
+(allow sysctl-write
+	(sysctl-name "kern.ipc.maxsockbuf")
+	(sysctl-name "net.inet.ipsec.esp_port"))
 
 ;;; Allow racoon to check entitlements
-       (allow iokit-open
-       (iokit-user-client-class "AppleMobileFileIntegrityUserClient"))
+(allow iokit-open
+	(iokit-user-client-class "AppleMobileFileIntegrityUserClient"))
\ No newline at end of file
-- 
2.47.2