gnunet-daemon-testbed-blacklist.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. This file is part of GNUnet
  3. Copyright (C) 2008--2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file testbed/gnunet-daemon-testbed-blacklist.c
  18. * @brief daemon to restrict incoming connections from other peers at the
  19. * transport layer of a peer
  20. * @author Sree Harsha Totakura <sreeharsha@totakura.in>
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "gnunet_transport_service.h"
  25. /**
  26. * Logging shorthand
  27. */
  28. #define LOG(type,...) \
  29. GNUNET_log (type, __VA_ARGS__)
  30. /**
  31. * Debug logging shorthand
  32. */
  33. #define DEBUG(...) \
  34. LOG (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
  35. /**
  36. * Allow access from the peers read from the whitelist
  37. */
  38. #define ACCESS_ALLOW 1
  39. /**
  40. * Deny access from the peers read from the blacklist
  41. */
  42. #define ACCESS_DENY 0
  43. /**
  44. * The map to store the peer identities to allow/deny
  45. */
  46. static struct GNUNET_CONTAINER_MultiPeerMap *map;
  47. /**
  48. * The array of peer identities we read from whitelist/blacklist
  49. */
  50. static struct GNUNET_PeerIdentity *ilist;
  51. /**
  52. * The blacklist handle we obtain from transport when we register ourselves for
  53. * access control
  54. */
  55. static struct GNUNET_TRANSPORT_Blacklist *bh;
  56. /**
  57. * Are we allowing or denying access from peers
  58. */
  59. static int mode;
  60. /**
  61. * Cleaup and destroy the map
  62. */
  63. static void
  64. cleanup_map ()
  65. {
  66. if (NULL != map)
  67. {
  68. GNUNET_CONTAINER_multipeermap_destroy (map);
  69. map = NULL;
  70. }
  71. }
  72. /**
  73. * Shutdown task to cleanup our resources and exit.
  74. *
  75. * @param cls NULL
  76. */
  77. static void
  78. do_shutdown (void *cls)
  79. {
  80. cleanup_map ();
  81. if (NULL != bh)
  82. GNUNET_TRANSPORT_blacklist_cancel (bh);
  83. }
  84. /**
  85. * Function that decides if a connection is acceptable or not.
  86. *
  87. * @param cls closure
  88. * @param pid peer to approve or disapproave
  89. * @return GNUNET_OK if the connection is allowed, GNUNET_SYSERR if not
  90. */
  91. static int
  92. check_access (void *cls, const struct GNUNET_PeerIdentity * pid)
  93. {
  94. int contains;
  95. if (NULL != map)
  96. contains = GNUNET_CONTAINER_multipeermap_contains (map, pid);
  97. else
  98. contains = GNUNET_NO;
  99. if (ACCESS_DENY == mode)
  100. return (contains) ? GNUNET_SYSERR : GNUNET_OK;
  101. return (contains) ? GNUNET_OK : GNUNET_SYSERR;
  102. }
  103. /**
  104. * Setup the access control by reading the given file containing peer identities
  105. * and then establishing blacklist handler with the peer's transport service
  106. *
  107. * @param fname the filename to read the list of peer identities
  108. * @param cfg the configuration for connecting to the peer's transport service
  109. */
  110. static void
  111. setup_ac (const char *fname,
  112. const struct GNUNET_CONFIGURATION_Handle *cfg)
  113. {
  114. uint64_t fsize;
  115. unsigned int npeers;
  116. unsigned int cnt;
  117. GNUNET_assert (GNUNET_OK !=
  118. GNUNET_DISK_file_size (fname, &fsize, GNUNET_NO,
  119. GNUNET_YES));
  120. if (0 != (fsize % sizeof (struct GNUNET_PeerIdentity)))
  121. {
  122. GNUNET_break (0);
  123. return;
  124. }
  125. npeers = fsize / sizeof (struct GNUNET_PeerIdentity);
  126. if (0 != npeers)
  127. {
  128. map = GNUNET_CONTAINER_multipeermap_create (npeers, GNUNET_YES);
  129. ilist = GNUNET_malloc_large (fsize);
  130. GNUNET_assert (fsize == GNUNET_DISK_fn_read (fname, ilist, fsize));
  131. }
  132. for (cnt = 0; cnt < npeers; cnt++)
  133. {
  134. if (GNUNET_SYSERR ==
  135. GNUNET_CONTAINER_multipeermap_put (map, &ilist[cnt],
  136. &ilist[cnt],
  137. GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
  138. {
  139. cleanup_map ();
  140. GNUNET_free (ilist);
  141. return;
  142. }
  143. }
  144. GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
  145. bh = GNUNET_TRANSPORT_blacklist (cfg, &check_access, NULL);
  146. }
  147. /**
  148. * Main function that will be run.
  149. *
  150. * @param cls closure
  151. * @param args remaining command-line arguments
  152. * @param cfgfile name of the configuration file used (for saving, can be NULL!)
  153. * @param c configuration
  154. */
  155. static void
  156. run (void *cls,
  157. char *const *args,
  158. const char *cfgfile,
  159. const struct GNUNET_CONFIGURATION_Handle *c)
  160. {
  161. char *shome;
  162. char *fname;
  163. if (GNUNET_OK !=
  164. GNUNET_CONFIGURATION_get_value_filename (c,
  165. "PATHS",
  166. "GNUNET_HOME",
  167. &shome))
  168. {
  169. GNUNET_break (0);
  170. return;
  171. }
  172. GNUNET_asprintf (&fname,
  173. "%s/whitelist",
  174. shome);
  175. if (GNUNET_YES == GNUNET_DISK_file_test (fname))
  176. {
  177. mode = ACCESS_ALLOW;
  178. setup_ac (fname, c);
  179. GNUNET_free (shome);
  180. GNUNET_free (fname);
  181. return;
  182. }
  183. GNUNET_free (fname);
  184. GNUNET_asprintf (&fname,
  185. "%s/blacklist",
  186. shome);
  187. if (GNUNET_YES == GNUNET_DISK_file_test (fname))
  188. {
  189. mode = ACCESS_DENY;
  190. setup_ac (shome, c);
  191. }
  192. GNUNET_free (shome);
  193. GNUNET_free (fname);
  194. }
  195. /**
  196. * The main function.
  197. *
  198. * @param argc number of arguments from the command line
  199. * @param argv command line arguments
  200. * @return 0 ok, 1 on error
  201. */
  202. int
  203. main (int argc, char *const *argv)
  204. {
  205. static const struct GNUNET_GETOPT_CommandLineOption options[] = {
  206. GNUNET_GETOPT_OPTION_END
  207. };
  208. int ret;
  209. if (GNUNET_OK !=
  210. GNUNET_STRINGS_get_utf8_args (argc, argv,
  211. &argc, &argv))
  212. return 2;
  213. ret =
  214. (GNUNET_OK ==
  215. GNUNET_PROGRAM_run (argc, argv,
  216. "gnunet-daemon-testbed-blacklist",
  217. _("Daemon to restrict incoming transport layer connections during testbed deployments"),
  218. options, &run, NULL)) ? 0 : 1;
  219. GNUNET_free ((void*) argv);
  220. return ret;
  221. }