aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/gnunet-service-messenger_ego_store.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/gnunet-service-messenger_ego_store.c')
-rw-r--r--src/messenger/gnunet-service-messenger_ego_store.c469
1 files changed, 0 insertions, 469 deletions
diff --git a/src/messenger/gnunet-service-messenger_ego_store.c b/src/messenger/gnunet-service-messenger_ego_store.c
deleted file mode 100644
index 8250d0902..000000000
--- a/src/messenger/gnunet-service-messenger_ego_store.c
+++ /dev/null
@@ -1,469 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2022 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 * @author Tobias Frisch
22 * @file src/messenger/gnunet-service-messenger_ego_store.c
23 * @brief GNUnet MESSENGER service
24 */
25
26#include "gnunet-service-messenger_ego_store.h"
27
28#include "gnunet-service-messenger_handle.h"
29
30static void
31callback_update_ego (void *cls,
32 struct GNUNET_IDENTITY_Ego *ego,
33 void **ctx,
34 const char *identifier)
35{
36 if ((!ctx) || (!identifier))
37 return;
38
39 struct GNUNET_MESSENGER_EgoStore *store = cls;
40
41 if (ego)
42 {
43 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", identifier);
44 update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key (ego));
45 }
46 else
47 {
48 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego got deleted: '%s'\n", identifier);
49 delete_store_ego (store, identifier);
50 }
51}
52
53void
54init_ego_store(struct GNUNET_MESSENGER_EgoStore *store,
55 const struct GNUNET_CONFIGURATION_Handle *config)
56{
57 GNUNET_assert ((store) && (config));
58
59 store->cfg = config;
60 store->identity = GNUNET_IDENTITY_connect (config, &callback_update_ego, store);
61 store->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
62 store->handles = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
63
64 store->lu_start = NULL;
65 store->lu_end = NULL;
66
67 store->op_start = NULL;
68 store->op_end = NULL;
69}
70
71static int
72iterate_destroy_egos (void *cls,
73 const struct GNUNET_HashCode *key,
74 void *value)
75{
76 struct GNUNET_MESSENGER_Ego *ego = value;
77 GNUNET_free(ego);
78 return GNUNET_YES;
79}
80
81void
82clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store)
83{
84 GNUNET_assert (store);
85
86 struct GNUNET_MESSENGER_EgoOperation *op;
87
88 while (store->op_start)
89 {
90 op = store->op_start;
91
92 GNUNET_IDENTITY_cancel (op->operation);
93 GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, op);
94
95 if (op->identifier)
96 GNUNET_free (op->identifier);
97
98 GNUNET_free (op);
99 }
100
101 struct GNUNET_MESSENGER_EgoLookup *lu;
102
103 while (store->lu_start)
104 {
105 lu = store->lu_start;
106
107 GNUNET_IDENTITY_ego_lookup_cancel(lu->lookup);
108 GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, lu);
109
110 if (lu->identifier)
111 GNUNET_free(lu->identifier);
112
113 GNUNET_free (lu);
114 }
115
116 GNUNET_CONTAINER_multihashmap_iterate (store->egos, iterate_destroy_egos, NULL);
117 GNUNET_CONTAINER_multihashmap_destroy (store->egos);
118
119 GNUNET_CONTAINER_multihashmap_destroy (store->handles);
120
121 if (store->identity)
122 {
123 GNUNET_IDENTITY_disconnect (store->identity);
124
125 store->identity = NULL;
126 }
127}
128
129static int
130iterate_create_ego (void *cls,
131 const struct GNUNET_HashCode *key,
132 void *value)
133{
134 struct GNUNET_MESSENGER_SrvHandle *handle = value;
135 set_srv_handle_ego (handle, (struct GNUNET_MESSENGER_Ego*) cls);
136 return GNUNET_YES;
137}
138
139static void
140callback_ego_create (void *cls,
141 const struct GNUNET_IDENTITY_PrivateKey *key,
142 const char *emsg)
143{
144 struct GNUNET_MESSENGER_EgoOperation *element = cls;
145 struct GNUNET_MESSENGER_EgoStore *store = element->store;
146
147 GNUNET_assert (element->identifier);
148
149 if (emsg)
150 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
151
152 if (key)
153 {
154 struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store, element->identifier, key);
155
156 struct GNUNET_HashCode hash;
157 GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash);
158
159 GNUNET_CONTAINER_multihashmap_get_multiple (store->handles, &hash, iterate_create_ego, msg_ego);
160 }
161 else
162 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n");
163
164 GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
165 GNUNET_free (element->identifier);
166 GNUNET_free (element);
167}
168
169void
170create_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
171 const char *identifier)
172{
173 GNUNET_assert ((store) && (identifier));
174
175 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store create ego: %s\n", identifier);
176
177 struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation);
178
179 element->store = store;
180 element->cls = NULL;
181
182 element->identifier = GNUNET_strdup (identifier);
183
184 element->operation = GNUNET_IDENTITY_create (
185 store->identity,
186 identifier,
187 NULL,
188 GNUNET_IDENTITY_TYPE_ECDSA,
189 callback_ego_create,
190 element
191 );
192
193 GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
194}
195
196void
197bind_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
198 const char *identifier,
199 void *handle)
200{
201 GNUNET_assert ((store) && (identifier) && (handle));
202
203 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store bind ego: %s\n", identifier);
204
205 struct GNUNET_HashCode hash;
206 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
207
208 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle))
209 return;
210
211 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->handles, &hash, handle,
212 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))
213 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Putting handle binding to ego store failed!\n");
214}
215
216void
217unbind_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
218 const char *identifier,
219 void *handle)
220{
221 GNUNET_assert ((store) && (identifier) && (handle));
222
223 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store unbind ego: %s\n", identifier);
224
225 struct GNUNET_HashCode hash;
226 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
227
228 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains_value(store->handles, &hash, handle))
229 return;
230
231 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(store->handles, &hash, handle))
232 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing handle binding from ego store failed!\n");
233}
234
235static void
236callback_ego_lookup (void *cls,
237 struct GNUNET_IDENTITY_Ego *ego)
238{
239 struct GNUNET_MESSENGER_EgoLookup *element = cls;
240 struct GNUNET_MESSENGER_EgoStore *store = element->store;
241
242 GNUNET_assert (element->identifier);
243
244 struct GNUNET_MESSENGER_Ego *msg_ego = NULL;
245
246 if (ego)
247 {
248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New ego looked up: '%s'\n", element->identifier);
249 msg_ego = update_store_ego (
250 store,
251 element->identifier,
252 GNUNET_IDENTITY_ego_get_private_key(ego)
253 );
254 }
255 else
256 {
257 struct GNUNET_HashCode hash;
258 GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash);
259
260 if (GNUNET_CONTAINER_multihashmap_get (store->egos, &hash))
261 {
262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looked up ego got deleted: '%s'\n", element->identifier);
263 delete_store_ego(store, element->identifier);
264 }
265 }
266
267 if (element->cb)
268 element->cb(element->cls, element->identifier, msg_ego);
269
270 GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, element);
271 GNUNET_free (element->identifier);
272 GNUNET_free (element);
273}
274
275void
276lookup_store_ego(struct GNUNET_MESSENGER_EgoStore *store,
277 const char *identifier,
278 GNUNET_MESSENGER_EgoLookupCallback lookup,
279 void *cls)
280{
281 GNUNET_assert (store);
282
283 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store lookup ego: %s\n", identifier);
284
285 if (!identifier)
286 {
287 lookup(cls, identifier, NULL);
288 return;
289 }
290
291 struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct GNUNET_MESSENGER_EgoLookup);
292
293 element->store = store;
294
295 element->cb = lookup;
296 element->cls = cls;
297
298 element->identifier = GNUNET_strdup (identifier);
299
300 element->lookup = GNUNET_IDENTITY_ego_lookup(store->cfg, identifier, callback_ego_lookup, element);
301
302 GNUNET_CONTAINER_DLL_insert (store->lu_start, store->lu_end, element);
303}
304
305struct GNUNET_MESSENGER_Ego*
306update_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
307 const char *identifier,
308 const struct GNUNET_IDENTITY_PrivateKey *key)
309{
310 GNUNET_assert ((store) && (identifier) && (key));
311
312 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store update ego: %s\n", identifier);
313
314 struct GNUNET_HashCode hash;
315 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
316
317 struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
318
319 if (!ego)
320 {
321 ego = GNUNET_new(struct GNUNET_MESSENGER_Ego);
322 GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
323 }
324
325 GNUNET_memcpy(&(ego->priv), key, sizeof(*key));
326
327 if (GNUNET_OK != GNUNET_IDENTITY_key_get_public (key, &(ego->pub)))
328 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n");
329
330 return ego;
331}
332
333void
334delete_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
335 const char *identifier)
336{
337 GNUNET_assert ((store) && (identifier));
338
339 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store delete ego: %s\n", identifier);
340
341 struct GNUNET_HashCode hash;
342 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
343
344 struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
345
346 if (ego)
347 {
348 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
349 return;
350 }
351
352 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego))
353 {
354 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing ego from store failed!\n");
355 return;
356 }
357
358 GNUNET_free(ego);
359}
360
361static void
362callback_ego_rename (void *cls,
363 const char *emsg)
364{
365 struct GNUNET_MESSENGER_EgoOperation *element = cls;
366 struct GNUNET_MESSENGER_EgoStore *store = element->store;
367
368 GNUNET_assert (element->identifier);
369
370 if (emsg)
371 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
372
373 struct GNUNET_HashCode hash;
374 GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash);
375
376 struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
377
378 if (!ego)
379 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Ego is not stored!\n");
380
381 char *identifier = (char*) element->cls;
382
383 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego))
384 {
385 GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
386
387 GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego,
388 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
389 }
390 else
391 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n");
392
393 GNUNET_free (identifier);
394
395 GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
396 GNUNET_free (element->identifier);
397 GNUNET_free (element);
398}
399
400void
401rename_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
402 const char *old_identifier,
403 const char *new_identifier)
404{
405 GNUNET_assert ((store) && (old_identifier) && (new_identifier));
406
407 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store rename ego: %s -> %s\n", old_identifier, new_identifier);
408
409 struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation);
410
411 element->store = store;
412 element->cls = GNUNET_strdup (new_identifier);
413
414 element->identifier = GNUNET_strdup (old_identifier);
415
416 element->operation = GNUNET_IDENTITY_rename (
417 store->identity,
418 old_identifier,
419 new_identifier,
420 callback_ego_rename,
421 element
422 );
423
424 GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
425}
426
427static void
428callback_ego_delete (void *cls,
429 const char *emsg)
430{
431 struct GNUNET_MESSENGER_EgoOperation *element = cls;
432 struct GNUNET_MESSENGER_EgoStore *store = element->store;
433
434 GNUNET_assert (element->identifier);
435
436 if (emsg)
437 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
438
439 create_store_ego (store, element->identifier);
440
441 GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
442 GNUNET_free (element->identifier);
443 GNUNET_free (element);
444}
445
446void
447renew_store_ego (struct GNUNET_MESSENGER_EgoStore *store,
448 const char *identifier)
449{
450 GNUNET_assert ((store) && (identifier));
451
452 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Store renew ego: %s\n", identifier);
453
454 struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation);
455
456 element->store = store;
457 element->cls = NULL;
458
459 element->identifier = GNUNET_strdup (identifier);
460
461 element->operation = GNUNET_IDENTITY_delete(
462 store->identity,
463 identifier,
464 callback_ego_delete,
465 element
466 );
467
468 GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element);
469}