Skip to content

Commit

Permalink
Introduce caspermocks.
Browse files Browse the repository at this point in the history
The idea behinds mocks is that we don't need to ifdef a lot of code in
tools itself but those defines are hidden in the casper library.
Right now the mocks are implemented as define/inlines functions.
There was a very long discussion how this should be implemented.
This approach has some advantages like we don't need to link to any additional
libraries. Unfortunately there are also some disadvantages for example it is
easy to get library out of sync between two versions of functions or that we
need extra define to compile program with casper support.
This isn't an ideal solution but it's good enough for now and should simplify
capsicumizing programs. This also doesn't close us any other ways to do those
mocks and this should evolve in time.

Discussed with:	pjd, emaste, ed, rwatson, bapt, cem, bdrewery
Differential Revision:    https://reviews.freebsd.org/D8753
  • Loading branch information
oshogbo committed Oct 28, 2017
1 parent b8c7b15 commit ceb36bc
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 9 deletions.
2 changes: 1 addition & 1 deletion lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libcalendar \
libcam \
libcapsicum \
libcasper \
libcompat \
libcrypt \
libdevctl \
Expand Down Expand Up @@ -127,7 +128,6 @@ SUBDIR.${MK_ATM}+= libngatm
SUBDIR.${MK_BLACKLIST}+=libblacklist
SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp
SUBDIR.${MK_BSNMP}+= libbsnmp
SUBDIR.${MK_CASPER}+= libcasper

.if !defined(COMPAT_32BIT) && !defined(COMPAT_SOFTFP)
SUBDIR.${MK_CLANG}+= clang
Expand Down
6 changes: 6 additions & 0 deletions lib/libcasper/Makefile.inc
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# $FreeBSD$

.include <src.opts.mk>

.if ${MK_CASPER} != "no"
CFLAGS+=-DWITH_CASPER
.endif

.include "../Makefile.inc"
7 changes: 6 additions & 1 deletion lib/libcasper/libcasper/Makefile
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
# $FreeBSD$

.include <src.opts.mk>

PACKAGE=${LIB}
LIB= casper

SHLIB_MAJOR= 0
SHLIBDIR?= /lib

.if ${MK_CASPER} != "no"
LIB= casper

SRCS= libcasper.c
SRCS+= libcasper_impl.c
SRCS+= libcasper_service.c
SRCS+= service.c
SRCS+= zygote.c
.endif

INCS= libcasper.h
INCS+= libcasper_service.h
Expand Down
131 changes: 129 additions & 2 deletions lib/libcasper/libcasper/libcasper.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*-
* Copyright (c) 2012-2013 The FreeBSD Foundation
* Copyright (c) 2015 Mariusz Zaborski <[email protected]>
* Copyright (c) 2015-2017 Mariusz Zaborski <[email protected]>
* All rights reserved.
*
* This software was developed by Pawel Jakub Dawidek under sponsorship from
Expand Down Expand Up @@ -33,7 +33,15 @@
#ifndef _LIBCASPER_H_
#define _LIBCASPER_H_

#ifdef HAVE_CASPER
#define WITH_CASPER
#endif

#include <sys/types.h>
#include <sys/nv.h>

#include <stdlib.h>
#include <unistd.h>

#ifndef _NVLIST_T_DECLARED
#define _NVLIST_T_DECLARED
Expand All @@ -44,72 +52,191 @@ typedef struct nvlist nvlist_t;

#ifndef _CAP_CHANNEL_T_DECLARED
#define _CAP_CHANNEL_T_DECLARED
#ifdef WITH_CASPER
struct cap_channel;

typedef struct cap_channel cap_channel_t;
#endif
#else
struct cap_channel {
int cch_fd;
};
typedef struct cap_channel cap_channel_t;
#endif /* ! WITH_CASPER */
#endif /* ! _CAP_CHANNEL_T_DECLARED */

/*
* The functions opens unrestricted communication channel to Casper.
*/
#ifdef WITH_CASPER
cap_channel_t *cap_init(void);
#else
static inline cap_channel_t *
cap_init(void)
{
cap_channel_t *chan;

chan = malloc(sizeof(*chan));
if (chan != NULL) {
chan->cch_fd = -1;
}
return (chan);
}
#endif

/*
* The functions to communicate with service.
*/
#ifdef WITH_CASPER
cap_channel_t *cap_service_open(const cap_channel_t *chan, const char *name);
int cap_service_limit(const cap_channel_t *chan,
const char * const *names, size_t nnames);
#else
#define cap_service_open(chan, name) (cap_init())
#define cap_service_limit(chan, names, nnames) (0)
#endif

/*
* The function creates cap_channel_t based on the given socket.
*/
#ifdef WITH_CASPER
cap_channel_t *cap_wrap(int sock);
#else
static inline cap_channel_t *
cap_wrap(int sock)
{
cap_channel_t *chan;

chan = cap_init();
if (chan != NULL) {
chan->cch_fd = sock;
}
return (chan);
}
#endif

/*
* The function returns communication socket and frees cap_channel_t.
*/
#ifdef WITH_CASPER
int cap_unwrap(cap_channel_t *chan);
#else
#define cap_unwrap(chan) (chan->cch_fd)
#endif

/*
* The function clones the given capability.
*/
#ifdef WITH_CASPER
cap_channel_t *cap_clone(const cap_channel_t *chan);
#else
static inline cap_channel_t *
cap_clone(const cap_channel_t *chan)
{
cap_channel_t *newchan;

newchan = cap_init();
if (newchan == NULL) {
return (NULL);
}

if (chan->cch_fd == -1) {
newchan->cch_fd = -1;
} else {
newchan->cch_fd = dup(chan->cch_fd);
if (newchan->cch_fd < 0) {
free(newchan);
newchan = NULL;
}
}

return (newchan);
}
#endif

