diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger_ego_store.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger_ego_store.c | 469 |
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 | |||
30 | static void | ||
31 | callback_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 | |||
53 | void | ||
54 | init_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 | |||
71 | static int | ||
72 | iterate_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 | |||
81 | void | ||
82 | clear_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 | |||
129 | static int | ||
130 | iterate_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 | |||
139 | static void | ||
140 | callback_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 | |||
169 | void | ||
170 | create_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 | |||
196 | void | ||
197 | bind_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 | |||
216 | void | ||
217 | unbind_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 | |||
235 | static void | ||
236 | callback_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 | |||
275 | void | ||
276 | lookup_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 | |||
305 | struct GNUNET_MESSENGER_Ego* | ||
306 | update_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 | |||
333 | void | ||
334 | delete_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 | |||
361 | static void | ||
362 | callback_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 | |||
400 | void | ||
401 | rename_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 | |||
427 | static void | ||
428 | callback_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 | |||
446 | void | ||
447 | renew_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 | } | ||