- doxygen
[oweals/gnunet.git] / src / pt / test_gns_vpn.c
index 9789ce7d914bf4dee08f2228bd9d11c2bf7125ba..e686ce8b49360bdf81d494f39361c12601eaea7f 100644 (file)
@@ -4,7 +4,7 @@
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 2, or (at your
+     by the Free Software Foundation; either version 3, or (at your
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
      option) any later version.
 
      GNUnet is distributed in the hope that it will be useful, but
 #include <microhttpd.h>
 #include "gnunet_namestore_service.h"
 #include "gnunet_gns_service.h"
 #include <microhttpd.h>
 #include "gnunet_namestore_service.h"
 #include "gnunet_gns_service.h"
-#include "gnunet_testing_lib-new.h"
+#include "gnunet_testing_lib.h"
 
 #define PORT 8080
 
 #define PORT 8080
-#define TEST_DOMAIN "www.gnunet"
+#define TEST_DOMAIN "www.gnu"
 
 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
 
 
 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
 
@@ -217,9 +217,9 @@ curl_main ()
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n");
     do_shutdown ();
     }
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Download complete, shutting down!\n");
     do_shutdown ();
-    return;    
+    return;
   }
   }
-  GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max)); 
+  GNUNET_assert (CURLM_OK == curl_multi_fdset (multi, &rs, &ws, &es, &max));
   if ( (CURLM_OK != curl_multi_timeout (multi, &timeout)) ||
        (-1 == timeout) )
     delay = GNUNET_TIME_UNIT_SECONDS;
   if ( (CURLM_OK != curl_multi_timeout (multi, &timeout)) ||
        (-1 == timeout) )
     delay = GNUNET_TIME_UNIT_SECONDS;
@@ -236,13 +236,14 @@ curl_main ()
                                              &nrs,
                                              &nws,
                                              &curl_task,
                                              &nrs,
                                              &nws,
                                              &curl_task,
-                                             NULL);  
+                                             NULL);
 }
 
 }
 
+
 static void
 start_curl (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
 static void
 start_curl (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
-  GNUNET_asprintf (&url, 
+  GNUNET_asprintf (&url,
                   "http://%s/hello_world",     
                   TEST_DOMAIN);
   curl = curl_easy_init ();
                   "http://%s/hello_world",     
                   TEST_DOMAIN);
   curl = curl_easy_init ();
@@ -261,12 +262,15 @@ start_curl (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   curl_main ();
 }
 
   curl_main ();
 }
 
+
 static void
 disco_ns (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   GNUNET_NAMESTORE_disconnect (namestore);
 static void
 disco_ns (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   GNUNET_NAMESTORE_disconnect (namestore);
+  namestore = NULL;
 }
 
 }
 
+
 /**
  * Callback invoked from the namestore service once record is
  * created.
 /**
  * Callback invoked from the namestore service once record is
  * created.
@@ -276,7 +280,7 @@ disco_ns (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  *                will match 'result_af' from the request
  * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
  *                that the VPN allocated for the redirection;
  *                will match 'result_af' from the request
  * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
  *                that the VPN allocated for the redirection;
- *                traffic to this IP will now be redirected to the 
+ *                traffic to this IP will now be redirected to the
  *                specified target peer; NULL on error
  */
 static void
  *                specified target peer; NULL on error
  */
 static void
@@ -286,23 +290,19 @@ commence_testing (void *cls, int32_t success, const char *emsg)
 
   if ((emsg != NULL) && (GNUNET_YES != success))
   {
 
   if ((emsg != NULL) && (GNUNET_YES != success))
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "NS failed to create record %s\n", emsg);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
             "NS failed to create record %s\n", emsg);
     GNUNET_SCHEDULER_shutdown ();
     return;
   }
-  
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), start_curl, NULL);
-
+  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10), &start_curl, NULL);
 }
 
 
 }
 
 
-
-
 /**
  * Function to keep the HTTP server running.
  */
 /**
  * Function to keep the HTTP server running.
  */
-static void 
+static void
 mhd_main (void);
 
 
 mhd_main (void);
 
 
@@ -316,7 +316,7 @@ mhd_task (void *cls,
 }
 
 
 }
 
 