/*
* The function closes the given capability.
*/
#ifdef WITH_CASPER
void cap_close(cap_channel_t *chan);
#else
static inline void
cap_close(cap_channel_t *chan)
{

if (chan->cch_fd >= 0) {
close(chan->cch_fd);
}
free(chan);
}
#endif

/*
* The function returns socket descriptor associated with the given
* cap_channel_t for use with select(2)/kqueue(2)/etc.
*/
#ifdef WITH_CASPER
int cap_sock(const cap_channel_t *chan);
#else
#define cap_sock(chan) (chan->cch_fd)
#endif

/*
* The function limits the given capability.
* It always destroys 'limits' on return.
*/
#ifdef WITH_CASPER
int cap_limit_set(const cap_channel_t *chan, nvlist_t *limits);
#else
#define cap_limit_set(chan, limits) (0)
#endif

/*
* The function returns current limits of the given capability.
*/
#ifdef WITH_CASPER
int cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp);
#else
static inline int
cap_limit_get(const cap_channel_t *chan __unused, nvlist_t **limitsp)
{

*limitsp = nvlist_create(0);
return (0);
}
#endif

/*
* Function sends nvlist over the given capability.
*/
#ifdef WITH_CASPER
int cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl);
#else
#define cap_send_nvlist(chan, nvl) (0)
#endif

/*
* Function receives nvlist over the given capability.
*/
#ifdef WITH_CASPER
nvlist_t *cap_recv_nvlist(const cap_channel_t *chan, int flags);
#else
#define cap_recv_nvlist(chan, flags) (0)
#endif

/*
* Function sends the given nvlist, destroys it and receives new nvlist in
* response over the given capability.
*/
#ifdef WITH_CASPER
nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags);
#else
static inline nvlist_t *
cap_xfer_nvlist(const cap_channel_t *chan __unused, nvlist_t *nvl, int flags)
{

nvlist_destroy(nvl);
return (nvlist_create(flags));
}
#endif

#endif /* !_LIBCASPER_H_ */
2 changes: 2 additions & 0 deletions lib/libcasper/services/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# $FreeBSD$

.include <src.opts.mk>

SUBDIR= cap_dns
SUBDIR+= cap_grp
SUBDIR+= cap_pwd
Expand Down
5 changes: 4 additions & 1 deletion lib/libcasper/services/cap_dns/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ SHLIBDIR?= /lib/casper
.include <src.opts.mk>

PACKAGE=libcasper
LIB= cap_dns

SHLIB_MAJOR= 0
INCSDIR?= ${INCLUDEDIR}/casper

.if ${MK_CASPER} != "no"
LIB= cap_dns

SRCS= cap_dns.c
.endif

INCS= cap_dns.h

Expand Down
18 changes: 18 additions & 0 deletions lib/libcasper/services/cap_dns/cap_dns.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@
#ifndef _CAP_DNS_H_
#define _CAP_DNS_H_

#ifdef HAVE_CASPER
#define WITH_CASPER
#endif

#include <sys/socket.h> /* socklen_t */

struct addrinfo;
struct hostent;

#ifdef WITH_CASPER
struct hostent *cap_gethostbyname(cap_channel_t *chan, const char *name);
struct hostent *cap_gethostbyname2(cap_channel_t *chan, const char *name,
int type);
Expand All @@ -53,5 +58,18 @@ int cap_dns_type_limit(cap_channel_t *chan, const char * const *types,
size_t ntypes);
int cap_dns_family_limit(cap_channel_t *chan, const int *families,
size_t nfamilies);
#else
#define cap_gethostbyname(chan, name) gethostbyname(name)
#define cap_gethostbyname2(chan, name, type) gethostbyname2(name, type)
#define cap_gethostbyaddr(chan, addr, len, type) gethostbyaddr(addr, len, type)

#define cap_getaddrinfo(chan, hostname, servname, hints, res) \
getaddrinfo(hostname, servname, hints, res)
#define cap_getnameinfo(chan, sa, salen, host, hostlen, serv, servlen, flags) \
getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)

#define cap_dns_type_limit(chan, types, ntypes) (0)
#define cap_dns_family_limit(chan, families, nfamilies) (0)
#endif

#endif /* !_CAP_DNS_H_ */
4 changes: 4 additions & 0 deletions lib/libcasper/services/cap_dns/tests/Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# $FreeBSD$

.include <src.opts.mk>

TAP_TESTS_C= dns_test

.if ${MK_CASPER} != "no"
LIBADD+= casper
LIBADD+= cap_dns
.endif
LIBADD+= nv

WARNS?= 3
Expand Down
1 change: 1 addition & 0 deletions lib/libcasper/services/cap_dns/tests/dns_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
__FBSDID("$FreeBSD$");

#include <sys/capsicum.h>
#include <sys/nv.h>

#include <arpa/inet.h>
#include <netinet/in.h>
Expand Down
5 changes: 4 additions & 1 deletion lib/libcasper/services/cap_grp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ SHLIBDIR?= /lib/casper
.include <src.opts.mk>

PACKAGE=libcasper
LIB= cap_grp

SHLIB_MAJOR= 0
INCSDIR?= ${INCLUDEDIR}/casper

.if ${MK_CASPER} != "no"
LIB= cap_grp

SRCS= cap_grp.c
.endif

INCS= cap_grp.h

Expand Down
Loading

0 comments on commit ceb36bc

Please sign in to comment.