]> git.saurik.com Git - apple/ipsec.git/blobdiff - ipsec-tools/racoon/pfkey_racoon.c
ipsec-332.100.1.tar.gz
[apple/ipsec.git] / ipsec-tools / racoon / pfkey_racoon.c
index f977c029b251a73444a4dd2664a7999b47dd54d6..57c2fa9e279b907ee50452dec8b03056c76dca45 100644 (file)
 #include "vpn_control.h"
 #include "vpn_control_var.h"
 #include "ike_session.h"
-#include "ipsecSessionTracer.h"
-#include "ipsecMessageTracer.h"
 #include "power_mgmt.h"
 #include "session.h"
-#include "ikev2_rfc.h"
-#include "api_support.h"
 
 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
 #define SADB_X_EALG_AESCBC  SADB_X_EALG_RIJNDAELCBC
@@ -159,15 +155,14 @@ NULL,     /* SADB_X_SPDSETIDX */
 pk_recvspdexpire,
 NULL,  /* SADB_X_SPDDELETE2 */
 pk_recvgetsastat, /* SADB_GETSASTAT */
-NULL,  /* SADB_X_NAT_T_NEW_MAPPING */
-NULL, /* SADB_X_MIGRATE */
-#if (SADB_MAX > 25)
-#error "SADB extra message?"
+NULL,  /* SADB_X_SPDENABLE */
+NULL, /* SADB_X_SPDDISNABLE */
+NULL, /* SADB_MIGRATE */
+#if (SADB_MAX > 26)
+#warning "SADB extra message?"
 #endif
 };
 
-static int addnewsp (caddr_t *);
-
 /* cope with old kame headers - ugly */
 #ifndef SADB_X_AALG_MD5
 #define SADB_X_AALG_MD5                SADB_AALG_MD5   
@@ -224,7 +219,7 @@ pfkey_process(msg)
                /* when SPD is empty, treat the state as no error. */
                if (msg->sadb_msg_type == SADB_X_SPDDUMP &&
                    msg->sadb_msg_errno == ENOENT)
-                       pri = ASL_LEVEL_DEBUG;
+                       pri = ASL_LEVEL_NOTICE;
                else
                        pri = ASL_LEVEL_ERR;
 
@@ -234,7 +229,6 @@ pfkey_process(msg)
                        strerror(msg->sadb_msg_errno));
                goto end;
        }
