]> git.saurik.com Git - apple/ipsec.git/commitdiff
ipsec-305.tar.gz macos-1012 os-x-1012 v305
authorApple <opensource@apple.com>
Thu, 22 Sep 2016 17:57:34 +0000 (17:57 +0000)
committerApple <opensource@apple.com>
Thu, 22 Sep 2016 17:57:34 +0000 (17:57 +0000)
entitlements.plist
ipsec-tools/Common/pfkey.c
ipsec-tools/racoon/com.apple.racoon.plist
ipsec-tools/racoon/crypto_cssm.c
ipsec-tools/racoon/main.c
ipsec-tools/racoon/session.c
ipsec-tools/racoon/session.h
ipsec-tools/racoon/vpn.c
ipsec-tools/racoon/vpn_control.c
ipsec-tools/racoon/vpn_control_var.h
racoon.sb

index bb6a89a0491c98f54f24cfe4a305e68f99d4a90f..a630f63bd3249651d6bccbe3daba6aa5c29d6cb2 100644 (file)
@@ -18,5 +18,7 @@
        </array>
        <key>com.apple.private.nehelper.privileged</key>
        <true/>
        </array>
        <key>com.apple.private.nehelper.privileged</key>
        <true/>
+       <key>com.apple.private.system-keychain</key>
+       <true/>
 </dict>
 </plist>
 </dict>
 </plist>
index 2a8a765d2e720844f19fe4ce290787c95c886a31..3330ec7b1dd59bb8f779d77e1ae212bcf73051dc 100644 (file)
@@ -51,6 +51,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
+#include <ifaddrs.h>
 
 #include "var.h"
 #include "ipsec_strerror.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)
 {
               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 len;
+       int ret = -1;
        caddr_t p;
        int plen;
        caddr_t ep;
        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;
        }
 
                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)
        /* 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_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));
                
        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));
 
        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;
 
        }
        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);
                             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) {
                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) {
        }
        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) {
        }
        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) {
        }
        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) {
        }
 
        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) {
                }
        }
        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) {
        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) {
        }
        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) {
        }
        
        if (p != ep) {
-               free(newmsg);
-               return -1;
+               goto err;
        }
 
        /* send message */
        len = pfkey_send(so, newmsg, len);
        }
 
        /* 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;
 
        __ipsec_errcode = EIPSEC_NO_ERROR;
-       return len;
+       ret = len;
+       
+err:
+       if (ifap != NULL) {
+               freeifaddrs(ifap);
+       }
+
+       if (newmsg != NULL) {
+               free(newmsg);
+       }
+
+       return ret;
 }
 
 
 }
 
 
index f0c233ba9bc42df47b1dd9f286017460c0771f16..c5f03e74b440392ef39510b2989cd2479873272e 100644 (file)
Binary files a/ipsec-tools/racoon/com.apple.racoon.plist and b/ipsec-tools/racoon/com.apple.racoon.plist differ
index 1b28547f0d5f6b4582c7ac226990750aa76dcaa9..e8fdc98b0c8929d5f051aaf227b8cd5cac4d28e8 100644 (file)
@@ -34,6 +34,7 @@
 #include <Security/SecIdentity.h>
 #include <Security/SecItem.h>
 #include <TargetConditionals.h>
 #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>
 #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;
 
 
        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
        
     
 #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;
        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,
        
        /* 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;
     
        if (persistFind == NULL)
                goto end;
     
-    status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
+       status = SecItemCopyMatching(persistFind, (CFTypeRef *)&identityRef);
        if (status != noErr)
                goto end;
 
        if (status != noErr)
                goto end;
 
index 631b86c9828dbe93b7a5507ff80b27633507ded0..4d654cbd286757c7adedbf44d3d600f53ef740e1 100644 (file)
 #include "crypto_openssl.h"
 #include "vendorid.h"
 
 #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"
 #include <CoreFoundation/CoreFoundation.h>
 #include "power_mgmt.h"
 #include "preferences.h"
@@ -150,17 +155,21 @@ main(ac, av)
 {
        int error;
 
 {
        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();
 
        /*
         * 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*/
        if (geteuid() != 0) {
                errx(1, "must be root to invoke this program.");
                /* NOTREACHED*/
index 11915b2133ea467fa3daf74ced598336ae89d948..1f9dee4a883d4a805e9827c787a0a19de5f9aefc 100644 (file)
@@ -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 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 *);
 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;
 
 static volatile sig_atomic_t sigreq[NSIG + 1];
 int terminated = 0;
