gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r38037 - in gnunet/src: dns include tun


From: gnunet
Subject: [GNUnet-SVN] r38037 - in gnunet/src: dns include tun
Date: Wed, 28 Sep 2016 00:25:06 +0200

Author: grothoff
Date: 2016-09-28 00:25:05 +0200 (Wed, 28 Sep 2016)
New Revision: 38037

Modified:
   gnunet/src/dns/Makefile.am
   gnunet/src/dns/dnsstub.c
   gnunet/src/dns/gnunet-helper-dns.c
   gnunet/src/dns/gnunet-service-dns.c
   gnunet/src/dns/test_gnunet_dns.sh
   gnunet/src/include/gnunet_tun_lib.h
   gnunet/src/tun/tun.c
Log:
fixes relating to intercepting DNS queries over IPv6

Modified: gnunet/src/dns/Makefile.am
===================================================================
--- gnunet/src/dns/Makefile.am  2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/dns/Makefile.am  2016-09-27 22:25:05 UTC (rev 38037)
@@ -89,6 +89,7 @@
 libgnunetdnsstub_la_SOURCES = \
  dnsstub.c
 libgnunetdnsstub_la_LIBADD = \
+  $(top_builddir)/src/tun/libgnunettun.la \
  $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
 libgnunetdnsstub_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) \

Modified: gnunet/src/dns/dnsstub.c
===================================================================
--- gnunet/src/dns/dnsstub.c    2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/dns/dnsstub.c    2016-09-27 22:25:05 UTC (rev 38037)
@@ -24,6 +24,7 @@
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
+#include "gnunet_tun_lib.h"
 #include "gnunet_dnsstub_lib.h"
 
 /**
@@ -381,9 +382,7 @@
                _("Failed to send DNS request to %s\n"),
                GNUNET_a2s (sa, salen));
   rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
-
   return rs;
-
 }
 
 
@@ -441,9 +440,10 @@
     }
     dns = (struct GNUNET_TUN_DnsHeader *) buf;
     if ( (addrlen != rs->addrlen) ||
-        (0 != memcmp (&rs->addr,
-                      &addr,
-                      addrlen)) ||
+        (GNUNET_YES !=
+          GNUNET_TUN_sockaddr_cmp ((struct sockaddr *) &rs->addr,
+                                   (struct sockaddr *) &addr,
+                                   GNUNET_YES)) ||
        (0 == GNUNET_TIME_absolute_get_remaining (rs->timeout).rel_value_us) )
     {
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,

Modified: gnunet/src/dns/gnunet-helper-dns.c
===================================================================
--- gnunet/src/dns/gnunet-helper-dns.c  2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/dns/gnunet-helper-dns.c  2016-09-27 22:25:05 UTC (rev 38037)
@@ -101,6 +101,11 @@
 static const char *sbin_iptables;
 
 /**
+ * Name and full path of IPTABLES binary.
+ */
+static const char *sbin_ip6tables;
+
+/**
  * Name and full path of sysctl binary
  */
 static const char *sbin_sysctl;
@@ -757,7 +762,7 @@
     return 254;
   }
 #endif
-  if (0 == strncmp(argv[6], "1", 2))
+  if (0 == strncmp (argv[6], "1", 2))
     nortsetup = 1;
 
   if (0 == nortsetup)
@@ -774,6 +779,17 @@
               strerror (errno));
       return 3;
     }
+    if (0 == access ("/sbin/ip6tables", X_OK))
+      sbin_ip6tables = "/sbin/ip6tables";
+    else if (0 == access ("/usr/sbin/ip6tables", X_OK))
+      sbin_ip6tables = "/usr/sbin/ip6tables";
+    else
+    {
+      fprintf (stderr,
+              "Fatal: executable ip6tables not found in approved directories: 
%s\n",
+              strerror (errno));
+      return 3;
+    }
     if (0 == access ("/sbin/ip", X_OK))
       sbin_ip = "/sbin/ip";
     else if (0 == access ("/usr/sbin/ip", X_OK))
@@ -942,6 +958,16 @@
       if (0 != fork_and_exec (sbin_iptables, mangle_args))
         goto cleanup_rest;
     }
+    {
+      char *const mangle_args[] =
+        {
+        "ip6tables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
+        "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j",
+        "ACCEPT", NULL
+        };
+      if (0 != fork_and_exec (sbin_ip6tables, mangle_args))
+        goto cleanup_rest;
+    }
     /* Mark all of the other DNS traffic using our mark DNS_MARK */
     {
       char *const mark_args[] =
@@ -953,6 +979,16 @@
       if (0 != fork_and_exec (sbin_iptables, mark_args))
         goto cleanup_mangle_1;
     }
