mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-17 04:22:59 +03:00
tpws,nfqws : remove cap library dependency
This commit is contained in:
parent
0d8ffde17a
commit
3c76e45692
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.
@ -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
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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
Normal file
126
tpws/sec.c
Normal file
@ -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
Normal file
12
tpws/sec.h
Normal file
@ -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
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…
x
Reference in New Issue
Block a user