Revert "tpws,nfqws : remove cap library dependency"

This reverts commit 3c76e45692038077249b63a9666b11d930f8e283.
This commit is contained in:
bol-van 2020-01-20 15:10:49 +03:00
parent 81a6ece230
commit eb6f962ba3
15 changed files with 155 additions and 169 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
CC ?= gcc CC ?= gcc
CFLAGS += -std=c99 -s -O3 CFLAGS += -std=c99 -s -O3
LIBS = -lnetfilter_queue -lnfnetlink -lz LIBS = -lnetfilter_queue -lnfnetlink -lcap -lz
SRC_FILES = *.c SRC_FILES = *.c
all: nfqws all: nfqws
@ -10,4 +10,3 @@ nfqws: $(SRC_FILES)
clean: clean:
rm -f nfqws *.o rm -f nfqws *.o

View File

@ -5,26 +5,26 @@
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
bool checkpcap(uint64_t caps) bool setpcap(cap_value_t *caps, int ncaps)
{ {
struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; cap_t capabilities;
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; 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;
} }
bool setpcap(uint64_t caps) if (cap_set_proc(capabilities))
{ {
struct __user_cap_header_struct ch = {_LINUX_CAPABILITY_VERSION_3, getpid()}; cap_free(capabilities);
struct __user_cap_data_struct cd[2]; return false;
}
cd[0].effective = cd[0].permitted = (uint32_t)caps; cap_free(capabilities);
cd[0].inheritable = 0; return true;
cd[1].effective = cd[1].permitted = (uint32_t)(caps>>32);
cd[1].inheritable = 0;
return !capset(&ch,cd);
} }
int getmaxcap() int getmaxcap()
{ {
@ -40,25 +40,27 @@ int getmaxcap()
} }
bool dropcaps() bool dropcaps()
{ {
uint64_t caps = (1<<CAP_NET_ADMIN)|(1<<CAP_NET_RAW); // 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);
int maxcap = getmaxcap(); int maxcap = getmaxcap();
if (setpcap(caps|(1<<CAP_SETPCAP))) if (setpcap(cap_values, capct))
{ {
for (int cap = 0; cap <= maxcap; cap++) for (int cap = 0; cap <= maxcap; cap++)
{ {
if (prctl(PR_CAPBSET_DROP, cap)<0) if (cap_drop_bound(cap))
{ {
fprintf(stderr, "could not drop bound cap %d\n", cap); fprintf(stderr, "could not drop cap %d\n", cap);
perror("cap_drop_bound"); perror("cap_drop_bound");
} }
} }
} }
// now without CAP_SETPCAP // now without CAP_SETPCAP
if (!setpcap(caps)) if (!setpcap(cap_values, capct - 1))
{ {
perror("setpcap"); perror("setpcap");
return checkpcap(caps); return false;
} }
return true; return true;
} }

View File

@ -4,7 +4,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdbool.h> #include <stdbool.h>
bool setpcap(uint64_t caps); bool setpcap(cap_value_t *caps, int ncaps);
int getmaxcap(); int getmaxcap();
bool dropcaps(); bool dropcaps();
bool droproot(uid_t uid, gid_t gid); bool droproot(uid_t uid, gid_t gid);

View File

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

View File

@ -1,126 +0,0 @@
#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;
}

View File

@ -1,12 +0,0 @@
#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);

View File

@ -20,6 +20,8 @@
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <getopt.h> #include <getopt.h>
#include <pwd.h> #include <pwd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/resource.h> #include <sys/resource.h>
#include <time.h> #include <time.h>
@ -27,7 +29,6 @@
#include "tpws_conn.h" #include "tpws_conn.h"
#include "hostlist.h" #include "hostlist.h"
#include "params.h" #include "params.h"
#include "sec.h"
struct params_s params; struct params_s params;
@ -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) static bool find_listen_addr(struct sockaddr_storage *salisten, bool bindll, int *if_index)
@ -683,7 +806,7 @@ int main(int argc, char *argv[]) {
set_ulimit(); set_ulimit();
if (!droproot(params.uid,params.gid)) if (!droproot())
{ {
goto exiterr; goto exiterr;
} }