diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 6d122dc..4b31cce 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/armhf/nfqws b/binaries/armhf/nfqws index d708da7..8684278 100755 Binary files a/binaries/armhf/nfqws and b/binaries/armhf/nfqws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index 3b55548..c59e141 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index 914424f..a22bdda 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index 475d573..fa01ece 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 7b827bd..d9e1ce4 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 64bca70..42424ac 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 36ee0cb..4531e0f 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/Makefile b/nfq/Makefile index 9db5c09..a138ba7 100644 --- a/nfq/Makefile +++ b/nfq/Makefile @@ -1,6 +1,6 @@ CC ?= gcc CFLAGS += -std=c99 -s -O3 -LIBS = -lnetfilter_queue -lnfnetlink -lz +LIBS = -lnetfilter_queue -lnfnetlink -lcap -lz SRC_FILES = *.c all: nfqws @@ -10,4 +10,3 @@ nfqws: $(SRC_FILES) clean: rm -f nfqws *.o - diff --git a/nfq/sec.c b/nfq/sec.c index 019d2d9..38612d2 100644 --- a/nfq/sec.c +++ b/nfq/sec.c @@ -5,26 +5,26 @@ #include #include -bool checkpcap(uint64_t caps) +bool setpcap(cap_value_t *caps, int ncaps) { - struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; - struct __user_cap_data_struct cd[2]; - uint32_t c0 = (uint32_t)caps; - uint32_t c1 = (uint32_t)(caps>>32); + cap_t capabilities; - return !capget(&ch,cd) && (cd[0].effective & c0)==c0 && (cd[0].effective & c1)==c1; -} -bool setpcap(uint64_t caps) -{ - struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; - struct __user_cap_data_struct cd[2]; - - cd[0].effective = cd[0].permitted = (uint32_t)caps; - cd[0].inheritable = 0; - cd[1].effective = cd[1].permitted = (uint32_t)(caps>>32); - cd[1].inheritable = 0; + if (!(capabilities = cap_init())) + return false; - return !capset(&ch,cd); + if (ncaps && (cap_set_flag(capabilities, CAP_PERMITTED, ncaps, caps, CAP_SET) || + cap_set_flag(capabilities, CAP_EFFECTIVE, ncaps, caps, CAP_SET))) + { + cap_free(capabilities); + return false; + } + if (cap_set_proc(capabilities)) + { + cap_free(capabilities); + return false; + } + cap_free(capabilities); + return true; } int getmaxcap() { @@ -40,25 +40,27 @@ int getmaxcap() } bool dropcaps() { - uint64_t caps = (1< #include -bool setpcap(uint64_t caps); +bool setpcap(cap_value_t *caps, int ncaps); int getmaxcap(); bool dropcaps(); bool droproot(uid_t uid, gid_t gid); diff --git a/tpws/Makefile b/tpws/Makefile index b8a3430..7094d43 100644 --- a/tpws/Makefile +++ b/tpws/Makefile @@ -1,6 +1,6 @@ CC ?= gcc CFLAGS += -std=c99 -s -O3 -LIBS = -lz +LIBS = -lz -lcap SRC_FILES = *.c all: tpws diff --git a/tpws/sec.c b/tpws/sec.c deleted file mode 100644 index 0cf2abc..0000000 --- a/tpws/sec.c +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include "sec.h" -#include -#include -#include - -bool checkpcap(uint64_t caps) -{ - struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; - struct __user_cap_data_struct cd[2]; - uint32_t c0 = (uint32_t)caps; - uint32_t c1 = (uint32_t)(caps>>32); - - return !capget(&ch,cd) && (cd[0].effective & c0)==c0 && (cd[0].effective & c1)==c1; -} -bool setpcap(uint64_t caps) -{ - struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; - struct __user_cap_data_struct cd[2]; - - cd[0].effective = cd[0].permitted = (uint32_t)caps; - cd[0].inheritable = 0; - cd[1].effective = cd[1].permitted = (uint32_t)(caps>>32); - cd[1].inheritable = 0; - - return !capset(&ch,cd); -} -int getmaxcap() -{ - int maxcap = CAP_LAST_CAP; - FILE *F = fopen("/proc/sys/kernel/cap_last_cap", "r"); - if (F) - { - int n = fscanf(F, "%d", &maxcap); - fclose(F); - } - return maxcap; - -} -bool dropcaps() -{ - uint64_t caps = 0; - int maxcap = getmaxcap(); - - if (setpcap(caps|(1< -#include -#include - -bool setpcap(uint64_t caps); -int getmaxcap(); -bool dropcaps(); -bool droproot(uid_t uid, gid_t gid); -void daemonize(); -bool writepid(const char *filename); diff --git a/tpws/tpws.c b/tpws/tpws.c index f1d855c..2b671b7 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include @@ -27,8 +29,7 @@ #include "tpws_conn.h" #include "hostlist.h" #include "params.h" -#include "sec.h" - + struct params_s params; bool bHup = false; @@ -421,6 +422,128 @@ void parse_params(int argc, char *argv[]) } } +static void daemonize() +{ + int pid,fd; + + pid = fork(); + if (pid == -1) + { + perror("fork: "); + exit(2); + } + else if (pid != 0) + exit(0); + + if (setsid() == -1) + exit(2); + if (chdir("/") == -1) + exit(2); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + /* redirect fd's 0,1,2 to /dev/null */ + open("/dev/null", O_RDWR); + /* stdin */ + fd=dup(0); + /* stdout */ + fd=dup(0); + /* stderror */ +} + +static bool setpcap(cap_value_t *caps,int ncaps) +{ + cap_t capabilities; + + if (!(capabilities = cap_init())) + return false; + + if (ncaps && (cap_set_flag(capabilities, CAP_PERMITTED, ncaps, caps, CAP_SET) || + cap_set_flag(capabilities, CAP_EFFECTIVE, ncaps, caps, CAP_SET))) + { + cap_free(capabilities); + return false; + } + if (cap_set_proc(capabilities)) + { + cap_free(capabilities); + return false; + } + cap_free(capabilities); + return true; +} +static int getmaxcap() +{ + int maxcap = CAP_LAST_CAP; + FILE *F = fopen("/proc/sys/kernel/cap_last_cap","r"); + if (F) + { + int n=fscanf(F,"%d",&maxcap); + fclose(F); + } + return maxcap; + +} +static bool dropcaps() +{ + // must have CAP_SETPCAP at the end. its required to clear bounding set + cap_value_t cap_values[] = {CAP_SETPCAP}; + int capct=sizeof(cap_values)/sizeof(*cap_values); + int maxcap = getmaxcap(); + + if (setpcap(cap_values, capct)) + { + for(int cap=0;cap<=maxcap;cap++) + { + if (cap_drop_bound(cap)) + { + fprintf(stderr,"could not drop cap %d\n",cap); + perror("cap_drop_bound"); + } + } + } + // now without CAP_SETPCAP + if (!setpcap(cap_values, capct - 1)) + { + perror("setpcap"); + return false; + } + return true; +} +static bool droproot() +{ + if (params.uid || params.gid) + { + if (prctl(PR_SET_KEEPCAPS, 1L)) + { + perror("prctl(PR_SET_KEEPCAPS): "); + return false; + } + if (setgid(params.gid)) + { + perror("setgid: "); + return false; + } + if (setuid(params.uid)) + { + perror("setuid: "); + return false; + } + } + return dropcaps(); +} + + +static bool writepid(const char *filename) +{ + FILE *F; + if (!(F=fopen(filename,"w"))) + return false; + fprintf(F,"%d",getpid()); + fclose(F); + return true; +} + static bool find_listen_addr(struct sockaddr_storage *salisten, bool bindll, int *if_index) @@ -683,11 +806,11 @@ int main(int argc, char *argv[]) { set_ulimit(); - if (!droproot(params.uid,params.gid)) + if (!droproot()) { goto exiterr; } - + fprintf(stderr,"Running as UID=%u GID=%u\n",getuid(),getgid()); if (listen(listen_fd, BACKLOG) == -1) {