diff --git a/tools/regression/priv/Makefile b/tools/regression/priv/Makefile index 1377513daabb..6f494a89bd4b 100644 --- a/tools/regression/priv/Makefile +++ b/tools/regression/priv/Makefile @@ -46,4 +46,7 @@ SRCS= main.c \ NO_MAN= WARNS= 3 +DPADD+= ${LIBIPSEC} +LDADD+= -lipsec + .include diff --git a/tools/regression/priv/main.c b/tools/regression/priv/main.c index 11f92498d89c..5dd411a22d46 100644 --- a/tools/regression/priv/main.c +++ b/tools/regression/priv/main.c @@ -135,8 +135,27 @@ static struct test tests[] = { { "priv_msgbuf_unprivok", priv_msgbuf_unprivok_setup, priv_msgbuf_unprivok, priv_msgbuf_cleanup }, - { "priv_netinet_ipsec_pfkey", priv_netinet_ipsec_pfkey_setup, - priv_netinet_ipsec_pfkey, priv_netinet_ipsec_pfkey_cleanup }, + { "priv_netinet_ipsec_pfkey", NULL, priv_netinet_ipsec_pfkey, NULL }, + + { "priv_netinet_ipsec_policy4_bypass", + priv_netinet_ipsec_policy4_bypass_setup, + priv_netinet_ipsec_policy4_bypass, + priv_netinet_ipsec_policy_bypass_cleanup }, + + { "priv_netinet_ipsec_policy6_bypass", + priv_netinet_ipsec_policy6_bypass_setup, + priv_netinet_ipsec_policy6_bypass, + priv_netinet_ipsec_policy_bypass_cleanup }, + + { "priv_netinet_ipsec_policy4_entrust", + priv_netinet_ipsec_policy4_entrust_setup, + priv_netinet_ipsec_policy4_entrust, + priv_netinet_ipsec_policy_entrust_cleanup }, + + { "priv_netinet_ipsec_policy6_entrust", + priv_netinet_ipsec_policy6_entrust_setup, + priv_netinet_ipsec_policy6_entrust, + priv_netinet_ipsec_policy_entrust_cleanup }, { "priv_netinet_raw", priv_netinet_raw_setup, priv_netinet_raw, priv_netinet_raw_cleanup }, diff --git a/tools/regression/priv/main.h b/tools/regression/priv/main.h index 04c992e8fa15..475a47ebbd17 100644 --- a/tools/regression/priv/main.h +++ b/tools/regression/priv/main.h @@ -138,9 +138,17 @@ void priv_msgbuf_unprivok(int, int, struct test *); void priv_msgbuf_cleanup(int, int, struct test *); -int priv_netinet_ipsec_pfkey_setup(int, int, struct test *); void priv_netinet_ipsec_pfkey(int, int, struct test *); -void priv_netinet_ipsec_pfkey_cleanup(int, int, struct test *); +int priv_netinet_ipsec_policy4_bypass_setup(int, int, struct test *); +void priv_netinet_ipsec_policy4_bypass(int, int, struct test *); +int priv_netinet_ipsec_policy6_bypass_setup(int, int, struct test *); +void priv_netinet_ipsec_policy6_bypass(int, int, struct test *); +void priv_netinet_ipsec_policy_bypass_cleanup(int, int, struct test *); +int priv_netinet_ipsec_policy4_entrust_setup(int, int, struct test *); +void priv_netinet_ipsec_policy4_entrust(int, int, struct test *); +int priv_netinet_ipsec_policy6_entrust_setup(int, int, struct test *); +void priv_netinet_ipsec_policy6_entrust(int, int, struct test *); +void priv_netinet_ipsec_policy_entrust_cleanup(int, int, struct test *); int priv_netinet_raw_setup(int, int, struct test *); void priv_netinet_raw(int, int, struct test *); diff --git a/tools/regression/priv/priv_netinet_ipsec.c b/tools/regression/priv/priv_netinet_ipsec.c index e3729c62cd2f..c2014da1d246 100644 --- a/tools/regression/priv/priv_netinet_ipsec.c +++ b/tools/regression/priv/priv_netinet_ipsec.c @@ -34,19 +34,126 @@ #include #include #include +#include +#include +#include #include +#include #include #include "main.h" -int -priv_netinet_ipsec_pfkey_setup(int asroot, int injail, struct test *test) +static char policy_bypass[] = "in bypass"; +static char policy_entrust[] = "in entrust"; +static char *bypassbuf = NULL; +static char *entrustbuf = NULL; +static int sd = -1; + + +static int +priv_netinet_ipsec_policy_bypass_setup_af(int asroot, int injail, + struct test *test, int af) { + bypassbuf = ipsec_set_policy(policy_bypass, sizeof(policy_bypass) - 1); + if (bypassbuf == NULL) { + warn("%s: ipsec_set_policy(NULL)", __func__); + return (-1); + } + switch (af) { + case AF_INET: + sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) { + warn("%s: socket4", __func__); + return (-1); + } + break; + case AF_INET6: + sd = socket(AF_INET6, SOCK_DGRAM, 0); + if (sd < 0) { + warn("%s: socket6", __func__); + return (-1); + } + break; + default: + warnx("%s: unexpected address family", __func__); + return (-1); + } return (0); } +int +priv_netinet_ipsec_policy4_bypass_setup(int asroot, int injail, + struct test *test) +{ + + return (priv_netinet_ipsec_policy_bypass_setup_af(asroot, injail, test, + AF_INET)); +} + +int +priv_netinet_ipsec_policy6_bypass_setup(int asroot, int injail, + struct test *test) +{ + + return (priv_netinet_ipsec_policy_bypass_setup_af(asroot, injail, test, + AF_INET6)); +} + + + +static int +priv_netinet_ipsec_policy_entrust_setup_af(int asroot, int injail, + struct test *test, int af) +{ + + entrustbuf = ipsec_set_policy(policy_entrust, sizeof(policy_entrust)-1); + if (entrustbuf == NULL) { + warn("%s: ipsec_set_policy(NULL)", __func__); + return (-1); + } + switch (af) { + case AF_INET: + sd = socket(AF_INET, SOCK_DGRAM, 0); + if (sd < 0) { + warn("%s: socket4", __func__); + return (-1); + } + break; + case AF_INET6: + sd = socket(AF_INET6, SOCK_DGRAM, 0); + if (sd < 0) { + warn("%s: socket6", __func__); + return (-1); + } + break; + default: + warnx("%s: unexpected address family", __func__); + return (-1); + } + return (0); +} + +int +priv_netinet_ipsec_policy4_entrust_setup(int asroot, int injail, + struct test *test) +{ + + return (priv_netinet_ipsec_policy_entrust_setup_af(asroot, injail, test, + AF_INET)); +} + +int +priv_netinet_ipsec_policy6_entrust_setup(int asroot, int injail, + struct test *test) +{ + + return (priv_netinet_ipsec_policy_entrust_setup_af(asroot, injail, test, + AF_INET6)); +} + + void priv_netinet_ipsec_pfkey(int asroot, int injail, struct test *test) { @@ -77,9 +184,134 @@ priv_netinet_ipsec_pfkey(int asroot, int injail, struct test *test) (void)close(fd); } -void -priv_netinet_ipsec_pfkey_cleanup(int asroot, int injail, struct test *test) -{ +static void +priv_netinet_ipsec_policy_bypass_af(int asroot, int injail, struct test *test, + int af) +{ + int error, level, optname; + + switch (af) { + case AF_INET: + level = IPPROTO_IP; + optname = IP_IPSEC_POLICY; + break; + case AF_INET6: + level = IPPROTO_IPV6; + optname = IPV6_IPSEC_POLICY; + break; + default: + warnx("%s: unexpected address family", __func__); + return; + } + error = setsockopt(sd, level, optname, + bypassbuf, ipsec_get_policylen(bypassbuf)); + if (asroot && injail) + expect("priv_netinet_ipsec_policy_bypass(asroot, injail)", + error, -1, EACCES); /* see ipsec_set_policy */ + if (asroot && !injail) + expect("priv_netinet_ipsec_policy_bypass(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_netinet_ipsec_policy_bypass(!asroot, injail)", + error, -1, EACCES); /* see ipsec_set_policy */ + if (!asroot && !injail) + expect("priv_netinet_ipsec_policy_bypass(!asroot, !injail)", + error, -1, EACCES); /* see ipsec_set_policy */ +} + +void +priv_netinet_ipsec_policy4_bypass(int asroot, int injail, struct test *test) +{ + + priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET); +} + +void +priv_netinet_ipsec_policy6_bypass(int asroot, int injail, struct test *test) +{ + + priv_netinet_ipsec_policy_bypass_af(asroot, injail, test, AF_INET6); +} + + +static void +priv_netinet_ipsec_policy_entrust_af(int asroot, int injail, struct test *test, + int af) +{ + int error, level, optname; + + switch (af) { + case AF_INET: + level = IPPROTO_IP; + optname = IP_IPSEC_POLICY; + break; + case AF_INET6: + level = IPPROTO_IPV6; + optname = IPV6_IPSEC_POLICY; + break; + default: + warnx("%s: unexpected address family", __func__); + return; + } + error = setsockopt(sd, level, optname, + entrustbuf, ipsec_get_policylen(entrustbuf)); + if (asroot && injail) + expect("priv_netinet_ipsec_policy_entrust(asroot, injail)", + error, 0, 0); /* XXX ipsec_set_policy */ + if (asroot && !injail) + expect("priv_netinet_ipsec_policy_entrust(asroot, !injail)", + error, 0, 0); + if (!asroot && injail) + expect("priv_netinet_ipsec_policy_entrust(!asroot, injail)", + error, 0, 0); /* XXX ipsec_set_policy */ + if (!asroot && !injail) + expect("priv_netinet_ipsec_policy_entrust(!asroot, !injail)", + error, 0, 0); /* XXX ipsec_set_policy */ +} + +void +priv_netinet_ipsec_policy4_entrust(int asroot, int injail, struct test *test) +{ + + priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET); +} + +void +priv_netinet_ipsec_policy6_entrust(int asroot, int injail, struct test *test) +{ + + priv_netinet_ipsec_policy_entrust_af(asroot, injail, test, AF_INET6); +} + + +void +priv_netinet_ipsec_policy_bypass_cleanup(int asroot, int injail, + struct test *test) +{ + + if (bypassbuf != NULL) { + free(bypassbuf); + bypassbuf = NULL; + } + if (sd >= 0) { + close(sd); + sd = -1; + } +} + +void +priv_netinet_ipsec_policy_entrust_cleanup(int asroot, int injail, + struct test *test) +{ + + if (entrustbuf != NULL) { + free(entrustbuf); + entrustbuf = NULL; + } + if (sd >= 0) { + close(sd); + sd = -1; + } }