-
     
        /* safety check */
        if (msg->sadb_msg_type >= ARRAYLEN(pkrecvf)) {
@@ -245,7 +239,7 @@ pfkey_process(msg)
        }
 
        if (pkrecvf[msg->sadb_msg_type] == NULL) {
-               plog(ASL_LEVEL_INFO
+               plog(ASL_LEVEL_NOTICE
                        "unsupported PF_KEY message %s\n",
                        s_pfkey_type(msg->sadb_msg_type));
                goto end;
@@ -275,7 +269,7 @@ pfkey_handler(void *unused)
        ssize_t len;
 
        if (slept_at || woke_at) {
-               plog(ASL_LEVEL_DEBUG, 
+               plog(ASL_LEVEL_DEBUG,
                         "ignoring pfkey port until power-mgmt event is handled.\n");
                return;
        }
@@ -292,7 +286,7 @@ pfkey_handler(void *unused)
                        return;                 
                } else {
                        /* short message - msg not ready */
-                       plog(ASL_LEVEL_DEBUG, "recv short message from pfkey\n");
+                       plog(ASL_LEVEL_NOTICE, "recv short message from pfkey\n");
                        return;
                }
        }
@@ -306,7 +300,7 @@ pfkey_post_handler()
        struct saved_msg_elem *elem_tmp = NULL;
 
        if (slept_at || woke_at) {
-               plog(ASL_LEVEL_DEBUG, 
+               plog(ASL_LEVEL_NOTICE,
                         "ignoring (saved) pfkey messages until power-mgmt event is handled.\n");
                return;
        }
@@ -794,6 +788,7 @@ pfkey_convertfromipsecdoi(iph2, proto_id, t_id, hashtype,
                if ((*a_keylen = keylen_aalg(hashtype)) == ~0)
                        goto bad;
                *a_keylen >>= 3;
+                       
                if (*e_type == SADB_EALG_NONE) {
                        plog(ASL_LEVEL_ERR, "no ESP algorithm.\n");
                        goto bad;
@@ -1096,7 +1091,6 @@ pk_sendupdate(iph2)
        u_int wsize = 4;  /* XXX static size of window */ 
        int proxy = 0;
        struct ph2natt natt;
-    struct satrns *tr;
     int authtype;
 
        /* sanity check */
@@ -1296,7 +1290,6 @@ pk_recvupdate(mhp)
                         iph2->status);
                return -1;
        }
-    //%%%% fix for IKEv2
        if (iph2->status != IKEV1_STATE_QUICK_I_ADDSA &&
         iph2->status != IKEV1_STATE_QUICK_R_ADDSA) {
                plog(ASL_LEVEL_ERR,
@@ -1330,11 +1323,14 @@ pk_recvupdate(mhp)
                                    sa->sadb_sa_spi,
                                    sa_mode));
 
-                       plog(ASL_LEVEL_INFO, 
-                               "IPsec-SA established: %s\n",
-                               sadbsecas2str(iph2->dst, iph2->src,
-                                       msg->sadb_msg_satype, sa->sadb_sa_spi,
-                                       sa_mode));
+                       plog(ASL_LEVEL_NOTICE, 
+                                "IPsec-SA established (update): satype=%u spi=%#x mode=%u\n",
+                                msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
+                       plog(ASL_LEVEL_DEBUG,
+                                "IPsec-SA established (update): %s\n",
+                                sadbsecas2str(iph2->dst, iph2->src,
+                                                          msg->sadb_msg_satype, sa->sadb_sa_spi,
+                                                          sa_mode));
                }
 
                if (pr->ok == 0)
@@ -1350,18 +1346,6 @@ pk_recvupdate(mhp)
        /* update status */
        fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_ESTABLISHED);
 
-       if (iph2->side == INITIATOR) {
-               IPSECSESSIONTRACEREVENT(iph2->parent_session,
-                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_SUCC,
-                                                               CONSTSTR("Initiator, Quick-Mode"),
-                                                               CONSTSTR(NULL));
-       } else {
-               IPSECSESSIONTRACEREVENT(iph2->parent_session,
-                                                               IPSECSESSIONEVENTCODE_IKEV1_PH2_RESP_SUCC,
-                                                               CONSTSTR("Responder, Quick-Mode"),
-                                                               CONSTSTR(NULL));
-       }
-
        ike_session_ph2_established(iph2);
 
        IPSECLOGASLMSG("IPSec Phase 2 established (Initiated by %s).\n",
@@ -1409,7 +1393,6 @@ pk_sendadd(iph2)
        u_int wsize = 4; /* XXX static size of window */ 
        int proxy = 0;
        struct ph2natt natt;
-    struct satrns *tr;
     int authtype;
 
        /* sanity check */
@@ -1613,8 +1596,11 @@ pk_recvadd(mhp)
         * because they must be updated by SADB_UPDATE message
         */
 
-       plog(ASL_LEVEL_INFO, 
-               "IPsec-SA established: %s\n",
+       plog(ASL_LEVEL_NOTICE,
+                "IPsec-SA established (add): satype=%u spi=%#x mode=%u\n",
+                msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
+       plog(ASL_LEVEL_DEBUG,
+               "IPsec-SA established (add): %s\n",
                sadbsecas2str(iph2->src, iph2->dst,
                        msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
                        
@@ -1622,12 +1608,6 @@ pk_recvadd(mhp)
        
 #ifdef ENABLE_VPNCONTROL_PORT
                {
-                       u_int32_t address;
-                       
-                       if (iph2->dst->ss_family == AF_INET)
-                               address = ((struct sockaddr_in *)iph2->dst)->sin_addr.s_addr;
-                       else
-                               address = 0;
                        vpncontrol_notify_phase_change(0, FROM_LOCAL, NULL, iph2);
                }       
 #endif
@@ -1673,7 +1653,10 @@ pk_recvexpire(mhp)
                return -1;
        }
 
-       plog(ASL_LEVEL_INFO, 
+       plog(ASL_LEVEL_NOTICE,
+                "IPsec-SA expired: satype=%u spi=%#x mode=%u\n",
+                msg->sadb_msg_satype, ntohl(sa->sadb_sa_spi), sa_mode);
+       plog(ASL_LEVEL_DEBUG,
                "IPsec-SA expired: %s\n",
                sadbsecas2str(src, dst,
                        msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
@@ -1709,31 +1692,29 @@ pk_recvexpire(mhp)
 
        /* turn off the timer for calling isakmp_ph2expire() */ 
        SCHED_KILL(iph2->sce);
+       
+       fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
+       
+       /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
+       /* allocate buffer for status management of pfkey message */
+       if (iph2->side == INITIATOR &&
+               !ike_session_has_other_established_ph2(iph2->parent_session, iph2) &&
+               !ike_session_drop_rekey(iph2->parent_session, IKE_SESSION_REKEY_TYPE_PH2)) {
+
+               ike_session_initph2(iph2);
+
+               /* start isakmp initiation by using ident exchange */
+               if (isakmp_post_acquire(iph2) < 0) {
+                       plog(ASL_LEVEL_ERR,
+                               "failed to begin ipsec sa "
+                               "re-negotiation.\n");
+                       ike_session_unlink_phase2(iph2);
+                       return -1;
+               }
 
-               fsm_set_state(&iph2->status, IKEV1_STATE_PHASE2_EXPIRED);
-
-    {
-        /* INITIATOR, begin phase 2 exchange only if there's no other established ph2. */
-        /* allocate buffer for status management of pfkey message */
-        if (iph2->side == INITIATOR &&
-            !ike_session_has_other_established_ph2(iph2->parent_session, iph2) &&
-            !ike_session_drop_rekey(iph2->parent_session, IKE_SESSION_REKEY_TYPE_PH2)) {
-
-            ike_session_initph2(iph2);
-
-            /* start isakmp initiation by using ident exchange */
-            if (isakmp_post_acquire(iph2) < 0) {
-                plog(ASL_LEVEL_ERR,
-                    "failed to begin ipsec sa "
-                    "re-negotiation.\n");
-                ike_session_unlink_phase2(iph2);
-                return -1;
-            }
-
-            return 0;
-            /*NOTREACHED*/
-        }
-    }
+               return 0;
+               /*NOTREACHED*/
+       }
 
 
        /* If not received SADB_EXPIRE, INITIATOR delete ph2handle. */
@@ -1910,6 +1891,7 @@ pk_recvacquire(mhp)
 
        iph2->satype = msg->sadb_msg_satype;
        iph2->seq = msg->sadb_msg_seq;
+       vpncontrol_set_nat64_prefix(&iph2->nat64_prefix);
        /* set end addresses of SA */
                                                 // Wcast_align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
        iph2->src = dupsaddr(ALIGNED_CAST(struct sockaddr_storage *)PFKEY_ADDR_SADDR(mhp[SADB_EXT_ADDRESS_SRC]));
@@ -1989,13 +1971,13 @@ pk_recvacquire(mhp)
                goto err;
        }
        
-#if !TARGET_OS_EMBEDDED
+#if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
        if ( lcconf->vt == NULL){
                if (!(lcconf->vt = vproc_transaction_begin(NULL)))
                        plog(ASL_LEVEL_ERR, 
                                "vproc_transaction_begin returns NULL.\n");
        }
-#endif                         
+#endif // !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
 
        
        return 0;
@@ -2931,13 +2913,14 @@ pk_getseq()
        return eay_random();
 }
 
-static int
+int
 addnewsp(mhp)
        caddr_t *mhp;
 {
        struct secpolicy *new;
        struct sadb_address *saddr, *daddr;
        struct sadb_x_policy *xpl;
+       struct sadb_ext *ext;
 
        /* sanity check */
        if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
@@ -2950,7 +2933,14 @@ addnewsp(mhp)
 
        saddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];    // Wcast-align fix (void*) - mhp contains pointers to aligned structs in malloc'd msg buffer
        daddr = ALIGNED_CAST(struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
+
        xpl = ALIGNED_CAST(struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
+       /* validity check */
+       if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
+               plog(ASL_LEVEL_ERR,
+                       "invalid msg length.\n");
+               return -1;
+       }
 
        new = newsp();
        if (new == NULL) {
@@ -2979,17 +2969,16 @@ addnewsp(mhp)
                struct sadb_x_ipsecrequest *xisr;
                struct ipsecrequest **p_isr = &new->req;
 
-               /* validity check */
-               if (PFKEY_EXTLEN(xpl) < sizeof(*xpl)) {
-                       plog(ASL_LEVEL_ERR, 
-                               "invalid msg length.\n");
-                       return -1;
-               }
-
                tlen = PFKEY_EXTLEN(xpl) - sizeof(*xpl);
                xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
 
                while (tlen > 0) {
+                       if (tlen < sizeof(*xisr) ||
+                               tlen < xisr->sadb_x_ipsecrequest_len) {
+                               plog(ASL_LEVEL_ERR,
+                                       "invalid msg length for ipsec request.\n");
+                               return -1;
+                       }
 
                        /* length check */
                        if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
@@ -3056,13 +3045,28 @@ addnewsp(mhp)
                        /* set IP addresses if there */
                        if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
                                struct sockaddr *paddr;
+                               int rem_buf_len = xisr->sadb_x_ipsecrequest_len - sizeof(*xisr);
 
                                paddr = (struct sockaddr *)(xisr + 1);
+                               if (rem_buf_len < sizeof(*paddr) ||
+                                       rem_buf_len < sysdep_sa_len(paddr)) {
+                                       plog(ASL_LEVEL_ERR,
+                                               "invalid msg length for src ip address.\n");
+                                       return -1;
+                               }
                                bcopy(paddr, &(*p_isr)->saidx.src,
                                        sysdep_sa_len(paddr));
 
+                               rem_buf_len -= sysdep_sa_len(paddr);
+
                                paddr = (struct sockaddr *)((caddr_t)paddr
                                                        + sysdep_sa_len(paddr));
+                               if (rem_buf_len < sizeof(*paddr) ||
+                                       rem_buf_len < sysdep_sa_len(paddr)) {
+                                       plog(ASL_LEVEL_ERR,
+                                               "invalid msg length for dst ip address.\n");
+                                       return -1;
+                               }
                                bcopy(paddr, &(*p_isr)->saidx.dst,
                                        sysdep_sa_len(paddr));
                        }
@@ -3087,6 +3091,7 @@ addnewsp(mhp)
        default:
                plog(ASL_LEVEL_ERR, 
                        "invalid policy type.\n");
+               delsp(new);
                return -1;
        }