+    {
+      char *const mark_args[] =
+        {
+        "ip6tables", "-t", "mangle", "-I", "OUTPUT", "2", "-p",
+        "udp", "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK,
+        NULL
+        };
+      if (0 != fork_and_exec (sbin_ip6tables, mark_args))
+        goto cleanup_mangle_1;
+    }
     /* Forward all marked DNS traffic to our DNS_TABLE */
     {
       char *const forward_args[] =
@@ -962,6 +998,14 @@
       if (0 != fork_and_exec (sbin_ip, forward_args))
         goto cleanup_mark_2;
     }
+    {
+      char *const forward_args[] =
+        {
+          "ip", "-6", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, 
NULL
+        };
+      if (0 != fork_and_exec (sbin_ip, forward_args))
+        goto cleanup_mark_2;
+    }
     /* Finally, add rule in our forwarding table to pass to our virtual 
interface */
     {
       char *const route_args[] =
@@ -972,6 +1016,15 @@
       if (0 != fork_and_exec (sbin_ip, route_args))
         goto cleanup_forward_3;
     }
+    {
+      char *const route_args[] =
+        {
+          "ip", "-6", "route", "add", "default", "dev", dev,
+          "table", DNS_TABLE, NULL
+        };
+      if (0 != fork_and_exec (sbin_ip, route_args))
+        goto cleanup_forward_3;
+    }
   }
 
   /* drop privs *except* for the saved UID; this is not perfect, but better
@@ -1028,6 +1081,16 @@
     if (0 != fork_and_exec (sbin_ip, route_clean_args))
       r += 1;
   }
+  if (0 == nortsetup)
+  {
+    char *const route_clean_args[] =
+      {
+       "ip", "-6", "route", "del", "default", "dev", dev,
+       "table", DNS_TABLE, NULL
+      };
+    if (0 != fork_and_exec (sbin_ip, route_clean_args))
+      r += 1;
+  }
  cleanup_forward_3:
   if (0 == nortsetup)
   {
@@ -1038,6 +1101,15 @@
     if (0 != fork_and_exec (sbin_ip, forward_clean_args))
       r += 2;
   }
+  if (0 == nortsetup)
+  {
+    char *const forward_clean_args[] =
+      {
+       "ip", "-6", "rule", "del", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL
+      };
+    if (0 != fork_and_exec (sbin_ip, forward_clean_args))
+      r += 2;
+  }
  cleanup_mark_2:
   if (0 == nortsetup)
   {
@@ -1049,6 +1121,16 @@
     if (0 != fork_and_exec (sbin_iptables, mark_clean_args))
       r += 4;
   }
+  if (0 == nortsetup)
+  {
+    char *const mark_clean_args[] =
+      {
+       "ip6tables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
+       "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, NULL
+      };
+    if (0 != fork_and_exec (sbin_ip6tables, mark_clean_args))
+      r += 4;
+  }
  cleanup_mangle_1:
   if (0 == nortsetup)
   {
@@ -1061,6 +1143,17 @@
     if (0 != fork_and_exec (sbin_iptables, mangle_clean_args))
       r += 8;
   }
+  if (0 == nortsetup)
+  {
+    char *const mangle_clean_args[] =
+      {
+       "ip6tables", "-m", "owner", "-t", "mangle", "-D", "OUTPUT", "-p", "udp",
+        "--gid-owner", mygid, "--dport", DNS_PORT, "-j", "ACCEPT",
+       NULL
+      };
+    if (0 != fork_and_exec (sbin_ip6tables, mangle_clean_args))
+      r += 8;
+  }
 
  cleanup_rest:
   /* close virtual interface */

Modified: gnunet/src/dns/gnunet-service-dns.c
===================================================================
--- gnunet/src/dns/gnunet-service-dns.c 2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/dns/gnunet-service-dns.c 2016-09-27 22:25:05 UTC (rev 38037)
@@ -410,7 +410,7 @@
        destination_port = src->sin6_port;
        GNUNET_TUN_initialize_ipv6_header (&ip6,
                                           IPPROTO_UDP,
-                                          reply_len - sizeof (struct 
GNUNET_TUN_IPv6Header),
+                                          reply_len - off - sizeof (struct 
GNUNET_TUN_IPv6Header),
                                           &dst->sin6_addr,
                                           &src->sin6_addr);
        GNUNET_memcpy (&buf[off], &ip6, sizeof (ip6));
@@ -916,7 +916,7 @@
     ip6 = (const struct GNUNET_TUN_IPv6Header *) &tun[1];
     if ( (msize < sizeof (struct GNUNET_TUN_IPv6Header)) ||
         (ip6->version != 6) ||
-        (ntohs (ip6->payload_length) != msize) ||
+        (ntohs (ip6->payload_length) != msize - sizeof (struct 
GNUNET_TUN_IPv6Header)) ||
         (ip6->next_header != IPPROTO_UDP) )
     {
       /* non-IP/UDP packet received on TUN (or with extensions) */
@@ -924,7 +924,7 @@
                  _("Received malformed IPv6-UDP packet on TUN interface.\n"));
       return GNUNET_OK;
     }
