-/* $OpenBSD: pfkeyv2.c,v 1.142 2015/04/16 19:18:10 markus Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.143 2015/04/16 19:24:13 markus Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
case SADB_SATYPE_UNSPEC:
s = splsoftnet();
- /*
- * Go through the list of policies, delete those that
- * are not socket-attached.
- */
for (ipo = TAILQ_FIRST(&ipsec_policy_head);
ipo != NULL; ipo = tmpipo) {
tmpipo = TAILQ_NEXT(ipo, ipo_list);
- if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET) &&
- ipo->ipo_rdomain == rdomain)
+ if (ipo->ipo_rdomain == rdomain)
ipsec_delete_policy(ipo);
}
splx(s);
void *buffer = 0;
int i, buflen, error = 0;
- /* Do not dump policies attached to a socket. */
- if (ipo->ipo_flags & IPSP_POLICY_SOCKET)
- return (0);
-
if (w->w_where) {
void *headers[SADB_EXT_MAX + 1];
struct sadb_msg msg;
-/* $OpenBSD: in_pcb.c,v 1.169 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.170 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
} else
#endif
ip_freemoptions(inp->inp_moptions);
-#ifdef IPSEC
- /* IPsec cleanup here */
- if (inp->inp_tdb_in)
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in,
- inp, inp_tdb_in_next);
- if (inp->inp_tdb_out)
- TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
- inp_tdb_out_next);
- if (inp->inp_ipo)
- ipsec_delete_policy(inp->inp_ipo);
-#endif
#if NPF > 0
if (inp->inp_pf_sk) {
struct pf_state_key *sk;
-/* $OpenBSD: in_pcb.h,v 1.88 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.89 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
#define SL_ESP_TRANS 1 /* ESP transport level */
#define SL_ESP_NETWORK 2 /* ESP network (encapsulation) level */
#define SL_IPCOMP 3 /* Compression level */
- u_int inp_secrequire:4, /* Condensed State from above */
- inp_secresult:4; /* Result from Key Management */
-#define SR_FAILED 1 /* Negotiation failed permanently */
-#define SR_SUCCESS 2 /* SA successfully established */
-#define SR_WAIT 3 /* Waiting for SA */
u_char inp_ip_minttl; /* minimum TTL or drop */
- TAILQ_ENTRY(inpcb) inp_tdb_in_next, inp_tdb_out_next;
- struct tdb *inp_tdb_in, *inp_tdb_out;
- struct ipsec_policy *inp_ipo;
#define inp_flowinfo inp_hu.hu_ipv6.ip6_flow
int inp_cksum6;
-/* $OpenBSD: ip_ipsp.c,v 1.210 2015/04/14 14:20:01 mikeb Exp $ */
+/* $OpenBSD: ip_ipsp.c,v 1.211 2015/04/16 19:24:13 markus Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
tdbp = malloc(sizeof(*tdbp), M_TDB, M_WAITOK | M_ZERO);
- /* Init Incoming SA-Binding Queues. */
- TAILQ_INIT(&tdbp->tdb_inp_out);
- TAILQ_INIT(&tdbp->tdb_inp_in);
-
TAILQ_INIT(&tdbp->tdb_policy_head);
/* Record establishment time. */
tdb_free(struct tdb *tdbp)
{
struct ipsec_policy *ipo;
- struct inpcb *inp;
if (tdbp->tdb_xform) {
(*(tdbp->tdb_xform->xf_zeroize))(tdbp);
pfsync_delete_tdb(tdbp);
#endif
- /* Cleanup inp references. */
- for (inp = TAILQ_FIRST(&tdbp->tdb_inp_in); inp;
- inp = TAILQ_FIRST(&tdbp->tdb_inp_in)) {
- TAILQ_REMOVE(&tdbp->tdb_inp_in, inp, inp_tdb_in_next);
- inp->inp_tdb_in = NULL;
- }
-
- for (inp = TAILQ_FIRST(&tdbp->tdb_inp_out); inp;
- inp = TAILQ_FIRST(&tdbp->tdb_inp_out)) {
- TAILQ_REMOVE(&tdbp->tdb_inp_out, inp, inp_tdb_out_next);
- inp->inp_tdb_out = NULL;
- }
-
/* Cleanup SPD references. */
for (ipo = TAILQ_FIRST(&tdbp->tdb_policy_head); ipo;
ipo = TAILQ_FIRST(&tdbp->tdb_policy_head)) {
return EINVAL;
}
-/*
- * Check which transformations are required.
- */
-u_int8_t
-get_sa_require(struct inpcb *inp)
-{
- u_int8_t sareq = 0;
-
- if (inp != NULL) {
- sareq |= inp->inp_seclevel[SL_AUTH] >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_AUTH : 0;
- sareq |= inp->inp_seclevel[SL_ESP_TRANS] >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_CONF : 0;
- sareq |= inp->inp_seclevel[SL_ESP_NETWORK] >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_TUNNEL : 0;
- } else {
- /*
- * Code left for documentation purposes, these
- * conditions are always evaluated to false.
- */
- sareq |= IPSEC_AUTH_LEVEL_DEFAULT >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_AUTH : 0;
- sareq |= IPSEC_ESP_TRANS_LEVEL_DEFAULT >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_CONF : 0;
- sareq |= IPSEC_ESP_NETWORK_LEVEL_DEFAULT >= IPSEC_LEVEL_USE ?
- NOTIFY_SATYPE_TUNNEL : 0;
- }
-
- return (sareq);
-}
-
-/*
- * Add an inpcb to the list of inpcb which reference this tdb directly.
- */
-void
-tdb_add_inp(struct tdb *tdb, struct inpcb *inp, int inout)
-{
- if (inout) {
- if (inp->inp_tdb_in) {
- if (inp->inp_tdb_in == tdb)
- return;
-
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
- inp_tdb_in_next);
- }
-
- inp->inp_tdb_in = tdb;
- TAILQ_INSERT_TAIL(&tdb->tdb_inp_in, inp, inp_tdb_in_next);
- } else {
- if (inp->inp_tdb_out) {
- if (inp->inp_tdb_out == tdb)
- return;
-
- TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out, inp,
- inp_tdb_out_next);
- }
-
- inp->inp_tdb_out = tdb;
- TAILQ_INSERT_TAIL(&tdb->tdb_inp_out, inp, inp_tdb_out_next);
- }
-}
-
#ifdef ENCDEBUG
/* Return a printable string for the address. */
const char *
-/* $OpenBSD: ip_ipsp.h,v 1.165 2015/04/14 14:20:01 mikeb Exp $ */
+/* $OpenBSD: ip_ipsp.h,v 1.166 2015/04/16 19:24:13 markus Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr),
};
#define IPSP_POLICY_NONE 0x0000 /* No flags set */
-#define IPSP_POLICY_SOCKET 0x0001 /* Socket-attached policy */
#define IPSP_POLICY_STATIC 0x0002 /* Static policy */
#define IPSP_IPSEC_USE 0 /* Use if existing, don't acquire */
#define IPSP_DENY 4 /* Deny traffic */
#define IPSP_IPSEC_DONTACQ 5 /* Require, but don't acquire */
-/* Notification types */
-#define NOTIFY_SOFT_EXPIRE 0 /* Soft expiration of SA */
-#define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */
-#define NOTIFY_REQUEST_SA 2 /* Establish an SA */
-
-#define NOTIFY_SATYPE_CONF 1 /* SA should do encryption */
-#define NOTIFY_SATYPE_AUTH 2 /* SA should do authentication */
-#define NOTIFY_SATYPE_TUNNEL 4 /* SA should use tunneling */
-#define NOTIFY_SATYPE_COMP 5 /* SA (IPCA) should use compression */
-
/* Identity types */
#define IPSP_IDENTITY_NONE 0
#define IPSP_IDENTITY_PREFIX 1
struct sockaddr_encap tdb_filter; /* What traffic is acceptable */
struct sockaddr_encap tdb_filtermask; /* And the mask */
- TAILQ_HEAD(tdb_inp_head_in, inpcb) tdb_inp_in;
- TAILQ_HEAD(tdb_inp_head_out, inpcb) tdb_inp_out;
TAILQ_HEAD(tdb_policy_head, ipsec_policy) tdb_policy_head;
TAILQ_ENTRY(tdb) tdb_sync_entry;
};
extern TAILQ_HEAD(ipsec_policy_head, ipsec_policy) ipsec_policy_head;
extern TAILQ_HEAD(ipsec_acquire_head, ipsec_acquire) ipsec_acquire_head;
-/* Check if a given tdb has encryption, authentication and/or tunneling */
-#define TDB_ATTRIB(x) (((x)->tdb_encalgxform ? NOTIFY_SATYPE_CONF : 0) | \
- ((x)->tdb_authalgxform ? NOTIFY_SATYPE_AUTH : 0) | \
- ((x)->tdb_compalgxform ? NOTIFY_SATYPE_COMP : 0))
-
-/* Traverse spi chain and get attributes */
-
-#define SPI_CHAIN_ATTRIB(have, TDB_DIR, TDBP) \
-do { \
- int s = splsoftnet(); \
- struct tdb *tmptdb = (TDBP); \
- \
- (have) = 0; \
- while (tmptdb && tmptdb->tdb_xform) { \
- if (tmptdb == NULL || tmptdb->tdb_flags & TDBF_INVALID) \
- break; \
- (have) |= TDB_ATTRIB(tmptdb); \
- tmptdb = tmptdb->TDB_DIR; \
- } \
- splx(s); \
-} while (/* CONSTCOND */ 0)
-
/* Misc. */
-uint8_t get_sa_require(struct inpcb *);
#ifdef ENCDEBUG
const char *ipsp_address(union sockaddr_union *, char *, socklen_t);
#endif /* ENCDEBUG */
/* TDB management routines */
-void tdb_add_inp(struct tdb *, struct inpcb *, int);
uint32_t reserve_spi(u_int, u_int32_t, u_int32_t, union sockaddr_union *,
union sockaddr_union *, u_int8_t, int *);
struct tdb *gettdb(u_int, u_int32_t, union sockaddr_union *, u_int8_t);
int ipsec_delete_policy(struct ipsec_policy *);
ssize_t ipsec_hdrsz(struct tdb *);
void ipsec_adjust_mtu(struct mbuf *, u_int32_t);
-struct ipsec_policy *ipsec_add_policy(struct inpcb *, int, int);
struct ipsec_acquire *ipsec_get_acquire(u_int32_t);
#endif /* _KERNEL */
-/* $OpenBSD: ip_output.c,v 1.277 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: ip_output.c,v 1.278 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
struct mbuf *m = *mp;
int optval = 0;
struct proc *p = curproc; /* XXX */
-#ifdef IPSEC
- struct ipsec_ref *ipr;
- size_t iprlen;
- u_int16_t opt16val;
-#endif
int error = 0;
u_int rtid = 0;
break;
}
- /* Unlink cached output TDB to force a re-search */
- if (inp->inp_tdb_out) {
- int s = splsoftnet();
- TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out,
- inp, inp_tdb_out_next);
- splx(s);
- }
-
- if (inp->inp_tdb_in) {
- int s = splsoftnet();
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in,
- inp, inp_tdb_in_next);
- splx(s);
- }
-
switch (optname) {
case IP_AUTH_LEVEL:
if (optval < IPSEC_AUTH_LEVEL_DEFAULT &&
inp->inp_seclevel[SL_IPCOMP] = optval;
break;
}
- if (!error)
- inp->inp_secrequire = get_sa_require(inp);
#endif
break;
case IP_IPSEC_LOCAL_ID:
case IP_IPSEC_REMOTE_ID:
-#ifndef IPSEC
error = EOPNOTSUPP;
-#else
- if (m == NULL || m->m_len < 2) {
- error = EINVAL;
- break;
- }
-
- m_copydata(m, 0, 2, (caddr_t) &opt16val);
-
- /* If the type is 0, then we cleanup and return */
- if (opt16val == 0) {
- switch (optname) {
- case IP_IPSEC_LOCAL_ID:
- if (inp->inp_ipo != NULL &&
- inp->inp_ipo->ipo_srcid != NULL) {
- ipsp_reffree(inp->inp_ipo->ipo_srcid);
- inp->inp_ipo->ipo_srcid = NULL;
- }
- break;
- case IP_IPSEC_REMOTE_ID:
- if (inp->inp_ipo != NULL &&
- inp->inp_ipo->ipo_dstid != NULL) {
- ipsp_reffree(inp->inp_ipo->ipo_dstid);
- inp->inp_ipo->ipo_dstid = NULL;
- }
- break;
- }
-
- error = 0;
- break;
- }
-
- /* Can't have an empty payload */
- if (m->m_len == 2) {
- error = EINVAL;
- break;
- }
-
- /* Allocate if needed */
- if (inp->inp_ipo == NULL) {
- inp->inp_ipo = ipsec_add_policy(inp,
- AF_INET, IPSP_DIRECTION_OUT);
- if (inp->inp_ipo == NULL) {
- error = ENOBUFS;
- break;
- }
- }
-
- iprlen = sizeof(struct ipsec_ref) + m->m_len - 2;
- ipr = malloc(iprlen, M_CREDENTIALS, M_NOWAIT);
- if (ipr == NULL) {
- error = ENOBUFS;
- break;
- }
-
- ipr->ref_count = 1;
- ipr->ref_malloctype = M_CREDENTIALS;
- ipr->ref_len = m->m_len - 2;
- ipr->ref_type = opt16val;
- m_copydata(m, 2, m->m_len - 2, (caddr_t)(ipr + 1));
-
- switch (optname) {
- case IP_IPSEC_LOCAL_ID:
- /* Check valid types and NUL-termination */
- if (ipr->ref_type < IPSP_IDENTITY_PREFIX ||
- ipr->ref_type > IPSP_IDENTITY_CONNECTION ||
- ((char *)(ipr + 1))[ipr->ref_len - 1]) {
- free(ipr, M_CREDENTIALS, iprlen);
- error = EINVAL;
- } else {
- if (inp->inp_ipo->ipo_srcid != NULL)
- ipsp_reffree(inp->inp_ipo->ipo_srcid);
- inp->inp_ipo->ipo_srcid = ipr;
- }
- break;
- case IP_IPSEC_REMOTE_ID:
- /* Check valid types and NUL-termination */
- if (ipr->ref_type < IPSP_IDENTITY_PREFIX ||
- ipr->ref_type > IPSP_IDENTITY_CONNECTION ||
- ((char *)(ipr + 1))[ipr->ref_len - 1]) {
- free(ipr, M_CREDENTIALS, iprlen);
- error = EINVAL;
- } else {
- if (inp->inp_ipo->ipo_dstid != NULL)
- ipsp_reffree(inp->inp_ipo->ipo_dstid);
- inp->inp_ipo->ipo_dstid = ipr;
- }
- break;
- }
-
- /* Unlink cached output TDB to force a re-search */
- if (inp->inp_tdb_out) {
- int s = splsoftnet();
- TAILQ_REMOVE(&inp->inp_tdb_out->tdb_inp_out,
- inp, inp_tdb_out_next);
- splx(s);
- }
-
- if (inp->inp_tdb_in) {
- int s = splsoftnet();
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in,
- inp, inp_tdb_in_next);
- splx(s);
- }
-#endif
break;
case SO_RTABLE:
if (m == NULL || m->m_len < sizeof(u_int)) {
break;
case IP_IPSEC_LOCAL_ID:
case IP_IPSEC_REMOTE_ID:
-#ifndef IPSEC
error = EOPNOTSUPP;
-#else
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof(u_int16_t);
- ipr = NULL;
- switch (optname) {
- case IP_IPSEC_LOCAL_ID:
- if (inp->inp_ipo != NULL)
- ipr = inp->inp_ipo->ipo_srcid;
- opt16val = IPSP_IDENTITY_NONE;
- break;
- case IP_IPSEC_REMOTE_ID:
- if (inp->inp_ipo != NULL)
- ipr = inp->inp_ipo->ipo_dstid;
- opt16val = IPSP_IDENTITY_NONE;
- break;
- }
- if (ipr == NULL)
- *mtod(m, u_int16_t *) = opt16val;
- else {
- size_t len;
-
- len = m->m_len + ipr->ref_len;
- if (len > MCLBYTES) {
- m_free(m);
- error = EINVAL;
- break;
- }
- /* allocate mbuf cluster for larger option */
- if (len > MLEN) {
- MCLGET(m, M_WAITOK);
- if ((m->m_flags & M_EXT) == 0) {
- m_free(m);
- error = ENOBUFS;
- break;
- }
-
- }
- m->m_len = len;
- *mtod(m, u_int16_t *) = ipr->ref_type;
- m_copyback(m, sizeof(u_int16_t), ipr->ref_len,
- ipr + 1, M_NOWAIT);
- }
-#endif
break;
case SO_RTABLE:
*mp = m = m_get(M_WAIT, MT_SOOPTS);
-/* $OpenBSD: ip_spd.c,v 1.82 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: ip_spd.c,v 1.83 2015/04/16 19:24:13 markus Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
*
int ipsp_acquire_sa(struct ipsec_policy *, union sockaddr_union *,
union sockaddr_union *, struct sockaddr_encap *, struct mbuf *);
-void ipsec_update_policy(struct inpcb *, struct ipsec_policy *, int, int);
struct ipsec_acquire *ipsp_pending_acquire(struct ipsec_policy *,
union sockaddr_union *);
void ipsp_delete_acquire(void *);
return 0;
/* Delete from SPD. */
- if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET)) {
- memset(&info, 0, sizeof(info));
- info.rti_info[RTAX_DST] = (struct sockaddr *)&ipo->ipo_addr;
- info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&ipo->ipo_mask;
-
- /* XXX other tables? */
- err = rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, NULL,
- ipo->ipo_rdomain);
- }
+ memset(&info, 0, sizeof(info));
+ info.rti_info[RTAX_DST] = (struct sockaddr *)&ipo->ipo_addr;
+ info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&ipo->ipo_mask;
+
+ /* XXX other tables? */
+ err = rtrequest1(RTM_DELETE, &info, RTP_DEFAULT, NULL,
+ ipo->ipo_rdomain);
+
if (ipo->ipo_tdb != NULL)
TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo,
ipo_tdb_next);
if (ipo->ipo_dstid)
ipsp_reffree(ipo->ipo_dstid);
- if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET))
- ipsec_in_use--;
+ ipsec_in_use--;
pool_put(&ipsec_policy_pool, ipo);
return err;
}
-/*
- * Add a policy to the SPD.
- */
-struct ipsec_policy *
-ipsec_add_policy(struct inpcb *inp, int af, int direction)
-{
- struct ipsec_policy *ipon;
-
- if (ipsec_policy_pool_initialized == 0) {
- ipsec_policy_pool_initialized = 1;
- pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy),
- 0, 0, 0, "ipsec policy", NULL);
- }
-
- ipon = pool_get(&ipsec_policy_pool, PR_NOWAIT|PR_ZERO);
- if (ipon == NULL)
- return NULL;
-
- ipon->ipo_ref_count = 1;
- ipon->ipo_flags |= IPSP_POLICY_SOCKET;
-
- ipon->ipo_type = IPSP_IPSEC_REQUIRE; /* XXX */
-
- /* XXX
- * We should actually be creating a linked list of
- * policies (for tunnel/transport and ESP/AH), as needed.
- */
- ipon->ipo_sproto = IPPROTO_ESP;
- ipon->ipo_rdomain = rtable_l2(inp->inp_rtableid);
-
- TAILQ_INIT(&ipon->ipo_acquires);
- TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list);
-
- ipsec_update_policy(inp, ipon, af, direction);
-
- return ipon;
-}
-
-/*
- * Update a PCB-attached policy.
- */
-void
-ipsec_update_policy(struct inpcb *inp, struct ipsec_policy *ipon, int af,
- int direction)
-{
- ipon->ipo_addr.sen_len = ipon->ipo_mask.sen_len = SENT_LEN;
- ipon->ipo_addr.sen_family = ipon->ipo_mask.sen_family = PF_KEY;
- ipon->ipo_src.sa.sa_family = ipon->ipo_dst.sa.sa_family = af;
-
- switch (af) {
- case AF_INET:
- ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP4;
- ipon->ipo_addr.sen_ip_src = inp->inp_laddr;
- ipon->ipo_addr.sen_ip_dst = inp->inp_faddr;
- ipon->ipo_addr.sen_sport = inp->inp_lport;
- ipon->ipo_addr.sen_dport = inp->inp_fport;
- ipon->ipo_addr.sen_proto =
- inp->inp_socket->so_proto->pr_protocol;
- ipon->ipo_addr.sen_direction = direction;
-
- ipon->ipo_mask.sen_ip_src.s_addr = 0xffffffff;
- ipon->ipo_mask.sen_ip_dst.s_addr = 0xffffffff;
- ipon->ipo_mask.sen_sport = ipon->ipo_mask.sen_dport = 0xffff;
- ipon->ipo_mask.sen_proto = 0xff;
- ipon->ipo_mask.sen_direction = direction;
-
- ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in);
- ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in);
- ipon->ipo_src.sin.sin_addr = inp->inp_laddr;
- ipon->ipo_dst.sin.sin_addr = inp->inp_faddr;
- break;
-
- case AF_INET6:
-#ifdef INET6
- ipon->ipo_addr.sen_type = ipon->ipo_mask.sen_type = SENT_IP6;
- ipon->ipo_addr.sen_ip6_src = inp->inp_laddr6;
- ipon->ipo_addr.sen_ip6_dst = inp->inp_faddr6;
- ipon->ipo_addr.sen_ip6_sport = inp->inp_lport;
- ipon->ipo_addr.sen_ip6_dport = inp->inp_fport;
- ipon->ipo_addr.sen_ip6_proto =
- inp->inp_socket->so_proto->pr_protocol;
- ipon->ipo_addr.sen_ip6_direction = direction;
-
- ipon->ipo_mask.sen_ip6_src = in6mask128;
- ipon->ipo_mask.sen_ip6_dst = in6mask128;
- ipon->ipo_mask.sen_ip6_sport = 0xffff;
- ipon->ipo_mask.sen_ip6_dport = 0xffff;
- ipon->ipo_mask.sen_ip6_proto = 0xff;
- ipon->ipo_mask.sen_ip6_direction = direction;
-
- ipon->ipo_src.sa.sa_len = sizeof(struct sockaddr_in6);
- ipon->ipo_dst.sa.sa_len = sizeof(struct sockaddr_in6);
- ipon->ipo_src.sin6.sin6_addr = inp->inp_laddr6;
- ipon->ipo_dst.sin6.sin6_addr = inp->inp_faddr6;
-#endif /* INET6 */
- break;
- }
-}
-
/*
* Delete a pending IPsec acquire record.
*/
{
struct ipsec_acquire *ipa;
- /*
- * ACQUIRE on local sockets is restricted to avoid abuse of
- * authentication keys that the IKE daemon has already loaded.
- */
- if (ipo->ipo_flags & IPSP_POLICY_SOCKET)
- return EINVAL;
-
/* Check whether request has been made already. */
if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL)
return 0;
ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction,
struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo)
{
- struct ipsec_policy sipon;
- struct tdb_ident *tdbi;
- struct m_tag *mtag;
- struct tdb *tdb = NULL;
-
/* Sanity check. */
if (inp == NULL)
goto justreturn;
- /* Verify that we need to check for socket policy. */
- if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS ||
- inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_NONE) &&
- (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS ||
- inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_NONE) &&
- (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS ||
- inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_NONE))
- goto justreturn;
-
- switch (direction) {
- case IPSP_DIRECTION_IN:
- /*
- * Some further checking: if the socket has specified
- * that it will accept unencrypted traffic, don't
- * bother checking any further -- just accept the packet.
- */
- if ((inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_AVAIL ||
- inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_USE) &&
- (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_AVAIL ||
- inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_USE) &&
- (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL ||
- inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_USE))
- goto justreturn;
-
- /* Initialize socket policy if unset. */
- if (inp->inp_ipo == NULL) {
- inp->inp_ipo = ipsec_add_policy(inp, af,
- IPSP_DIRECTION_OUT);
- if (inp->inp_ipo == NULL) {
- *error = ENOBUFS;
- return NULL;
- }
- }
-
- /*
- * So we *must* have protected traffic. Let's see what
- * we have received then.
- */
- if (inp->inp_tdb_in != NULL) {
- if (inp->inp_tdb_in == tdbp)
- goto justreturn; /* We received packet under a
- * previously-accepted TDB. */
-
- /*
- * We should be receiving protected traffic, and
- * have an SA in place, but packet was received
- * unprotected. Simply discard.
- */
- if (tdbp == NULL) {
- *error = -EINVAL;
- return NULL;
- }
-
- /* Update, since we may need all the relevant info. */
- ipsec_update_policy(inp, inp->inp_ipo, af,
- IPSP_DIRECTION_OUT);
-
- /*
- * Check that the TDB the packet was received under
- * is acceptable under the socket policy. If so,
- * accept the packet; otherwise, discard.
- */
- if (tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
- !memcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
- SA_LEN(&tdbp->tdb_src.sa)) &&
- ipsp_aux_match(tdbp, inp->inp_ipo->ipo_srcid,
- inp->inp_ipo->ipo_dstid, &inp->inp_ipo->ipo_addr,
- &inp->inp_ipo->ipo_mask))
- goto justreturn;
- else {
- *error = -EINVAL;
- return NULL;
- }
- } else {
- /* Update, since we may need all the relevant info. */
- ipsec_update_policy(inp, inp->inp_ipo, af,
- IPSP_DIRECTION_OUT);
-
- /*
- * If the packet was received under an SA, see if
- * it's acceptable under socket policy. If it is,
- * accept the packet.
- */
- if (tdbp != NULL &&
- tdbp->tdb_sproto == inp->inp_ipo->ipo_sproto &&
- !memcmp(&tdbp->tdb_src, &inp->inp_ipo->ipo_dst,
- SA_LEN(&tdbp->tdb_src.sa)) &&
- ipsp_aux_match(tdbp, inp->inp_ipo->ipo_srcid,
- inp->inp_ipo->ipo_dstid, &inp->inp_ipo->ipo_addr,
- &inp->inp_ipo->ipo_mask))
- goto justreturn;
-
- /*
- * If the packet was not received under an SA, or
- * if the SA it was received under is not acceptable,
- * see if we already have an acceptable SA
- * established. If we do, discard packet.
- */
- if (inp->inp_ipo->ipo_last_searched <=
- ipsec_last_added) {
- inp->inp_ipo->ipo_last_searched = time_second;
-
- /* Do we have an SA already established ? */
- if (gettdbbysrc(rtable_l2(inp->inp_rtableid),
- &inp->inp_ipo->ipo_dst,
- inp->inp_ipo->ipo_sproto,
- inp->inp_ipo->ipo_srcid,
- inp->inp_ipo->ipo_dstid,
- &inp->inp_ipo->ipo_addr,
- &inp->inp_ipo->ipo_mask) != NULL) {
- *error = -EINVAL;
- return NULL;
- }
- /* Fall through */
- }
-
- /*
- * If we don't have an appropriate SA, acquire one
- * and discard the packet.
- */
- ipsp_acquire_sa(inp->inp_ipo, &inp->inp_ipo->ipo_dst,
- &inp->inp_ipo->ipo_src, &inp->inp_ipo->ipo_addr, m);
- *error = -EINVAL;
- return NULL;
- }
-
- break;
-
- case IPSP_DIRECTION_OUT:
- /* Do we have a cached entry ? */
- if (inp->inp_tdb_out != NULL) {
- /*
- * If we also have to apply a different TDB as
- * a result of a system-wide policy, add a tag
- * to the packet.
- */
- if (ipo != NULL && m != NULL &&
- ipo->ipo_tdb != NULL &&
- ipo->ipo_tdb != inp->inp_tdb_out) {
- tdb = inp->inp_tdb_out;
- goto tagandreturn;
- } else
- return inp->inp_tdb_out;
- }
-
- /*
- * We need to either find an SA with the appropriate
- * characteristics and link it to the PCB, or acquire
- * one.
- */
- /* XXX Only support one policy/protocol for now. */
- if (inp->inp_ipo != NULL) {
- if (inp->inp_ipo->ipo_last_searched <=
- ipsec_last_added) {
- inp->inp_ipo->ipo_last_searched = time_second;
-
- /* Update, just in case. */
- ipsec_update_policy(inp, inp->inp_ipo, af,
- IPSP_DIRECTION_OUT);
-
- tdb = gettdbbydst(rtable_l2(inp->inp_rtableid),
- &inp->inp_ipo->ipo_dst,
- inp->inp_ipo->ipo_sproto,
- inp->inp_ipo->ipo_srcid,
- inp->inp_ipo->ipo_dstid,
- &inp->inp_ipo->ipo_addr,
- &inp->inp_ipo->ipo_mask);
- }
- } else {
- /*
- * Construct a pseudo-policy, with just the necessary
- * fields.
- */
- ipsec_update_policy(inp, &sipon, af,
- IPSP_DIRECTION_OUT);
-
- tdb = gettdbbydst(rtable_l2(inp->inp_rtableid),
- &sipon.ipo_dst, IPPROTO_ESP, NULL, NULL,
- &sipon.ipo_addr, &sipon.ipo_mask);
- }
-
- /* If we found an appropriate SA... */
- if (tdb != NULL) {
- tdb_add_inp(tdb, inp, 0); /* Latch onto PCB. */
+ /* We only support IPSEC_LEVEL_BYPASS or IPSEC_LEVEL_AVAIL */
- if (ipo != NULL && ipo->ipo_tdb != NULL &&
- ipo->ipo_tdb != inp->inp_tdb_out && m != NULL)
- goto tagandreturn;
- else
- return tdb;
- } else {
- /* Do we need to acquire one ? */
- switch (inp->inp_seclevel[SL_ESP_TRANS]) {
- case IPSEC_LEVEL_BYPASS:
- case IPSEC_LEVEL_AVAIL:
- /* No need to do anything. */
- goto justreturn;
- case IPSEC_LEVEL_USE:
- case IPSEC_LEVEL_REQUIRE:
- case IPSEC_LEVEL_UNIQUE:
- /* Initialize socket policy if unset. */
- if (inp->inp_ipo == NULL) {
- inp->inp_ipo = ipsec_add_policy(inp, af, IPSP_DIRECTION_OUT);
- if (inp->inp_ipo == NULL) {
- *error = ENOBUFS;
- return NULL;
- }
- }
-
- /* Acquire a new SA. */
- if ((*error = ipsp_acquire_sa(inp->inp_ipo,
- &inp->inp_ipo->ipo_dst,
- &inp->inp_ipo->ipo_src,
- &inp->inp_ipo->ipo_addr, m)) == 0)
- *error = -EINVAL;
-
- return NULL;
- default:
- DPRINTF(("ipsp_spd_inp: unknown sock security"
- " level %d",
- inp->inp_seclevel[SL_ESP_TRANS]));
- *error = -EINVAL;
- return NULL;
- }
- }
- break;
-
- default: /* Should never happen. */
- *error = -EINVAL;
- return NULL;
- }
-
- tagandreturn:
- if (tdb == NULL)
+ if (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS &&
+ inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS &&
+ inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)
goto justreturn;
- mtag = m_tag_get(PACKET_TAG_IPSEC_PENDING_TDB,
- sizeof (struct tdb_ident), M_NOWAIT);
- if (mtag == NULL) {
- *error = ENOMEM;
- return NULL;
- }
+ if (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_AVAIL &&
+ inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_AVAIL &&
+ inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_AVAIL)
+ goto justreturn;
- tdbi = (struct tdb_ident *)(mtag + 1);
- tdbi->spi = ipo->ipo_tdb->tdb_spi;
- tdbi->proto = ipo->ipo_tdb->tdb_sproto;
- tdbi->rdomain = rtable_l2(inp->inp_rtableid);
- bcopy(&ipo->ipo_tdb->tdb_dst, &tdbi->dst,
- ipo->ipo_tdb->tdb_dst.sa.sa_len);
- m_tag_prepend(m, mtag);
- return tdb;
+ *error = -EINVAL;
+ return NULL;
justreturn:
if (ipo != NULL)
-/* $OpenBSD: tcp_input.c,v 1.288 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.289 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
tcpstat.tcps_rcvnosec++;
goto drop;
}
-
- /* Latch SA */
- if (inp->inp_tdb_in != tdb) {
- if (tdb) {
- tdb_add_inp(tdb, inp, 1);
- if (inp->inp_ipo == NULL) {
- inp->inp_ipo = ipsec_add_policy(inp, af,
- IPSP_DIRECTION_OUT);
- if (inp->inp_ipo == NULL) {
- goto drop;
- }
- }
- if (inp->inp_ipo->ipo_dstid == NULL &&
- tdb->tdb_srcid != NULL) {
- inp->inp_ipo->ipo_dstid = tdb->tdb_srcid;
- tdb->tdb_srcid->ref_count++;
- }
- } else { /* Just reset */
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
- inp_tdb_in_next);
- inp->inp_tdb_in = NULL;
- }
- }
#endif /* IPSEC */
/*
struct inpcb *newinp = sotoinpcb(so);
bcopy(inp->inp_seclevel, newinp->inp_seclevel,
sizeof(inp->inp_seclevel));
- newinp->inp_secrequire = inp->inp_secrequire;
- if (inp->inp_ipo != NULL) {
- newinp->inp_ipo = inp->inp_ipo;
- inp->inp_ipo->ipo_ref_count++;
- }
}
#endif /* IPSEC */
#ifdef INET6
-/* $OpenBSD: udp_usrreq.c,v 1.197 2015/04/14 12:22:15 mikeb Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.198 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
udpstat.udps_nosec++;
goto bad;
}
-
- /* Latch SA only if the socket is connected */
- if (inp->inp_tdb_in != tdb &&
- (inp->inp_socket->so_state & SS_ISCONNECTED)) {
- if (tdb) {
- tdb_add_inp(tdb, inp, 1);
- if (inp->inp_ipo == NULL) {
- inp->inp_ipo = ipsec_add_policy(inp,
- srcsa.sa.sa_family, IPSP_DIRECTION_OUT);
- if (inp->inp_ipo == NULL) {
- goto bad;
- }
- }
- if (inp->inp_ipo->ipo_dstid == NULL &&
- tdb->tdb_srcid != NULL) {
- inp->inp_ipo->ipo_dstid = tdb->tdb_srcid;
- tdb->tdb_srcid->ref_count++;
- }
- } else { /* Just reset */
- TAILQ_REMOVE(&inp->inp_tdb_in->tdb_inp_in, inp,
- inp_tdb_in_next);
- inp->inp_tdb_in = NULL;
- }
- }
/* create ipsec options while we know that tdb cannot be modified */
if (tdb)
ipsecflowinfo = tdb->tdb_spi;
-
#endif /*IPSEC */
opts = NULL;
-/* $OpenBSD: ip6_output.c,v 1.168 2015/03/14 03:38:52 jsg Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.169 2015/04/16 19:24:13 markus Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
struct mbuf *m = *mp;
int error, optval;
struct proc *p = curproc; /* For IPSec and rdomain */
-#ifdef IPSEC
- struct tdb *tdb;
- struct tdb_ident *tdbip, tdbi;
- int s;
-#endif
u_int rtid = 0;
error = optval = 0;
break;
case IPSEC6_OUTSA:
-#ifndef IPSEC
error = EINVAL;
-#else
- if (m == NULL ||
- m->m_len != sizeof(struct tdb_ident)) {
- error = EINVAL;
- break;
- }
- tdbip = mtod(m, struct tdb_ident *);
- s = splsoftnet();
- tdb = gettdb(tdbip->rdomain, tdbip->spi,
- &tdbip->dst, tdbip->proto);
- if (tdb == NULL)
- error = ESRCH;
- else
- tdb_add_inp(tdb, inp, 0);
- splx(s);
-#endif
break;
case IPV6_AUTH_LEVEL:
inp->inp_seclevel[SL_IPCOMP] = optval;
break;
}
- if (!error)
- inp->inp_secrequire = get_sa_require(inp);
#endif
break;
case SO_RTABLE:
break;
case IPSEC6_OUTSA:
-#ifndef IPSEC
error = EINVAL;
-#else
- s = splsoftnet();
- if (inp->inp_tdb_out == NULL) {
- error = ENOENT;
- } else {
- tdbi.spi = inp->inp_tdb_out->tdb_spi;
- tdbi.dst = inp->inp_tdb_out->tdb_dst;
- tdbi.proto = inp->inp_tdb_out->tdb_sproto;
- tdbi.rdomain =
- inp->inp_tdb_out->tdb_rdomain;
- *mp = m = m_get(M_WAIT, MT_SOOPTS);
- m->m_len = sizeof(tdbi);
- bcopy((caddr_t)&tdbi, mtod(m, caddr_t),
- m->m_len);
- }
- splx(s);
-#endif
break;
case IPV6_AUTH_LEVEL:
-/* $OpenBSD: inet.c,v 1.141 2015/04/14 17:53:13 mikeb Exp $ */
+/* $OpenBSD: inet.c,v 1.142 2015/04/16 19:24:13 markus Exp $ */
/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
/*
p("%u", inp_seclevel[1], ", ");
p("%u", inp_seclevel[2], ", ");
p("%u", inp_seclevel[3], "\n ");
- p("%#x", inp_secrequire, ", ");
- p("%#x", inp_secresult, "\n ");
p("%u", inp_ip_minttl, "\n ");
- pp("%p", inp_tdb_in, ", ");
- pp("%p", inp_tdb_out, ", ");
- pp("%p", inp_ipo, "\n ");
p("%d", inp_cksum6, "\n ");
pp("%p", inp_icmp6filt, "\n ");
pp("%p", inp_pf_sk, "\n ");