mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
Revert "tpws,nfqws : remove cap library dependency"
This reverts commit 3c76e45692
.
This commit is contained in:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user