Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,21 @@ if test x"$transparent_enabled" = x"yes"; then
AC_DEFINE(TRANSPARENT_PROXY)
fi

dnl Support capsicum using libcasper for priv sep of networking code
AH_TEMPLATE([WITH_CASPER],
[Include support for using tinyproxy in capabilitiy mode.])
TP_ARG_ENABLE(capsicum,
[Enable capsicum code (default is YES)],
yes)
if test x"$capsicum_enabled" = x"yes"; then
ADDITIONAL_OBJECTS="$ADDITIONAL_OBJECTS cap.o"
AC_DEFINE(WITH_CASPER)
AC_CHECK_LIB(casper, cap_init, , [AC_CHECK_LIB(casper, cap_init)])
AC_CHECK_LIB(cap_net, cap_bind, , [AC_CHECK_LIB(cap_net, cap_bind)])
AC_CHECK_LIB(cap_syslog, cap_syslog, , [AC_CHECK_LIB(cap_syslog, cap_syslog)])
AC_CHECK_LIB(nv, nvlist_create, , [AC_CHECK_LIB(nv, nvlist_create)])
fi

dnl Let user decide whether he wants support for manpages
dnl Which require either pod2man or a tarball release
AH_TEMPLATE([MANPAGE_SUPPORT],
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ tinyproxy_SOURCES = \

EXTRA_tinyproxy_SOURCES = filter.c filter.h \
reverse-proxy.c reverse-proxy.h \
cap.c cap.h \
transparent-proxy.c transparent-proxy.h
tinyproxy_DEPENDENCIES = @ADDITIONAL_OBJECTS@
tinyproxy_LDADD = @ADDITIONAL_OBJECTS@ -lpthread
Expand Down
8 changes: 7 additions & 1 deletion src/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "sock.h"
#include "sblist.h"
#include "hostspec.h"
#include "cap.h"

/*
* Hold the information about a particular access control. We store
Expand Down Expand Up @@ -148,7 +149,12 @@ acl_string_processing (struct acl_s *acl, const char *ip_address,
if(string_addr[0] == 0) {
/* only do costly hostname resolution when it is absolutely needed,
and only once */
if(getnameinfo ((void *) addr, sizeof (*addr),
#ifdef WITH_CASPER
if(cap_getnameinfo (cap_net,
#else
if(getnameinfo (
#endif /* ifdef WITH_CASPER */
(void *) addr, sizeof (*addr),
string_addr, HOSTNAME_LENGTH, NULL, 0, 0) != 0)
return -1;
}
Expand Down
46 changes: 46 additions & 0 deletions src/cap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "common.h"
#include "cap.h"
#include "log.h"
#include <err.h>

void cap_begin(void) {
cap_in = cap_init();
if (cap_in == NULL)
err(1, "Failed to communicate with libcasper");

if (caph_limit_stdio() == -1)
err(1, "Failed to limit stdio");
}

void cap_server_socket(int fd) {
cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE);
if (caph_rights_limit(fd, &rights) == -1)
err(1, "Unable to apply rights for sandbox");
}

void cap_start(bool syslog) {
if (caph_enter_casper() == -1)
err(1, "Failed to enter capability mode");

log_message(LOG_NOTICE, "entered capability mode");

cap_net = cap_service_open(cap_in, "system.net");
if (cap_net == NULL)
err(1, "Failed to open the system.net libcasper service");

if (syslog) {
cap_log = cap_service_open(cap_in, "system.syslog");
if (cap_log == NULL)
err(1, "Failed to open the system.syslog libcasper service");
}

cap_close(cap_in);

limit = cap_net_limit_init(cap_net, CAPNET_NAME2ADDR | CAPNET_CONNECT);
if (limit == NULL)
err(1, "Failed to create system.net limits");

if (cap_net_limit(limit) == -1)
err(1, "Failed to apply system.net limits");
}

28 changes: 28 additions & 0 deletions src/cap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include "common.h"

#ifdef WITH_CASPER

/* hack to make capsicum work */
#ifndef inline
#define inline
#endif

#include <capsicum_helpers.h>

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

#include <libcasper.h>
#include <casper/cap_net.h>
#include <casper/cap_syslog.h>

extern cap_rights_t rights;
extern cap_channel_t *cap_net, *cap_log, *cap_in;
extern cap_net_limit_t *limit;

void cap_begin(void);
void cap_server_socket(int fd);
void cap_start(bool syslog);

#endif /* WITH_CASPER */

9 changes: 9 additions & 0 deletions src/child.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "loop.h"
#include "conns.h"
#include "mypoll.h"
#include "cap.h"
#include <pthread.h>

static sblist* listen_fds;
Expand Down Expand Up @@ -95,8 +96,16 @@ void child_main_loop (void)
int *fd = sblist_get(listen_fds, i);
fds[i].fd = *fd;
fds[i].events |= MYPOLL_READ;

#ifdef WITH_CASPER
cap_server_socket(fds[i].fd);
#endif /* ifdef WITH_CASPER */
}

#ifdef WITH_CASPER
cap_start(config->syslog);
#endif /* ifdef WITH_CASPER */

/*
* We have to wait for connections on multiple fds,
* so use select/poll/whatever.
Expand Down
20 changes: 19 additions & 1 deletion src/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "heap.h"
#include "log.h"
#include "cap.h"
#include "utils.h"
#include "sblist.h"
#include "conf.h"
Expand Down Expand Up @@ -166,7 +167,16 @@ void log_message (int level, const char *fmt, ...)
if (config->syslog) {
pthread_mutex_lock(&log_mutex);
vsnprintf (str, STRING_LENGTH, fmt, args);
syslog (level, "%s", str);
#ifdef WITH_CASPER
/* only use after entered cap mode*/
if (cap_log == NULL)
syslog (level, "%s", str);
else
cap_syslog (cap_log,
#else
syslog (
#endif /* ifdef WITH_CASPER */
level, "%s", str);
pthread_mutex_unlock(&log_mutex);
} else {
char *p;
Expand Down Expand Up @@ -290,6 +300,14 @@ int setup_logging (void)
}

logging_initialized = TRUE;

#ifdef WITH_CASPER
if (!config->syslog) {
if (caph_limit_stream(log_file_fd, CAPH_WRITE | CAPH_IGNORE_EBADF) == -1)
err(1, "Failed to limit logfile write");
}
#endif

send_stored_logs ();

return 0;
Expand Down
17 changes: 16 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "sock.h"
#include "stats.h"
#include "utils.h"
#include "cap.h"

/*
* Global Structures
Expand All @@ -53,6 +54,12 @@ static struct config_s configs[2];
static const char* config_file;
unsigned int received_sighup = FALSE; /* boolean */

#ifdef WITH_CASPER
cap_rights_t rights;
cap_channel_t *cap_net = NULL, *cap_log = NULL, *cap_in = NULL;
cap_net_limit_t *limit = NULL;
#endif /* ifdef WITH_CASPER */

static struct config_s*
get_next_config(void)
{
Expand Down Expand Up @@ -113,7 +120,6 @@ display_usage (void)
" -h Display this usage information.\n"
" -v Display version information.\n");

/* Display the modes compiled into tinyproxy */
printf ("\nFeatures compiled in:\n");

#ifdef XTINYPROXY_ENABLE
Expand Down Expand Up @@ -146,6 +152,11 @@ display_usage (void)
features++;
#endif /* UPSTREAM_SUPPORT */

#ifdef WITH_CASPER
printf (" Capsicum support\n");
features++;
#endif /* WITH_CASPER */

if (0 == features)
printf (" None\n");

Expand Down Expand Up @@ -332,6 +343,10 @@ main (int argc, char **argv)
}
}

