Index: lib/libcasper/Makefile =================================================================== --- lib/libcasper/Makefile +++ lib/libcasper/Makefile @@ -1,6 +1,7 @@ # $FreeBSD$ SUBDIR= libcasper +SUBDIR+= libcaspermock SUBDIR+= services SUBDIR_PARALLEL= Index: lib/libcasper/libcasper/libcasper.h =================================================================== --- lib/libcasper/libcasper/libcasper.h +++ lib/libcasper/libcasper/libcasper.h @@ -112,4 +112,7 @@ */ nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags); +/* Function tells do we have support of Casper or do we use mocked version. */ +bool cap_enable(const cap_channel_t *chan); + #endif /* !_LIBCASPER_H_ */ Index: lib/libcasper/libcasper/libcasper.c =================================================================== --- lib/libcasper/libcasper/libcasper.c +++ lib/libcasper/libcasper/libcasper.c @@ -335,3 +335,16 @@ nvlist_add_null(limits, names[i]); return (cap_limit_set(chan, limits)); } + +bool +cap_enable(const cap_channel_t *chan) +{ + + if (chan != NULL) { + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + return (true); + } + + return (false); +} + Index: lib/libcasper/libcaspermock/libcasper.c =================================================================== --- /dev/null +++ lib/libcasper/libcaspermock/libcasper.c @@ -0,0 +1,193 @@ +/*- + * Copyright (c) 2016 Mariusz Zaborski + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "libcasper.h" + +#define CAP_CHANNEL_MAGIC 0xcac8b42 +struct cap_channel { + /* + * Magic value helps to ensure that a pointer to the right structure is + * passed to our functions. + */ + int cch_magic; +}; + +cap_channel_t * +cap_init(void) +{ + + return (cap_wrap(-1)); +} + +cap_channel_t * +cap_wrap(int sock __unused) +{ + cap_channel_t *chan; + + chan = malloc(sizeof(*chan)); + if (chan != NULL) + chan->cch_magic = CAP_CHANNEL_MAGIC; + + return (chan); +} + +int +cap_unwrap(cap_channel_t *chan) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + chan->cch_magic = 0; + free(chan); + + return (-1); +} + +cap_channel_t * +cap_clone(const cap_channel_t *chan __unused) +{ + + return (cap_wrap(-1)); +} + +void +cap_close(cap_channel_t *chan) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + chan->cch_magic = 0; + free(chan); +} + +int +cap_sock(const cap_channel_t *chan) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (-1); +} + +int +cap_limit_set(const cap_channel_t *chan, nvlist_t *limits __unused) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (0); +} + +int +cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + *limitsp = nvlist_create(0); + + return (0); +} + +int +cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl __unused) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (0); +} + +nvlist_t * +cap_recv_nvlist(const cap_channel_t *chan, int flags __unused) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (0); +} + +nvlist_t * +cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags __unused) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + nvlist_destroy(nvl); + + return (nvlist_create(0)); +} + +cap_channel_t * +cap_service_open(const cap_channel_t *chan __unused, const char *name __unused) +{ + + return (cap_wrap(-1)); +} + +int +cap_service_limit(const cap_channel_t *chan, const char * const *names __unused, + size_t nnames __unused) +{ + + assert(chan != NULL); + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (0); +} + +bool +cap_enable(const cap_channel_t *chan) +{ + + if (chan != NULL) + assert(chan->cch_magic == CAP_CHANNEL_MAGIC); + + return (false); +} Index: lib/libcasper/libcaspermock/libcasper_service.c =================================================================== --- /dev/null +++ lib/libcasper/libcaspermock/libcasper_service.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2016 Mariusz Zaborski + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include "libcasper_impl.h" + +struct casper_service * +service_register(const char *name __unused, + service_limit_func_t *limitfunc __unused, + service_command_func_t *commandfunc __unused, uint64_t flags __unused) +{ + + return (NULL); +} Index: lib/libcasper/services/cap_dns/cap_dns.c =================================================================== --- lib/libcasper/services/cap_dns/cap_dns.c +++ lib/libcasper/services/cap_dns/cap_dns.c @@ -124,6 +124,9 @@ cap_gethostbyname(cap_channel_t *chan, const char *name) { + if (!cap_enable(chan)) + return (gethostbyname(name)); + return (cap_gethostbyname2(chan, name, AF_INET)); } @@ -133,6 +136,9 @@ struct hostent *hp; nvlist_t *nvl; + if (!cap_enable(chan)) + return (gethostbyname2(name, type)); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "gethostbyname"); nvlist_add_number(nvl, "family", (uint64_t)type); @@ -160,6 +166,9 @@ struct hostent *hp; nvlist_t *nvl; + if (!cap_enable(chan)) + return (gethostbyaddr(addr, len, type)); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "gethostbyaddr"); nvlist_add_binary(nvl, "addr", addr, (size_t)len); @@ -224,6 +233,9 @@ nvlist_t *nvl; int error, n; + if (!cap_enable(chan)) + return (getaddrinfo(hostname, servname, hints, res)); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "getaddrinfo"); if (hostname != NULL) @@ -284,6 +296,11 @@ nvlist_t *nvl; int error; + if (!cap_enable(chan)) { + return (getnameinfo(sa, salen, host, hostlen, serv, servlen, + flags)); + } + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "getnameinfo"); nvlist_add_number(nvl, "hostlen", (uint64_t)hostlen); Index: lib/libcasper/services/cap_grp/cap_grp.c =================================================================== --- lib/libcasper/services/cap_grp/cap_grp.c +++ lib/libcasper/services/cap_grp/cap_grp.c @@ -267,6 +267,9 @@ cap_getgrent(cap_channel_t *chan) { + if (!cap_enable(chan)) + return (getgrent()); + return (cap_getgrcommon(chan, "getgrent", NULL, 0)); } @@ -274,6 +277,9 @@ cap_getgrnam(cap_channel_t *chan, const char *name) { + if (!cap_enable(chan)) + return (getgrnam(name)); + return (cap_getgrcommon(chan, "getgrnam", name, 0)); } @@ -281,6 +287,9 @@ cap_getgrgid(cap_channel_t *chan, gid_t gid) { + if (!cap_enable(chan)) + return (getgrgid(gid)); + return (cap_getgrcommon(chan, "getgrgid", NULL, gid)); } @@ -289,6 +298,9 @@ size_t bufsize, struct group **result) { + if (!cap_enable(chan)) + return (getgrent_r(grp, buffer, bufsize, result)); + return (cap_getgrcommon_r(chan, "getgrent_r", NULL, 0, grp, buffer, bufsize, result)); } @@ -298,6 +310,9 @@ char *buffer, size_t bufsize, struct group **result) { + if (!cap_enable(chan)) + return (getgrnam_r(name, grp, buffer, bufsize, result)); + return (cap_getgrcommon_r(chan, "getgrnam_r", name, 0, grp, buffer, bufsize, result)); } @@ -307,6 +322,9 @@ size_t bufsize, struct group **result) { + if (!cap_enable(chan)) + return (getgrgid_r(gid, grp, buffer, bufsize, result)); + return (cap_getgrcommon_r(chan, "getgrgid_r", NULL, gid, grp, buffer, bufsize, result)); } @@ -316,6 +334,9 @@ { nvlist_t *nvl; + if (!cap_enable(chan)) + return (setgroupent(stayopen)); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "setgroupent"); nvlist_add_bool(nvl, "stayopen", stayopen != 0); @@ -337,6 +358,9 @@ { nvlist_t *nvl; + if (!cap_enable(chan)) + return (setgrent()); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "setgrent"); nvl = cap_xfer_nvlist(chan, nvl, 0); @@ -357,6 +381,9 @@ { nvlist_t *nvl; + if (!cap_enable(chan)) + return (endgrent()); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "endgrent"); /* Ignore any errors, we have no way to report them. */ @@ -369,6 +396,9 @@ nvlist_t *limits, *nvl; unsigned int i; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { @@ -391,6 +421,9 @@ nvlist_t *limits, *nvl; unsigned int i; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { @@ -415,6 +448,9 @@ char nvlname[64]; int n; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { Index: lib/libcasper/services/cap_pwd/cap_pwd.c =================================================================== --- lib/libcasper/services/cap_pwd/cap_pwd.c +++ lib/libcasper/services/cap_pwd/cap_pwd.c @@ -227,6 +227,9 @@ cap_getpwent(cap_channel_t *chan) { + if (!cap_enable(chan)) + return (getpwent()); + return (cap_getpwcommon(chan, "getpwent", NULL, 0)); } @@ -234,6 +237,9 @@ cap_getpwnam(cap_channel_t *chan, const char *login) { + if (!cap_enable(chan)) + return (getpwnam(login)); + return (cap_getpwcommon(chan, "getpwnam", login, 0)); } @@ -241,6 +247,9 @@ cap_getpwuid(cap_channel_t *chan, uid_t uid) { + if (!cap_enable(chan)) + return (getpwuid(uid)); + return (cap_getpwcommon(chan, "getpwuid", NULL, uid)); } @@ -249,6 +258,9 @@ size_t bufsize, struct passwd **result) { + if (!cap_enable(chan)) + return (getpwent_r(pwd, buffer, bufsize, result)); + return (cap_getpwcommon_r(chan, "getpwent_r", NULL, 0, pwd, buffer, bufsize, result)); } @@ -258,6 +270,9 @@ char *buffer, size_t bufsize, struct passwd **result) { + if (!cap_enable(chan)) + return (getpwnam_r(name, pwd, buffer, bufsize, result)); + return (cap_getpwcommon_r(chan, "getpwnam_r", name, 0, pwd, buffer, bufsize, result)); } @@ -267,6 +282,9 @@ size_t bufsize, struct passwd **result) { + if (!cap_enable(chan)) + return (getpwuid_r(uid, pwd, buffer, bufsize, result)); + return (cap_getpwcommon_r(chan, "getpwuid_r", NULL, uid, pwd, buffer, bufsize, result)); } @@ -276,6 +294,9 @@ { nvlist_t *nvl; + if (!cap_enable(chan)) + return (setpassent(stayopen)); + nvl = nvlist_create(0); nvlist_add_string(nvl, "cmd", "setpassent"); nvlist_add_bool(nvl, "stayopen", stayopen != 0); @@ -307,6 +328,9 @@ cap_setpwent(cap_channel_t *chan) { + if (!cap_enable(chan)) + return (setpwent()); + cap_set_end_pwent(chan, "setpwent"); } @@ -314,6 +338,9 @@ cap_endpwent(cap_channel_t *chan) { + if (!cap_enable(chan)) + return (endpwent()); + cap_set_end_pwent(chan, "endpwent"); } @@ -323,6 +350,9 @@ nvlist_t *limits, *nvl; unsigned int i; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { @@ -345,6 +375,9 @@ nvlist_t *limits, *nvl; unsigned int i; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { @@ -369,6 +402,9 @@ unsigned int i; int n; + if (!cap_enable(chan)) + return (0); + if (cap_limit_get(chan, &limits) < 0) return (-1); if (limits == NULL) { Index: lib/libcasper/services/cap_random/cap_random.c =================================================================== --- lib/libcasper/services/cap_random/cap_random.c +++ lib/libcasper/services/cap_random/cap_random.c @@ -53,6 +53,11 @@ uint8_t *ptr; size_t left, randbufsize; + if (!cap_enable(chan)) { + arc4random_buf(buf, nbytes); + return (0); + } + left = nbytes; ptr = buf; Index: lib/libcasper/services/cap_sysctl/cap_sysctl.c =================================================================== --- lib/libcasper/services/cap_sysctl/cap_sysctl.c +++ lib/libcasper/services/cap_sysctl/cap_sysctl.c @@ -53,6 +53,9 @@ uint8_t operation; size_t oldlen; + if (!cap_enable(chan)) + return (sysctlbyname(name, oldp, oldlenp, newp, newlen)); + operation = 0; if (oldp != NULL) operation |= CAP_SYSCTL_READ; Index: share/mk/bsd.libnames.mk =================================================================== --- share/mk/bsd.libnames.mk +++ share/mk/bsd.libnames.mk @@ -37,6 +37,7 @@ LIBCAP_RANDOM?= ${DESTDIR}${LIBDIR}/libcap_random.a LIBCAP_SYSCTL?= ${DESTDIR}${LIBDIR}/libcap_sysctl.a LIBCASPER?= ${DESTDIR}${LIBDIR}/libcasper.a +LIBCASPERMOCK?= ${DESTDIR}${LIBDIR}/libcaspermock.a LIBCOMPAT?= ${DESTDIR}${LIBDIR}/libcompat.a LIBCOMPILER_RT?=${DESTDIR}${LIBDIR}/libcompiler_rt.a LIBCOM_ERR?= ${DESTDIR}${LIBDIR}/libcom_err.a Index: share/mk/src.libnames.mk =================================================================== --- share/mk/src.libnames.mk +++ share/mk/src.libnames.mk @@ -70,6 +70,7 @@ calendar \ cam \ casper \ + caspermock \ cap_dns \ cap_grp \ cap_pwd \ @@ -230,6 +231,7 @@ _DP_cam= sbuf _DP_kvm= elf _DP_casper= nv +_DP_caspermock= nv _DP_cap_dns= nv _DP_cap_grp= nv _DP_cap_pwd= nv @@ -518,6 +520,7 @@ LIBBLOCKSRUNTIMEDIR= ${OBJTOP}/lib/libblocksruntime LIBBSNMPDIR= ${OBJTOP}/lib/libbsnmp/libbsnmp LIBCASPERDIR= ${OBJTOP}/lib/libcasper/libcasper +LIBCASPERMOCKDIR= ${OBJTOP}/lib/libcasper/libcaspermock LIBCAP_DNSDIR= ${OBJTOP}/lib/libcasper/services/cap_dns LIBCAP_GRPDIR= ${OBJTOP}/lib/libcasper/services/cap_grp LIBCAP_PWDDIR= ${OBJTOP}/lib/libcasper/services/cap_pwd