diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/ip_ipsp.c | 78 | ||||
-rw-r--r-- | sys/netinet/ip_ipsp.h | 5 | ||||
-rw-r--r-- | sys/netinet/ip_spd.c | 473 |
3 files changed, 164 insertions, 392 deletions
diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 87018272ac8..14aa50126b2 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.c,v 1.128 2001/06/05 11:31:31 angelos Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.129 2001/06/07 16:19:47 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -315,11 +315,7 @@ gettdbbyaddr(union sockaddr_union *dst, struct ipsec_policy *ipo, { if (ipo->ipo_srcid != NULL) { - if ((tdbp->tdb_srcid->ref_type != - ipo->ipo_srcid->ref_type) || - (tdbp->tdb_srcid->ref_len != ipo->ipo_srcid->ref_len) || - (bcmp(tdbp->tdb_srcid + 1, ipo->ipo_srcid + 1, - ipo->ipo_srcid->ref_len))) + if (!ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_srcid)) continue; } @@ -333,11 +329,7 @@ gettdbbyaddr(union sockaddr_union *dst, struct ipsec_policy *ipo, { if (ipo->ipo_dstid != NULL) { - if ((tdbp->tdb_dstid->ref_type != - ipo->ipo_dstid->ref_type) || - (tdbp->tdb_dstid->ref_len != ipo->ipo_dstid->ref_len) || - (bcmp(tdbp->tdb_dstid + 1, ipo->ipo_dstid + 1, - ipo->ipo_dstid->ref_len))) + if (!ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_dstid)) continue; } @@ -352,12 +344,8 @@ gettdbbyaddr(union sockaddr_union *dst, struct ipsec_policy *ipo, { if (ipo->ipo_local_cred != NULL) { - if ((tdbp->tdb_local_cred->ref_type != - ipo->ipo_local_cred->ref_type) || - (tdbp->tdb_local_cred->ref_len != - ipo->ipo_local_cred->ref_len) || - (bcmp(tdbp->tdb_local_cred + 1, ipo->ipo_local_cred + 1, - ipo->ipo_local_cred->ref_len))) + if (!ipsp_ref_match(ipo->ipo_local_cred, + tdbp->tdb_local_cred)) continue; } } @@ -404,63 +392,32 @@ gettdbbysrc(union sockaddr_union *src, struct ipsec_policy *ipo, */ if (tdbp->tdb_srcid != NULL) { - if (ipo->ipo_srcid != NULL) + if (ipo->ipo_dstid != NULL) { - if ((tdbp->tdb_srcid->ref_type != - ipo->ipo_srcid->ref_type) || - (tdbp->tdb_srcid->ref_len != ipo->ipo_srcid->ref_len) || - (bcmp(tdbp->tdb_srcid + 1, ipo->ipo_srcid + 1, - ipo->ipo_srcid->ref_len))) + if (!ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_srcid)) continue; } /* Otherwise, this is fine */ } else - if (ipo->ipo_srcid != NULL) + if (ipo->ipo_dstid != NULL) continue; if (tdbp->tdb_dstid != NULL) { - if (ipo->ipo_dstid != NULL) + if (ipo->ipo_srcid != NULL) { - if ((tdbp->tdb_dstid->ref_type != - ipo->ipo_dstid->ref_type) || - (tdbp->tdb_dstid->ref_len != ipo->ipo_dstid->ref_len) || - (bcmp(tdbp->tdb_dstid + 1, ipo->ipo_dstid + 1, - ipo->ipo_dstid->ref_len))) + if (!ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_dstid)) continue; } /* Otherwise, this is fine */ } else - if (ipo->ipo_dstid != NULL) + if (ipo->ipo_srcid != NULL) continue; - /* Check for credential matches */ - if (tdbp->tdb_local_cred != NULL) - { - if (ipo->ipo_local_cred != NULL) - { - if ((tdbp->tdb_local_cred->ref_type != - ipo->ipo_local_cred->ref_type) || - (tdbp->tdb_local_cred->ref_len != - ipo->ipo_local_cred->ref_len) || - (bcmp(tdbp->tdb_local_cred, ipo->ipo_local_cred + 1, - ipo->ipo_local_cred->ref_len))) - continue; - } - } - else - if (ipo->ipo_local_cred != NULL) - continue; /* If no credential was used in the TDB, try - * to establish a new SA with the given - * credential, since some type of access control - * may be done on the other side based on that - * credential. - */ - /* XXX Check for filter matches */ break; } @@ -1533,3 +1490,16 @@ ipsp_parse_headers(struct mbuf *m, int off, u_int8_t proto) } } } + +/* Return true if the two structures match. */ +int +ipsp_ref_match(struct ipsec_ref *ref1, struct ipsec_ref *ref2) +{ + if (ref1->ref_type != ref2->ref_type || + ref1->ref_len != ref2->ref_len || + bcmp(ref1 + 1, ref2 + 1, ref1->ref_len)) + return 0; + + return 1; +} + diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 4a284f628f0..988fcdb4244 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipsp.h,v 1.101 2001/06/01 07:56:46 angelos Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.102 2001/06/07 16:19:47 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -601,8 +601,6 @@ extern int ipsp_acquire_sa(struct ipsec_policy *, union sockaddr_union *, extern struct ipsec_policy *ipsec_add_policy(struct sockaddr_encap *, struct sockaddr_encap *, union sockaddr_union *, int, int); -extern int ipsp_match_policy(struct tdb *, struct ipsec_policy *, - struct mbuf *, int); extern int ipsec_delete_policy(struct ipsec_policy *); extern void ipsp_acquire_expirations(void *); extern struct ipsec_acquire *ipsp_pending_acquire(union sockaddr_union *); @@ -614,5 +612,6 @@ extern void ipsp_reffree(struct ipsec_ref *); extern void ipsp_skipcrypto_unmark(struct tdb_ident *); extern void ipsp_skipcrypto_mark(struct tdb_ident *); extern struct m_tag *ipsp_parse_headers(struct mbuf *, int, u_int8_t); +extern int ipsp_ref_match(struct ipsec_ref *, struct ipsec_ref *); #endif /* _KERNEL */ #endif /* _NETINET_IPSP_H_ */ diff --git a/sys/netinet/ip_spd.c b/sys/netinet/ip_spd.c index 09bd594d0bb..71e8bd72b41 100644 --- a/sys/netinet/ip_spd.c +++ b/sys/netinet/ip_spd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_spd.c,v 1.21 2001/05/30 12:22:15 angelos Exp $ */ +/* $OpenBSD: ip_spd.c,v 1.22 2001/06/07 16:19:47 angelos Exp $ */ /* * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) @@ -232,7 +232,6 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type != SENT_IPSP)) { - DPRINTF(("ipsp_spd_lookup(): no gw, or gw data not IPSP\n")); RTFREE(re->re_rt); *error = EHOSTUNREACH; return NULL; @@ -242,7 +241,6 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, RTFREE(re->re_rt); if (ipo == NULL) { - DPRINTF(("ipsp_spd_lookup(): no policy present\n")); *error = EHOSTUNREACH; return NULL; } @@ -269,72 +267,41 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, return NULL; } - /* - * Check for non-specific destination in the policy. If a specific - * destination was specified, use that -- otherwise, use the relevant - * information from the packet. - */ + /* Check for non-specific destination in the policy. */ switch (ipo->ipo_dst.sa.sa_family) { #ifdef INET case AF_INET: - if ((ipo->ipo_dst.sin.sin_addr.s_addr != INADDR_ANY) && - (ipo->ipo_dst.sin.sin_addr.s_addr != INADDR_BROADCAST)) - { - if (direction == IPSP_DIRECTION_OUT) - bcopy(&ipo->ipo_dst, &sdst, sizeof(union sockaddr_union)); - else - bcopy(&ipo->ipo_dst, &ssrc, sizeof(union sockaddr_union)); - } - else + if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) || + (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST)) dignore = 1; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - if ((!IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) && - (!bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, + if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) || + (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, sizeof(in6mask128)))) - { - if (direction == IPSP_DIRECTION_OUT) - bcopy(&ipo->ipo_dst, &sdst, sizeof(union sockaddr_union)); - else - bcopy(&ipo->ipo_dst, &ssrc, sizeof(union sockaddr_union)); - } - else dignore = 1; break; #endif /* INET6 */ } + /* Likewise for source. */ switch (ipo->ipo_src.sa.sa_family) { #ifdef INET case AF_INET: - if (ipo->ipo_src.sin.sin_addr.s_addr != INADDR_ANY) - { - if (direction == IPSP_DIRECTION_OUT) - bcopy(&ipo->ipo_src, &ssrc, sizeof(union sockaddr_union)); - else - bcopy(&ipo->ipo_src, &sdst, sizeof(union sockaddr_union)); - } - else - signore = 1; + if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY) + signore = 1; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - if (!IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr)) - { - if (direction == IPSP_DIRECTION_OUT) - bcopy(&ipo->ipo_src, &ssrc, sizeof(union sockaddr_union)); - else - bcopy(&ipo->ipo_src, &sdst, sizeof(union sockaddr_union)); - } - else - signore = 1; + if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr)) + signore = 1; break; #endif /* INET6 */ } @@ -359,57 +326,54 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) { /* Direct match */ - if (bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len) == 0) + if (!bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len) || dignore) { *error = 0; return NULL; } - - /* Same-host */ - switch (ipo->ipo_dst.sa.sa_family) - { -#ifdef INET - case AF_INET: - if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) || - (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST)) - { - *error = 0; - return NULL; - } - break; -#endif /* INET */ - -#ifdef INET6 - case AF_INET6: - if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr) || - !bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, - sizeof(in6mask128))) - { - *error = 0; - return NULL; - } - break; -#endif /* INET6 */ - } } /* Check that the cached TDB (if present), is appropriate */ if (ipo->ipo_tdb) { - if (bcmp(&sdst, &ipo->ipo_tdb->tdb_dst, sdst.sa.sa_len) || - (ipo->ipo_last_searched <= ipsec_last_added)) + if ((ipo->ipo_last_searched <= ipsec_last_added) || + (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) || + bcmp(dignore ? &sdst : &ipo->ipo_dst, &ipo->ipo_tdb->tdb_dst, + ipo->ipo_tdb->tdb_dst.sa.sa_len)) + goto nomatchout; + + /* Match source ID */ + if (ipo->ipo_srcid) { - TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, - ipo_tdb_next); - ipo->ipo_tdb = NULL; - ipo->ipo_last_searched = 0; + if (ipo->ipo_tdb->tdb_srcid == NULL || + !ipsp_ref_match(ipo->ipo_srcid, ipo->ipo_tdb->tdb_srcid)) + goto nomatchout; + } - /* Fall through to acquisition of TDB */ + /* Match destination ID */ + if (ipo->ipo_dstid) + { + if (ipo->ipo_tdb->tdb_dstid == NULL || + !ipsp_ref_match(ipo->ipo_dstid, ipo->ipo_tdb->tdb_dstid)) + goto nomatchout; } - else + + /* Match local credentials used */ + if (ipo->ipo_local_cred) { - return ipo->ipo_tdb; /* Cached entry is good, we're done */ + if (ipo->ipo_tdb->tdb_local_cred == NULL || + !ipsp_ref_match(ipo->ipo_local_cred, + ipo->ipo_tdb->tdb_local_cred)) + goto nomatchout; } + + return ipo->ipo_tdb; /* Cached entry is good, we're done */ + + nomatchout: + /* Cached TDB was not good */ + TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next); + ipo->ipo_tdb = NULL; + ipo->ipo_last_searched = 0; } /* @@ -421,41 +385,13 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, * destinations exist but are not used, possibly leading to an * explosion in the number of acquired SAs). */ - if ( -#ifdef INET - ((ipo->ipo_dst.sa.sa_family == AF_INET) && - (ipo->ipo_dst.sin.sin_addr.s_addr != INADDR_ANY) && - (ipo->ipo_dst.sin.sin_addr.s_addr != INADDR_BROADCAST)) || -#endif /* INET */ -#ifdef INET6 - ((ipo->ipo_dst.sa.sa_family == AF_INET6) && - !IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr) && - bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, - sizeof(in6mask128))) || -#endif /* INET6 */ - 0) - { - if (ipo->ipo_last_searched <= ipsec_last_added) - { - ipo->ipo_last_searched = time.tv_sec; /* "touch" the entry */ - - /* Find an appropriate SA from among the existing SAs */ - ipo->ipo_tdb = gettdbbyaddr(&sdst, ipo, m, af); - if (ipo->ipo_tdb) - { - TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo, - ipo_tdb_next); - *error = 0; - return ipo->ipo_tdb; - } - } - } - else + if (ipo->ipo_last_searched <= ipsec_last_added) { ipo->ipo_last_searched = time.tv_sec; /* "touch" the entry */ /* Find an appropriate SA from among the existing SAs */ - ipo->ipo_tdb = gettdbbyaddr(&sdst, ipo, m, af); + ipo->ipo_tdb = gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst, + ipo, m, af); if (ipo->ipo_tdb) { TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo, @@ -470,7 +406,8 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, { case IPSP_IPSEC_REQUIRE: /* Acquire SA through key management */ - if (ipsp_acquire_sa(ipo, &sdst, signore ? NULL : &ssrc, + if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst, + signore ? NULL : &ipo->ipo_src, ddst, m) != 0) { *error = EACCES; @@ -478,14 +415,14 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, } /* Fall through */ - case IPSP_IPSEC_DONTACQ: *error = -EINVAL; /* Silently drop packet */ return NULL; case IPSP_IPSEC_ACQUIRE: /* Acquire SA through key management */ - if (ipsp_acquire_sa(ipo, &sdst, signore ? NULL : &ssrc, + if (ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst, + signore ? NULL : &ipo->ipo_src, ddst, NULL) != 0) { *error = EACCES; @@ -493,7 +430,6 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, } /* Fall through */ - case IPSP_IPSEC_USE: *error = 0; /* Let packet through */ return NULL; @@ -501,129 +437,124 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, } else /* IPSP_DIRECTION_IN */ { - /* Check the cached entry */ - if ((ipo->ipo_tdb) && - (((ipo->ipo_tdb->tdb_src.sa.sa_family != 0) && - bcmp(&ssrc, &ipo->ipo_tdb->tdb_src, ssrc.sa.sa_len)) || - (ipo->ipo_last_searched <= ipsec_last_added))) + if (tdbp != NULL) { + if (ipo->ipo_tdb == tdbp) + { + *error = 0; /* Accept packet */ + return NULL; + } + + if (bcmp(dignore ? &ssrc : &ipo->ipo_dst, &tdbp->tdb_src, + tdbp->tdb_src.sa.sa_len) || + (ipo->ipo_sproto != tdbp->tdb_sproto)) + goto nomatchin; + + /* Match source ID */ + if (ipo->ipo_srcid) + { + if (tdbp->tdb_dstid == NULL || + !ipsp_ref_match(ipo->ipo_srcid, tdbp->tdb_dstid)) + goto nomatchin; + } + + /* Match destination ID */ + if (ipo->ipo_dstid) + { + if (tdbp->tdb_srcid == NULL || + !ipsp_ref_match(ipo->ipo_dstid, tdbp->tdb_srcid)) + goto nomatchin; + } + + /* Add it to the cache */ + if (ipo->ipo_tdb) + TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next); + ipo->ipo_tdb = tdbp; + TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo, ipo_tdb_next); + *error = 0; + return NULL; + + nomatchin: /* Nothing needed here, falling through */ + } + + /* Check whether cached entry applies */ + if (ipo->ipo_tdb) + { + /* + * We only need to check that the correct security protocol and + * security gateway are set; credentials/IDs will be the same, + * since the cached entry is linked on this policy. + */ + if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto && + !bcmp(&ipo->ipo_tdb->tdb_src, dignore ? &ssrc : &ipo->ipo_dst, + ipo->ipo_tdb->tdb_src.sa.sa_len)) + goto skipinputsearch; + + /* Not applicable, unlink */ TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, ipo_tdb_next); ipo->ipo_tdb = NULL; - ipo->ipo_last_searched = 0; } - switch (ipo->ipo_type) + /* Find whether there exists an appropriate SA */ + if (ipo->ipo_last_searched <= ipsec_last_added) { - case IPSP_IPSEC_DONTACQ: - /* Does protection match stated policy ? */ - if (tdbp && ipsp_match_policy(tdbp, ipo, m, af)) - { - /* Accept packet */ - *error = 0; - return NULL; - } + ipo->ipo_last_searched = time.tv_sec; /* "touch" */ - /* Silently drop packet */ - *error = EHOSTUNREACH; - return NULL; + ipo->ipo_tdb = gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst, + ipo, m, af); + if (ipo->ipo_tdb) + TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo, + ipo_tdb_next); + } + skipinputsearch: + switch (ipo->ipo_type) + { case IPSP_IPSEC_REQUIRE: - if (tdbp && ipsp_match_policy(tdbp, ipo, m, af)) - { - /* Accept packet */ - *error = 0; - return NULL; - } - - /* If we have a cached entry, just discard the packet */ + /* If an appropriate SA exists, don't acquire another */ if (ipo->ipo_tdb) { - *error = EHOSTUNREACH; + *error = -EINVAL; return NULL; } - /* - * Find whether there exists an appropriate SA. If so, drop - * the packet. Otherwise, try to acquire one (from below). - * - * If no SA has been added since the last time we did a lookup, - * there's no point searching for one. - */ - if (ipo->ipo_last_searched <= ipsec_last_added) - { - ipo->ipo_last_searched = time.tv_sec; /* "touch" */ - - if ((ipo->ipo_tdb = gettdbbysrc(&ssrc, ipo, - m, af)) != NULL) - { - TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo, - ipo_tdb_next); - *error = EHOSTUNREACH; - return NULL; - } - } - /* Acquire SA through key management */ - if ((*error = ipsp_acquire_sa(ipo, &ssrc, - dignore ? NULL : &sdst, + if ((*error = ipsp_acquire_sa(ipo, + dignore ? &ssrc : &ipo->ipo_dst, + signore ? NULL : &ipo->ipo_src, ddst, m)) != 0) return NULL; + /* Fall through */ + case IPSP_IPSEC_DONTACQ: + /* Drop packet */ *error = -EINVAL; return NULL; - case IPSP_IPSEC_USE: - /* - * It doesn't matter what protection it had (if any), - * just accept it -- equivalent to PERMIT for input. - * This means we can't say that we want in incoming - * packet to be unprotected -- at least not directly; - * we can always have a DENY policy for ESP/AH packets. - */ - *error = 0; - return NULL; - case IPSP_IPSEC_ACQUIRE: - /* - * We don't check for policy match, since we would - * accept clear-text packets as well. - */ - - /* If we have a cached entry, just accept the packet */ + /* If an appropriate SA exists, don't acquire another */ if (ipo->ipo_tdb) { *error = 0; return NULL; } - /* - * Find whether there exists an appropriate SA. If so, accept - * the packet. Otherwise, try to acquire one (from below). - * - * If no SA has been added since the last time we did a lookup, - * there's no point searching for one. - */ - if (ipo->ipo_last_searched <= ipsec_last_added) - { - ipo->ipo_last_searched = time.tv_sec; /* "touch" */ - - if ((ipo->ipo_tdb = gettdbbysrc(&ssrc, ipo, - m, af)) != NULL) - { - TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, ipo, - ipo_tdb_next); - *error = 0; - return NULL; - } - } - /* Acquire SA through key management */ - if ((*error = ipsp_acquire_sa(ipo, &ssrc, - dignore ? NULL : &sdst, + if ((*error = ipsp_acquire_sa(ipo, + dignore ? &ssrc : &ipo->ipo_dst, + signore ? NULL : &ipo->ipo_src, ddst, NULL)) != 0) return NULL; - /* Just accept the packet */ + /* Fall through */ + case IPSP_IPSEC_USE: + /* + * It doesn't matter what protection it had (if any), + * just accept it -- equivalent to PERMIT for input. + * This means we can't say that we want in incoming + * packet to be unprotected -- at least not directly; + * we can always have a DENY policy for ESP/AH packets. + */ *error = 0; return NULL; } @@ -634,134 +565,6 @@ ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, return NULL; } - -/* - * See if a specific SA satisfies stated policy. Return 0 if false, 1 (or - * non-zero) otherwise. - */ -int -ipsp_match_policy(struct tdb *tdb, struct ipsec_policy *ipo, - struct mbuf *m, int af) -{ - union sockaddr_union peer; - int pflag = 0; - - switch (ipo->ipo_dst.sa.sa_family) - { -#ifdef INET - case AF_INET: - if (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) - pflag = 1; - else - if (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST) - pflag = 2; - break; -#endif /* INET */ - -#ifdef INET6 - case AF_INET6: - if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) - pflag = 1; - else - if (!bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, - sizeof(in6mask128))) - pflag = 2; - break; -#endif /* INET6 */ - - case 0: /* Just in case */ - pflag = 1; - break; - - default: - return 0; /* Unknown/unsupported network protocol */ - } - - if (pflag == 0) - { - bcopy(&ipo->ipo_dst, &peer, sizeof(union sockaddr_union)); - } - else - if (pflag == 1) - { - bzero(&peer, sizeof(union sockaddr_union)); - - /* Need to copy the source address from the packet */ - switch (af) - { -#ifdef INET - case AF_INET: - peer.sin.sin_family = AF_INET; - peer.sin.sin_len = sizeof(struct sockaddr_in); - m_copydata(m, offsetof(struct ip, ip_src), - sizeof(struct in_addr), - (caddr_t) &peer.sin.sin_addr); - break; -#endif /* INET */ - -#ifdef INET6 - case AF_INET6: - peer.sin6.sin6_family = AF_INET6; - peer.sin6.sin6_len = sizeof(struct sockaddr_in6); - m_copydata(m, offsetof(struct ip6_hdr, ip6_src), - sizeof(struct in6_addr), - (caddr_t) &peer.sin6.sin6_addr); - break; -#endif /* INET6 */ - - default: - return 0; /* Unknown/unsupported network protocol */ - } - } - - /* - * Does the packet use the right security protocol and is coming from - * the right peer ? - */ - if (tdb->tdb_sproto == ipo->ipo_sproto) - { - /* - * We accept any peer that has a valid SA with us -- this means - * we depend on the higher-level (key mgmt.) protocol to enforce - * policy. - */ - if (pflag == 2) - return 1; - - if (bcmp(&tdb->tdb_src, &peer, tdb->tdb_src.sa.sa_len)) - { - switch (tdb->tdb_src.sa.sa_family) - { -#ifdef INET - case AF_INET: - if (tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY) - return 1; - else - return 0; -#endif /* INET */ - -#ifdef INET6 - case AF_INET6: - if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) - return 1; - else - return 0; -#endif /* INET6 */ - - case 0: - return 1; - - default: - return 0; - } - } - else - return 1; - } - - return 0; -} - /* * Delete a policy from the SPD. */ |