Browse Source

tpws,nfqws : remove cap library dependency

pull/53/head
bol-van 6 years ago
parent
commit
3c76e45692
  1. BIN
      binaries/aarch64/nfqws
  2. BIN
      binaries/armhf/nfqws
  3. BIN
      binaries/mips32r1-lsb/nfqws
  4. BIN
      binaries/mips32r1-msb/nfqws
  5. BIN
      binaries/mips64r2-msb/nfqws
  6. BIN
      binaries/ppc/nfqws
  7. BIN
      binaries/x86/nfqws
  8. BIN
      binaries/x86_64/nfqws
  9. 3
      nfq/Makefile
  10. 48
      nfq/sec.c
  11. 2
      nfq/sec.h
  12. 2
      tpws/Makefile
  13. 126
      tpws/sec.c
  14. 12
      tpws/sec.h
  15. 131
      tpws/tpws.c

BIN
binaries/aarch64/nfqws

Binary file not shown.

BIN
binaries/armhf/nfqws

Binary file not shown.

BIN
binaries/mips32r1-lsb/nfqws

Binary file not shown.

BIN
binaries/mips32r1-msb/nfqws

Binary file not shown.

BIN
binaries/mips64r2-msb/nfqws

Binary file not shown.

BIN
binaries/ppc/nfqws

Binary file not shown.

BIN
binaries/x86/nfqws

Binary file not shown.

BIN
binaries/x86_64/nfqws

Binary file not shown.

3
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

48
nfq/sec.c

@ -5,26 +5,26 @@
#include <unistd.h>
#include <fcntl.h>
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<<CAP_NET_ADMIN)|(1<<CAP_NET_RAW);
int maxcap = getmaxcap();
if (setpcap(cap_values, capct))
if (setpcap(caps|(1<<CAP_SETPCAP)))
{
for (int cap = 0; cap <= maxcap; cap++)
{
if (cap_drop_bound(cap))
if (prctl(PR_CAPBSET_DROP, cap)<0)
{
fprintf(stderr, "could not drop cap %d\n", cap);
fprintf(stderr, "could not drop bound cap %d\n", cap);
perror("cap_drop_bound");
}
}
}
// now without CAP_SETPCAP
if (!setpcap(cap_values, capct - 1))
if (!setpcap(caps))
{
perror("setpcap");
return false;
return checkpcap(caps);
}
return true;
}

2
nfq/sec.h

@ -4,7 +4,7 @@
#include <sys/types.h>
#include <stdbool.h>
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);

2
tpws/Makefile

@ -1,6 +1,6 @@
CC ?= gcc
CFLAGS += -std=c99 -s -O3
LIBS = -lz -lcap
LIBS = -lz
SRC_FILES = *.c
all: tpws

126
tpws/sec.c

@ -0,0 +1,126 @@
#include <stdio.h>
#include <stdlib.h>
#include "sec.h"
#include <sys/prctl.h>
#include <unistd.h>
#include <fcntl.h>
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<<CAP_SETPCAP)))
{
for (int cap = 0; cap <= maxcap; cap++)
{
if (prctl(PR_CAPBSET_DROP, cap)<0)
{
fprintf(stderr, "could not drop bound cap %d\n", cap);
perror("cap_drop_bound");
}
}
}
// now without CAP_SETPCAP
if (!setpcap(caps))
{
perror("setpcap");
return checkpcap(caps);
}
return true;
}
bool droproot(uid_t uid, gid_t gid)
{
if (uid || gid)
{
if (prctl(PR_SET_KEEPCAPS, 1L))
{
perror("prctl(PR_SET_KEEPCAPS): ");
return false;
}
if (setgid(gid))
{
perror("setgid: ");
return false;
}
if (setuid(uid))
{
perror("setuid: ");
return false;
}
}
return dropcaps();
}
void daemonize()
{
int pid;
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);
int fd;
/* stdin */
fd = dup(0);
/* stdout */
fd = dup(0);
/* stderror */
}
bool writepid(const char *filename)
{
FILE *F;
if (!(F = fopen(filename, "w")))
return false;
fprintf(F, "%d", getpid());
fclose(F);
return true;
}

12
tpws/sec.h

@ -0,0 +1,12 @@
#pragma once
#include <sys/capability.h>
#include <sys/types.h>
#include <stdbool.h>
bool setpcap(uint64_t caps);
int getmaxcap();
bool dropcaps();
bool droproot(uid_t uid, gid_t gid);
void daemonize();
bool writepid(const char *filename);

131
tpws/tpws.c

@ -20,8 +20,6 @@
#include <netinet/tcp.h>
#include <getopt.h>
#include <pwd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <time.h>
@ -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) {

Loading…
Cancel
Save