-static void 
+static void
 mhd_main ()
 {
   struct GNUNET_NETWORK_FDSet nrs;
 mhd_main ()
 {
   struct GNUNET_NETWORK_FDSet nrs;
@@ -351,9 +351,10 @@ mhd_main ()
                                             &nrs,
                                             &nws,
                                             &mhd_task,
                                             &nrs,
                                             &nws,
                                             &mhd_task,
-                                            NULL);  
+                                            NULL);
 }
 
 }
 
+
 static void
 run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *cfg,
 static void
 run (void *cls,
      const struct GNUNET_CONFIGURATION_Handle *cfg,
@@ -362,11 +363,11 @@ run (void *cls,
   enum MHD_FLAG flags;
   struct GNUNET_PeerIdentity id;
   struct GNUNET_CRYPTO_HashAsciiEncoded peername;
   enum MHD_FLAG flags;
   struct GNUNET_PeerIdentity id;
   struct GNUNET_CRYPTO_HashAsciiEncoded peername;
-  struct GNUNET_CRYPTO_RsaPrivateKey *host_key;
-  struct GNUNET_NAMESTORE_RecordData rd;
+  struct GNUNET_CRYPTO_EddsaPrivateKey *host_key;
+  struct GNUNET_GNSRECORD_Data rd;
   char *rd_string;
   char *zone_keyfile;
   char *rd_string;
   char *zone_keyfile;
-  
+
   GNUNET_TESTING_peer_get_identity (peer, &id);
   GNUNET_CRYPTO_hash_to_enc ((struct GNUNET_HashCode*)&id, &peername);
 
   GNUNET_TESTING_peer_get_identity (peer, &id);
   GNUNET_CRYPTO_hash_to_enc ((struct GNUNET_HashCode*)&id, &peername);
 
@@ -382,7 +383,7 @@ run (void *cls,
                          MHD_OPTION_END);
   GNUNET_assert (NULL != mhd);
   mhd_main ();
                          MHD_OPTION_END);
   GNUNET_assert (NULL != mhd);
   mhd_main ();
-  
+
   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
                                                             "ZONEKEY",
                                                             &zone_keyfile))
   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
                                                             "ZONEKEY",
                                                             &zone_keyfile))
@@ -391,61 +392,64 @@ run (void *cls,
     return;
   }
 
     return;
   }
 
-  host_key = GNUNET_CRYPTO_rsa_key_create_from_file (zone_keyfile);
-  rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value;
-  GNUNET_asprintf (&rd_string, "6 %s %s", (char*)&peername, "www.gnunet.");
-  GNUNET_assert (GNUNET_OK == GNUNET_NAMESTORE_string_to_value (GNUNET_GNS_RECORD_VPN,
+  host_key = GNUNET_CRYPTO_eddsa_key_create_from_file (zone_keyfile);
+  rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
+  GNUNET_asprintf (&rd_string, "6 %s %s", (char*)&peername, "www.gnu.");
+  GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_string_to_value (GNUNET_GNSRECORD_TYPE_VPN,
                                                                rd_string,
                                                                (void**)&rd.data,
                                                                &rd.data_size));
                                                                rd_string,
                                                                (void**)&rd.data,
                                                                &rd.data_size));
-  rd.record_type = GNUNET_GNS_RECORD_VPN;
-
-  GNUNET_NAMESTORE_record_create (namestore,
-                                  host_key,
-                                  "www",
-                                  &rd,
-                                  &commence_testing,
-                                  NULL);
+  rd.record_type = GNUNET_GNSRECORD_TYPE_VPN;
+
+  GNUNET_NAMESTORE_records_store (namestore,
+                                 host_key,
+                                 "www",
+                                 1, &rd,
+                                 &commence_testing,
+                                 NULL);
   GNUNET_free ((void**)rd.data);
   GNUNET_free (rd_string);
   GNUNET_free (zone_keyfile);
   GNUNET_free ((void**)rd.data);
   GNUNET_free (rd_string);
   GNUNET_free (zone_keyfile);
-  GNUNET_CRYPTO_rsa_key_free (host_key);
+  GNUNET_free (host_key);
 }
 
 
 /**
 }
 
 
 /**
- * Test if the given AF is supported by this system.
- * 
- * @param af to test
- * @return GNUNET_OK if the AF is supported
+ * Open '/dev/null' and make the result the given
+ * file descriptor.
+ *
+ * @param target_fd desired FD to point to /dev/null
+ * @param flags open flags (O_RDONLY, O_WRONLY)
  */
  */