-    udp = (const struct GNUNET_TUN_UdpHeader*) &ip6[1];
+    udp = (const struct GNUNET_TUN_UdpHeader *) &ip6[1];
     msize -= sizeof (struct GNUNET_TUN_IPv6Header);
     break;
   default:
@@ -939,6 +939,8 @@
        (DNS_PORT != ntohs (udp->destination_port)) )
   {
     /* non-DNS packet received on TUN, ignore */
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                _("DNS interceptor got non-DNS packet (dropped)\n"));
     GNUNET_STATISTICS_update (stats,
                              gettext_noop ("# Non-DNS UDP packet received via 
TUN interface"),
                              1, GNUNET_NO);

Modified: gnunet/src/dns/test_gnunet_dns.sh
===================================================================
--- gnunet/src/dns/test_gnunet_dns.sh   2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/dns/test_gnunet_dns.sh   2016-09-27 22:25:05 UTC (rev 38037)
@@ -6,7 +6,7 @@
   echo "This test only works if run as root.  Skipping."
   exit 77
 fi
-if ! which sudo > /dev/null 
+if ! which sudo > /dev/null
 then
   echo "This test requires sudo.  Skipping."
   exit 77
@@ -17,7 +17,7 @@
   exit 77
 fi
 if ! which nslookup > /dev/null
-then 
+then
   echo "This test requires nslookup.  Skipping."
   exit 77
 fi
@@ -38,7 +38,7 @@
 sleep 1
 # need to run 'nslookup' as 'nobody', as gnunet-service-dns runs as root
 # and thus 'root' is excepted from DNS interception!
-LO=`sudo -u nobody nslookup gnunet.org | grep Address | tail -n1`
+LO=`sudo -u nobody nslookup -type=A gnunet.org | grep Address | tail -n1`
 if [ "$LO" != "Address: 127.0.0.1" ]
 then
  echo "Fail: got address $LO, wanted 127.0.0.1"

Modified: gnunet/src/include/gnunet_tun_lib.h
===================================================================
--- gnunet/src/include/gnunet_tun_lib.h 2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/include/gnunet_tun_lib.h 2016-09-27 22:25:05 UTC (rev 38037)
@@ -918,6 +918,20 @@
 
 
 /**
+ * Check if two sockaddrs are equal.
+ *
+ * @param sa one address
+ * @param sb another address
+ * @param include_port also check ports
+ * @return #GNUNET_YES if they are equal
+ */
+int
+GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
+                         const struct sockaddr *sb,
+                         int include_port);
+
+
+/**
  * Compute the CADET port given a service descriptor
  * (returned from #GNUNET_TUN_service_name_to_hash) and
  * a TCP/UDP port @a ip_port.

Modified: gnunet/src/tun/tun.c
===================================================================
--- gnunet/src/tun/tun.c        2016-09-27 18:36:44 UTC (rev 38036)
+++ gnunet/src/tun/tun.c        2016-09-27 22:25:05 UTC (rev 38037)
@@ -70,7 +70,7 @@
  *
  * @param ip header to initialize
  * @param protocol protocol to use (i.e. IPPROTO_UDP), technically 
"next_header" for IPv6
- * @param payload_length number of bytes of payload that follow (excluding 
IPv4 header)
+ * @param payload_length number of bytes of payload that follow (excluding 
IPv6 header)
  * @param src source IP address to use
  * @param dst destination IP address to use
  */
@@ -268,4 +268,44 @@
 }
 
 
+/**
+ * Check if two sockaddrs are equal.
+ *
+ * @param sa one address
+ * @param sb another address
+ * @param include_port also check ports
+ * @return #GNUNET_YES if they are equal
+ */
+int
+GNUNET_TUN_sockaddr_cmp (const struct sockaddr *sa,
+                         const struct sockaddr *sb,
+                         int include_port)
+{
+  if (sa->sa_family != sb->sa_family)
+    return GNUNET_NO;
+
+  switch (sa->sa_family)
+  {
+  case AF_INET:
+    {
+      const struct sockaddr_in *sa4 = (const struct sockaddr_in *) sa;
+      const struct sockaddr_in *sb4 = (const struct sockaddr_in *) sb;
+      return (sa4->sin_addr.s_addr == sb4->sin_addr.s_addr);
+    }
+  case AF_INET6:
+    {
+      const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *) sa;
+      const struct sockaddr_in6 *sb6 = (const struct sockaddr_in6 *) sb;
+
+      return (0 == memcmp(&sa6->sin6_addr,
+                          &sb6->sin6_addr,
+                          sizeof (struct in6_addr)));
+    }
+  default:
+    GNUNET_break (0);
+    return GNUNET_SYSERR;
+  }
+}
+
+
 /* end of tun.c */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]