From e97d2cf9e57aa916003425bfe70d778860032d0f Mon Sep 17 00:00:00 2001 From: Apple Date: Mon, 21 Mar 2011 20:59:57 +0000 Subject: [PATCH] ipsec-93.13.tar.gz --- ipsec-tools/racoon/isakmp_quick.c | 19 ++-------- ipsec-tools/racoon/main.c | 4 +-- ipsec-tools/racoon/oakley.c | 6 +++- ipsec-tools/racoon/policy.c | 58 +++++++++++++++++++++++++++++-- ipsec-tools/racoon/policy.h | 2 +- ipsec-tools/racoon/session.c | 49 +++++++++++++++++++++++++- 6 files changed, 113 insertions(+), 25 deletions(-) diff --git a/ipsec-tools/racoon/isakmp_quick.c b/ipsec-tools/racoon/isakmp_quick.c index 2b73f65..4c37b4d 100644 --- a/ipsec-tools/racoon/isakmp_quick.c +++ b/ipsec-tools/racoon/isakmp_quick.c @@ -2597,7 +2597,7 @@ get_proposal_r_remote(iph2, use_remote_addr) spidx.ul_proto = IPSEC_ULPROTO_ANY; /* get inbound policy */ - sp_in = getsp_r(&spidx); + sp_in = getsp_r(&spidx, iph2); if (sp_in == NULL || sp_in->policy == IPSEC_POLICY_GENERATE) { if (iph2->ph1->rmconf->gen_policy) { if (sp_in) @@ -2622,21 +2622,6 @@ get_proposal_r_remote(iph2, use_remote_addr) "no policy found: %s\n", spidx2str(&spidx)); return ISAKMP_INTERNAL_ERROR; } - } else { - /* Refresh existing generated policies - */ - if (iph2->ph1->rmconf->gen_policy) { - plog(LLV_INFO, LOCATION, NULL, - "Update the generated policy : %s\n", - spidx2str(&spidx)); - iph2->spidx_gen = racoon_malloc(sizeof(spidx)); - if (!iph2->spidx_gen) { - plog(LLV_ERROR, LOCATION, NULL, - "buffer allocation failed.\n"); - return ISAKMP_INTERNAL_ERROR; - } - memcpy(iph2->spidx_gen, &spidx, sizeof(spidx)); - } } /* get outbound policy */ @@ -2652,7 +2637,7 @@ get_proposal_r_remote(iph2, use_remote_addr) spidx.prefs = spidx.prefd; spidx.prefd = pref; - sp_out = getsp_r(&spidx); + sp_out = getsp_r(&spidx, iph2); if (!sp_out) { plog(LLV_WARNING, LOCATION, NULL, "no outbound policy found: %s\n", diff --git a/ipsec-tools/racoon/main.c b/ipsec-tools/racoon/main.c index 7d4827e..0c16d83 100644 --- a/ipsec-tools/racoon/main.c +++ b/ipsec-tools/racoon/main.c @@ -108,7 +108,7 @@ static void restore_params __P((void)); static void save_params __P((void)); static void saverestore_params __P((int)); static void cleanup_pidfile __P((void)); -static int launchedbylaunchd(void); +int launchedbylaunchd __P((void)); pid_t racoon_pid = 0; int print_pid = 1; /* for racoon only */ @@ -391,7 +391,7 @@ skip: } -static int +int launchedbylaunchd(){ int launchdlaunched = 1; launch_data_t checkin_response = NULL; diff --git a/ipsec-tools/racoon/oakley.c b/ipsec-tools/racoon/oakley.c index 0fad2e6..5e888c1 100644 --- a/ipsec-tools/racoon/oakley.c +++ b/ipsec-tools/racoon/oakley.c @@ -2655,6 +2655,10 @@ oakley_savecr(iph1, gen) case ISAKMP_CERT_X509SIGN: case ISAKMP_CERT_KERBEROS: case ISAKMP_CERT_SPKI: + if (iph1->cr_p) { + oakley_delcert(iph1->cr_p); + iph1->cr_p = NULL; + } c = &iph1->cr_p; break; case ISAKMP_CERT_X509KE: @@ -3297,7 +3301,7 @@ oakley_delcert(cert) VPTRINIT(cert->pl); racoon_free(cert); } - + /* * compute IV and set to ph1handle * IV = hash(g^xi | g^xr) diff --git a/ipsec-tools/racoon/policy.c b/ipsec-tools/racoon/policy.c index 82d6981..d9bb5de 100644 --- a/ipsec-tools/racoon/policy.c +++ b/ipsec-tools/racoon/policy.c @@ -90,14 +90,66 @@ getsp(spidx) */ #if 1 struct secpolicy * -getsp_r(spidx) +getsp_r(spidx, iph2) struct policyindex *spidx; + struct ph2handle *iph2; { struct secpolicy *p; + int mismatched_outer_addr = 0; for (p = TAILQ_FIRST(&sptree); p; p = TAILQ_NEXT(p, chain)) { - if (!cmpspidxwild(spidx, &p->spidx)) - return p; + if (!cmpspidxwild(spidx, &p->spidx)) { + if (spidx->dir != IPSEC_DIR_ANY) { + struct ipsecrequest *isr; + for (isr = p->req; isr != NULL; isr = isr->next) { + if (isr->saidx.mode != IPSEC_MODE_TUNNEL) { + plog(LLV_DEBUG2, LOCATION, NULL, "%s, skipping policy. dir %d, mode %d\n", + __FUNCTION__, spidx->dir, isr->saidx.mode); + continue; + } + + // for tunnel mode: verify the outer ip addresses match the phase2's addresses + if (spidx->dir == IPSEC_DIR_INBOUND) { + // TODO: look out for wildcards + if (!cmpsaddrwop(iph2->dst, (struct sockaddr *)&isr->saidx.src) && + !cmpsaddrwop(iph2->src, (struct sockaddr *)&isr->saidx.dst)) { + plog(LLV_DEBUG2, LOCATION, NULL, "%s, inbound policy outer addresses matched phase2's addresses\n", + __FUNCTION__); + return p; + } else { + mismatched_outer_addr = 1; + } + } else if (spidx->dir == IPSEC_DIR_OUTBOUND) { + // TODO: look out for wildcards + if (!cmpsaddrwop(iph2->src, (struct sockaddr *)&isr->saidx.src) && + !cmpsaddrwop(iph2->dst, (struct sockaddr *)&isr->saidx.dst)) { + plog(LLV_DEBUG2, LOCATION, NULL, "%s, outbound policy outer addresses matched phase2's addresses\n", + __FUNCTION__); + return p; + } else { + mismatched_outer_addr = 1; + } + } else { + mismatched_outer_addr = 1; + } + if (mismatched_outer_addr) { + plog(LLV_DEBUG2, LOCATION, NULL, "%s, policy outer addresses matched phase2's addresses: dir %d\n", + __FUNCTION__, spidx->dir); + plog(LLV_DEBUG, LOCATION, NULL, "src1: %s\n", + saddr2str(iph2->src)); + plog(LLV_DEBUG, LOCATION, NULL, "src2: %s\n", + saddr2str((struct sockaddr *)&isr->saidx.src)); + plog(LLV_DEBUG, LOCATION, NULL, "dst1: %s\n", + saddr2str(iph2->dst)); + plog(LLV_DEBUG, LOCATION, NULL, "dst2: %s\n", + saddr2str((struct sockaddr *)&isr->saidx.dst)); + } + } + } + if (!mismatched_outer_addr) { + return p; + } + } } return NULL; diff --git a/ipsec-tools/racoon/policy.h b/ipsec-tools/racoon/policy.h index 858b4b7..48904b0 100644 --- a/ipsec-tools/racoon/policy.h +++ b/ipsec-tools/racoon/policy.h @@ -117,7 +117,7 @@ do { \ struct ph2handle; struct policyindex; extern struct secpolicy *getsp __P((struct policyindex *)); -extern struct secpolicy *getsp_r __P((struct policyindex *)); +extern struct secpolicy *getsp_r __P((struct policyindex *, struct ph2handle *)); struct secpolicy *getspbyspid __P((u_int32_t)); extern int cmpspidxstrict __P((struct policyindex *, struct policyindex *)); extern int cmpspidxwild __P((struct policyindex *, struct policyindex *)); diff --git a/ipsec-tools/racoon/session.c b/ipsec-tools/racoon/session.c index c5c98da..64a4668 100644 --- a/ipsec-tools/racoon/session.c +++ b/ipsec-tools/racoon/session.c @@ -70,6 +70,9 @@ #include #include +#if __APPLE__ +#include +#endif #include "libpfkey.h" @@ -108,6 +111,7 @@ extern pid_t racoon_pid; +extern int launchedbylaunchd(void); static void close_session __P((void)); static void check_rtsock __P((void *)); static void initfds __P((void)); @@ -140,6 +144,35 @@ reinit_socks (void) initfds(); } +#ifdef __APPLE__ +static int64_t racoon_keepalive = -1; + +/* + * This is used to (manually) update racoon's launchd keepalive, which is needed because racoon is (mostly) + * launched on demand and for requires a keepalive on dirty/failure exits. + * The launchd plist can't be used for this because RunOnLoad is required to have keepalive on a failure exit. + */ +int64_t +launchd_update_racoon_keepalive (Boolean enabled) +{ + if (launchedbylaunchd()) { + vproc_t vp = vprocmgr_lookup_vproc("com.apple.racoon"); + if (vp) { + int64_t val = (__typeof__(val))enabled; + if (vproc_swap_integer(vp, + VPROC_GSK_BASIC_KEEPALIVE, + &val, + &racoon_keepalive)) { + plog(LLV_ERROR2, LOCATION, NULL, + "failed to swap launchd keepalive integer %d\n", enabled); + } + vproc_release(vp); + } + } + return racoon_keepalive; +} +#endif // __APPLE__ + int session(void) { @@ -226,7 +259,14 @@ session(void) "cannot open %s", pid_file); } } - + +#ifdef __APPLE__ +#if !TARGET_OS_EMBEDDED + // enable keepalive for recovery (from crashes and bad exits... after init) + (void)launchd_update_racoon_keepalive(true); +#endif // !TARGET_OS_EMBEDDED +#endif // __APPLE__ + while (1) { if (!TAILQ_EMPTY(&lcconf->saved_msg_queue)) pfkey_post_handler(); @@ -340,6 +380,13 @@ close_session() close_sockets(); backupsa_clean(); +#ifdef __APPLE__ +#if !TARGET_OS_EMBEDDED + // a clean exit, so disable launchd keepalive + (void)launchd_update_racoon_keepalive(false); +#endif // !TARGET_OS_EMBEDDED +#endif // __APPLE__ + plog(LLV_INFO, LOCATION, NULL, "racoon shutdown\n"); exit(0); } -- 2.47.2