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