+int pending_signal_handle = 0;
 
 static int64_t racoon_keepalive = -1;
 
 
 static int64_t racoon_keepalive = -1;
 
@@ -482,7 +482,7 @@ static int signals[] = {
 };
 
 
 };
 
 
-static void
+void
 check_sigreq()
 {
        int sig;
 check_sigreq()
 {
        int sig;
@@ -603,9 +603,14 @@ signal_handler(int sig, siginfo_t *sigi, void *ctx)
     if ( sig == SIGTERM ){
         terminated = 1;
     }
     if ( sig == SIGTERM ){
         terminated = 1;
     }
+
+       pending_signal_handle = 1;
     dispatch_async(main_queue, 
                    ^{
     dispatch_async(main_queue, 
                    ^{
-                        check_sigreq(); 
+                                               if (pending_signal_handle) {
+                                                       check_sigreq();
+                                                       pending_signal_handle = 0;
+                                               }
                    });
 }
 
                    });
 }
 
index b17ca707ca1a0abff921c6e96f18b518a9602330..78424e1dcf3b9cd5cbe1cb4fe4c0b2644b7d6ecd 100644 (file)
 
 #include "handler.h"
 
 
 #include "handler.h"
 
+extern int pending_signal_handle;
+
 extern void session (void);
 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);
 extern RETSIGTYPE signal_handler (int, siginfo_t *, void *);
 extern void check_auto_exit (void);
 extern void dying (void);
index 054842946783148685f3bba09e821e9b77c0ddd5..393e4d3bddf3f2503d2c2680862eaa862e7a4c67 100644 (file)
@@ -245,7 +245,7 @@ vpn_disconnect(struct bound_addr *srv, const char *reason)
 }
 
 int
 }
 
 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;
 {
        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);
        }
 
        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));
        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();
 
        for (i = 0; i < ntohs(pkt->selector_count); i++, selector_ptr++) {
                new_sainfo = create_sainfo();
index 35be49158c2f3c716f7374be117a8d976f973ee7..1b70dd2daec25b91fa1947d030be432ee031f229 100644 (file)
@@ -119,7 +119,7 @@ gid_t vpncontrolsock_group = 0;
 mode_t vpncontrolsock_mode = 0600;
 
 static struct sockaddr_un sunaddr;
 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);
 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;
        }
 
                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)
 
 end:
        if (combuf)
@@ -325,7 +331,7 @@ end:
 }
 
 static int
 }
 
 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;
 {
        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:
                        {
        
                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;
                                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");
                        
                                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:
                        {
                        
                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;
                                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:
                        {
 
                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;
                                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:
                        {
 
                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;
 
                                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) {
                                        "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:
                        {
 
                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;
                                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:
                        {
 
                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;
 
                                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) {
                                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:
                        {
                        
                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;
                                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:
                        {
                        
                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;
                                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 */
                                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;
                                        }
                                }
                                                break;
                                        }
                                }
@@ -515,6 +590,12 @@ vpncontrol_process(struct vpnctl_socket_elem *elem, char *combuf)
 
                case VPNCTL_CMD_START_DPD:
             {
 
                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;
                 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:
                        {
 
                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;
                                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:
                        {
 
                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;
                                struct vpnctl_cmd_connect *pkt = ALIGNED_CAST(struct vpnctl_cmd_connect *)combuf;
                                struct bound_addr *addr;
                                struct bound_addr *t_addr;
index ee9b47fc73e9d94f5885c80cfcb3bad5dc97e8dc..bd52157698f1f1af4f336c0b84648970f0b960b8 100644 (file)
@@ -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_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*);
 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*);
index ec523137f423882d3f832e0ea9409f2918f69c6c..34e24592def1cb2fe7e394706138a234f0b35578 100644 (file)
--- a/racoon.sb
+++ b/racoon.sb
 
 (allow system-info (info-type "net.link.addr"))
 
 
 (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*
 (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
 (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 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