From ed6aacba92cc6f832c82e56fec4fd4d161342e6b Mon Sep 17 00:00:00 2001 From: Sree Harsha Totakura Date: Thu, 19 Sep 2013 15:56:45 +0000 Subject: - testbed daemon for transport blacklisting --- src/testbed/Makefile.am | 15 +- src/testbed/gnunet-daemon-testbed-blacklist.c | 268 ++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 src/testbed/gnunet-daemon-testbed-blacklist.c (limited to 'src/testbed') diff --git a/src/testbed/Makefile.am b/src/testbed/Makefile.am index 76495e856..b61f184d9 100644 --- a/src/testbed/Makefile.am +++ b/src/testbed/Makefile.am @@ -24,7 +24,8 @@ pkgcfg_DATA = \ libexec_PROGRAMS = \ gnunet-service-testbed \ gnunet-helper-testbed \ - gnunet-service-testbed-logger + gnunet-service-testbed-logger \ + gnunet-daemon-testbed-blacklist bin_PROGRAMS = \ $(ll_binaries) \ @@ -58,6 +59,8 @@ gnunet_service_testbed_logger_SOURCES = \ gnunet-service-testbed-logger.c gnunet_service_testbed_logger_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la +gnunet_service_testbed_logger_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la gnunet_testbed_profiler_SOURCES = \ gnunet-testbed-profiler.c @@ -65,6 +68,7 @@ gnunet_testbed_profiler_LDADD = $(XLIB) \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/testbed/libgnunettestbed.la gnunet_testbed_profiler_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ libgnunettestbed.la gnunet_helper_testbed_SOURCES = \ @@ -78,6 +82,15 @@ gnunet_helper_testbed_DEPENDENCIES = \ gnunet-service-testbed.$(OBJEXT) \ libgnunettestbed.la +gnunet_daemon_testbed_blacklist_SOURCES = gnunet-daemon-testbed-blacklist.c +gnunet_daemon_testbed_blacklist_LDADD = $(XLIB) \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(LTLIBINTL) +gnunet_daemon_testbed_blacklist_DEPENDENCIES = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/util/libgnunetutil.la + gnunet_testbed_mpi_spawn_SOURCES = gnunet_testbed_mpi_spawn.c gnunet_testbed_mpi_spawn_LDADD = $(XLIB) \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/testbed/gnunet-daemon-testbed-blacklist.c b/src/testbed/gnunet-daemon-testbed-blacklist.c new file mode 100644 index 000000000..04e920924 --- /dev/null +++ b/src/testbed/gnunet-daemon-testbed-blacklist.c @@ -0,0 +1,268 @@ +/* + This file is part of GNUnet + (C) 2008--2013 Christian Grothoff (and other contributing authors) + + 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 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + + +/** + * @file testbed/gnunet-daemon-testbed-blacklist + * @brief daemon to restrict incoming connections from other peers at the + * transport layer of a peer + * @author Sree Harsha Totakura + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_transport_service.h" + + +/** + * Logging shorthand + */ +#define LOG(type,...) \ + GNUNET_log (type, __VA_ARGS__) + +/** + * Debug logging shorthand + */ +#define DEBUG(...) \ + LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__) + +/** + * Allow access from the peers read from the whitelist + */ +#define ACCESS_ALLOW 1 + +/** + * Deny access from the peers read from the blacklist + */ +#define ACCESS_DENY 0 + +/** + * The map to store the peer identities to allow/deny + */ +static struct GNUNET_CONTAINER_MultiHashMap *map; + +/** + * The array of peer identities we read from whitelist/blacklist + */ +static struct GNUNET_PeerIdentity *ilist; + +/** + * The blacklist handle we obtain from transport when we register ourselves for + * access control + */ +struct GNUNET_TRANSPORT_Blacklist *bh; + +/** + * Task for shutdown + */ +static GNUNET_SCHEDULER_TaskIdentifier shutdown_task; + +/** + * Are we allowing or denying access from peers + */ +static int mode; + + +/** + * @ingroup hashmap + * Iterator over hash map entries. + * + * @param cls closure + * @param key current key code + * @param value value in the hash map + * @return #GNUNET_YES if we should continue to + * iterate, + * #GNUNET_NO if not. + */ +static int +iterator (void *cls, const struct GNUNET_HashCode *key, void *value) +{ + GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (map, key, + value)); + return GNUNET_YES; +} + + +/** + * Cleaup and destroy the map + */ +static void +cleanup_map () +{ + if (NULL != map) + { + GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_multihashmap_iterate (map, + &iterator, + NULL)); + GNUNET_CONTAINER_multihashmap_destroy (map); + map = NULL; + } +} + + +/** + * Shutdown task to cleanup our resources and exit. + * + * @param cls NULL + * @param tc scheduler task context + */ +static void +do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + cleanup_map (); + if (NULL != bh) + GNUNET_TRANSPORT_blacklist_cancel (bh); +} + + +/** + * Function that decides if a connection is acceptable or not. + * + * @param cls closure + * @param pid peer to approve or disapproave + * @return GNUNET_OK if the connection is allowed, GNUNET_SYSERR if not + */ +static int +check_access (void *cls, const struct GNUNET_PeerIdentity * pid) +{ + int contains; + + if (NULL != map) + contains = GNUNET_CONTAINER_multihashmap_contains (map, &(pid->hashPubKey)); + else + contains = GNUNET_NO; + if (ACCESS_DENY == mode) + return (contains) ? GNUNET_SYSERR : GNUNET_OK; + return (contains) ? GNUNET_OK : GNUNET_SYSERR; +} + + +/** + * Setup the access control by reading the given file containing peer identities + * and then establishing blacklist handler with the peer's transport service + * + * @param fname the filename to read the list of peer identities + * @param cfg the configuration for connecting to the peer's transport service + */ +static void +setup_ac (const char *fname, const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + uint64_t fsize; + unsigned int npeers; + unsigned int cnt; + + GNUNET_assert (GNUNET_OK != GNUNET_DISK_file_size (fname, &fsize, GNUNET_NO, + GNUNET_YES)); + if (0 != (fsize % sizeof (struct GNUNET_PeerIdentity))) + { + GNUNET_break (0); + return; + } + npeers = fsize / sizeof (struct GNUNET_PeerIdentity); + if (0 != npeers) + { + map = GNUNET_CONTAINER_multihashmap_create (npeers, GNUNET_YES); + ilist = GNUNET_malloc_large (fsize); + GNUNET_assert (fsize == GNUNET_DISK_fn_read (fname, ilist, fsize)); + } + for (cnt = 0; cnt < npeers; cnt++) + { + if (GNUNET_SYSERR == GNUNET_CONTAINER_multihashmap_put (map, &(ilist[cnt].hashPubKey), + &ilist[cnt], + GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) + { + cleanup_map (); + GNUNET_free (ilist); + return; + } + } + shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &do_shutdown, NULL); + bh = GNUNET_TRANSPORT_blacklist (cfg, &check_access, NULL); +} + + +/** + * Main function that will be run. + * + * @param cls closure + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param c configuration + */ +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + char *shome; + char fname[PATH_MAX]; + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (c, "PATHS", + "SERVICEHOME", + &shome)) + { + GNUNET_break (0); + return; + } + GNUNET_assert (0 < GNUNET_snprintf (fname, PATH_MAX, "%s/whitelist", shome)); + if (GNUNET_YES == GNUNET_DISK_file_test (fname)) + { + mode = ACCESS_ALLOW; + setup_ac (fname, c); + GNUNET_free (shome); + return; + } + GNUNET_assert (0 < GNUNET_snprintf (fname, PATH_MAX, "%s/blacklist", shome)); + if (GNUNET_YES == GNUNET_DISK_file_test (fname)) + { + mode = ACCESS_DENY; + setup_ac (shome, c); + } + GNUNET_free (shome); + return; +} + + +/** + * The main function. + * + * @param argc number of arguments from the command line + * @param argv command line arguments + * @return 0 ok, 1 on error + */ +int +main (int argc, char *const *argv) +{ + static const struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + int ret; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + ret = + (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-daemon-testbed-blacklist", + _ + ("Daemon to restrict incoming transport layer connections during testbed deployments"), + options, &run, NULL)) ? 0 : 1; + GNUNET_free ((void*) argv); + return ret; +} -- cgit v1.2.3