#ifdef WITH_CASPER
cap_begin();
#endif /* ifdef WITH_CASPER */

if (reload_config(0)) {
exit (EX_SOFTWARE);
}
Expand Down
15 changes: 13 additions & 2 deletions src/sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "conf.h"
#include "loop.h"
#include "sblist.h"
#include "cap.h"

/*
* Return a human readable error for getaddrinfo() and getnameinfo().
Expand Down Expand Up @@ -151,7 +152,12 @@ int opensock (const char *host, int port, const char *bind_to)

snprintf (portstr, sizeof (portstr), "%d", port);

n = getaddrinfo (host, portstr, &hints, &res);
#ifdef WITH_CASPER
n = cap_getaddrinfo (cap_net,
#else
n = getaddrinfo (
#endif /* ifdef WITH_CASPER */
host, portstr, &hints, &res);
if (n != 0) {
log_message (LOG_ERR,
"opensock: Could not retrieve address info for %s:%d: %s", host, port, get_gai_error (n));
Expand Down Expand Up @@ -185,7 +191,12 @@ int opensock (const char *host, int port, const char *bind_to)

set_socket_timeout(sockfd);

if (connect (sockfd, res->ai_addr, res->ai_addrlen) == 0) {
#ifdef WITH_CASPER
if (cap_connect (cap_net,
#else
if (connect (
#endif /* ifdef WITH_CASPER */
sockfd, res->ai_addr, res->ai_addrlen) == 0) {
union sockaddr_union *p = (void*) res->ai_addr, u;
int af = res->ai_addr->sa_family;
unsigned dport = ntohs(af == AF_INET ? p->v4.sin_port : p->v6.sin6_port);
Expand Down