Compare commits

..

2 Commits

Author SHA1 Message Date
bol-van
4f0fdb24f2 nfqws,tpws: support multiple gids in --uid 2025-05-10 11:11:56 +03:00
bol-van
6d52b49b98 nfqws: do not reconstruct synack-split in syn mode 2025-05-10 09:41:26 +03:00
10 changed files with 234 additions and 115 deletions

View File

@ -494,5 +494,6 @@ nfqws: --synack-split
tpws: ipcache of host names tpws: ipcache of host names
nfqws,tpws: set 1024 repeat limit to fakes and dups nfqws,tpws: set 1024 repeat limit to fakes and dups
nfqws,tpws: do more before daemonize nfqws,tpws: do more before daemonize
nfqws,tpws: accept multiple gids in --gid
init.d: remove --ipset parameter prohibition init.d: remove --ipset parameter prohibition
init.d, blockcheck: drop time exceeded icmp for nfqws-related connections init.d, blockcheck: drop time exceeded icmp for nfqws-related connections

View File

@ -1188,10 +1188,19 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
//ConntrackPoolDump(&params.conntrack); //ConntrackPoolDump(&params.conntrack);
if (dp->wsize && tcp_synack_segment(dis->tcp)) if (tcp_synack_segment(dis->tcp))
{ {
tcp_rewrite_winsize(dis->tcp, dp->wsize, dp->wscale); if (dp->wsize)
verdict=VERDICT_MODIFY; {
tcp_rewrite_winsize(dis->tcp, dp->wsize, dp->wscale);
verdict=VERDICT_MODIFY;
}
if (dp->synack_split==SS_SYN)
{
DLOG("split SYNACK : clearing ACK bit\n");
dis->tcp->th_flags &= ~TH_ACK;
verdict=VERDICT_MODIFY;
}
} }
if (bReverse) if (bReverse)
@ -1280,50 +1289,43 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
} }
} }
if (dp->synack_split!=SS_NONE && tcp_synack_segment(dis->tcp)) if ((dp->synack_split==SS_SYNACK || dp->synack_split==SS_ACKSYN) && tcp_synack_segment(dis->tcp))
{ {
// reconstruct required
dis->tcp->th_flags &= ~TH_ACK; dis->tcp->th_flags &= ~TH_ACK;
tcp_fix_checksum(dis->tcp,dis->transport_len, dis->ip, dis->ip6); tcp_fix_checksum(dis->tcp,dis->transport_len, dis->ip, dis->ip6);
char ss[2],i,ct; char ss[2],i;
if (dp->synack_split==SS_SYN) if (dp->synack_split==SS_SYNACK)
{ {
ct=1;
ss[0] = 'S'; ss[0] = 'S';
ss[1] = 'A';
} }
else else
{ {
ct=2; ss[0] = 'A';
if (dp->synack_split==SS_SYNACK) ss[1] = 'S';
{
ss[0] = 'S';
ss[1] = 'A';
}
else
{
ss[0] = 'A';
ss[1] = 'S';
}
pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_ACK, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, SCALE_NONE, timestamps,
DF,ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
FOOL_NONE,0,0,NULL, 0, pkt1, &pkt1_len))
{
DLOG_ERR("cannot prepare split SYNACK ACK part\n");
goto send_orig;
}
} }
for (int i=0;i<ct;i++) pkt1_len = sizeof(pkt1);
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, TH_ACK, false, 0, dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, SCALE_NONE, timestamps,
DF,ttl_orig,IP4_TOS(dis->ip),IP4_IP_ID_FIX(dis->ip),IP6_FLOW(dis->ip6),
FOOL_NONE,0,0,NULL, 0, pkt1, &pkt1_len))
{
DLOG_ERR("cannot prepare split SYNACK ACK part\n");
goto send_orig;
}
for (int i=0;i<2;i++)
{ {
switch(ss[i]) switch(ss[i])
{ {
case 'S': case 'S':
DLOG("sending split SYNACK : SYN\n"); DLOG("split SYNACK : SYN\n");
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , dis->data_pkt, dis->len_pkt)) if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , dis->data_pkt, dis->len_pkt))
goto send_orig; goto send_orig;
break; break;
case 'A': case 'A':
DLOG("sending split SYNACK : ACK\n"); DLOG("split SYNACK : ACK\n");
if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len)) if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , pkt1, pkt1_len))
goto send_orig; goto send_orig;
break; break;

