Check capabilities with kernel methods. Removes the need for libcap on the target system.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2019-03-17 10:57:48 +01:00
parent 9ed84ff717
commit 6186cd1cf6
2 changed files with 41 additions and 9 deletions
+1 -1
View File
@@ -98,7 +98,7 @@ CCFLAGS=-std=gnu11 -I$(IDIR) $(WARNFLAGS) -D_FILE_OFFSET_BITS=64 $(HARDENING_FLA
# for dnsmasq we need the nettle crypto library and the gmp maths library
# We link the two libraries statically. Although this increases the binary file size by about 1 MB, it saves about 5 MB of shared libraries and makes deployment easier
#LIBS=-pthread -lnettle -lgmp -lhogweed
LIBS=-pthread -lrt -lcap -Wl,-Bstatic -L/usr/local/lib -lhogweed -lgmp -lnettle -Wl,-Bdynamic
LIBS=-pthread -lrt -Wl,-Bstatic -L/usr/local/lib -lhogweed -lgmp -lnettle -Wl,-Bdynamic
# Flags for compiling with libidn : -lidn
# Flags for compiling with libidn2: -lidn2
+40 -8
View File
@@ -8,36 +8,68 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
// Definition of LINUX_CAPABILITY_VERSION_*
#define FTLDNS
#include "dnsmasq/dnsmasq.h"
#undef __USE_XOPEN
#include "FTL.h"
#include <sys/capability.h>
bool check_capabilities()
{
if(!cap_get_bound(CAP_NET_ADMIN))
int capsize = 1; /* for header version 1 */
cap_user_header_t hdr = NULL;
cap_user_data_t data = NULL;
/* find version supported by kernel */
hdr = calloc(sizeof(*hdr), capsize);
memset(hdr, 0, sizeof(*hdr));
capget(hdr, NULL);
if (hdr->version != LINUX_CAPABILITY_VERSION_1)
{
/* if unknown version, use largest supported version (3) */
if (hdr->version != LINUX_CAPABILITY_VERSION_2)
hdr->version = LINUX_CAPABILITY_VERSION_3;
capsize = 2;
}
data = calloc(sizeof(*data), capsize);
capget(hdr, data); /* Get current values, for verification */
bool missing = true;
if (!(data->permitted & (1 << CAP_NET_ADMIN)))
{
// Needed for ARP-injection (used when we're the DHCP server)
logg("**************************************************************");
logg("WARNING: Required linux capability CAP_NET_ADMIN not available");
logg("**************************************************************");
return false;
missing = true;
}
if(!cap_get_bound(CAP_NET_RAW))
if (!(data->permitted & (1 << CAP_NET_RAW)))
{
// Needed for raw socket access (necessary for ICMP)
logg("************************************************************");
logg("WARNING: Required linux capability CAP_NET_RAW not available");
logg("************************************************************");
return false;
missing = true;
}
if(!cap_get_bound(CAP_NET_BIND_SERVICE))
if (!(data->permitted & (1 << CAP_NET_BIND_SERVICE)))
{
// Necessary for dynamic port binding
logg("*********************************************************************");
logg("WARNING: Required linux capability CAP_NET_BIND_SERVICE not available");
logg("*********************************************************************");
return false;
missing = true;
}
if (!(data->permitted & (1 << CAP_SETUID)))
{
// Necessary for changing our own user ID ("daemonizing")
logg("*********************************************************************");
logg("WARNING: Required linux capability CAP_SETUID not available");
logg("*********************************************************************");
missing = true;
}
// All okay!
return true;
return missing;
}