diff options
author | 2020-02-07 13:01:34 +0000 | |
---|---|---|
committer | 2020-02-07 13:01:34 +0000 | |
commit | a3b4c2abd806f43bf603f8f0086c568ea77dc3d0 (patch) | |
tree | ac1c82243a071104951c9de3c1c3440edf17afe0 | |
parent | Unhook usr.sbin/bind from the build and hook up new dig source (diff) | |
download | wireguard-openbsd-a3b4c2abd806f43bf603f8f0086c568ea77dc3d0.tar.xz wireguard-openbsd-a3b4c2abd806f43bf603f8f0086c568ea77dc3d0.zip |
Extend the ipsecctl(8) parser to set the udpencap flag and port
number of an SA. This will be useful to test IPsec with NAT-T.
OK sthen@ tobhe@
-rw-r--r-- | sbin/ipsecctl/ipsec.conf.5 | 8 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsecctl.h | 4 | ||||
-rw-r--r-- | sbin/ipsecctl/parse.y | 48 | ||||
-rw-r--r-- | sbin/ipsecctl/pfkey.c | 23 |
4 files changed, 65 insertions, 18 deletions
diff --git a/sbin/ipsecctl/ipsec.conf.5 b/sbin/ipsecctl/ipsec.conf.5 index a956a37835c..53d0c8bf030 100644 --- a/sbin/ipsecctl/ipsec.conf.5 +++ b/sbin/ipsecctl/ipsec.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ipsec.conf.5,v 1.156 2019/11/10 20:51:52 landry Exp $ +.\" $OpenBSD: ipsec.conf.5,v 1.157 2020/02/07 13:01:34 bluhm Exp $ .\" .\" Copyright (c) 2004 Mathieu Sauve-Frankel All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 10 2019 $ +.Dd $Mdocdate: February 7 2020 $ .Dt IPSEC.CONF 5 .Os .Sh NAME @@ -890,6 +890,10 @@ and The SPI identifies a specific SA. .Ar number is a 32-bit value and needs to be unique. +.It Ic udpencap Op Ic port Ar dport +For NAT-Traversal encapsulate the IPsec traffic in UDP. +The port number of the peer can be set to +.Ar dport . .It Ic auth Ar algorithm For ESP and AH an authentication algorithm can be specified. diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h index 05e7618c8a8..6919659b730 100644 --- a/sbin/ipsecctl/ipsecctl.h +++ b/sbin/ipsecctl/ipsecctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsecctl.h,v 1.73 2017/11/20 10:51:24 mpi Exp $ */ +/* $OpenBSD: ipsecctl.h,v 1.74 2020/02/07 13:01:34 bluhm Exp $ */ /* * Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org> * @@ -208,6 +208,8 @@ struct ipsec_rule { u_int8_t ikemode; u_int8_t p1ie; u_int8_t p2ie; + u_int8_t udpencap; + u_int16_t udpdport; u_int16_t sport; u_int16_t dport; u_int32_t spi; diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y index 87ae7acbeb8..d61f6d5e151 100644 --- a/sbin/ipsecctl/parse.y +++ b/sbin/ipsecctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.177 2019/08/26 18:53:58 tobhe Exp $ */ +/* $OpenBSD: parse.y,v 1.178 2020/02/07 13:01:34 bluhm Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -205,7 +205,8 @@ int validate_sa(u_int32_t, u_int8_t, struct ipsec_transforms *, struct ipsec_key *, struct ipsec_key *, u_int8_t); struct ipsec_rule *create_sa(u_int8_t, u_int8_t, struct ipsec_hosts *, - u_int32_t, struct ipsec_transforms *, + u_int32_t, u_int8_t, u_int16_t, + struct ipsec_transforms *, struct ipsec_key *, struct ipsec_key *); struct ipsec_rule *reverse_sa(struct ipsec_rule *, u_int32_t, struct ipsec_key *, struct ipsec_key *); @@ -257,6 +258,10 @@ typedef struct { u_int32_t spiin; } spis; struct { + u_int8_t encap; + u_int16_t port; + } udpencap; + struct { struct ipsec_key *keyout; struct ipsec_key *keyin; } authkeys; @@ -281,7 +286,7 @@ typedef struct { %token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE %token PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFETIME %token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG -%token INCLUDE BUNDLE +%token INCLUDE BUNDLE UDPENCAP %token <v.string> STRING %token <v.number> NUMBER %type <v.string> string @@ -300,6 +305,7 @@ typedef struct { %type <v.ids> ids %type <v.id> id %type <v.spis> spispec +%type <v.udpencap> udpencap %type <v.authkeys> authkeyspec %type <v.enckeys> enckeyspec %type <v.string> bundlestring @@ -347,7 +353,7 @@ tcpmd5rule : TCPMD5 hosts spispec authkeyspec { struct ipsec_rule *r; r = create_sa(IPSEC_TCPMD5, IPSEC_TRANSPORT, &$2, - $3.spiout, NULL, $4.keyout, NULL); + $3.spiout, 0, 0, NULL, $4.keyout, NULL); if (r == NULL) YYERROR; @@ -357,17 +363,17 @@ tcpmd5rule : TCPMD5 hosts spispec authkeyspec { } ; -sarule : satype tmode hosts spispec transforms authkeyspec +sarule : satype tmode hosts spispec udpencap transforms authkeyspec enckeyspec bundlestring { struct ipsec_rule *r; - r = create_sa($1, $2, &$3, $4.spiout, $5, $6.keyout, - $7.keyout); + r = create_sa($1, $2, &$3, $4.spiout, $5.encap, $5.port, + $6, $7.keyout, $8.keyout); if (r == NULL) YYERROR; - if (expand_rule(r, NULL, 0, $4.spiin, $6.keyin, - $7.keyin, $8)) + if (expand_rule(r, NULL, 0, $4.spiin, $7.keyin, + $8.keyin, $9)) errx(1, "sarule: expand_rule"); } ; @@ -668,6 +674,19 @@ spispec : SPI STRING { } ; +udpencap : /* empty */ { + $$.encap = 0; + } + | UDPENCAP { + $$.encap = 1; + $$.port = 0; + } + | UDPENCAP PORT NUMBER { + $$.encap = 1; + $$.port = $3; + } + ; + transforms : { if ((ipsec_transforms = calloc(1, sizeof(struct ipsec_transforms))) == NULL) @@ -1014,6 +1033,7 @@ lookup(char *s) { "transport", TRANSPORT }, { "tunnel", TUNNEL }, { "type", TYPE }, + { "udpencap", UDPENCAP }, { "use", USE } }; const struct keywords *p; @@ -2209,6 +2229,8 @@ copyrule(struct ipsec_rule *rule) r->dport = rule->dport; r->ikemode = rule->ikemode; r->spi = rule->spi; + r->udpencap = rule->udpencap; + r->udpdport = rule->udpdport; r->nr = rule->nr; return (r); @@ -2398,8 +2420,8 @@ add_sabundle(struct ipsec_rule *r, char *bundle) struct ipsec_rule * create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts, - u_int32_t spi, struct ipsec_transforms *xfs, struct ipsec_key *authkey, - struct ipsec_key *enckey) + u_int32_t spi, u_int8_t udpencap, u_int16_t udpdport, + struct ipsec_transforms *xfs, struct ipsec_key *authkey, struct ipsec_key *enckey) { struct ipsec_rule *r; @@ -2416,6 +2438,8 @@ create_sa(u_int8_t satype, u_int8_t tmode, struct ipsec_hosts *hosts, r->src = hosts->src; r->dst = hosts->dst; r->spi = spi; + r->udpencap = udpencap; + r->udpdport = udpdport; r->xfs = xfs; r->authkey = authkey; r->enckey = enckey; @@ -2443,6 +2467,8 @@ reverse_sa(struct ipsec_rule *rule, u_int32_t spi, struct ipsec_key *authkey, reverse->src = copyhost(rule->dst); reverse->dst = copyhost(rule->src); reverse->spi = spi; + reverse->udpencap = rule->udpencap; + reverse->udpdport = rule->udpdport; reverse->xfs = copytransforms(rule->xfs); reverse->authkey = authkey; reverse->enckey = enckey; diff --git a/sbin/ipsecctl/pfkey.c b/sbin/ipsecctl/pfkey.c index 1f7aa0c0522..b1d5c5e5893 100644 --- a/sbin/ipsecctl/pfkey.c +++ b/sbin/ipsecctl/pfkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkey.c,v 1.61 2019/06/28 13:32:44 deraadt Exp $ */ +/* $OpenBSD: pfkey.c,v 1.62 2020/02/07 13:01:34 bluhm Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> * Copyright (c) 2003, 2004 Markus Friedl <markus@openbsd.org> @@ -49,6 +49,7 @@ static int pfkey_flow(int, u_int8_t, u_int8_t, u_int8_t, u_int8_t, struct ipsec_auth *, u_int8_t); static int pfkey_sa(int, u_int8_t, u_int8_t, u_int32_t, struct ipsec_addr_wrap *, struct ipsec_addr_wrap *, + u_int8_t, u_int16_t, struct ipsec_transforms *, struct ipsec_key *, struct ipsec_key *, u_int8_t); static int pfkey_sabundle(int, u_int8_t, u_int8_t, u_int8_t, @@ -388,6 +389,7 @@ pfkey_flow(int sd, u_int8_t satype, u_int8_t action, u_int8_t direction, static int pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, struct ipsec_addr_wrap *src, struct ipsec_addr_wrap *dst, + u_int8_t encap, u_int16_t dport, struct ipsec_transforms *xfs, struct ipsec_key *authkey, struct ipsec_key *enckey, u_int8_t tmode) { @@ -395,6 +397,7 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, struct sadb_sa sa; struct sadb_address sa_src, sa_dst; struct sadb_key sa_authkey, sa_enckey; + struct sadb_x_udpencap udpencap; struct sockaddr_storage ssrc, sdst; struct iovec iov[IOV_CNT]; ssize_t n; @@ -541,6 +544,12 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, sa_dst.sadb_address_len = (sizeof(sa_dst) + ROUNDUP(sdst.ss_len)) / 8; sa_dst.sadb_address_exttype = SADB_EXT_ADDRESS_DST; + if (encap) { + sa.sadb_sa_flags |= SADB_X_SAFLAGS_UDPENCAP; + udpencap.sadb_x_udpencap_exttype = SADB_X_EXT_UDPENCAP; + udpencap.sadb_x_udpencap_len = sizeof(udpencap) / 8; + udpencap.sadb_x_udpencap_port = htons(dport); + } if (action == SADB_ADD && !authkey && !enckey && satype != SADB_X_SATYPE_IPCOMP && satype != SADB_X_SATYPE_IPIP) { /* XXX ENCNULL */ warnx("no key specified"); @@ -592,6 +601,12 @@ pfkey_sa(int sd, u_int8_t satype, u_int8_t action, u_int32_t spi, smsg.sadb_msg_len += sa_dst.sadb_address_len; iov_cnt++; + if (encap) { + iov[iov_cnt].iov_base = &udpencap; + iov[iov_cnt].iov_len = sizeof(udpencap); + smsg.sadb_msg_len += udpencap.sadb_x_udpencap_len; + iov_cnt++; + } if (authkey) { /* authentication key */ iov[iov_cnt].iov_base = &sa_authkey; @@ -1170,12 +1185,12 @@ pfkey_ipsec_establish(int action, struct ipsec_rule *r) switch (action) { case ACTION_ADD: ret = pfkey_sa(fd, satype, SADB_ADD, r->spi, - r->src, r->dst, r->xfs, r->authkey, r->enckey, - r->tmode); + r->src, r->dst, r->udpencap, r->udpdport, + r->xfs, r->authkey, r->enckey, r->tmode); break; case ACTION_DELETE: ret = pfkey_sa(fd, satype, SADB_DELETE, r->spi, - r->src, r->dst, r->xfs, NULL, NULL, r->tmode); + r->src, r->dst, 0, 0, r->xfs, NULL, NULL, r->tmode); break; default: return -1; |