View File

@ -30,6 +30,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <syslog.h> #include <syslog.h>
#include <grp.h>
#ifdef __CYGWIN__ #ifdef __CYGWIN__
#include "win.h" #include "win.h"
@ -297,7 +298,7 @@ static int nfq_main(void)
} }
sec_harden(); sec_harden();
if (params.droproot && !droproot(params.uid, params.gid) || !dropcaps()) if (params.droproot && !droproot(params.uid, params.gid, params.gid_count) || !dropcaps())
goto err; goto err;
print_id(); print_id();
if (params.droproot && !test_list_files()) if (params.droproot && !test_list_files())
@ -421,7 +422,7 @@ static int dvt_main(void)
goto exiterr; goto exiterr;
if (params.droproot && !droproot(params.uid, params.gid)) if (params.droproot && !droproot(params.uid, params.gid, params.gid_count))
goto exiterr; goto exiterr;
print_id(); print_id();
if (params.droproot && !test_list_files()) if (params.droproot && !test_list_files())
@ -527,13 +528,7 @@ static int win_main(const char *windivert_filter)
WINDIVERT_ADDRESS wa; WINDIVERT_ADDRESS wa;
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
if (params.daemon) if (params.daemon) daemonize();
{
// cygwin loses current dir
char *cwd = get_current_dir_name();
daemonize();
chdir(cwd);
}
if (*params.pidfile && !writepid(params.pidfile)) if (*params.pidfile && !writepid(params.pidfile))
{ {
@ -648,33 +643,6 @@ static int win_main(const char *windivert_filter)
static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
{
int v;
char *p;
if ((p = strchr(s,':'))) *p++=0;
v = atoi(s);
if (v < 0 || v>65535)
{
DLOG_ERR("bad wsize\n");
return false;
}
*wsize=(uint16_t)v;
if (p && *p)
{
v = atoi(p);
if (v < 0 || v>255)
{
DLOG_ERR("bad wscale\n");
return false;
}
*wscale = (uint8_t)v;
}
return true;
}
#if !defined( __OpenBSD__) && !defined(__ANDROID__) #if !defined( __OpenBSD__) && !defined(__ANDROID__)
static void cleanup_args() static void cleanup_args()
@ -707,6 +675,61 @@ static void exit_clean(int code)
exit(code); exit(code);
} }
static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_count, int max_gids)
{
unsigned int u;
char c, *p, *e;
*gid_count=0;
if ((e = strchr(optarg,':'))) *e++=0;
if (sscanf(opt,"%u",&u)!=1) return false;
*uid = (uid_t)u;
for (p=e ; p ; )
{
if ((e = strchr(p,',')))
{
c=*e;
*e=0;
}
if (p)
{
if (sscanf(p,"%u",&u)!=1) return false;
if (*gid_count>=max_gids) return false;
gid[(*gid_count)++] = (gid_t)u;
}
if (e) *e++=c;
p = e;
}
return true;
}
static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
{
int v;
char *p;
if ((p = strchr(s,':'))) *p++=0;
v = atoi(s);
if (v < 0 || v>65535)
{
DLOG_ERR("bad wsize\n");
return false;
}
*wsize=(uint16_t)v;
if (p && *p)
{
v = atoi(p);
if (v < 0 || v>255)
{
DLOG_ERR("bad wscale\n");
return false;
}
*wscale = (uint8_t)v;
}
return true;
}
static bool parse_cutoff(const char *opt, unsigned int *value, char *mode) static bool parse_cutoff(const char *opt, unsigned int *value, char *mode)
{ {
*mode = (*opt=='n' || *opt=='d' || *opt=='s') ? *opt++ : 'n'; *mode = (*opt=='n' || *opt=='d' || *opt=='s') ? *opt++ : 'n';
@ -1468,7 +1491,7 @@ static void exithelp(void)
" --pidfile=<filename>\t\t\t\t; write pid to file\n" " --pidfile=<filename>\t\t\t\t; write pid to file\n"
#ifndef __CYGWIN__ #ifndef __CYGWIN__
" --user=<username>\t\t\t\t; drop root privs\n" " --user=<username>\t\t\t\t; drop root privs\n"
" --uid=uid[:gid]\t\t\t\t; drop root privs\n" " --uid=uid[:gid1,gid2,...]\t\t\t; drop root privs\n"
#endif #endif
#ifdef __linux__ #ifdef __linux__
" --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n" " --bind-fix4\t\t\t\t\t; apply outgoing interface selection fix for generated ipv4 packets\n"
@ -1965,9 +1988,10 @@ int main(int argc, char **argv)
LIST_INIT(&params.ssid_filter); LIST_INIT(&params.ssid_filter);
LIST_INIT(&params.nlm_filter); LIST_INIT(&params.nlm_filter);
#else #else
if (can_drop_root()) // are we root ? if (can_drop_root())
{ {
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid params.uid = params.gid[0] = 0x7FFFFFFF; // default uid:gid
params.gid_count = 1;
params.droproot = true; params.droproot = true;
} }
#endif #endif
@ -2065,26 +2089,45 @@ int main(int argc, char **argv)
break; break;
#ifndef __CYGWIN__ #ifndef __CYGWIN__
case IDX_USER: case IDX_USER:
{
struct passwd *pwd = getpwnam(optarg);
if (!pwd)
{ {
struct passwd *pwd = getpwnam(optarg); DLOG_ERR("non-existent username supplied\n");
if (!pwd)
{
DLOG_ERR("non-existent username supplied\n");
exit_clean(1);
}
params.uid = pwd->pw_uid;
params.gid = pwd->pw_gid;
params.droproot = true;
}
break;
case IDX_UID:
params.gid = 0x7FFFFFFF; // default gid. drop gid=0
params.droproot = true;
if (sscanf(optarg, "%u:%u", &params.uid, &params.gid)<1)
{
DLOG_ERR("--uid should be : uid[:gid]\n");
exit_clean(1); exit_clean(1);
} }
params.uid = pwd->pw_uid;
params.gid_count=MAX_GIDS;
#ifdef __APPLE__
// silence warning
if (getgrouplist(optarg,pwd->pw_gid,(int*)params.gid,&params.gid_count)<0)
#else
if (getgrouplist(optarg,pwd->pw_gid,params.gid,&params.gid_count)<0)
#endif
{
DLOG_ERR("getgrouplist failed. too much groups ?\n");
exit_clean(1);
}
if (!params.gid_count)
{
params.gid[0] = pwd->pw_gid;
params.gid_count = 1;
}
params.droproot = true;
break;
}
case IDX_UID:
params.droproot = true;
if (!parse_uid(optarg,&params.uid,params.gid,&params.gid_count,MAX_GIDS))
{
DLOG_ERR("--uid should be : uid[:gid,gid,...]\n");
exit_clean(1);
}
if (!params.gid_count)
{
params.gid[0] = 0x7FFFFFFF;
params.gid_count = 1;
}
break; break;
#endif #endif
case IDX_WSIZE: case IDX_WSIZE:

View File

@ -63,6 +63,8 @@
#define FAKE_MAX_TCP 1460 #define FAKE_MAX_TCP 1460
#define FAKE_MAX_UDP 1472 #define FAKE_MAX_UDP 1472
#define MAX_GIDS 64
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG }; enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
struct fake_tls_mod_cache struct fake_tls_mod_cache
@ -191,7 +193,8 @@ struct params_s
#else #else
bool droproot; bool droproot;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid[MAX_GIDS];
int gid_count;
#endif #endif
char pidfile[PATH_MAX]; char pidfile[PATH_MAX];

View File

@ -295,8 +295,13 @@ bool can_drop_root(void)
#endif #endif
} }
bool droproot(uid_t uid, gid_t gid) bool droproot(uid_t uid, gid_t *gid, int gid_count)
{ {
if (gid_count<1)
{
DLOG_ERR("droproot: no groups specified");
return false;
}
#ifdef __linux__ #ifdef __linux__
if (prctl(PR_SET_KEEPCAPS, 1L)) if (prctl(PR_SET_KEEPCAPS, 1L))
{ {
@ -305,12 +310,12 @@ bool droproot(uid_t uid, gid_t gid)
} }
#endif #endif
// drop all SGIDs // drop all SGIDs
if (setgroups(0,NULL)) if (setgroups(gid_count,gid))
{ {
DLOG_PERROR("setgroups"); DLOG_PERROR("setgroups");
return false; return false;
} }
if (setgid(gid)) if (setgid(gid[0]))
{ {
DLOG_PERROR("setgid"); DLOG_PERROR("setgid");
return false; return false;
@ -343,9 +348,13 @@ void print_id(void)
#endif #endif
void daemonize(void) void daemonize(void)
{ {
int pid; int pid;
#ifdef __CYGWIN__
char *cwd = get_current_dir_name();
#endif
pid = fork(); pid = fork();
if (pid == -1) if (pid == -1)
@ -356,6 +365,10 @@ void daemonize(void)
else if (pid != 0) else if (pid != 0)
exit(0); exit(0);
#ifdef __CYGWIN__
chdir(get_current_dir_name());
#endif
if (setsid() == -1) if (setsid() == -1)
exit(2); exit(2);
if (chdir("/") == -1) if (chdir("/") == -1)

View File

@ -84,7 +84,7 @@ bool dropcaps(void);
#ifndef __CYGWIN__ #ifndef __CYGWIN__
bool sec_harden(void); bool sec_harden(void);
bool can_drop_root(void); bool can_drop_root(void);
bool droproot(uid_t uid, gid_t gid); bool droproot(uid_t uid, gid_t *gid, int gid_count);
void print_id(void); void print_id(void);
#endif #endif

View File

@ -4,6 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <time.h> #include <time.h>
#if !defined( __OpenBSD__) && !defined(__ANDROID__) #if !defined( __OpenBSD__) && !defined(__ANDROID__)
@ -18,13 +19,15 @@
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3 #define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60 #define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
#define FIX_SEG_DEFAULT_MAX_WAIT 50 #define FIX_SEG_DEFAULT_MAX_WAIT 50
#define IPCACHE_LIFETIME 7200 #define IPCACHE_LIFETIME 7200
#define MAX_GIDS 64
enum bindll { unwanted=0, no, prefer, force }; enum bindll { unwanted=0, no, prefer, force };
#define MAX_BINDS 32 #define MAX_BINDS 32
struct bind_s struct bind_s
{ {
char bindaddr[64],bindiface[IF_NAMESIZE]; char bindaddr[64],bindiface[IF_NAMESIZE];
@ -33,7 +36,7 @@ struct bind_s
int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll; int bind_wait_ifup,bind_wait_ip,bind_wait_ip_ll;
}; };
#define MAX_SPLITS 16 #define MAX_SPLITS 16
enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG }; enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSLOG };
@ -116,8 +119,9 @@ struct params_s
bool droproot; bool droproot;
bool daemon; bool daemon;
uid_t uid; uid_t uid;
gid_t gid; gid_t gid[MAX_GIDS];
char pidfile[256]; int gid_count;
char pidfile[PATH_MAX];
int maxconn,resolver_threads,maxfiles,max_orphan_time; int maxconn,resolver_threads,maxfiles,max_orphan_time;
int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf; int local_rcvbuf,local_sndbuf,remote_rcvbuf,remote_sndbuf;
#if defined(__linux__) || defined(__APPLE__) #if defined(__linux__) || defined(__APPLE__)

View File

@ -169,25 +169,24 @@ static bool set_seccomp(void)
bool sec_harden(void) bool sec_harden(void)
{ {
bool bRes = true;
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0))
{ {
DLOG_PERROR("PR_SET_NO_NEW_PRIVS(prctl)"); DLOG_PERROR("PR_SET_NO_NEW_PRIVS(prctl)");
return false; bRes = false;
} }
#if ARCH_NR!=0 #if ARCH_NR!=0
if (!set_seccomp()) if (!set_seccomp())
{ {
DLOG_PERROR("seccomp"); DLOG_PERROR("seccomp");
if (errno==EINVAL) DLOG_ERR("seccomp: this can be safely ignored if kernel does not support seccomp\n"); if (errno==EINVAL) DLOG_ERR("seccomp: this can be safely ignored if kernel does not support seccomp\n");
return false; bRes = false;
} }
#endif #endif
return true; return bRes;
} }
bool checkpcap(uint64_t caps) bool checkpcap(uint64_t caps)
{ {
if (!caps) return true; // no special caps reqd if (!caps) return true; // no special caps reqd
@ -270,8 +269,13 @@ bool can_drop_root(void)
#endif #endif
} }
bool droproot(uid_t uid, gid_t gid) bool droproot(uid_t uid, gid_t *gid, int gid_count)
{ {
if (gid_count<1)
{
DLOG_ERR("droproot: no groups specified");
return false;
}
#ifdef __linux__ #ifdef __linux__
if (prctl(PR_SET_KEEPCAPS, 1L)) if (prctl(PR_SET_KEEPCAPS, 1L))
{ {
@ -280,12 +284,12 @@ bool droproot(uid_t uid, gid_t gid)
} }
#endif #endif
// drop all SGIDs // drop all SGIDs
if (setgroups(0,NULL)) if (setgroups(gid_count,gid))
{ {
DLOG_PERROR("setgroups"); DLOG_PERROR("setgroups");
return false; return false;
} }
if (setgid(gid)) if (setgid(gid[0]))
{ {
DLOG_PERROR("setgid"); DLOG_PERROR("setgid");
return false; return false;

View File

@ -84,7 +84,7 @@ bool dropcaps(void);
bool sec_harden(void); bool sec_harden(void);
bool can_drop_root(); bool can_drop_root();
bool droproot(uid_t uid, gid_t gid); bool droproot(uid_t uid, gid_t *gid, int gid_count);
void print_id(void); void print_id(void);
void daemonize(void); void daemonize(void);
bool writepid(const char *filename); bool writepid(const char *filename);

View File

@ -23,6 +23,7 @@
#include <sys/resource.h> #include <sys/resource.h>
#include <time.h> #include <time.h>
#include <syslog.h> #include <syslog.h>
#include <grp.h>
#ifdef __ANDROID__ #ifdef __ANDROID__
#include "andr/ifaddrs.h" #include "andr/ifaddrs.h"
@ -214,7 +215,7 @@ static void exithelp(void)
" --daemon\t\t\t\t; daemonize\n" " --daemon\t\t\t\t; daemonize\n"
" --pidfile=<filename>\t\t\t; write pid to file\n" " --pidfile=<filename>\t\t\t; write pid to file\n"
" --user=<username>\t\t\t; drop root privs\n" " --user=<username>\t\t\t; drop root privs\n"
" --uid=uid[:gid]\t\t\t; drop root privs\n" " --uid=uid[:gid1,gid2,...]\t\t; drop root privs\n"
#if defined(__FreeBSD__) #if defined(__FreeBSD__)
" --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n" " --enable-pf\t\t\t\t; enable PF redirector support. required in FreeBSD when used with PF firewall.\n"
#endif #endif
@ -583,6 +584,35 @@ static bool parse_ip_list(char *opt, ipset *pp)
return true; return true;
} }
static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_count, int max_gids)
{
unsigned int u;
char c, *p, *e;
*gid_count=0;
if ((e = strchr(optarg,':'))) *e++=0;
if (sscanf(opt,"%u",&u)!=1) return false;
*uid = (uid_t)u;
for (p=e ; p ; )
{
if ((e = strchr(p,',')))
{
c=*e;
*e=0;
}
if (p)
{
if (sscanf(p,"%u",&u)!=1) return false;
if (*gid_count>=max_gids) return false;
gid[(*gid_count)++] = (gid_t)u;
}
if (e) *e++=c;
p = e;
}
return true;
}
#if !defined( __OpenBSD__) && !defined(__ANDROID__) #if !defined( __OpenBSD__) && !defined(__ANDROID__)
// no static to not allow optimizer to inline this func (save stack) // no static to not allow optimizer to inline this func (save stack)
void config_from_file(const char *filename) void config_from_file(const char *filename)
@ -837,8 +867,9 @@ void parse_params(int argc, char *argv[])
if (can_drop_root()) if (can_drop_root())
{ {
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid params.uid = params.gid[0] = 0x7FFFFFFF; // default uid:gid
params.droproot = true; params.gid_count = 1;
params.droproot = true;
} }
struct desync_profile_list *dpl; struct desync_profile_list *dpl;
@ -954,18 +985,37 @@ void parse_params(int argc, char *argv[])
exit_clean(1); exit_clean(1);
} }
params.uid = pwd->pw_uid; params.uid = pwd->pw_uid;
params.gid = pwd->pw_gid; params.gid_count=MAX_GIDS;
#ifdef __APPLE__
// silence warning
if (getgrouplist(optarg,pwd->pw_gid,(int*)params.gid,&params.gid_count)<0)
#else
if (getgrouplist(optarg,pwd->pw_gid,params.gid,&params.gid_count)<0)
#endif
{
DLOG_ERR("getgrouplist failed. too much groups ?\n");
exit_clean(1);
}
if (!params.gid_count)
{
params.gid[0] = pwd->pw_gid;
params.gid_count = 1;
}
params.droproot = true; params.droproot = true;
break; break;
} }
case IDX_UID: case IDX_UID:
params.gid=0x7FFFFFFF; // default git. drop gid=0
params.droproot = true; params.droproot = true;
if (sscanf(optarg,"%u:%u",&params.uid,&params.gid)<1) if (!parse_uid(optarg,&params.uid,params.gid,&params.gid_count,MAX_GIDS))
{ {
DLOG_ERR("--uid should be : uid[:gid]\n"); DLOG_ERR("--uid should be : uid[:gid,gid,...]\n");
exit_clean(1); exit_clean(1);
} }
if (!params.gid_count)
{
params.gid[0] = 0x7FFFFFFF;
params.gid_count = 1;
}
break; break;
case IDX_MAXCONN: case IDX_MAXCONN:
params.maxconn = atoi(optarg); params.maxconn = atoi(optarg);
@ -1273,8 +1323,7 @@ void parse_params(int argc, char *argv[])
} }
break; break;
case IDX_PIDFILE: case IDX_PIDFILE:
strncpy(params.pidfile,optarg,sizeof(params.pidfile)); snprintf(params.pidfile,sizeof(params.pidfile),"%s",optarg);
params.pidfile[sizeof(params.pidfile)-1]='\0';
break; break;
case IDX_DEBUG: case IDX_DEBUG:
if (optarg) if (optarg)
@ -2087,7 +2136,7 @@ int main(int argc, char *argv[])
set_ulimit(); set_ulimit();
sec_harden(); sec_harden();
if (params.droproot && !droproot(params.uid,params.gid)) if (params.droproot && !droproot(params.uid,params.gid,params.gid_count))
goto exiterr; goto exiterr;
#ifdef __linux__ #ifdef __linux__
if (!dropcaps()) if (!dropcaps())