about summary refs log tree commit diff
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.gz
dnsfunnel-fe49776280489a3bb9405f2d7651d1b16e4fe2e6.tar.xz
dnsfunnel-fe49776280489a3bb9405f2d7651d1b16e4fe2e6.zip
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 (;;)                
   {