-static int
-test_af (int af)
+static void
+open_dev_null (int target_fd,
+              int flags)
 {
 {
-  int s;
+  int fd;
 
 
-  s = socket (af, SOCK_STREAM, 0);
-  if (-1 == s)
+  fd = open ("/dev/null", flags);
+  if (-1 == fd)
+    abort ();
+  if (fd == target_fd)
+    return;
+  if (-1 == dup2 (fd, target_fd))
   {
   {
-    if (EAFNOSUPPORT == errno)
-      return GNUNET_NO;
-    fprintf (stderr, "Failed to create test socket: %s\n", STRERROR (errno));
-    return GNUNET_SYSERR;
+    (void) close (fd);
+    abort ();
   }
   }
-  close (s);
-  return GNUNET_OK;
+  (void) close (fd);
 }
 
 
 /**
  * Run the given command and wait for it to complete.
 }
 
 
 /**
  * Run the given command and wait for it to complete.
- * 
+ *
  * @param file name of the binary to run
  * @param cmd command line arguments (as given to 'execv')
  * @return 0 on success, 1 on any error
  */
 static int
  * @param file name of the binary to run
  * @param cmd command line arguments (as given to 'execv')
  * @return 0 on success, 1 on any error
  */
 static int
-fork_and_exec (const char *file, 
+fork_and_exec (const char *file,
               char *const cmd[])
 {
   int status;
               char *const cmd[])
 {
   int status;
@@ -455,8 +459,8 @@ fork_and_exec (const char *file,
   pid = fork ();
   if (-1 == pid)
   {
   pid = fork ();
   if (-1 == pid)
   {
-    fprintf (stderr, 
-            "fork failed: %s\n", 
+    fprintf (stderr,
+            "fork failed: %s\n",
             strerror (errno));
     return 1;
   }
             strerror (errno));
     return 1;
   }
@@ -465,23 +469,25 @@ fork_and_exec (const char *file,
     /* we are the child process */
     /* close stdin/stdout to not cause interference
        with the helper's main protocol! */
     /* we are the child process */
     /* close stdin/stdout to not cause interference
        with the helper's main protocol! */
-    (void) close (0); 
-    (void) close (1); 
+    (void) close (0);
+    open_dev_null (0, O_RDONLY);
+    (void) close (1);
+    open_dev_null (1, O_WRONLY);
     (void) execv (file, cmd);
     /* can only get here on error */
     (void) execv (file, cmd);
     /* can only get here on error */
-    fprintf (stderr, 
-            "exec `%s' failed: %s\n", 
+    fprintf (stderr,
+            "exec `%s' failed: %s\n",
             file,
             strerror (errno));
     _exit (1);
   }
   /* keep running waitpid as long as the only error we get is 'EINTR' */
   while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
             file,
             strerror (errno));
     _exit (1);
   }
   /* keep running waitpid as long as the only error we get is 'EINTR' */
   while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
-         (errno == EINTR) ); 
+         (errno == EINTR) );
   if (-1 == ret)
   {
   if (-1 == ret)
   {
-    fprintf (stderr, 
-            "waitpid failed: %s\n", 
+    fprintf (stderr,
+            "waitpid failed: %s\n",
             strerror (errno));
     return 1;
   }
             strerror (errno));
     return 1;
   }
@@ -495,27 +501,30 @@ int
 main (int argc, char *const *argv)
 {
   char *sbin_iptables;
 main (int argc, char *const *argv)
 {
   char *sbin_iptables;
+  char *bin_vpn;
+  char *bin_exit;
+  char *bin_dns;
   char *const iptables_args[] =
   {
     "iptables", "-t", "mangle", "-L", "-v", NULL
   };
   char *const iptables_args[] =
   {
     "iptables", "-t", "mangle", "-L", "-v", NULL
   };
-  
+
   if (0 == access ("/sbin/iptables", X_OK))
     sbin_iptables = "/sbin/iptables";
   else if (0 == access ("/usr/sbin/iptables", X_OK))
     sbin_iptables = "/usr/sbin/iptables";
   else
   {
   if (0 == access ("/sbin/iptables", X_OK))
     sbin_iptables = "/sbin/iptables";
   else if (0 == access ("/usr/sbin/iptables", X_OK))
     sbin_iptables = "/usr/sbin/iptables";
   else
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "Executable iptables not found in approved directories: %s, skipping\n",
             strerror (errno));
     return 0;
   }
             "Executable iptables not found in approved directories: %s, skipping\n",
             strerror (errno));
     return 0;
   }
