summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-01-12 10:03:51 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2021-01-12 10:03:51 +0000
commitfe49776280489a3bb9405f2d7651d1b16e4fe2e6 (patch)
tree7748b5950bd6cf3092c378cc17de6838372db75d /src
parent54e0e8469f9465877a155308cc2a8cc5b85fbfad (diff)
downloaddnsfunnel-fe49776280489a3bb9405f2d7651d1b16e4fe2e6.tar.xz
First big batch of fixes, remove dnsfunnel-daemon, etc.
Diffstat (limited to 'src')
-rw-r--r--src/dnsfunnel/deps-exe/dnsfunnel-daemon1
-rw-r--r--src/dnsfunnel/deps-exe/dnsfunneld2
-rw-r--r--src/dnsfunnel/dnsfunnel-daemon.c150
-rw-r--r--src/dnsfunnel/dnsfunnel-translate.c4
-rw-r--r--src/dnsfunnel/dnsfunneld.c178
5 files changed, 133 insertions, 202 deletions
diff --git a/src/dnsfunnel/deps-exe/dnsfunnel-daemon b/src/dnsfunnel/deps-exe/dnsfunnel-daemon
deleted file mode 100644
index e7187fe..0000000
--- a/src/dnsfunnel/deps-exe/dnsfunnel-daemon
+++ /dev/null
@@ -1 +0,0 @@
--lskarnet
diff --git a/src/dnsfunnel/deps-exe/dnsfunneld b/src/dnsfunnel/deps-exe/dnsfunneld
index 90302a1..88d6d31 100644
--- a/src/dnsfunnel/deps-exe/dnsfunneld
+++ b/src/dnsfunnel/deps-exe/dnsfunneld
@@ -2,3 +2,5 @@ dnsfunneld_answer.o
dnsfunneld_process.o
-ls6dns
-lskarnet
+${SOCKET_LIB}
+${SYSCLOCK_LIB}
diff --git a/src/dnsfunnel/dnsfunnel-daemon.c b/src/dnsfunnel/dnsfunnel-daemon.c
deleted file mode 100644
index 1df6a38..0000000
--- a/src/dnsfunnel/dnsfunnel-daemon.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/sysdeps.h>
-
-#ifndef SKALIBS_HASCHROOT
-# error "this program can only be built on systems that provide a chroot() function"
-#endif
-
-#include <skalibs/nonposix.h> /* chroot */
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <stdlib.h>
-
-#include <skalibs/uint16.h>
-#include <skalibs/types.h>
-#include <skalibs/fmtscan.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr2.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/socket.h>
-#include <skalibs/exec.h>
-
-#include <dnsfunnel/config.h>
-
-#define USAGE "dnsfunnel-daemon [ -v verbosity ] [ -d notif ] [ -U | -u uid -g gid ] [ -i ip:port ] [ -R root ] [ -b bufsize ] [ -f cachelist ] [ -T | -t ] [ -N | -n ] "
-#define dieusage() strerr_dieusage(100, USAGE)
-
-int main (int argc, char const *const *argv)
-{
- int notif = 0 ;
- unsigned int verbosity = 1 ;
- unsigned int bufsize = 131072 ;
- int flagU = 0 ;
- uid_t uid = -1 ;
- gid_t gid = -1 ;
- char const *ipport = "127.0.0.1:53" ;
- char const *newroot = 0 ;
- char const *cachelist = DNSFUNNEL_DEFAULT_CACHELIST ;
- uint32_t ops = 0 ;
- PROG = "dnsfunnel-daemon" ;
- {
- subgetopt_t l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "v:d:Uu:g:i:R:b:f:TtNn", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 'd' : if (!uint0_scan(l.arg, (unsigned int *)&notif)) dieusage() ; break ;
- case 'U' : flagU = 1 ; break ;
- case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
- case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
- case 'i' : ipport = l.arg ; break ;
- case 'R' : newroot = l.arg ; break ;
- case 'b' : if (!uint0_scan(l.arg, &bufsize)) dieusage() ; break ;
- case 'f' : cachelist = l.arg ; break ;
- case 'T' : ops &= ~1 ; break ;
- case 't' : ops |= 1 ; break ;
- case 'N' : ops &= ~2 ; break ;
- case 'n' : ops |= 2 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
-
- {
- int fd ;
- char ip[4] ;
- uint16_t port ;
- size_t pos = ip4_scan(ipport, ip) ;
- if (!pos) dieusage() ;
- if (ipport[pos] != ':') dieusage() ;
- if (!uint160_scan(ipport + pos + 1, &port)) dieusage() ;
- fd = socket_udp4() ;
- if (fd < 0) strerr_diefu1sys(111, "create UDP socket") ;
- if (socket_bind4_reuse(fd, ip, port) < 0)
- {
- char fmti[IP4_FMT] ;
- char fmtp[UINT16_FMT] ;
- fmti[ip4_fmt(fmti, ip)] = 0 ;
- fmtp[uint16_fmt(fmtp, port)] = 0 ;
- strerr_diefu4sys(111, "bind on ip ", fmti, " port ", fmtp) ;
- }
- if (bufsize) socket_tryreservein(fd, bufsize) ;
- if (fd_move(0, fd) < 0)
- strerr_diefu1sys(111, "move file descriptors") ;
- }
-
- if (newroot)
- {
- if (chdir(newroot) < 0 || chroot(".") < 0)
- strerr_diefu2sys(111, "chroot to ", newroot) ;
- }
-
- if (flagU)
- {
- char const *x = getenv("UID") ;
- if (x && !uid0_scan(x, &uid))
- strerr_dieinvalid(100, "UID") ;
- x = getenv("GID") ;
- if (x && !gid0_scan(x, &gid))
- strerr_dieinvalid(100, "GID") ;
- }
- if (gid != (gid_t)-1 && setgid(gid) < 0)
- {
- char fmt[GID_FMT] ;
- fmt[gid_fmt(fmt, gid)] = 0 ;
- strerr_diefu2sys(111, "setgid to ", fmt) ;
- }
- if (uid != (uid_t)-1 && setuid(uid) < 0)
- {
- char fmt[UID_FMT] ;
- fmt[uid_fmt(fmt, uid)] = 0 ;
- strerr_diefu2sys(111, "setuid to ", fmt) ;
- }
-
- {
- char const *newargv[10] = { "dnsfunneld" } ;
- char const *newenvp[1] = { 0 } ;
- unsigned int m = 1 ;
- char fmtv[UINT_FMT] ;
- char fmtn[UINT_FMT] ;
- char fmto[UINT_FMT] ;
- if (verbosity != 1)
- {
- fmtv[uint_fmt(fmtv, verbosity)] = 0 ;
- newargv[m++] = "-v" ;
- newargv[m++] = fmtv ;
- }
- if (notif)
- {
- fmtn[uint_fmt(fmtn, notif)] = 0 ;
- newargv[m++] = "-d" ;
- newargv[m++] = fmtn ;
- }
- if (ops)
- {
- fmto[uint_fmt(fmto, ops)] = 0 ;
- newargv[m++] = "-o" ;
- newargv[m++] = fmto ;
- }
- newargv[m++] = "--" ;
- newargv[m++] = cachelist ;
- newargv[m++] = 0 ;
- xexec_ae(DNSFUNNEL_BINPREFIX "dnsfunneld", newargv, newenvp) ;
- }
-}
diff --git a/src/dnsfunnel/dnsfunnel-translate.c b/src/dnsfunnel/dnsfunnel-translate.c
index 70610b8..d842629 100644
--- a/src/dnsfunnel/dnsfunnel-translate.c
+++ b/src/dnsfunnel/dnsfunnel-translate.c
@@ -12,8 +12,6 @@
#include <s6-dns/s6dns-constants.h>
-#include <dnsfunnel/config.h>
-
#define USAGE "dnsfunnel-translate [ -i resolvconf ] [ -o cachelist ] [ -x ignoredip ]"
#define dieusage() strerr_dieusage(100, USAGE)
@@ -48,7 +46,7 @@ int main (int argc, char const *const *argv)
{
ip46_t list[S6DNS_MAX_SERVERS] = { IP46_ZERO } ;
char const *resolvconf = "/etc/resolv.conf" ;
- char const *cachelist = DNSFUNNEL_DEFAULT_CACHELIST ;
+ char const *cachelist = "/run/dnsfunnel/root/caches" ;
char ignore[4] = "\177\0\0\1" ;
size_t n ;
PROG = "dnsfunnel-translate" ;
diff --git a/src/dnsfunnel/dnsfunneld.c b/src/dnsfunnel/dnsfunneld.c
index bd4dc89..12e9866 100644
--- a/src/dnsfunnel/dnsfunneld.c
+++ b/src/dnsfunnel/dnsfunneld.c
@@ -1,12 +1,22 @@
/* ISC license. */
+#include <skalibs/sysdeps.h>
+
+#ifdef SKALIBS_HASCHROOT
+# include <skalibs/nonposix.h>
+#endif
+
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <skalibs/uint16.h>
#include <skalibs/uint32.h>
+#include <skalibs/fmtscan.h>
#include <skalibs/types.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/error.h>
@@ -26,7 +36,7 @@
#include "dnsfunneld.h"
-#define USAGE "dnsfunneld [ -v verbosity ] [ -d notif ] [ -o operations ] cachelist"
+#define USAGE "dnsfunneld [ -v verbosity ] [ -1 ] [ -U | -u uid -g gid ] [ -i ip:port ] [ -R root ] [ -b bufsize ] [ -T | -t ] [ -N | -n ]"
#define dieusage() strerr_dieusage(100, USAGE)
#define DNSFUNNELD_INPUT_MAX 64
@@ -34,7 +44,6 @@
unsigned int verbosity = 1 ;
static tain_t globaltto = TAIN_INFINITE_RELATIVE ;
static int cont = 1 ;
-static char const *cachelistfile = 0 ;
static s6dns_ip46list_t cachelist ;
static uint32_t ops = 0 ;
@@ -61,7 +70,7 @@ static int load_cachelist (int initial)
char buf[4096] ;
ip46full_t list[S6DNS_MAX_SERVERS] ;
size_t n ;
- ssize_t r = openreadnclose_nb(cachelistfile, buf, 4095) ;
+ ssize_t r = openreadnclose_nb("caches", buf, 4095) ;
if (r < 0) return -1 ;
buf[r++] = 0 ;
ip46_scanlist(list, S6DNS_MAX_SERVERS, buf, &n) ;
@@ -84,8 +93,8 @@ static inline void handle_signals (void)
switch (load_cachelist(0))
{
case 0 : query_process_reload() ; break ;
- case -1 : strerr_warnwu2sys("read ", cachelistfile) ; break ;
- case -2 : strerr_warnw2x("invalid cache list in ", cachelistfile) ; break ;
+ case -1 : strerr_warnwu1sys("read ./caches") ; break ;
+ case -2 : strerr_warnw1x("invalid cache list in ./caches") ; break ;
default : X() ;
}
break ;
@@ -147,64 +156,137 @@ static inline void sanitize_and_new (char const *buf, unsigned int len, char con
int main (int argc, char const *const *argv)
{
int spfd = -1 ;
- int notif = -1 ;
PROG = "dnsfunneld" ;
+
{
+ unsigned int bufsize = 131072 ;
+ int flagU = 0 ;
+ uid_t uid = -1 ;
+ gid_t gid = -1 ;
+ char const *ipport = "127.0.0.1:53" ;
+ char const *root = "/run/dnsfunnel/root" ;
+ int notif = 0 ;
+ int fd ;
+ char ip[4] ;
+ size_t pos ;
+ uint16_t port ;
subgetopt_t l = SUBGETOPT_ZERO ;
+
for (;;)
{
- int opt = subgetopt_r(argc, argv, "v:d:o:", &l) ;
+ int opt = subgetopt_r(argc, argv, "v:1Uu:g:i:R:b:TtNn", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 'd' : if (!uint0_scan(l.arg, (unsigned int *)&notif)) dieusage() ; break ;
- case 'o' : if (!uint320_scan(l.arg, &ops)) dieusage() ; break ;
+ case '1' : notif = 1 ; break ;
+ case 'U' : flagU = 1 ; break ;
+ case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
+ case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
+ case 'i' : ipport = l.arg ; break ;
+ case 'R' : root = l.arg ; break ;
+ case 'b' : if (!uint0_scan(l.arg, &bufsize)) dieusage() ; break ;
+ case 'T' : ops &= ~1 ; break ;
+ case 't' : ops |= 1 ; break ;
+ case 'N' : ops &= ~2 ; break ;
+ case 'n' : ops |= 2 ; break ;
default : dieusage() ;
}
}
argc -= l.ind ; argv += l.ind ;
- if (!argc) dieusage() ;
- }
- if (notif >= 0)
- {
- if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
- if (fcntl(notif, F_GETFD) < 0) strerr_dief1sys(100, "invalid notification fd") ;
- }
- if (ndelay_on(0) < 0) strerr_diefu1sys(111, "turn stdin non-blocking") ;
- if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
- cachelistfile = argv[0] ;
- switch (load_cachelist(1))
- {
- case 0 : break ;
- case -1 : strerr_diefu2sys(111, "read ", cachelistfile) ;
- case -2 : strerr_dief2x(100, "invalid cache list in ", cachelistfile) ;
- default : X() ;
- }
- if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ;
- spfd = selfpipe_init() ;
- if (spfd < 0) strerr_diefu1sys(111, "init selfpipe") ;
- {
- sigset_t set ;
- sigemptyset(&set) ;
- sigaddset(&set, SIGTERM) ;
- sigaddset(&set, SIGHUP) ;
- if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ;
- }
- if (!gensetdyn_new(&queries, &sentinel))
- strerr_diefu1sys(111, "initialize query structure") ;
- *QUERY(sentinel) = dfquery_zero ;
- QUERY(sentinel)->next = sentinel ;
- if (!query_process_init())
- strerr_diefu1sys(111, "initialize query processing") ;
- tain_now_set_stopwatch_g() ;
-
- if (notif >= 0)
- {
- fd_write(notif, "\n", 1) ;
- fd_close(notif) ;
+ pos = ip4_scan(ipport, ip) ;
+ if (!pos) dieusage() ;
+ if (ipport[pos] != ':') dieusage() ;
+ if (!uint160_scan(ipport + pos + 1, &port)) dieusage() ;
+ if (fcntl(1, F_GETFD) < 0)
+ {
+ if (notif) strerr_dief1sys(100, "option -1 given but stdout unavailable") ;
+ }
+ else if (!notif) close(1) ;
+ fd = socket_udp4() ;
+ if (fd < 0) strerr_diefu1sys(111, "create UDP socket") ;
+ if (socket_bind4_reuse(fd, ip, port) < 0)
+ {
+ char fmti[IP4_FMT] ;
+ char fmtp[UINT16_FMT] ;
+ fmti[ip4_fmt(fmti, ip)] = 0 ;
+ fmtp[uint16_fmt(fmtp, port)] = 0 ;
+ strerr_diefu4sys(111, "bind on ip ", fmti, " port ", fmtp) ;
+ }
+ if (bufsize) socket_tryreservein(fd, bufsize) ;
+ if (fd_move(0, fd) < 0)
+ strerr_diefu1sys(111, "move file descriptors") ;
+ if (ndelay_on(0) < 0) strerr_diefu1sys(111, "turn stdin non-blocking") ;
+ if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "ignore SIGPIPE") ;
+ if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ;
+
+ if (root[0])
+ {
+#ifdef SKALIBS_HASCHROOT
+ if (chdir(root) < 0 || chroot(".") < 0)
+ strerr_diefu2sys(111, "chroot to ", root) ;
+#else
+ errno = ENOSYS ;
+ strerr_warnwu2sys("chroot to ", root) ;
+#endif
+ }
+
+ if (flagU)
+ {
+ char const *x = getenv("UID") ;
+ if (x && !uid0_scan(x, &uid))
+ strerr_dieinvalid(100, "UID") ;
+ x = getenv("GID") ;
+ if (x && !gid0_scan(x, &gid))
+ strerr_dieinvalid(100, "GID") ;
+ }
+ if (gid != (gid_t)-1 && setgid(gid) < 0)
+ {
+ char fmt[GID_FMT] ;
+ fmt[gid_fmt(fmt, gid)] = 0 ;
+ strerr_diefu2sys(111, "setgid to ", fmt) ;
+ }
+ if (uid != (uid_t)-1 && setuid(uid) < 0)
+ {
+ char fmt[UID_FMT] ;
+ fmt[uid_fmt(fmt, uid)] = 0 ;
+ strerr_diefu2sys(111, "setuid to ", fmt) ;
+ }
+
+ switch (load_cachelist(1))
+ {
+ case 0 : break ;
+ case -1 : strerr_diefu1sys(111, "read ./caches") ;
+ case -2 : strerr_dief1x(100, "invalid cache list in ./caches") ;
+ default : X() ;
+ }
+ spfd = selfpipe_init() ;
+ if (spfd < 0) strerr_diefu1sys(111, "init selfpipe") ;
+ {
+ sigset_t set ;
+ sigemptyset(&set) ;
+ sigaddset(&set, SIGTERM) ;
+ sigaddset(&set, SIGHUP) ;
+ if (selfpipe_trapset(&set) < 0) strerr_diefu1sys(111, "trap signals") ;
+ }
+ if (!gensetdyn_new(&queries, &sentinel))
+ strerr_diefu1sys(111, "initialize query structure") ;
+ *QUERY(sentinel) = dfquery_zero ;
+ QUERY(sentinel)->next = sentinel ;
+ if (!query_process_init())
+ strerr_diefu1sys(111, "initialize query processing") ;
+ tain_now_set_stopwatch_g() ;
+
+ if (notif)
+ {
+ fd_write(1, "\n", 1) ;
+ close(1) ;
+ }
}
+
+
+ /* The main loop is here */
for (;;)
{