diff options
author | Niels Provos <provos@cvs.openbsd.org> | 1998-05-18 21:11:13 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 1998-05-18 21:11:13 +0000 |
commit | 0a99f14607ee1c61291cc2ef2b27e12fa8150b57 (patch) | |
tree | 16d9ebdb669b92f649893f48e323f5efe1f65f1c | |
parent | 32b196f4e8de3c9182f2326dab7a9409ca8e45ad (diff) |
first step to the setsockopt/getsockopt interface as described in
draft-mcdonald-simple-ipsec-api, kernel notifies (EMT_REQUESTSA) signal
userland key management applications when security services are requested.
this is only for outgoing connections at the moment, incoming packets
are not yet checked against the selected socket policy.
31 files changed, 1065 insertions, 519 deletions
diff --git a/sys/net/encap.c b/sys/net/encap.c index d99914d9fc8..9b88b3b8c0b 100644 --- a/sys/net/encap.c +++ b/sys/net/encap.c @@ -1,27 +1,33 @@ -/* $OpenBSD: encap.c,v 1.21 1998/04/08 10:58:03 provos Exp $ */ +/* $OpenBSD: encap.c,v 1.22 1998/05/18 21:10:15 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -46,6 +52,9 @@ #ifdef INET #include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/in_pcb.h> #endif #include <net/encap.h> @@ -55,7 +64,12 @@ #include <sys/syslog.h> void encap_init(void); -void encap_sendnotify(int, struct tdb *); +void encap_sendnotify(int, struct tdb *, void *); +int encap_notify_sa(u_int32_t, struct in_addr, struct in_addr, + u_int16_t, u_int16_t, u_int16_t, u_int16_t); +int encap_enable_spi(u_int32_t, struct in_addr, struct in_addr, struct in_addr, + struct in_addr, struct in_addr, u_int16_t, u_int16_t, + u_int16_t, u_int16_t, u_int16_t); int encap_output __P((struct mbuf *, ...)); int encap_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *); @@ -65,6 +79,10 @@ extern int tdb_init(struct tdb *, struct mbuf *); extern struct domain encapdomain; +extern struct inpcbtable tcbtable; /* Notify - XXX */ +extern struct inpcbtable udbtable; /* Notify - XXX */ +extern struct inpcbtable rawcbtable; /* Notify - XXX */ + struct sockaddr encap_dst = { 2, PF_ENCAP, }; struct sockaddr encap_src = { 2, PF_ENCAP, }; struct sockproto encap_proto = { PF_ENCAP, }; @@ -158,6 +176,401 @@ encap_usrreq(register struct socket *so, int req, struct mbuf *m, } int +encap_notify_sa(u_int32_t spi, struct in_addr dst, struct in_addr src, + u_int16_t sport, u_int16_t dport, u_int16_t protocol, + u_int16_t sproto) +{ + struct inpcbtable *table = NULL; + struct inpcb *inp = NULL; + struct in_addr altm, zeroin_addr; + struct tdb *tdbp; + struct flow *flow; + int error = 0; + u_int8_t secrequire; + + altm.s_addr = INADDR_BROADCAST; + + switch (protocol) { + case IPPROTO_TCP: + table = &tcbtable; + break; + case IPPROTO_UDP: + table = &udbtable; + break; + default: + break; + } + + if (table != NULL) { + /* Protocols with own inpcb tables */ + bzero((caddr_t)&zeroin_addr, sizeof(zeroin_addr)); + inp = in_pcblookup(table, dst, dport, zeroin_addr, sport, + INPLOOKUP_WILDCARD); + } else { + /* RAW protocol - taken from raw_ip.c */ + /* XXX - we can have more than one inp sleeping here */ + for (inp = rawcbtable.inpt_queue.cqh_first; + inp != (struct inpcb *)&rawcbtable.inpt_queue; + inp = inp->inp_queue.cqe_next) { + if (!inp->inp_socket || + inp->inp_socket->so_proto->pr_protocol != protocol) + continue; + if (inp->inp_faddr.s_addr && + inp->inp_faddr.s_addr != dst.s_addr) + continue; + if (inp->inp_secrequire != 0 && + inp->inp_secresult == SR_WAIT) + break; + } + if (inp == (struct inpcb *)&rawcbtable.inpt_queue) + inp = NULL; + } + +#ifdef ENCDEBUG + if (encdebug && inp != NULL) + printf("encap: found inp for protocol %d\n", protocol); +#endif /* ENCDEBUG */ + + if (inp && inp->inp_secresult == SR_WAIT && inp->inp_secrequire != 0) { + secrequire = inp->inp_secrequire; + } else { + /* + * XXX - is this the right thing to do ?? We need to know if + * IPSec is already in use. + * This does only work for host-to-host + */ + flow = find_global_flow(src, altm, dst, altm, 0,0,0); + if (flow == (struct flow *)NULL) + return (ENOENT); + + SPI_CHAIN_ATTRIB(secrequire, tdb_onext, flow->flow_sa); +#ifdef ENCDEBUG + if (encdebug) + printf("encap: Existing flow (%0x) requires: %d\n", + flow, secrequire); +#endif /* ENCDEBUG */ + } + + if (spi == 0) { +#ifdef ENCDEBUG + if (encdebug) + printf("encap: key management failed\n"); +#endif + if (inp != NULL) { + inp->inp_secresult = SR_FAILED; + wakeup(inp); + } + return (0); + } else { + u_int8_t sa_have; + + tdbp = gettdb(spi, dst, sproto); + if (tdbp == NULL) + return (ENOENT); +#ifdef ENCDEBUG + if (encdebug) + printf("encap: found tdb\n"); +#endif /* ENCDEBUG */ + + SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdbp); + + /* Requirements not met */ + if (secrequire & ~sa_have) + return (EINVAL); +#ifdef ENCDEBUG + if (encdebug) + printf("encap: tdb meets requirements\n"); +#endif /* ENCDEBUG */ + + /* + * This is a stupid hack, we do not support socketwise + * keying at the moment, so we do it for the whole host + */ + error = encap_enable_spi(spi, dst, src, altm, dst, altm, + 0, 0, 0, sproto, + ENABLE_FLAG_REPLACE|ENABLE_FLAG_LOCAL); + + if (!error) { +#ifdef ENCDEBUG + if (encdebug) + printf("encap: key management succeeded\n"); +#endif /* ENCDEBUG */ + if (inp != NULL) { + inp->inp_secresult = SR_SUCCESS; + wakeup(inp); + } + } + } + + return (error); +} + +int +encap_enable_spi(u_int32_t spi, struct in_addr dst, + struct in_addr isrc, struct in_addr ismask, + struct in_addr idst, struct in_addr idmask, + u_int16_t sport, u_int16_t dport, + u_int16_t protocol, u_int16_t sproto, + u_int16_t flags) +{ + struct sockaddr_encap encapdst, encapgw, encapnetmask; + struct flow *flow, *flow2, *flow3, *flow4; + struct in_addr alts, altm; + struct tdb *tdbp; + int error = 0; + + tdbp = gettdb(spi, dst, sproto); + if (tdbp == NULL) + return (ENOENT); + + bzero((caddr_t) &encapdst, sizeof(struct sockaddr_encap)); + bzero((caddr_t) &encapnetmask, sizeof(struct sockaddr_encap)); + bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap)); + + flow = flow2 = flow3 = flow4 = (struct flow *) NULL; + + isrc.s_addr &= ismask.s_addr; + idst.s_addr &= idmask.s_addr; + + flow3 = find_global_flow(isrc, ismask, idst, idmask, + protocol, sport, dport); + if ((flow3 != (struct flow *) NULL) && !(flags & ENABLE_FLAG_REPLACE)) + return (EEXIST); + + /* Check for 0.0.0.0/255.255.255.255 if the flow is local */ + if (flags & ENABLE_FLAG_LOCAL) { + alts.s_addr = INADDR_ANY; + altm.s_addr = INADDR_BROADCAST; + flow4 = find_global_flow(alts, altm, idst, idmask, + protocol, sport, dport); + if (flow4 != (struct flow *) NULL) { + if (!(flags & ENABLE_FLAG_REPLACE)) + return (EEXIST); + else if (flow3 == flow4) + return (EINVAL); + } + } + + flow = get_flow(); + if (flow == (struct flow *) NULL) + return (ENOBUFS); + + flow->flow_src.s_addr = isrc.s_addr; + flow->flow_dst.s_addr = idst.s_addr; + flow->flow_srcmask.s_addr = ismask.s_addr; + flow->flow_dstmask.s_addr = idmask.s_addr; + flow->flow_proto = protocol; + flow->flow_sport = sport; + flow->flow_dport = dport; + + if (flags & ENABLE_FLAG_LOCAL) { + flow2 = get_flow(); + if (flow2 == (struct flow *) NULL) { + FREE(flow, M_TDB); + return (ENOBUFS); + } + + flow2->flow_src.s_addr = INADDR_ANY; + flow2->flow_dst.s_addr = idst.s_addr; + flow2->flow_srcmask.s_addr = INADDR_BROADCAST; + flow2->flow_dstmask.s_addr = idmask.s_addr; + flow2->flow_proto = protocol; + flow2->flow_sport = sport; + flow2->flow_dport = dport; + + put_flow(flow2, tdbp); + } + + put_flow(flow, tdbp); + + /* Setup the encap fields */ + encapdst.sen_len = SENT_IP4_LEN; + encapdst.sen_family = AF_ENCAP; + encapdst.sen_type = SENT_IP4; + encapdst.sen_ip_src.s_addr = flow->flow_src.s_addr; + encapdst.sen_ip_dst.s_addr = flow->flow_dst.s_addr; + encapdst.sen_proto = flow->flow_proto; + encapdst.sen_sport = flow->flow_sport; + encapdst.sen_dport = flow->flow_dport; + + encapgw.sen_len = SENT_IPSP_LEN; + encapgw.sen_family = AF_ENCAP; + encapgw.sen_type = SENT_IPSP; + encapgw.sen_ipsp_dst.s_addr = tdbp->tdb_dst.s_addr; + encapgw.sen_ipsp_spi = tdbp->tdb_spi; + encapgw.sen_ipsp_sproto = tdbp->tdb_sproto; + + encapnetmask.sen_len = SENT_IP4_LEN; + encapnetmask.sen_family = AF_ENCAP; + encapnetmask.sen_type = SENT_IP4; + encapnetmask.sen_ip_src.s_addr = flow->flow_srcmask.s_addr; + encapnetmask.sen_ip_dst.s_addr = flow->flow_dstmask.s_addr; + + if (flow->flow_proto) { + encapnetmask.sen_proto = 0xff; + + if (flow->flow_sport) + encapnetmask.sen_sport = 0xffff; + + if (flow->flow_dport) + encapnetmask.sen_dport = 0xffff; + } + + /* If this is set, delete any old route for this flow */ + if (flags & ENABLE_FLAG_REPLACE) + rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, + (struct sockaddr *) 0, + (struct sockaddr *) &encapnetmask, 0, + (struct rtentry **) 0); + + /* Add the entry in the routing table */ + error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, + (struct sockaddr *) &encapgw, + (struct sockaddr *) &encapnetmask, + RTF_UP | RTF_GATEWAY | RTF_STATIC, + (struct rtentry **) 0); + + if (error) { + encapdst.sen_len = SENT_IP4_LEN; + encapdst.sen_family = AF_ENCAP; + encapdst.sen_type = SENT_IP4; + encapdst.sen_ip_src.s_addr = flow3->flow_src.s_addr; + encapdst.sen_ip_dst.s_addr = flow3->flow_dst.s_addr; + encapdst.sen_proto = flow3->flow_proto; + encapdst.sen_sport = flow3->flow_sport; + encapdst.sen_dport = flow3->flow_dport; + + encapgw.sen_len = SENT_IPSP_LEN; + encapgw.sen_family = AF_ENCAP; + encapgw.sen_type = SENT_IPSP; + encapgw.sen_ipsp_dst.s_addr = flow3->flow_sa->tdb_dst.s_addr; + encapgw.sen_ipsp_spi = flow3->flow_sa->tdb_spi; + encapgw.sen_ipsp_sproto = flow3->flow_sa->tdb_sproto; + + encapnetmask.sen_len = SENT_IP4_LEN; + encapnetmask.sen_family = AF_ENCAP; + encapnetmask.sen_type = SENT_IP4; + encapnetmask.sen_ip_src.s_addr = flow3->flow_srcmask.s_addr; + encapnetmask.sen_ip_dst.s_addr = flow3->flow_dstmask.s_addr; + + if (flow3->flow_proto) { + encapnetmask.sen_proto = 0xff; + + if (flow3->flow_sport) + encapnetmask.sen_sport = 0xffff; + + if (flow->flow_dport) + encapnetmask.sen_dport = 0xffff; + } + + /* Try to add the old entry back in */ + rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, + (struct sockaddr *) &encapgw, + (struct sockaddr *) &encapnetmask, + RTF_UP | RTF_GATEWAY | RTF_STATIC, + (struct rtentry **) 0); + + delete_flow(flow, tdbp); + if (flow2) + delete_flow(flow2, tdbp); + return (error); + } + + /* If this is a "local" packet flow */ + if (flags & ENABLE_FLAG_LOCAL) { + encapdst.sen_ip_src.s_addr = INADDR_ANY; + encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST; + + if (flags & ENABLE_FLAG_REPLACE) + rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, + (struct sockaddr *) 0, + (struct sockaddr *) &encapnetmask, 0, + (struct rtentry **) 0); + + error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, + (struct sockaddr *) &encapgw, + (struct sockaddr *) &encapnetmask, + RTF_UP | RTF_GATEWAY | RTF_STATIC, + (struct rtentry **) 0); + + if (error) { + /* Delete the first entry inserted */ + encapdst.sen_ip_src.s_addr = isrc.s_addr; + encapnetmask.sen_ip_src.s_addr = ismask.s_addr; + + rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, + (struct sockaddr *) 0, + (struct sockaddr *) &encapnetmask, 0, + (struct rtentry **) 0); + + /* Setup the old entries */ + encapdst.sen_len = SENT_IP4_LEN; + encapdst.sen_family = AF_ENCAP; + encapdst.sen_type = SENT_IP4; + encapdst.sen_ip_src.s_addr = flow3->flow_src.s_addr; + encapdst.sen_ip_dst.s_addr = flow3->flow_dst.s_addr; + encapdst.sen_proto = flow3->flow_proto; + encapdst.sen_sport = flow3->flow_sport; + encapdst.sen_dport = flow3->flow_dport; + + encapgw.sen_len = SENT_IPSP_LEN; + encapgw.sen_family = AF_ENCAP; + encapgw.sen_type = SENT_IPSP; + encapgw.sen_ipsp_dst.s_addr = flow3->flow_sa->tdb_dst.s_addr; + encapgw.sen_ipsp_spi = flow3->flow_sa->tdb_spi; + encapgw.sen_ipsp_sproto = flow3->flow_sa->tdb_sproto; + + encapnetmask.sen_len = SENT_IP4_LEN; + encapnetmask.sen_family = AF_ENCAP; + encapnetmask.sen_type = SENT_IP4; + encapnetmask.sen_ip_src.s_addr = flow3->flow_srcmask.s_addr; + encapnetmask.sen_ip_dst.s_addr = flow3->flow_dstmask.s_addr; + + if (flow3->flow_proto) { + encapnetmask.sen_proto = 0xff; + + if (flow3->flow_sport) + encapnetmask.sen_sport = 0xffff; + + if (flow->flow_dport) + encapnetmask.sen_dport = 0xffff; + } + + rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, + (struct sockaddr *) &encapgw, + (struct sockaddr *) &encapnetmask, + RTF_UP | RTF_GATEWAY | RTF_STATIC, + (struct rtentry **) 0); + + encapdst.sen_ip_src.s_addr = INADDR_ANY; + encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST; + + rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, + (struct sockaddr *) &encapgw, + (struct sockaddr *) &encapnetmask, + RTF_UP | RTF_GATEWAY | RTF_STATIC, + (struct rtentry **) 0); + + delete_flow(flow, tdbp); + delete_flow(flow2, tdbp); + return (error); + } + } + + /* + * If we're here, it means we've successfully added the new + * entries, so free the old ones. + */ + if (flow3) + delete_flow(flow3, flow3->flow_sa); + + if (flow4) + delete_flow(flow4, flow4->flow_sa); + + return 0; +} + +int #ifdef __STDC__ encap_output(struct mbuf *m, ...) #else @@ -168,7 +581,7 @@ va_dcl { #define SENDERR(e) do { error = e; goto flush;} while (0) struct sockaddr_encap encapdst, encapgw, encapnetmask; - struct flow *flow, *flow2, *flow3, *flow4; + struct flow *flow, *flow2; int len, emlen, error = 0; struct in_addr alts, altm; struct encap_msghdr *emp; @@ -453,267 +866,12 @@ va_dcl if (emlen != EMT_ENABLESPI_FLEN) SENDERR(EINVAL); - tdbp = gettdb(emp->em_ena_spi, emp->em_ena_dst, - emp->em_ena_sproto); - if (tdbp == NULL) - SENDERR(ENOENT); - - flow = flow2 = flow3 = flow4 = (struct flow *) NULL; - - emp->em_ena_isrc.s_addr &= emp->em_ena_ismask.s_addr; - emp->em_ena_idst.s_addr &= emp->em_ena_idmask.s_addr; - - flow3 = find_global_flow(emp->em_ena_isrc, emp->em_ena_ismask, - emp->em_ena_idst, emp->em_ena_idmask, - emp->em_ena_protocol, emp->em_ena_sport, - emp->em_ena_dport); - if (flow3 != (struct flow *) NULL) - if (!(emp->em_ena_flags & ENABLE_FLAG_REPLACE)) - SENDERR(EEXIST); - - /* Check for 0.0.0.0/255.255.255.255 if the flow is local */ - if (emp->em_ena_flags & ENABLE_FLAG_LOCAL) - { - alts.s_addr = INADDR_ANY; - altm.s_addr = INADDR_BROADCAST; - flow4 = find_global_flow(alts, altm, emp->em_ena_idst, - emp->em_ena_idmask, - emp->em_ena_protocol, - emp->em_ena_sport, emp->em_ena_dport); - if (flow4 != (struct flow *) NULL) - { - if (!(emp->em_ena_flags & ENABLE_FLAG_REPLACE)) - SENDERR(EEXIST); - else if (flow3 == flow4) - SENDERR(EINVAL); - } - } - - flow = get_flow(); - if (flow == (struct flow *) NULL) - SENDERR(ENOBUFS); - - flow->flow_src.s_addr = emp->em_ena_isrc.s_addr; - flow->flow_dst.s_addr = emp->em_ena_idst.s_addr; - flow->flow_srcmask.s_addr = emp->em_ena_ismask.s_addr; - flow->flow_dstmask.s_addr = emp->em_ena_idmask.s_addr; - flow->flow_proto = emp->em_ena_protocol; - flow->flow_sport = emp->em_ena_sport; - flow->flow_dport = emp->em_ena_dport; - - if (emp->em_ena_flags & ENABLE_FLAG_LOCAL) - { - flow2 = get_flow(); - if (flow2 == (struct flow *) NULL) - { - FREE(flow, M_TDB); - SENDERR(ENOBUFS); - } - - flow2->flow_src.s_addr = INADDR_ANY; - flow2->flow_dst.s_addr = emp->em_ena_idst.s_addr; - flow2->flow_srcmask.s_addr = INADDR_BROADCAST; - flow2->flow_dstmask.s_addr = emp->em_ena_idmask.s_addr; - flow2->flow_proto = emp->em_ena_protocol; - flow2->flow_sport = emp->em_ena_sport; - flow2->flow_dport = emp->em_ena_dport; - - put_flow(flow2, tdbp); - } - - put_flow(flow, tdbp); - - /* Setup the encap fields */ - encapdst.sen_len = SENT_IP4_LEN; - encapdst.sen_family = AF_ENCAP; - encapdst.sen_type = SENT_IP4; - encapdst.sen_ip_src.s_addr = flow->flow_src.s_addr; - encapdst.sen_ip_dst.s_addr = flow->flow_dst.s_addr; - encapdst.sen_proto = flow->flow_proto; - encapdst.sen_sport = flow->flow_sport; - encapdst.sen_dport = flow->flow_dport; - - encapgw.sen_len = SENT_IPSP_LEN; - encapgw.sen_family = AF_ENCAP; - encapgw.sen_type = SENT_IPSP; - encapgw.sen_ipsp_dst.s_addr = tdbp->tdb_dst.s_addr; - encapgw.sen_ipsp_spi = tdbp->tdb_spi; - encapgw.sen_ipsp_sproto = tdbp->tdb_sproto; - - encapnetmask.sen_len = SENT_IP4_LEN; - encapnetmask.sen_family = AF_ENCAP; - encapnetmask.sen_type = SENT_IP4; - encapnetmask.sen_ip_src.s_addr = flow->flow_srcmask.s_addr; - encapnetmask.sen_ip_dst.s_addr = flow->flow_dstmask.s_addr; - - if (flow->flow_proto) - { - encapnetmask.sen_proto = 0xff; - - if (flow->flow_sport) - encapnetmask.sen_sport = 0xffff; - - if (flow->flow_dport) - encapnetmask.sen_dport = 0xffff; - } - - /* If this is set, delete any old route for this flow */ - if (emp->em_ena_flags & ENABLE_FLAG_REPLACE) - rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, - (struct sockaddr *) 0, - (struct sockaddr *) &encapnetmask, 0, - (struct rtentry **) 0); - - /* Add the entry in the routing table */ - error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, - (struct sockaddr *) &encapgw, - (struct sockaddr *) &encapnetmask, - RTF_UP | RTF_GATEWAY | RTF_STATIC, - (struct rtentry **) 0); - - if (error) - { - encapdst.sen_len = SENT_IP4_LEN; - encapdst.sen_family = AF_ENCAP; - encapdst.sen_type = SENT_IP4; - encapdst.sen_ip_src.s_addr = flow3->flow_src.s_addr; - encapdst.sen_ip_dst.s_addr = flow3->flow_dst.s_addr; - encapdst.sen_proto = flow3->flow_proto; - encapdst.sen_sport = flow3->flow_sport; - encapdst.sen_dport = flow3->flow_dport; - - encapgw.sen_len = SENT_IPSP_LEN; - encapgw.sen_family = AF_ENCAP; - encapgw.sen_type = SENT_IPSP; - encapgw.sen_ipsp_dst.s_addr = flow3->flow_sa->tdb_dst.s_addr; - encapgw.sen_ipsp_spi = flow3->flow_sa->tdb_spi; - encapgw.sen_ipsp_sproto = flow3->flow_sa->tdb_sproto; - - encapnetmask.sen_len = SENT_IP4_LEN; - encapnetmask.sen_family = AF_ENCAP; - encapnetmask.sen_type = SENT_IP4; - encapnetmask.sen_ip_src.s_addr = flow3->flow_srcmask.s_addr; - encapnetmask.sen_ip_dst.s_addr = flow3->flow_dstmask.s_addr; - - if (flow3->flow_proto) - { - encapnetmask.sen_proto = 0xff; - - if (flow3->flow_sport) - encapnetmask.sen_sport = 0xffff; - - if (flow->flow_dport) - encapnetmask.sen_dport = 0xffff; - } - - /* Try to add the old entry back in */ - rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, - (struct sockaddr *) &encapgw, - (struct sockaddr *) &encapnetmask, - RTF_UP | RTF_GATEWAY | RTF_STATIC, - (struct rtentry **) 0); - - delete_flow(flow, tdbp); - if (flow2) - delete_flow(flow2, tdbp); - SENDERR(error); - } - - /* If this is a "local" packet flow */ - if (emp->em_ena_flags & ENABLE_FLAG_LOCAL) - { - encapdst.sen_ip_src.s_addr = INADDR_ANY; - encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST; - - if (emp->em_ena_flags & ENABLE_FLAG_REPLACE) - rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, - (struct sockaddr *) 0, - (struct sockaddr *) &encapnetmask, 0, - (struct rtentry **) 0); - - error = rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, - (struct sockaddr *) &encapgw, - (struct sockaddr *) &encapnetmask, - RTF_UP | RTF_GATEWAY | RTF_STATIC, - (struct rtentry **) 0); - - if (error) - { - /* Delete the first entry inserted */ - encapdst.sen_ip_src.s_addr = emp->em_ena_isrc.s_addr; - encapnetmask.sen_ip_src.s_addr = emp->em_ena_ismask.s_addr; - - rtrequest(RTM_DELETE, (struct sockaddr *) &encapdst, - (struct sockaddr *) 0, - (struct sockaddr *) &encapnetmask, 0, - (struct rtentry **) 0); - - /* Setup the old entries */ - encapdst.sen_len = SENT_IP4_LEN; - encapdst.sen_family = AF_ENCAP; - encapdst.sen_type = SENT_IP4; - encapdst.sen_ip_src.s_addr = flow3->flow_src.s_addr; - encapdst.sen_ip_dst.s_addr = flow3->flow_dst.s_addr; - encapdst.sen_proto = flow3->flow_proto; - encapdst.sen_sport = flow3->flow_sport; - encapdst.sen_dport = flow3->flow_dport; - - encapgw.sen_len = SENT_IPSP_LEN; - encapgw.sen_family = AF_ENCAP; - encapgw.sen_type = SENT_IPSP; - encapgw.sen_ipsp_dst.s_addr = flow3->flow_sa->tdb_dst.s_addr; - encapgw.sen_ipsp_spi = flow3->flow_sa->tdb_spi; - encapgw.sen_ipsp_sproto = flow3->flow_sa->tdb_sproto; - - encapnetmask.sen_len = SENT_IP4_LEN; - encapnetmask.sen_family = AF_ENCAP; - encapnetmask.sen_type = SENT_IP4; - encapnetmask.sen_ip_src.s_addr = flow3->flow_srcmask.s_addr; - encapnetmask.sen_ip_dst.s_addr = flow3->flow_dstmask.s_addr; - - if (flow3->flow_proto) - { - encapnetmask.sen_proto = 0xff; - - if (flow3->flow_sport) - encapnetmask.sen_sport = 0xffff; - - if (flow->flow_dport) - encapnetmask.sen_dport = 0xffff; - } - - rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, - (struct sockaddr *) &encapgw, - (struct sockaddr *) &encapnetmask, - RTF_UP | RTF_GATEWAY | RTF_STATIC, - (struct rtentry **) 0); - - encapdst.sen_ip_src.s_addr = INADDR_ANY; - encapnetmask.sen_ip_src.s_addr = INADDR_BROADCAST; - - rtrequest(RTM_ADD, (struct sockaddr *) &encapdst, - (struct sockaddr *) &encapgw, - (struct sockaddr *) &encapnetmask, - RTF_UP | RTF_GATEWAY | RTF_STATIC, - (struct rtentry **) 0); - - delete_flow(flow, tdbp); - delete_flow(flow2, tdbp); - SENDERR(error); - } - } - - /* - * If we're here, it means we've successfully added the new - * entries, so free the old ones. - */ - if (flow3) - delete_flow(flow3, flow3->flow_sa); - - if (flow4) - delete_flow(flow4, flow4->flow_sa); - - error = 0; + error = encap_enable_spi(emp->em_ena_spi, emp->em_ena_dst, + emp->em_ena_isrc, emp->em_ena_ismask, + emp->em_ena_idst, emp->em_ena_idmask, + emp->em_ena_sport, emp->em_ena_dport, + emp->em_ena_protocol, emp->em_ena_sproto, + emp->em_ena_flags); break; @@ -813,20 +971,16 @@ va_dcl break; case EMT_NOTIFY: - if (emlen <= EMT_NOTIFY_FLEN) + if (emlen < EMT_NOTIFY_FLEN) SENDERR(EINVAL); if (emp->em_not_type != NOTIFY_REQUEST_SA) SENDERR(EINVAL); - - tdbp = gettdb(emp->em_not_spi, emp->em_not_dst, - emp->em_not_sproto); - if (tdbp == NULL) - SENDERR(ENOENT); - - /* XXX Not yet finished */ - SENDERR(EINVAL); + error = encap_notify_sa(emp->em_not_spi, + emp->em_not_dst, emp->em_not_src, + emp->em_not_sport, emp->em_not_dport, + emp->em_not_protocol, emp->em_not_sproto); break; @@ -845,7 +999,7 @@ flush: } void -encap_sendnotify(int subtype, struct tdb *tdbp) +encap_sendnotify(int subtype, struct tdb *tdbp, void *data) { struct encap_msghdr em; struct mbuf *m; @@ -870,13 +1024,25 @@ encap_sendnotify(int subtype, struct tdb *tdbp) break; case NOTIFY_REQUEST_SA: - /* XXX */ - return; - + em.em_not_dst.s_addr = tdbp->tdb_dst.s_addr; +#ifdef INET + if (data != NULL) { + struct inpcb *inp = (struct inpcb *) data; + struct socket *so = inp->inp_socket; + em.em_not_dport = inp->inp_fport; + em.em_not_sport = inp->inp_lport; + if (so != 0) + em.em_not_protocol = so->so_proto->pr_protocol; + } +#endif + em.em_not_type = subtype; + em.em_not_satype = tdbp->tdb_satype; + break; + default: #ifdef ENCDEBUG if (encdebug) - log(LOG_WARNING, "encap_sendnotify(): unknown subtype %d\n", subtype); + log(LOG_WARNING, "encap_sendnotify(): unknown subtype %d\n", subtype); #endif /* ENCDEBUG */ return; } diff --git a/sys/net/encap.h b/sys/net/encap.h index 35942e1d884..6eabab45ed2 100644 --- a/sys/net/encap.h +++ b/sys/net/encap.h @@ -1,27 +1,33 @@ -/* $OpenBSD: encap.h,v 1.11 1997/11/04 09:10:54 provos Exp $ */ +/* $OpenBSD: encap.h,v 1.12 1998/05/18 21:10:18 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -128,6 +134,17 @@ struct sockaddr_encap #define SENT_IPSP_LEN 20 /* + * For encapsulation routes are possible not only for the destination + * address but also for the protocol, source and destination ports + * if available + */ + +struct route_enc { + struct rtentry *re_rt; + struct sockaddr_encap re_dst; +}; + +/* * Tunnel descriptors are setup and torn down using a socket of the * AF_ENCAP domain. The following defines the messages that can * be sent down that socket. @@ -253,9 +270,9 @@ struct encap_msghdr #define NOTIFY_HARD_EXPIRE 1 /* Hard expiration of SA */ #define NOTIFY_REQUEST_SA 2 /* Establish an SA */ -#define NOTIFY_SATYPE_CONF 0 /* SA should do encryption */ -#define NOTIFY_SATYPE_AUTH 1 /* SA should do authentication */ -#define NOTIFY_SATYPE_TUNNEL 2 /* SA should use tunneling */ +#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 em_ena_spi Eu.Ena.Spi #define em_ena_dst Eu.Ena.Dst @@ -276,6 +293,7 @@ struct encap_msghdr #define em_not_type Eu.Notify.Notification_Type #define em_not_spi Eu.Notify.Spi #define em_not_dst Eu.Notify.Dst +#define em_not_src Eu.Notify.Src #define em_not_satype Eu.Notify.Satype #define em_not_userid Eu.Notify.UserID #define em_not_msgid Eu.Notify.MsgID diff --git a/sys/net/if_enc.c b/sys/net/if_enc.c index 6cd97361fc5..9281157441d 100644 --- a/sys/net/if_enc.c +++ b/sys/net/if_enc.c @@ -1,27 +1,33 @@ -/* $OpenBSD: if_enc.c,v 1.6 1997/11/04 09:10:55 provos Exp $ */ +/* $OpenBSD: if_enc.c,v 1.7 1998/05/18 21:10:19 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 3076d4ad368..2dbc4a2dd1c 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.5 1997/12/15 10:13:03 deraadt Exp $ */ +/* $OpenBSD: rtsock.c,v 1.6 1998/05/18 21:10:21 provos Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -411,7 +411,8 @@ rt_xaddrs(cp, cplim, rtinfo) /* * Copy data from a buffer back into the indicated mbuf chain, * starting "off" bytes from the beginning, extending the mbuf - * chain if necessary. + * chain if necessary. The mbuf needs to be properly initalized + * including the setting of m_len. */ void m_copyback(m0, off, len, cp) diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index b9099aaac54..2325d1a2fee 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: igmp.c,v 1.3 1997/02/05 15:48:21 deraadt Exp $ */ +/* $OpenBSD: igmp.c,v 1.4 1998/05/18 21:10:24 provos Exp $ */ /* $NetBSD: igmp.c,v 1.15 1996/02/13 23:41:25 christos Exp $ */ /* @@ -524,7 +524,7 @@ igmp_sendpkt(inm, type) #endif /* MROUTING */ ip_output(m, (struct mbuf *)0, (struct route *)0, IP_MULTICASTOPTS, - &imo); + &imo, NULL); ++igmpstat.igps_snd_reports; } diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 276f5050df5..2e5dbd87acb 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.12 1998/02/11 03:58:31 deraadt Exp $ */ +/* $OpenBSD: in.h,v 1.13 1998/05/18 21:10:26 provos Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -246,7 +246,7 @@ struct ip_opts { #define IPSEC_LEVEL_USE 0x02 /* Send secure, accept any */ #define IPSEC_LEVEL_REQUIRE 0x03 /* Require secure inbound, also use */ #define IPSEC_LEVEL_UNIQUE 0x04 /* Use outbound SA that is unique */ -#define IPSEC_LEVEL_DEFAULT IPSEC_LEVEL_NONE +#define IPSEC_LEVEL_DEFAULT IPSEC_LEVEL_AVAIL #define IPSEC_AUTH_LEVEL_DEFAULT IPSEC_LEVEL_DEFAULT #define IPSEC_ESP_TRANS_LEVEL_DEFAULT IPSEC_LEVEL_DEFAULT diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index e0b35d2c4c6..c1e1c4ea0b5 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.23 1998/02/14 18:50:35 mickey Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.24 1998/05/18 21:10:27 provos Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -59,11 +59,18 @@ #include <netinet/ip_var.h> #include <dev/rndvar.h> +#ifdef IPSEC +#include <net/encap.h> +#include <netinet/ip_ipsp.h> + +extern int check_ipsec_policy __P((struct inpcb *, u_int32_t)); +#endif + struct in_addr zeroin_addr; -extern u_char ipsec_auth_default_level; -extern u_char ipsec_esp_trans_default_level; -extern u_char ipsec_esp_network_default_level; +extern int ipsec_auth_default_level; +extern int ipsec_esp_trans_default_level; +extern int ipsec_esp_network_default_level; /* * These configure the range of local port addresses assigned to @@ -418,7 +425,11 @@ in_pcbconnect(v, nam) inp->inp_faddr = sin->sin_addr; inp->inp_fport = sin->sin_port; in_pcbrehash(inp); +#ifdef IPSEC + return (check_ipsec_policy(inp, 0)); +#else return (0); +#endif } void diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index 3c58a150412..c0645b46070 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.9 1997/08/26 20:02:30 deraadt Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.10 1998/05/18 21:10:28 provos Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -60,10 +60,15 @@ struct inpcb { struct ip inp_ip; /* header prototype; should have more */ struct mbuf *inp_options; /* IP options */ struct ip_moptions *inp_moptions; /* IP multicast options */ - u_char inp_seclevel[4]; /* Only the first 3 are used for now */ + u_char inp_seclevel[3]; /* Only the first 3 are used for now */ #define SL_AUTH 0 /* Authentication level */ #define SL_ESP_TRANS 1 /* ESP transport level */ #define SL_ESP_NETWORK 2 /* ESP network (encapsulation) level */ + u_int8_t 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 */ }; struct inpcbtable { diff --git a/sys/netinet/ip_ah.c b/sys/netinet/ip_ah.c index 89d968576ef..1266a8157df 100644 --- a/sys/netinet/ip_ah.c +++ b/sys/netinet/ip_ah.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ah.c,v 1.13 1997/11/04 09:10:58 provos Exp $ */ +/* $OpenBSD: ip_ah.c,v 1.14 1998/05/18 21:10:30 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_ah.h b/sys/netinet/ip_ah.h index b93e78847cd..1e19c80a32d 100644 --- a/sys/netinet/ip_ah.h +++ b/sys/netinet/ip_ah.h @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ah.h,v 1.11 1997/11/24 19:14:11 provos Exp $ */ +/* $OpenBSD: ip_ah.h,v 1.12 1998/05/18 21:10:31 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_ah_new.c b/sys/netinet/ip_ah_new.c index 9c48aa271e2..736e288f62e 100644 --- a/sys/netinet/ip_ah_new.c +++ b/sys/netinet/ip_ah_new.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ah_new.c,v 1.16 1998/02/22 01:23:30 niklas Exp $ */ +/* $OpenBSD: ip_ah_new.c,v 1.17 1998/05/18 21:10:33 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -65,7 +71,7 @@ #include <netinet/ip_ah.h> #include <sys/syslog.h> -extern void encap_sendnotify(int, struct tdb *); +extern void encap_sendnotify(int, struct tdb *, void *); struct ah_hash ah_new_hash[] = { { ALG_AUTH_MD5, "HMAC-MD5-96", @@ -514,14 +520,14 @@ ah_new_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -530,14 +536,14 @@ ah_new_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } @@ -766,14 +772,14 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -782,14 +788,14 @@ ah_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } diff --git a/sys/netinet/ip_ah_old.c b/sys/netinet/ip_ah_old.c index 5ecfbb0b3e1..c93f46a6a2d 100644 --- a/sys/netinet/ip_ah_old.c +++ b/sys/netinet/ip_ah_old.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ah_old.c,v 1.13 1998/03/18 10:16:27 provos Exp $ */ +/* $OpenBSD: ip_ah_old.c,v 1.14 1998/05/18 21:10:34 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -64,7 +70,7 @@ #include <netinet/ip_ah.h> #include <sys/syslog.h> -extern void encap_sendnotify(int, struct tdb *); +extern void encap_sendnotify(int, struct tdb *, void *); struct ah_hash ah_old_hash[] = { { ALG_AUTH_MD5, "Keyed MD5", @@ -414,14 +420,14 @@ ah_old_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -430,14 +436,14 @@ ah_old_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } @@ -645,14 +651,14 @@ ah_old_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -661,14 +667,14 @@ ah_old_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } diff --git a/sys/netinet/ip_auth.c b/sys/netinet/ip_auth.c index 29b8c040ff4..51eaf9abe06 100644 --- a/sys/netinet/ip_auth.c +++ b/sys/netinet/ip_auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_auth.c,v 1.2 1998/02/17 01:39:01 dgregor Exp $ */ +/* $OpenBSD: ip_auth.c,v 1.3 1998/05/18 21:10:36 provos Exp $ */ /* * Copyright (C) 1997 by Darren Reed & Guido van Rooij. * @@ -7,7 +7,7 @@ * to the original author and the contributors. */ #if !defined(lint) -static const char rcsid[] = "@(#)$Id: ip_auth.c,v 1.2 1998/02/17 01:39:01 dgregor Exp $"; +static const char rcsid[] = "@(#)$Id: ip_auth.c,v 1.3 1998/05/18 21:10:36 provos Exp $"; #endif #if !defined(_KERNEL) && !defined(KERNEL) @@ -361,7 +361,7 @@ fr_authioctlloop: # if SOLARIS error = fr_qout(fr_auth[i].fra_q, m); # else /* SOLARIS */ - error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL); + error = ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); # endif /* SOLARIS */ if (error) fr_authstats.fas_sendfail++; diff --git a/sys/netinet/ip_esp.c b/sys/netinet/ip_esp.c index 3cb5ac1bd7d..6c6fab1426c 100644 --- a/sys/netinet/ip_esp.c +++ b/sys/netinet/ip_esp.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_esp.c,v 1.13 1997/11/04 09:11:09 provos Exp $ */ +/* $OpenBSD: ip_esp.c,v 1.14 1998/05/18 21:10:40 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_esp.h b/sys/netinet/ip_esp.h index fb6c8aa7a13..31fa69160e0 100644 --- a/sys/netinet/ip_esp.h +++ b/sys/netinet/ip_esp.h @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_esp.h,v 1.16 1997/11/24 19:14:13 provos Exp $ */ +/* $OpenBSD: ip_esp.h,v 1.17 1998/05/18 21:10:41 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_esp_new.c b/sys/netinet/ip_esp_new.c index db82e166ed0..d0284704f1d 100644 --- a/sys/netinet/ip_esp_new.c +++ b/sys/netinet/ip_esp_new.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_esp_new.c,v 1.18 1998/05/05 08:54:48 provos Exp $ */ +/* $OpenBSD: ip_esp_new.c,v 1.19 1998/05/18 21:10:43 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -65,7 +71,7 @@ #include <netinet/ip_ah.h> #include <sys/syslog.h> -extern void encap_sendnotify(int, struct tdb *); +extern void encap_sendnotify(int, struct tdb *, void *); extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); extern void des_set_key(caddr_t, caddr_t); @@ -869,14 +875,14 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -885,14 +891,14 @@ esp_new_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } @@ -1192,14 +1198,14 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -1208,14 +1214,14 @@ esp_new_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } diff --git a/sys/netinet/ip_esp_old.c b/sys/netinet/ip_esp_old.c index 485f70c4d3b..43fe771e4b1 100644 --- a/sys/netinet/ip_esp_old.c +++ b/sys/netinet/ip_esp_old.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_esp_old.c,v 1.16 1998/05/05 08:54:50 provos Exp $ */ +/* $OpenBSD: ip_esp_old.c,v 1.17 1998/05/18 21:10:45 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -69,7 +75,7 @@ extern void des_ecb3_encrypt(caddr_t, caddr_t, caddr_t, caddr_t, caddr_t, int); extern void des_ecb_encrypt(caddr_t, caddr_t, caddr_t, int); extern void des_set_key(caddr_t, caddr_t); -extern int encap_sendnotify(int, struct tdb *); +extern int encap_sendnotify(int, struct tdb *, void *); static void des1_encrypt(void *, u_int8_t *); static void des3_encrypt(void *, u_int8_t *); @@ -552,14 +558,14 @@ esp_old_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -568,14 +574,14 @@ esp_old_input(struct mbuf *m, struct tdb *tdb) { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } @@ -830,14 +836,14 @@ esp_old_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_soft_packets) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_PACKETS; } else if (tdb->tdb_flags & TDBF_SOFT_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_soft_bytes) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_BYTES; } } @@ -846,14 +852,14 @@ esp_old_output(struct mbuf *m, struct sockaddr_encap *gw, struct tdb *tdb, { if (tdb->tdb_cur_packets >= tdb->tdb_exp_packets) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else if (tdb->tdb_flags & TDBF_BYTES) if (tdb->tdb_cur_bytes >= tdb->tdb_exp_bytes) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } diff --git a/sys/netinet/ip_fil.c b/sys/netinet/ip_fil.c index 38149344f8b..9314d8364cc 100644 --- a/sys/netinet/ip_fil.c +++ b/sys/netinet/ip_fil.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_fil.c,v 1.17 1998/03/04 23:20:41 dgregor Exp $ */ +/* $OpenBSD: ip_fil.c,v 1.18 1998/05/18 21:10:46 provos Exp $ */ /* * Copyright (C) 1993-1997 by Darren Reed. * @@ -8,7 +8,7 @@ */ #if !defined(lint) static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed"; -static const char rcsid[] = "@(#)$Id: ip_fil.c,v 1.17 1998/03/04 23:20:41 dgregor Exp $"; +static const char rcsid[] = "@(#)$Id: ip_fil.c,v 1.18 1998/05/18 21:10:46 provos Exp $"; #endif #ifndef SOLARIS @@ -900,7 +900,7 @@ struct tcpiphdr *ti; /* * extra 0 in case of multicast */ - err = ip_output(m, (struct mbuf *)0, 0, 0, 0); + err = ip_output(m, (struct mbuf *)0, 0, 0, 0, NULL); # endif return err; } diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 8571efe8258..e9850626854 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.8 1998/01/06 01:38:36 deraadt Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.9 1998/05/18 21:10:48 provos Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -597,7 +597,7 @@ icmp_send(m, opts) buf, inet_ntoa(ip->ip_src)); } #endif - (void) ip_output(m, opts, NULL, 0, NULL); + (void) ip_output(m, opts, NULL, 0, NULL, NULL); } n_time diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7b6991b2afe..42b26d1a25d 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.30 1998/02/14 18:50:36 mickey Exp $ */ +/* $OpenBSD: ip_input.c,v 1.31 1998/05/18 21:10:49 provos Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -95,9 +95,9 @@ int ip_directedbcast = IPDIRECTEDBCAST; int ipprintfs = 0; #endif -u_char ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT; -u_char ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT; -u_char ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT; +int ipsec_auth_default_level = IPSEC_AUTH_LEVEL_DEFAULT; +int ipsec_esp_trans_default_level = IPSEC_ESP_TRANS_LEVEL_DEFAULT; +int ipsec_esp_network_default_level = IPSEC_ESP_NETWORK_LEVEL_DEFAULT; /* from in_pcb.c */ extern int ipport_firstauto; @@ -1217,7 +1217,8 @@ ip_forward(m, srcrt) } error = ip_output(m, (struct mbuf *)0, &ipforward_rt, - (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0); + (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), + 0, NULL); if (error) ipstat.ips_cantforward++; else { diff --git a/sys/netinet/ip_ip4.c b/sys/netinet/ip_ip4.c index 2280d4fb4f9..f935edbe1c8 100644 --- a/sys/netinet/ip_ip4.c +++ b/sys/netinet/ip_ip4.c @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ip4.c,v 1.16 1998/03/18 10:51:36 provos Exp $ */ +/* $OpenBSD: ip_ip4.c,v 1.17 1998/05/18 21:10:51 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_ip4.h b/sys/netinet/ip_ip4.h index 1456aa12e8c..132d9706d60 100644 --- a/sys/netinet/ip_ip4.h +++ b/sys/netinet/ip_ip4.h @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ip4.h,v 1.9 1997/11/04 09:11:15 provos Exp $ */ +/* $OpenBSD: ip_ip4.h,v 1.10 1998/05/18 21:10:55 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. diff --git a/sys/netinet/ip_ipsp.c b/sys/netinet/ip_ipsp.c index 23d0b50b1fc..3d1e940947a 100644 --- a/sys/netinet/ip_ipsp.c +++ b/sys/netinet/ip_ipsp.c @@ -1,28 +1,33 @@ - -/* $OpenBSD: ip_ipsp.c,v 1.25 1998/05/17 16:52:56 provos Exp $ */ +/* $OpenBSD: ip_ipsp.c,v 1.26 1998/05/18 21:10:57 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -43,6 +48,7 @@ #include <sys/errno.h> #include <sys/time.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <net/if.h> #include <net/route.h> @@ -65,13 +71,19 @@ #include <dev/rndvar.h> #include <sys/syslog.h> -int tdb_init __P((struct tdb *, struct mbuf *)); -int ipsp_kern __P((int, char **, int)); +int tdb_init __P((struct tdb *, struct mbuf *)); +int ipsp_kern __P((int, char **, int)); +u_int8_t get_sa_require __P((struct inpcb *)); +int check_ipsec_policy __P((struct inpcb *, u_int32_t)); +extern void encap_sendnotify __P((int, struct tdb *, void *)); + +extern int ipsec_auth_default_level; +extern int ipsec_esp_trans_default_level; +extern int ipsec_esp_network_default_level; int encdebug = 0; u_int32_t kernfs_epoch = 0; -extern void encap_sendnotify(int, struct tdb *); /* * This is the proper place to define the various encapsulation transforms. @@ -101,6 +113,161 @@ struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])]; unsigned char ipseczeroes[IPSEC_ZEROES_SIZE]; /* zeroes! */ +/* + * Check which transformationes 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 { + sareq |= ipsec_auth_default_level >= IPSEC_LEVEL_USE ? + NOTIFY_SATYPE_AUTH : 0; + sareq |= ipsec_esp_trans_default_level >= IPSEC_LEVEL_USE ? + NOTIFY_SATYPE_CONF : 0; + sareq |= ipsec_esp_network_default_level >= IPSEC_LEVEL_USE ? + NOTIFY_SATYPE_TUNNEL : 0; + } + + return (sareq); +} + +/* + * Check the socket policy and request a new SA with a key management + * daemon. Sometime the inp does not contain the destination address + * in that case use dst. + */ + +int +check_ipsec_policy(struct inpcb *inp, u_int32_t daddr) +{ + struct socket *so; + struct route_enc re0, *re = &re0; + struct sockaddr_encap *dst; + struct tdb tmptdb; + u_int8_t sa_require, sa_have; + int error, i; + + if (inp == NULL || ((so=inp->inp_socket) == 0)) + return (EINVAL); + + /* If IPSEC is not required just use what we got */ + if (!(sa_require = inp->inp_secrequire)) + return 0; + + bzero((caddr_t) re, sizeof(*re)); + dst = (struct sockaddr_encap *) &re->re_dst; + dst->sen_family = AF_ENCAP; + dst->sen_len = SENT_IP4_LEN; + dst->sen_type = SENT_IP4; + dst->sen_ip_src = inp->inp_laddr; + dst->sen_ip_dst.s_addr = inp->inp_faddr.s_addr ? + inp->inp_faddr.s_addr : daddr; + dst->sen_proto = so->so_proto->pr_protocol; + switch (dst->sen_proto) { + case IPPROTO_UDP: + case IPPROTO_TCP: + dst->sen_sport = inp->inp_lport; + dst->sen_dport = inp->inp_fport; + break; + default: + dst->sen_sport = 0; + dst->sen_dport = 0; + } + + /* Try to find a flow */ + rtalloc((struct route *) re); + + if (re->re_rt != NULL) { + struct tdb *tdb; + struct sockaddr_encap *gw; + + gw = (struct sockaddr_encap *) (re->re_rt->rt_gateway); + + if (gw->sen_type == SENT_IPSP) { + tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, + gw->sen_ipsp_dst, + gw->sen_ipsp_sproto); + + SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb); + } else + sa_have = 0; + + RTFREE(re->re_rt); + + /* Check if our requirements are met */ + if (!(sa_require & ~sa_have)) + return 0; + } else + sa_have = 0; + + error = i = 0; + + inp->inp_secresult = SR_WAIT; + + /* If necessary try to notify keymanagement three times */ + while (i < 3) { +#ifdef ENCDEBUG + if (encdebug) + printf("ipsec: send SA request (%d), remote ip: %0x, SA type: %d\n", + i+1, dst->sen_ip_dst, sa_require); +#endif /* ENCDEBUG */ + + /* Send notify */ + bzero((caddr_t) &tmptdb, sizeof(tmptdb)); + tmptdb.tdb_src = dst->sen_ip_src; + tmptdb.tdb_dst = dst->sen_ip_dst; + /* + * When we already have an insufficient SA, we need to + * establish a new SA which combines the required + * attributes and the already existant. This can go + * once we can do socket specific keying. + */ + tmptdb.tdb_satype = sa_require | sa_have; + encap_sendnotify(NOTIFY_REQUEST_SA, &tmptdb, inp); + + /* + * Wait for the keymanagement daemon to establich a new SA, + * even on error check again, perhaps some other process + * already established the necessary SA. + */ + error = tsleep((caddr_t)inp, PSOCK|PCATCH, "ipsecnotify", 30*hz); + +#ifdef ENCDEBUG + if (encdebug) + printf("check_ipsec: sleep %d\n", error); +#endif /* ENCDEBUG */ + + if (error && error != EWOULDBLOCK) + break; + /* + * A Key Management daemon returned an apropriate SA back + * to the kernel, the kernel noted that state in the waiting + * socket. + */ + if (inp->inp_secresult == SR_SUCCESS) + return (0); + /* + * Key Management returned a permanent failure, we do not + * need to retry again. XXX - when more than one key + * management daemon is available we can not do that. + */ + if (inp->inp_secresult == SR_FAILED) + break; + i++; + } + + return (error ? error : EWOULDBLOCK); +} /* * Reserve an SPI; the SA is not valid yet though. Zero is reserved as @@ -267,7 +434,7 @@ handle_expirations(void *arg) { if (tdb->tdb_soft_timeout <= time.tv_sec) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_TIMER; } else @@ -275,7 +442,7 @@ handle_expirations(void *arg) if (tdb->tdb_first_use + tdb->tdb_soft_first_use <= time.tv_sec) { - encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb); + encap_sendnotify(NOTIFY_SOFT_EXPIRE, tdb, NULL); tdb->tdb_flags &= ~TDBF_SOFT_FIRSTUSE; } } @@ -285,7 +452,7 @@ handle_expirations(void *arg) { if (tdb->tdb_exp_timeout <= time.tv_sec) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } else @@ -293,7 +460,7 @@ handle_expirations(void *arg) if (tdb->tdb_first_use + tdb->tdb_exp_first_use <= time.tv_sec) { - encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb); + encap_sendnotify(NOTIFY_HARD_EXPIRE, tdb, NULL); tdb_delete(tdb, 0); } } diff --git a/sys/netinet/ip_ipsp.h b/sys/netinet/ip_ipsp.h index 013d5581ca0..9d8e4e05722 100644 --- a/sys/netinet/ip_ipsp.h +++ b/sys/netinet/ip_ipsp.h @@ -1,27 +1,33 @@ -/* $OpenBSD: ip_ipsp.h,v 1.18 1998/03/18 10:51:38 provos Exp $ */ +/* $OpenBSD: ip_ipsp.h,v 1.19 1998/05/18 21:10:59 provos Exp $ */ /* - * The author of this code is John Ioannidis, ji@tla.org, - * (except when noted otherwise). + * The authors of this code are John Ioannidis (ji@tla.org), + * Angelos D. Keromytis (kermit@csd.uch.gr) and + * Niels Provos (provos@physnet.uni-hamburg.de). * - * This code was written for BSD/OS in Athens, Greece, in November 1995. + * This code was written by John Ioannidis for BSD/OS in Athens, Greece, + * in November 1995. * * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996, - * by Angelos D. Keromytis, kermit@forthnet.gr. + * by Angelos D. Keromytis. * - * Additional transforms and features in 1997 by Angelos D. Keromytis and - * Niels Provos. + * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis + * and Niels Provos. * - * Copyright (C) 1995, 1996, 1997 by John Ioannidis, Angelos D. Keromytis + * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis * and Niels Provos. * * Permission to use, copy, and modify this software without fee * is hereby granted, provided that this entire notice is included in * all copies of any software which is or includes a copy or - * modification of this software. + * modification of this software. + * You may use this code under the GNU public license if you so wish. Please + * contribute changes back to the authors under this freer than GPL license + * so that we may further the use of strong encryption without limitations to + * all. * * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTY. IN PARTICULAR, NEITHER AUTHOR MAKES ANY + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR * PURPOSE. @@ -186,6 +192,26 @@ struct expiration *explist; extern struct xformsw xformsw[], *xformswNXFORMSW; u_int32_t notify_msgids; +/* Check if a given tdb has encryption, authentication and/or tunneling */ +#define TDB_ATTRIB(x) (((x)->tdb_confname != NULL ? NOTIFY_SATYPE_CONF : 0)| \ + ((x)->tdb_authname != NULL ? NOTIFY_SATYPE_AUTH : 0)| \ + ((x)->tdb_confname != NULL && \ + ((x)->tdb_flags & TDBF_TUNNELING) ? NOTIFY_SATYPE_TUNNEL : 0)) + +/* Traverse spi chain and get attributes */ + +#define SPI_CHAIN_ATTRIB(have, TDB_DIR, TDBP) {\ + 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; \ + } \ +} + /* TDB management routines */ extern u_int32_t reserve_spi(u_int32_t, struct in_addr, u_int8_t, int *); extern struct tdb *gettdb(u_int32_t, struct in_addr, u_int8_t); diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index 247a89077a2..4bb4da071db 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.c,v 1.7 1997/09/28 23:09:58 deraadt Exp $ */ +/* $OpenBSD: ip_mroute.c,v 1.8 1998/05/18 21:11:00 provos Exp $ */ /* $NetBSD: ip_mroute.c,v 1.27 1996/05/07 02:40:50 thorpej Exp $ */ /* @@ -1714,7 +1714,7 @@ tbf_send_packet(vifp,m) if (vifp->v_flags & VIFF_TUNNEL) { /* If tunnel options */ ip_output(m, (struct mbuf *)0, &vifp->v_route, - IP_FORWARDING, NULL); + IP_FORWARDING, NULL, NULL); } else { /* if physical interface option, extract the options and then send */ struct ip *ip = mtod(m, struct ip *); @@ -1727,7 +1727,7 @@ tbf_send_packet(vifp,m) #endif error = ip_output(m, (struct mbuf *)0, (struct route *)0, - IP_FORWARDING|IP_MULTICASTOPTS, &imo); + IP_FORWARDING|IP_MULTICASTOPTS, &imo, NULL); if (mrtdebug & DEBUG_XMIT) log(LOG_DEBUG, "phyint_send on vif %d err %d\n", vifp-viftable, error); } diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index d2283dd35c6..6f2a8534daf 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.26 1998/03/18 10:16:31 provos Exp $ */ +/* $OpenBSD: ip_output.c,v 1.27 1998/05/18 21:11:02 provos Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -45,6 +45,7 @@ #include <sys/socketvar.h> #include <sys/systm.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <net/if.h> #include <net/route.h> @@ -68,6 +69,9 @@ #include <netinet/udp.h> #include <netinet/tcp.h> #include <sys/syslog.h> + +extern u_int8_t get_sa_require __P((struct inpcb *)); + #endif static struct mbuf *ip_insertoptions __P((struct mbuf *, struct mbuf *, int *)); @@ -77,6 +81,12 @@ static void ip_mloopback int (*fr_checkp) __P((struct ip *, int, struct ifnet *, int, struct mbuf **)); #endif +#ifdef IPSEC +extern int ipsec_auth_default_level; +extern int ipsec_esp_trans_default_level; +extern int ipsec_esp_network_default_level; +#endif + /* * IP output. The packet in mbuf chain m contains a skeletal IP * header (with len, off, ttl, proto, tos, src, dst). @@ -110,6 +120,7 @@ ip_output(m0, va_alist) struct udphdr *udp; struct tcphdr *tcp; struct expiration *exp; + struct inpcb *inp; #endif va_start(ap, m0); @@ -117,6 +128,9 @@ ip_output(m0, va_alist) ro = va_arg(ap, struct route *); flags = va_arg(ap, int); imo = va_arg(ap, struct ip_moptions *); +#ifdef IPSEC + inp = va_arg(ap, struct inpcb *); +#endif va_end(ap); @@ -147,13 +161,20 @@ ip_output(m0, va_alist) /* * Check if the packet needs encapsulation */ - if (!(flags & IP_ENCAPSULATED)) { - struct route_enc { - struct rtentry *re_rt; - struct sockaddr_encap re_dst; - } re0, *re = &re0; + if (!(flags & IP_ENCAPSULATED) && + (inp == NULL || + (inp->inp_seclevel[SL_AUTH] != IPSEC_LEVEL_BYPASS || + inp->inp_seclevel[SL_ESP_TRANS] != IPSEC_LEVEL_BYPASS || + inp->inp_seclevel[SL_ESP_NETWORK] != IPSEC_LEVEL_BYPASS))) { + struct route_enc re0, *re = &re0; struct sockaddr_encap *dst, *gw; struct tdb *tdb; + u_int8_t sa_require, sa_have = 0; + + if (inp == NULL) + sa_require = get_sa_require(inp); + else + sa_require = inp->inp_secrequire; bzero((caddr_t) re, sizeof(*re)); dst = (struct sockaddr_encap *) &re->re_dst; @@ -234,6 +255,15 @@ ip_output(m0, va_alist) tdb = (struct tdb *) gettdb(gw->sen_ipsp_spi, gw->sen_ipsp_dst, gw->sen_ipsp_sproto); + /* + * Now we check if this tdb has all the transforms which + * are requried by the socket or our default policy. + */ + SPI_CHAIN_ATTRIB(sa_have, tdb_onext, tdb); + + if (sa_require & ~sa_have) + goto no_encap; + #ifdef ENCDEBUG if (encdebug && (tdb == NULL)) printf("ip_output(): non-existant TDB for SA %08x/%x/%d\n", @@ -396,12 +426,17 @@ expbail: NTOHS(ip->ip_len); NTOHS(ip->ip_off); return ip_output(m, NULL, NULL, - IP_ENCAPSULATED | IP_RAWOUTPUT, NULL); + IP_ENCAPSULATED | IP_RAWOUTPUT, NULL, NULL); no_encap: /* This is for possible future use, don't move or delete */ if (re->re_rt) RTFREE(re->re_rt); + /* We did no IPSec encapsulation but the socket required it */ + if (sa_require) { + error = EHOSTUNREACH; + goto done; + } } #endif /* IPSEC */ @@ -795,6 +830,7 @@ ip_ctloutput(op, so, level, optname, mp) register struct inpcb *inp = sotoinpcb(so); register struct mbuf *m = *mp; register int optval = 0; + struct proc *p = curproc; /* XXX */ int error = 0; if (level != IPPROTO_IP) { @@ -898,24 +934,48 @@ ip_ctloutput(op, so, level, optname, mp) #ifndef IPSEC error = EINVAL; #else - if (m == 0 || m->m_len != sizeof(u_char)) { + if (m == 0 || m->m_len != sizeof(int)) { error = EINVAL; break; } optval = *mtod(m, u_char *); + + if (optval < IPSEC_LEVEL_BYPASS || + optval > IPSEC_LEVEL_UNIQUE) { + error = EINVAL; + break; + } + switch (optname) { case IP_AUTH_LEVEL: + if (optval < ipsec_auth_default_level && + suser(p->p_ucred, &p->p_acflag)) { + error = EACCES; + break; + } inp->inp_seclevel[SL_AUTH] = optval; break; case IP_ESP_TRANS_LEVEL: + if (optval < ipsec_esp_trans_default_level && + suser(p->p_ucred, &p->p_acflag)) { + error = EACCES; + break; + } inp->inp_seclevel[SL_ESP_TRANS] = optval; break; case IP_ESP_NETWORK_LEVEL: + if (optval < ipsec_esp_network_default_level && + suser(p->p_ucred, &p->p_acflag)) { + error = EACCES; + break; + } inp->inp_seclevel[SL_ESP_NETWORK] = optval; break; } + if (!error) + inp->inp_secrequire = get_sa_require(inp); #endif break; diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c index e4aba65a05e..5ca4b919dcc 100644 --- a/sys/netinet/raw_ip.c +++ b/sys/netinet/raw_ip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip.c,v 1.10 1997/07/24 00:31:14 deraadt Exp $ */ +/* $OpenBSD: raw_ip.c,v 1.11 1998/05/18 21:11:04 provos Exp $ */ /* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */ /* @@ -56,6 +56,10 @@ #include <netinet/in_pcb.h> #include <netinet/in_var.h> +#ifdef IPSEC +extern int check_ipsec_policy __P((struct inpcb *, u_int32_t)); +#endif + #include <machine/stdarg.h> struct inpcbtable rawcbtable; @@ -208,7 +212,7 @@ rip_output(m, va_alist) ipstat.ips_rawout++; } return (ip_output(m, inp->inp_options, &inp->inp_route, flags, - inp->inp_moptions)); + inp->inp_moptions, inp)); } /* @@ -412,6 +416,9 @@ rip_usrreq(so, req, m, nam, control) } dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr; } +#ifdef IPSEC + if (!(error = check_ipsec_policy(inp, dst))) +#endif error = rip_output(m, so, dst); m = NULL; break; diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index 5d024b41c80..7bfe9d49fe1 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.9 1998/02/03 19:06:30 deraadt Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.10 1998/05/18 21:11:06 provos Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -566,7 +566,7 @@ send: ((struct ip *)ti)->ip_tos = tp->t_inpcb->inp_ip.ip_tos; /* XXX */ #if BSD >= 43 error = ip_output(m, tp->t_inpcb->inp_options, &tp->t_inpcb->inp_route, - so->so_options & SO_DONTROUTE, 0); + so->so_options & SO_DONTROUTE, 0, tp->t_inpcb); #else error = ip_output(m, (struct mbuf *)0, &tp->t_inpcb->inp_route, so->so_options & SO_DONTROUTE); diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index b02054e591b..3d5646e21f8 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.9 1997/08/26 20:02:33 deraadt Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.10 1998/05/18 21:11:07 provos Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -216,7 +216,7 @@ tcp_respond(tp, ti, m, ack, seq, flags) ti->ti_sum = in_cksum(m, tlen); ((struct ip *)ti)->ip_len = tlen; ((struct ip *)ti)->ip_ttl = ip_defttl; - (void) ip_output(m, NULL, ro, 0, NULL); + (void) ip_output(m, NULL, ro, 0, NULL, tp ? tp->t_inpcb : NULL); } /* diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 2b89813c071..f1f2cd1cb4f 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.20 1998/02/28 03:39:58 angelos Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.21 1998/05/18 21:11:09 provos Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -69,6 +69,10 @@ #include <netinet/tcp_debug.h> #include <dev/rndvar.h> +#ifdef IPSEC +extern int check_ipsec_policy __P((struct inpcb *, u_int32_t)); +#endif + /* * TCP protocol interface to socket abstraction. */ @@ -288,6 +292,11 @@ tcp_usrreq(so, req, m, nam, control) * marker if URG set. Possibly send more data. */ case PRU_SEND: +#ifdef IPSEC + error = check_ipsec_policy(inp, 0); + if (error) + break; +#endif sbappend(&so->so_snd, m); error = tcp_output(tp); break; diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index a4385204238..b3bf8845dd5 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_usrreq.c,v 1.14 1998/01/24 18:21:39 mickey Exp $ */ +/* $OpenBSD: udp_usrreq.c,v 1.15 1998/05/18 21:11:12 provos Exp $ */ /* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */ /* @@ -63,6 +63,10 @@ #include <netinet/udp.h> #include <netinet/udp_var.h> +#ifdef IPSEC +extern int check_ipsec_policy __P((struct inpcb *, u_int32_t)); +#endif + #include <machine/stdarg.h> /* @@ -501,7 +505,7 @@ udp_output(m, va_alist) udpstat.udps_opackets++; error = ip_output(m, inp->inp_options, &inp->inp_route, inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), - inp->inp_moptions); + inp->inp_moptions, inp); bail: if (addr) { @@ -611,6 +615,11 @@ udp_usrreq(so, req, m, addr, control) break; case PRU_SEND: +#ifdef IPSEC + error = check_ipsec_policy(inp,0); + if (error) + return (error); +#endif return (udp_output(m, inp, addr, control)); case PRU_ABORT: |