diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 4b31cce..6d122dc 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/armhf/nfqws b/binaries/armhf/nfqws index 8684278..d708da7 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 c59e141..3b55548 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 a22bdda..914424f 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 fa01ece..475d573 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 d9e1ce4..7b827bd 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 42424ac..64bca70 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 4531e0f..36ee0cb 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/Makefile b/nfq/Makefile index a138ba7..9db5c09 100644 --- a/nfq/Makefile +++ b/nfq/Makefile @@ -1,6 +1,6 @@ CC ?= gcc CFLAGS += -std=c99 -s -O3 -LIBS = -lnetfilter_queue -lnfnetlink -lcap -lz +LIBS = -lnetfilter_queue -lnfnetlink -lz SRC_FILES = *.c all: nfqws @@ -10,3 +10,4 @@ nfqws: $(SRC_FILES) clean: rm -f nfqws *.o + diff --git a/nfq/sec.c b/nfq/sec.c index 38612d2..019d2d9 100644 --- a/nfq/sec.c +++ b/nfq/sec.c @@ -5,26 +5,26 @@ #include #include -bool setpcap(cap_value_t *caps, int ncaps) +bool checkpcap(uint64_t caps) { - cap_t capabilities; + 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); - if (!(capabilities = cap_init())) - return false; + 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 (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; + return !capset(&ch,cd); } int getmaxcap() { @@ -40,27 +40,25 @@ int getmaxcap() } bool dropcaps() { - // must have CAP_SETPCAP at the end. its required to clear bounding set - cap_value_t cap_values[] = { CAP_NET_ADMIN,CAP_NET_RAW,CAP_SETPCAP }; - int capct = sizeof(cap_values) / sizeof(*cap_values); + uint64_t caps = (1< #include -bool setpcap(cap_value_t *caps, int ncaps); +bool setpcap(uint64_t caps); int getmaxcap(); bool dropcaps(); bool droproot(uid_t uid, gid_t gid); diff --git a/tpws/Makefile b/tpws/Makefile index 7094d43..b8a3430 100644 --- a/tpws/Makefile +++ b/tpws/Makefile @@ -1,6 +1,6 @@ CC ?= gcc CFLAGS += -std=c99 -s -O3 -LIBS = -lz -lcap +LIBS = -lz SRC_FILES = *.c all: tpws diff --git a/tpws/sec.c b/tpws/sec.c new file mode 100644 index 0000000..0cf2abc --- /dev/null +++ b/tpws/sec.c @@ -0,0 +1,126 @@ +#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 2b671b7..f1d855c 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include @@ -29,7 +27,8 @@ #include "tpws_conn.h" #include "hostlist.h" #include "params.h" - +#include "sec.h" + struct params_s params; bool bHup = false; @@ -422,128 +421,6 @@ 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) @@ -806,11 +683,11 @@ int main(int argc, char *argv[]) { set_ulimit(); - if (!droproot()) + if (!droproot(params.uid,params.gid)) { goto exiterr; } - + fprintf(stderr,"Running as UID=%u GID=%u\n",getuid(),getgid()); if (listen(listen_fd, BACKLOG) == -1) {