Date: Thu, 8 Sep 2016 20:01:26 +0000 (UTC) From: Mariusz Zaborski <oshogbo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305626 - in head: lib/libcasper/services/cap_dns lib/libcasper/services/cap_dns/tests lib/libcasper/services/cap_grp lib/libcasper/services/cap_grp/tests lib/libcasper/services/cap_pwd... Message-ID: <201609082001.u88K1QYU098501@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: oshogbo Date: Thu Sep 8 20:01:26 2016 New Revision: 305626 URL: https://svnweb.freebsd.org/changeset/base/305626 Log: Move libcasper tests from regression/capsicum/libcasper/ to lib/libcasper/service/${service_name}/tests. Reviewed by: emaste, ngie Differential Revision: https://reviews.freebsd.org/D7759 Added: head/lib/libcasper/services/cap_dns/tests/ head/lib/libcasper/services/cap_dns/tests/Makefile (contents, props changed) head/lib/libcasper/services/cap_dns/tests/dns_test.c - copied unchanged from r305625, head/tools/regression/capsicum/libcasper/dns.c head/lib/libcasper/services/cap_grp/tests/ head/lib/libcasper/services/cap_grp/tests/Makefile (contents, props changed) head/lib/libcasper/services/cap_grp/tests/grp_test.c - copied unchanged from r305625, head/tools/regression/capsicum/libcasper/grp.c head/lib/libcasper/services/cap_pwd/tests/ head/lib/libcasper/services/cap_pwd/tests/Makefile (contents, props changed) head/lib/libcasper/services/cap_pwd/tests/pwd_test.c - copied unchanged from r305625, head/tools/regression/capsicum/libcasper/pwd.c head/lib/libcasper/services/cap_sysctl/tests/ head/lib/libcasper/services/cap_sysctl/tests/Makefile (contents, props changed) head/lib/libcasper/services/cap_sysctl/tests/sysctl_test.c - copied unchanged from r305625, head/tools/regression/capsicum/libcasper/sysctl.c Deleted: head/tools/regression/capsicum/libcasper/ Modified: head/lib/libcasper/services/cap_dns/Makefile head/lib/libcasper/services/cap_grp/Makefile head/lib/libcasper/services/cap_pwd/Makefile head/lib/libcasper/services/cap_sysctl/Makefile Modified: head/lib/libcasper/services/cap_dns/Makefile ============================================================================== --- head/lib/libcasper/services/cap_dns/Makefile Thu Sep 8 19:47:57 2016 (r305625) +++ head/lib/libcasper/services/cap_dns/Makefile Thu Sep 8 20:01:26 2016 (r305626) @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <src.opts.mk> + PACKAGE=libcasper LIB= cap_dns @@ -15,4 +17,8 @@ LIBADD= nv CFLAGS+=-I${.CURDIR} +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.lib.mk> Added: head/lib/libcasper/services/cap_dns/tests/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libcasper/services/cap_dns/tests/Makefile Thu Sep 8 20:01:26 2016 (r305626) @@ -0,0 +1,11 @@ +# $FreeBSD$ + +TAP_TESTS_C= dns_test + +LIBADD+= casper +LIBADD+= cap_dns +LIBADD+= nv + +WARNS?= 3 + +.include <bsd.test.mk> Copied: head/lib/libcasper/services/cap_dns/tests/dns_test.c (from r305625, head/tools/regression/capsicum/libcasper/dns.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libcasper/services/cap_dns/tests/dns_test.c Thu Sep 8 20:01:26 2016 (r305626, copy of r305625, head/tools/regression/capsicum/libcasper/dns.c) @@ -0,0 +1,702 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/capsicum.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libcasper.h> + +#include <casper/cap_dns.h> + +static int ntest = 1; + +#define CHECK(expr) do { \ + if ((expr)) \ + printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + else \ + printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + ntest++; \ +} while (0) +#define CHECKX(expr) do { \ + if ((expr)) { \ + printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + } else { \ + printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + exit(1); \ + } \ + ntest++; \ +} while (0) + +#define GETHOSTBYNAME 0x01 +#define GETHOSTBYNAME2_AF_INET 0x02 +#define GETHOSTBYNAME2_AF_INET6 0x04 +#define GETHOSTBYADDR_AF_INET 0x08 +#define GETHOSTBYADDR_AF_INET6 0x10 +#define GETADDRINFO_AF_UNSPEC 0x20 +#define GETADDRINFO_AF_INET 0x40 +#define GETADDRINFO_AF_INET6 0x80 + +static bool +addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1) +{ + struct addrinfo *at0, *at1; + + if (ai0 == NULL && ai1 == NULL) + return (true); + if (ai0 == NULL || ai1 == NULL) + return (false); + + at0 = ai0; + at1 = ai1; + while (true) { + if ((at0->ai_flags == at1->ai_flags) && + (at0->ai_family == at1->ai_family) && + (at0->ai_socktype == at1->ai_socktype) && + (at0->ai_protocol == at1->ai_protocol) && + (at0->ai_addrlen == at1->ai_addrlen) && + (memcmp(at0->ai_addr, at1->ai_addr, + at0->ai_addrlen) == 0)) { + if (at0->ai_canonname != NULL && + at1->ai_canonname != NULL) { + if (strcmp(at0->ai_canonname, + at1->ai_canonname) != 0) { + return (false); + } + } + + if (at0->ai_canonname == NULL && + at1->ai_canonname != NULL) { + return (false); + } + if (at0->ai_canonname != NULL && + at1->ai_canonname == NULL) { + return (false); + } + + if (at0->ai_next == NULL && at1->ai_next == NULL) + return (true); + if (at0->ai_next == NULL || at1->ai_next == NULL) + return (false); + + at0 = at0->ai_next; + at1 = at1->ai_next; + } else { + return (false); + } + } + + /* NOTREACHED */ + fprintf(stderr, "Dead code reached in addrinfo_compare()\n"); + exit(1); +} + +static bool +hostent_aliases_compare(char **aliases0, char **aliases1) +{ + int i0, i1; + + if (aliases0 == NULL && aliases1 == NULL) + return (true); + if (aliases0 == NULL || aliases1 == NULL) + return (false); + + for (i0 = 0; aliases0[i0] != NULL; i0++) { + for (i1 = 0; aliases1[i1] != NULL; i1++) { + if (strcmp(aliases0[i0], aliases1[i1]) == 0) + break; + } + if (aliases1[i1] == NULL) + return (false); + } + + return (true); +} + +static bool +hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length) +{ + int i0, i1; + + if (addr_list0 == NULL && addr_list1 == NULL) + return (true); + if (addr_list0 == NULL || addr_list1 == NULL) + return (false); + + for (i0 = 0; addr_list0[i0] != NULL; i0++) { + for (i1 = 0; addr_list1[i1] != NULL; i1++) { + if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0) + break; + } + if (addr_list1[i1] == NULL) + return (false); + } + + return (true); +} + +static bool +hostent_compare(const struct hostent *hp0, const struct hostent *hp1) +{ + + if (hp0 == NULL && hp1 != NULL) + return (true); + + if (hp0 == NULL || hp1 == NULL) + return (false); + + if (hp0->h_name != NULL || hp1->h_name != NULL) { + if (hp0->h_name == NULL || hp1->h_name == NULL) + return (false); + if (strcmp(hp0->h_name, hp1->h_name) != 0) + return (false); + } + + if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases)) + return (false); + if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases)) + return (false); + + if (hp0->h_addrtype != hp1->h_addrtype) + return (false); + + if (hp0->h_length != hp1->h_length) + return (false); + + if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list, + hp0->h_length)) { + return (false); + } + if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list, + hp0->h_length)) { + return (false); + } + + return (true); +} + +static unsigned int +runtest(cap_channel_t *capdns) +{ + unsigned int result; + struct addrinfo *ais, *aic, hints, *hintsp; + struct hostent *hps, *hpc; + struct in_addr ip4; + struct in6_addr ip6; + + result = 0; + + hps = gethostbyname("example.com"); + if (hps == NULL) + fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com"); + hpc = cap_gethostbyname(capdns, "example.com"); + if (hostent_compare(hps, hpc)) + result |= GETHOSTBYNAME; + + hps = gethostbyname2("example.com", AF_INET); + if (hps == NULL) + fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com"); + hpc = cap_gethostbyname2(capdns, "example.com", AF_INET); + if (hostent_compare(hps, hpc)) + result |= GETHOSTBYNAME2_AF_INET; + + hps = gethostbyname2("example.com", AF_INET6); + if (hps == NULL) + fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com"); + hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6); + if (hostent_compare(hps, hpc)) + result |= GETHOSTBYNAME2_AF_INET6; + + hints.ai_flags = 0; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = 0; + hints.ai_protocol = 0; + hints.ai_addrlen = 0; + hints.ai_addr = NULL; + hints.ai_canonname = NULL; + hints.ai_next = NULL; + + hintsp = &hints; + + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_UNSPEC; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + + hints.ai_family = AF_INET; + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_INET; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + + hints.ai_family = AF_INET6; + if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) { + fprintf(stderr, + "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n", + gai_strerror(errno)); + } + if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) { + if (addrinfo_compare(ais, aic)) + result |= GETADDRINFO_AF_INET6; + freeaddrinfo(ais); + freeaddrinfo(aic); + } + + /* + * 8.8.178.135 is IPv4 address of freefall.freebsd.org + * as of 27 October 2013. + */ + inet_pton(AF_INET, "8.8.178.135", &ip4); + hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET); + if (hps == NULL) + fprintf(stderr, "Unable to resolve %s.\n", "8.8.178.135"); + hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET); + if (hostent_compare(hps, hpc)) + result |= GETHOSTBYADDR_AF_INET; + + /* + * 2001:1900:2254:206c::16:87 is IPv6 address of freefall.freebsd.org + * as of 27 October 2013. + */ + inet_pton(AF_INET6, "2001:1900:2254:206c::16:87", &ip6); + hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6); + if (hps == NULL) { + fprintf(stderr, "Unable to resolve %s.\n", + "2001:1900:2254:206c::16:87"); + } + hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6); + if (hostent_compare(hps, hpc)) + result |= GETHOSTBYADDR_AF_INET6; + + return (result); +} + +int +main(void) +{ + cap_channel_t *capcas, *capdns, *origcapdns; + const char *types[2]; + int families[2]; + + printf("1..91\n"); + + capcas = cap_init(); + CHECKX(capcas != NULL); + + origcapdns = capdns = cap_service_open(capcas, "system.dns"); + CHECKX(capdns != NULL); + + cap_close(capcas); + + /* No limits set. */ + + CHECK(runtest(capdns) == + (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 | + GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); + + /* + * Allow: + * type: NAME, ADDR + * family: AF_INET, AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + + CHECK(runtest(capdns) == + (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 | + GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); + + cap_close(capdns); + + /* + * Allow: + * type: NAME + * family: AF_INET, AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + + CHECK(runtest(capdns) == + (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6)); + + cap_close(capdns); + + /* + * Allow: + * type: ADDR + * family: AF_INET, AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + + CHECK(runtest(capdns) == + (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6)); + + cap_close(capdns); + + /* + * Allow: + * type: NAME, ADDR + * family: AF_INET + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == + (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET | + GETADDRINFO_AF_INET)); + + cap_close(capdns); + + /* + * Allow: + * type: NAME, ADDR + * family: AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == + (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); + + cap_close(capdns); + + /* Below we also test further limiting capability. */ + + /* + * Allow: + * type: NAME + * family: AF_INET + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET)); + + cap_close(capdns); + + /* + * Allow: + * type: NAME + * family: AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == GETHOSTBYNAME2_AF_INET6); + + cap_close(capdns); + + /* + * Allow: + * type: ADDR + * family: AF_INET + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET | GETADDRINFO_AF_INET)); + + cap_close(capdns); + + /* + * Allow: + * type: ADDR + * family: AF_INET6 + */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == 0); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == 0); + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + types[1] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + families[1] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); + + cap_close(capdns); + + /* Trying to rise the limits. */ + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 && + errno == ENOTCAPABLE); + CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 && + errno == ENOTCAPABLE); + + /* Do the limits still hold? */ + CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET)); + + cap_close(capdns); + + capdns = cap_clone(origcapdns); + CHECK(capdns != NULL); + + types[0] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 1) == 0); + families[0] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 1) == 0); + + types[0] = "NAME"; + types[1] = "ADDR"; + CHECK(cap_dns_type_limit(capdns, types, 2) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + families[1] = AF_INET6; + CHECK(cap_dns_family_limit(capdns, families, 2) == -1 && + errno == ENOTCAPABLE); + + types[0] = "NAME"; + CHECK(cap_dns_type_limit(capdns, types, 1) == -1 && + errno == ENOTCAPABLE); + families[0] = AF_INET; + CHECK(cap_dns_family_limit(capdns, families, 1) == -1 && + errno == ENOTCAPABLE); + + CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 && + errno == ENOTCAPABLE); + CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 && + errno == ENOTCAPABLE); + + /* Do the limits still hold? */ + CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 | + GETADDRINFO_AF_INET6)); + + cap_close(capdns); + + cap_close(origcapdns); + + exit(0); +} Modified: head/lib/libcasper/services/cap_grp/Makefile ============================================================================== --- head/lib/libcasper/services/cap_grp/Makefile Thu Sep 8 19:47:57 2016 (r305625) +++ head/lib/libcasper/services/cap_grp/Makefile Thu Sep 8 20:01:26 2016 (r305626) @@ -1,5 +1,7 @@ # $FreeBSD$ +.include <src.opts.mk> + PACKAGE=libcasper LIB= cap_grp @@ -15,4 +17,8 @@ LIBADD= nv CFLAGS+=-I${.CURDIR} +.if ${MK_TESTS} != "no" +SUBDIR+= tests +.endif + .include <bsd.lib.mk> Added: head/lib/libcasper/services/cap_grp/tests/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libcasper/services/cap_grp/tests/Makefile Thu Sep 8 20:01:26 2016 (r305626) @@ -0,0 +1,11 @@ +# $FreeBSD$ + +TAP_TESTS_C= grp_test + +LIBADD+= casper +LIBADD+= cap_grp +LIBADD+= nv + +WARNS?= 3 + +.include <bsd.test.mk> Copied: head/lib/libcasper/services/cap_grp/tests/grp_test.c (from r305625, head/tools/regression/capsicum/libcasper/grp.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lib/libcasper/services/cap_grp/tests/grp_test.c Thu Sep 8 20:01:26 2016 (r305626, copy of r305625, head/tools/regression/capsicum/libcasper/grp.c) @@ -0,0 +1,1550 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/capsicum.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <grp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libcasper.h> + +#include <casper/cap_grp.h> + +static int ntest = 1; + +#define CHECK(expr) do { \ + if ((expr)) \ + printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + else \ + printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + ntest++; \ +} while (0) +#define CHECKX(expr) do { \ + if ((expr)) { \ + printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + } else { \ + printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__); \ + exit(1); \ + } \ + ntest++; \ +} while (0) + +#define GID_WHEEL 0 +#define GID_OPERATOR 5 + +#define GETGRENT0 0x0001 +#define GETGRENT1 0x0002 +#define GETGRENT2 0x0004 +#define GETGRENT (GETGRENT0 | GETGRENT1 | GETGRENT2) +#define GETGRENT_R0 0x0008 +#define GETGRENT_R1 0x0010 +#define GETGRENT_R2 0x0020 +#define GETGRENT_R (GETGRENT_R0 | GETGRENT_R1 | GETGRENT_R2) +#define GETGRNAM 0x0040 +#define GETGRNAM_R 0x0080 +#define GETGRGID 0x0100 +#define GETGRGID_R 0x0200 +#define SETGRENT 0x0400 + +static bool +group_mem_compare(char **mem0, char **mem1) +{ + int i0, i1; + + if (mem0 == NULL && mem1 == NULL) + return (true); + if (mem0 == NULL || mem1 == NULL) + return (false); + + for (i0 = 0; mem0[i0] != NULL; i0++) { + for (i1 = 0; mem1[i1] != NULL; i1++) { + if (strcmp(mem0[i0], mem1[i1]) == 0) + break; + } + if (mem1[i1] == NULL) + return (false); + } + + return (true); +} + +static bool +group_compare(const struct group *grp0, const struct group *grp1) +{ + + if (grp0 == NULL && grp1 == NULL) + return (true); + if (grp0 == NULL || grp1 == NULL) + return (false); + + if (strcmp(grp0->gr_name, grp1->gr_name) != 0) + return (false); + + if (grp0->gr_passwd != NULL || grp1->gr_passwd != NULL) { + if (grp0->gr_passwd == NULL || grp1->gr_passwd == NULL) + return (false); + if (strcmp(grp0->gr_passwd, grp1->gr_passwd) != 0) + return (false); + } + + if (grp0->gr_gid != grp1->gr_gid) + return (false); + + if (!group_mem_compare(grp0->gr_mem, grp1->gr_mem)) + return (false); + + return (true); +} + +static unsigned int +runtest_cmds(cap_channel_t *capgrp) +{ + char bufs[1024], bufc[1024]; + unsigned int result; + struct group *grps, *grpc; + struct group sts, stc; + + result = 0; + + (void)setgrent(); + if (cap_setgrent(capgrp) == 1) + result |= SETGRENT; + + grps = getgrent(); + grpc = cap_getgrent(capgrp); + if (group_compare(grps, grpc)) { + result |= GETGRENT0; + grps = getgrent(); + grpc = cap_getgrent(capgrp); + if (group_compare(grps, grpc)) + result |= GETGRENT1; + } + + getgrent_r(&sts, bufs, sizeof(bufs), &grps); + cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc); + if (group_compare(grps, grpc)) { + result |= GETGRENT_R0; + getgrent_r(&sts, bufs, sizeof(bufs), &grps); + cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc); + if (group_compare(grps, grpc)) + result |= GETGRENT_R1; + } + + (void)setgrent(); + if (cap_setgrent(capgrp) == 1) + result |= SETGRENT; + + getgrent_r(&sts, bufs, sizeof(bufs), &grps); + cap_getgrent_r(capgrp, &stc, bufc, sizeof(bufc), &grpc); + if (group_compare(grps, grpc)) + result |= GETGRENT_R2; + + grps = getgrent(); + grpc = cap_getgrent(capgrp); + if (group_compare(grps, grpc)) + result |= GETGRENT2; + + grps = getgrnam("wheel"); + grpc = cap_getgrnam(capgrp, "wheel"); + if (group_compare(grps, grpc)) { + grps = getgrnam("operator"); + grpc = cap_getgrnam(capgrp, "operator"); + if (group_compare(grps, grpc)) + result |= GETGRNAM; + } + + getgrnam_r("wheel", &sts, bufs, sizeof(bufs), &grps); + cap_getgrnam_r(capgrp, "wheel", &stc, bufc, sizeof(bufc), &grpc); + if (group_compare(grps, grpc)) { + getgrnam_r("operator", &sts, bufs, sizeof(bufs), &grps); + cap_getgrnam_r(capgrp, "operator", &stc, bufc, sizeof(bufc), + &grpc); + if (group_compare(grps, grpc)) + result |= GETGRNAM_R; + } + + grps = getgrgid(GID_WHEEL); + grpc = cap_getgrgid(capgrp, GID_WHEEL); + if (group_compare(grps, grpc)) { + grps = getgrgid(GID_OPERATOR); + grpc = cap_getgrgid(capgrp, GID_OPERATOR); + if (group_compare(grps, grpc)) + result |= GETGRGID; + } + + getgrgid_r(GID_WHEEL, &sts, bufs, sizeof(bufs), &grps); + cap_getgrgid_r(capgrp, GID_WHEEL, &stc, bufc, sizeof(bufc), &grpc); + if (group_compare(grps, grpc)) { + getgrgid_r(GID_OPERATOR, &sts, bufs, sizeof(bufs), &grps); + cap_getgrgid_r(capgrp, GID_OPERATOR, &stc, bufc, sizeof(bufc), + &grpc); + if (group_compare(grps, grpc)) + result |= GETGRGID_R; + } + + return (result); +} + +static void +test_cmds(cap_channel_t *origcapgrp) +{ + cap_channel_t *capgrp; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609082001.u88K1QYU098501>