-  
+
   if (0 != fork_and_exec (sbin_iptables, iptables_args))
   {
     fprintf (stderr,
   if (0 != fork_and_exec (sbin_iptables, iptables_args))
   {
     fprintf (stderr,
-             "IPtables not available, Skipping.\n");
+             "Failed to run `iptables -t mangle -L -v'. Skipping test.\n");
     return 0;
   }
 
     return 0;
   }
 
@@ -529,34 +538,43 @@ main (int argc, char *const *argv)
     return 0;
   }
 
     return 0;
   }
 
-  if ( (GNUNET_YES !=
-       GNUNET_OS_check_helper_binary ("gnunet-helper-vpn")) ||
-       (GNUNET_YES !=
-       GNUNET_OS_check_helper_binary ("gnunet-helper-exit")) ||
-       (GNUNET_YES !=
-  GNUNET_OS_check_helper_binary ("gnunet-helper-dns")))
+  bin_vpn = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn");
+  bin_exit = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit");
+  bin_dns = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns");
+  if ( (0 != geteuid ()) &&
+       ( (GNUNET_YES !=
+         GNUNET_OS_check_helper_binary (bin_vpn, GNUNET_YES, "-d gnunet-vpn - - 169.1.3.3.7 255.255.255.0")) || //ipv4 only please!
+        (GNUNET_YES !=
+         GNUNET_OS_check_helper_binary (bin_exit, GNUNET_YES, "-d gnunet-vpn - - - 169.1.3.3.7 255.255.255.0")) || //no nat, ipv4 only
+        (GNUNET_YES !=
+         GNUNET_OS_check_helper_binary (bin_dns, GNUNET_YES, NULL))) ) // TODO: once we have a windows-testcase, add test parameters here
   {
     fprintf (stderr,
             "WARNING: gnunet-helper-{exit,vpn,dns} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n");
     fprintf (stderr,
             "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n");
   {
     fprintf (stderr,
             "WARNING: gnunet-helper-{exit,vpn,dns} binaries in $PATH are not SUID, refusing to run test (as it would have to fail).\n");
     fprintf (stderr,
             "Change $PATH ('.' in $PATH before $GNUNET_PREFIX/bin is problematic) or permissions (run 'make install' as root) to fix this!\n");
+    GNUNET_free (bin_vpn);
+    GNUNET_free (bin_exit);
+    GNUNET_free (bin_dns);
     return 0;
   }
     return 0;
   }
-  GNUNET_CRYPTO_setup_hostkey ("test_gns_vpn.conf");
-  
+  GNUNET_free (bin_vpn);
+  GNUNET_free (bin_exit);
+  GNUNET_free (bin_dns);
+
   dest_ip = "169.254.86.1";
   dest_af = AF_INET;
   src_af = AF_INET;
 
   dest_ip = "169.254.86.1";
   dest_af = AF_INET;
   src_af = AF_INET;
 
-  if (GNUNET_OK == test_af (AF_INET6))
+  if (GNUNET_OK == GNUNET_NETWORK_test_pf (PF_INET6))
     use_v6 = GNUNET_YES;
   else
     use_v6 = GNUNET_NO;
     use_v6 = GNUNET_YES;
   else
     use_v6 = GNUNET_NO;
-  
-  if ( (GNUNET_OK != test_af (src_af)) ||
-       (GNUNET_OK != test_af (dest_af)) )
+
+  if ( (GNUNET_OK != GNUNET_NETWORK_test_pf (src_af)) ||
+       (GNUNET_OK != GNUNET_NETWORK_test_pf (dest_af)) )
   {
   {
-    fprintf (stderr, 
+    fprintf (stderr,
             "Required address families not supported by this system, skipping test.\n");
     return 0;
   }
             "Required address families not supported by this system, skipping test.\n");
     return 0;
   }