Index: lib/libcasper/services/Makefile =================================================================== --- lib/libcasper/services/Makefile +++ lib/libcasper/services/Makefile @@ -6,6 +6,7 @@ SUBDIR+= cap_fileargs SUBDIR+= cap_grp SUBDIR+= cap_net +SUBDIR+= cap_netdb SUBDIR+= cap_pwd SUBDIR+= cap_sysctl SUBDIR+= cap_syslog Index: lib/libcasper/services/cap_netdb/Makefile =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/Makefile @@ -0,0 +1,32 @@ +# $FreeBSD$ + +SHLIBDIR?= /lib/casper + +.include + +PACKAGE= runtime + +SHLIB_MAJOR= 1 +INCSDIR?= ${INCLUDEDIR}/casper + +.if ${MK_CASPER} != "no" +SHLIB= cap_netdb + +SRCS= cap_netdb.c +.endif + +INCS= cap_netdb.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} + +HAS_TESTS= +SUBDIR.${MK_TESTS}+= tests + +MAN+= cap_netdb.3 + +MLINKS+=cap_netdb.3 libcap_netdb.3 +MLINKS+=cap_netdb.3 cap_getprotobyname.3 + +.include Index: lib/libcasper/services/cap_netdb/cap_netdb.h =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/cap_netdb.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2020 Ryan Moeller + * + * 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. + * + * $FreeBSD$ + */ + +#ifndef _CAP_NETDB_H_ +#define _CAP_NETDB_H_ + +#ifdef HAVE_CASPER +#define WITH_CASPER +#endif + +#include + +#include + +#ifdef WITH_CASPER +__BEGIN_DECLS + +struct protoent *cap_getprotobyname(cap_channel_t *chan, const char *name); + +__END_DECLS +#else +#define cap_getprotobyname(chan, name) getprotobyname(name) +#endif + +#endif /* !_CAP_NETDB_H_ */ Index: lib/libcasper/services/cap_netdb/cap_netdb.3 =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/cap_netdb.3 @@ -0,0 +1,91 @@ +.\" Copyright (c) 2020 Ryan Moeller +.\" All rights reserved. +.\" +.\" 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. +.\" +.\" $FreeBSD$ +.\" +.Dd May 12, 2020 +.Dt CAP_NETDB 3 +.Os +.Sh NAME +.Nm cap_getprotobyname , +.Nd "library for getting network proto entry in capability mode" +.Sh LIBRARY +.Lb libcap_netdb +.Sh SYNOPSIS +.In sys/nv.h +.In libcasper.h +.In casper/cap_netdb.h +.Ft "struct protoent *" +.Fn cap_getprotobyname "const cap_channel_t *chan" "const char *name" +.Sh DESCRIPTION +.Bf -symbolic +The function +.Fn cap_getprotobyname +is equivalent to +.Xr getprotobyname 3 +except that the connection to the +.Nm system.netdb +service needs to be provided. +.Sh EXAMPLES +The following example first opens a capability to casper and then uses this +capability to create the +.Nm system.netdb +casper service and uses it to look up a protocol by name. +.Bd -literal +cap_channel_t *capcas, *capnetdb; +struct protoent *ent; + +/* Open capability to Casper. */ +capcas = cap_init(); +if (capcas == NULL) + err(1, "Unable to contact Casper"); + +/* Enter capability mode sandbox. */ +if (caph_enter() < 0) + err(1, "Unable to enter capability mode"); + +/* Use Casper capability to create capability to the system.netdb service. */ +capnetdb = cap_service_open(capcas, "system.netdb"); +if (capnetdb == NULL) + err(1, "Unable to open system.netdb service"); + +/* Close Casper capability, we don't need it anymore. */ +cap_close(capcas); + +ent = cap_getprotobyname(capnetdb, "http"); +if (ent == NULL) + errx(1, "cap_getprotobyname failed to find http proto"); +.Ed +.Sh SEE ALSO +.Xr cap_enter 2 , +.Xr caph_enter 3 , +.Xr err 3 , +.Xr getprotobyname 3 , +.Xr capsicum 4 , +.Xr nv 9 +.Sh AUTHORS +The +.Nm cap_netdb +service was implemented by +.An Ryan Moeller Aq Mt freqlabs@FreeBSD.org . Index: lib/libcasper/services/cap_netdb/cap_netdb.c =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/cap_netdb.c @@ -0,0 +1,165 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Ryan Moeller + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cap_netdb.h" + +static void +protoent_free(struct protoent *pp) +{ + + free(pp->p_name); + pp->p_name = NULL; + if (pp->p_aliases != NULL) { + while (*pp->p_aliases != NULL) + free(*pp->p_aliases++); + free(pp->p_aliases); + } +} + +static struct protoent * +protoent_unpack(const nvlist_t *nvl, struct protoent *pp) +{ + const char * const *aliases = NULL; + size_t n; + + protoent_free(pp); + + pp->p_name = strdup(nvlist_get_string(nvl, "name")); + if (pp->p_name == NULL) + goto fail; + + aliases = nvlist_get_string_array(nvl, "aliases", &n); + if (aliases == NULL) + goto fail; + pp->p_aliases = calloc(sizeof(char *), n + 1); + if (pp->p_aliases == NULL) + goto fail; + pp->p_aliases[n] = NULL; + while (n-- > 0) { + if ((pp->p_aliases[n] = strdup(aliases[n])) == NULL) { + for (++n; pp->p_aliases[n] != NULL; ++n) { + free(pp->p_aliases[n]); + pp->p_aliases[n] = NULL; + } + goto fail; + } + } + + pp->p_proto = (int)nvlist_get_number(nvl, "proto"); + + return (pp); +fail: + protoent_free(pp); + return (NULL); +} + +struct protoent * +cap_getprotobyname(cap_channel_t *chan, const char *name) +{ + struct protoent *pp, pent = { 0 }; + nvlist_t *nvl; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "getprotobyname"); + nvlist_add_string(nvl, "name", name); + nvl = cap_xfer_nvlist(chan, nvl); + if (nvl == NULL || dnvlist_get_number(nvl, "error", 0) != 0) + return (NULL); + + pp = protoent_unpack(nvl, &pent); + nvlist_destroy(nvl); + return (pp); +} + +static void +protoent_pack(const struct protoent *pp, nvlist_t *nvl) +{ + int n = 0; + + nvlist_add_string(nvl, "name", pp->p_name); + + while (pp->p_aliases[n] != NULL) + ++n; + nvlist_add_string_array(nvl, "aliases", + (const char * const *)pp->p_aliases, n); + + nvlist_add_number(nvl, "proto", (uint64_t)pp->p_proto); +} + +static int +netdb_getprotobyname(const nvlist_t *limits __unused, const nvlist_t *nvlin, + nvlist_t *nvlout) +{ + struct protoent *pp; + + pp = getprotobyname(nvlist_get_string(nvlin, "name")); + if (pp == NULL) + return (ENOENT); + protoent_pack(pp, nvlout); + return (0); +} + +static int +netdb_limit(const nvlist_t *oldlimits __unused, + const nvlist_t *newlimits __unused) +{ + + return (0); +} + +static int +netdb_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, + nvlist_t *nvlout) +{ + int error; + + if (strcmp(cmd, "getprotobyname") == 0) + error = netdb_getprotobyname(limits, nvlin, nvlout); + else + error = NO_RECOVERY; + + return (error); +} + +CREATE_SERVICE("system.netdb", netdb_limit, netdb_command, 0); Index: lib/libcasper/services/cap_netdb/tests/Makefile =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/tests/Makefile @@ -0,0 +1,14 @@ +# $FreeBSD$ + +.include + +ATF_TESTS_C= netdb_test + +.if ${MK_CASPER} != "no" +LIBADD+= casper +LIBADD+= cap_netdb +CFLAGS+=-DWITH_CASPER +.endif +LIBADD+= nv + +.include Index: lib/libcasper/services/cap_netdb/tests/netdb_test.c =================================================================== --- /dev/null +++ lib/libcasper/services/cap_netdb/tests/netdb_test.c @@ -0,0 +1,94 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Ryan Moeller + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +static cap_channel_t * +initcap(void) +{ + cap_channel_t *capcas, *capnetdb; + + capcas = cap_init(); + ATF_REQUIRE(capcas != NULL); + + capnetdb = cap_service_open(capcas, "system.netdb"); + ATF_REQUIRE(capnetdb != NULL); + + cap_close(capcas); + + return (capnetdb); +} + +ATF_TC_WITHOUT_HEAD(cap_netdb__getprotobyname); +ATF_TC_BODY(cap_netdb__getprotobyname, tc) +{ + cap_channel_t *capnetdb; + struct protoent *pp; + size_t n = 0; + + capnetdb = initcap(); + + pp = cap_getprotobyname(capnetdb, "tcp"); + ATF_REQUIRE(pp != NULL); + + ATF_REQUIRE(pp->p_name != NULL); + ATF_REQUIRE(pp->p_aliases != NULL); + while (pp->p_aliases[n] != NULL) + ++n; + ATF_REQUIRE(n > 0); + ATF_REQUIRE(pp->p_proto != 0); + + cap_close(capnetdb); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, cap_netdb__getprotobyname); + + return (atf_no_error()); +} Index: share/mk/src.libnames.mk =================================================================== --- share/mk/src.libnames.mk +++ share/mk/src.libnames.mk @@ -91,6 +91,7 @@ cap_fileargs \ cap_grp \ cap_net \ + cap_netdb \ cap_pwd \ cap_sysctl \ cap_syslog \