mirror of
https://github.com/bol-van/zapret.git
synced 2025-04-17 04:22:59 +03:00
Revert "tpws,nfqws : remove cap library dependency"
This reverts commit 3c76e45692038077249b63a9666b11d930f8e283.
This commit is contained in:
parent
81a6ece230
commit
eb6f962ba3
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 -lz
|
||||
LIBS = -lnetfilter_queue -lnfnetlink -lcap -lz
|
||||
SRC_FILES = *.c
|
||||
|
||||
all: nfqws
|
||||
@ -10,4 +10,3 @@ 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 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<<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();
|
||||
|
||||
if (setpcap(caps|(1<<CAP_SETPCAP)))
|
||||
if (setpcap(cap_values, capct))
|
||||
{
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
// now without CAP_SETPCAP
|
||||
if (!setpcap(caps))
|
||||
if (!setpcap(cap_values, capct - 1))
|
||||
{
|
||||
perror("setpcap");
|
||||
return checkpcap(caps);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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);
|
||||
|
@ -1,6 +1,6 @@
|
||||
CC ?= gcc
|
||||
CFLAGS += -std=c99 -s -O3
|
||||
LIBS = -lz
|
||||
LIBS = -lz -lcap
|
||||
SRC_FILES = *.c
|
||||
|
||||
all: tpws
|
||||
|
126
tpws/sec.c
126
tpws/sec.c
@ -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;
|
||||
}
|
12
tpws/sec.h
12
tpws/sec.h
@ -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);
|
131
tpws/tpws.c
131
tpws/tpws.c
@ -20,6 +20,8 @@
|
||||
#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>
|
||||
|
||||
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user