GNUnet  0.17.6
gnunet-service-messenger_ego_store.c
Go to the documentation of this file.
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  */
27 
29 
30 static void
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
55  const struct GNUNET_CONFIGURATION_Handle *config)
56 {
57  GNUNET_assert ((store) && (config));
58 
59  store->cfg = config;
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
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
83 {
84  GNUNET_assert (store);
85 
87 
88  while (store->op_start)
89  {
90  op = store->op_start;
91 
92  GNUNET_IDENTITY_cancel (op->operation);
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 
109 
110  if (lu->identifier)
111  GNUNET_free(lu->identifier);
112 
113  GNUNET_free (lu);
114  }
115 
118 
120 
121  if (store->identity)
122  {
124 
125  store->identity = NULL;
126  }
127 }
128 
129 static int
131  const struct GNUNET_HashCode *key,
132  void *value)
133 {
136  return GNUNET_YES;
137 }
138 
139 static void
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 
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
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 
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,
190  element
191  );
192 
194 }
195 
196 void
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 
209  return;
210 
213  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Putting handle binding to ego store failed!\n");
214 }
215 
216 void
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 
229  return;
230 
232  GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Removing handle binding from ego store failed!\n");
233 }
234 
235 static void
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,
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
277  const char *identifier,
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 
292 
293  element->store = store;
294 
295  element->cb = lookup;
296  element->cls = cls;
297 
298  element->identifier = GNUNET_strdup (identifier);
299 
301 
303 }
304 
305 struct GNUNET_MESSENGER_Ego*
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);
323  }
324 
325  GNUNET_memcpy(&(ego->priv), key, sizeof(*key));
326 
328  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n");
329 
330  return ego;
331 }
332 
333 void
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
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,
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
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 
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,
421  element
422  );
423 
425 }
426 
427 static void
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
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 
455 
456  element->store = store;
457  element->cls = NULL;
458 
459  element->identifier = GNUNET_strdup (identifier);
460 
462  store->identity,
463  identifier,
465  element
466  );
467 
469 }
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
struct GNUNET_HashCode key
The key used in the DHT.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
static char * value
Value of the record to add/remove.
void renew_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier)
Replaces the registered EGO in a store under a specific identifier with a newly created one.
static int iterate_create_ego(void *cls, const struct GNUNET_HashCode *key, void *value)
static void callback_ego_create(void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg)
void delete_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier)
Deletes the registration of an EGO in a store under a specific identifier.
void bind_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier, void *handle)
Binds an EGO which was registered to a store under a specific identifier to a given handle
struct GNUNET_MESSENGER_Ego * update_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier, const struct GNUNET_IDENTITY_PrivateKey *key)
Updates the registration of an EGO to a store under a specific identifier with a new key.
void lookup_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier, GNUNET_MESSENGER_EgoLookupCallback lookup, void *cls)
Lookups an EGO which was registered to a store under a specific identifier.
static int iterate_destroy_egos(void *cls, const struct GNUNET_HashCode *key, void *value)
void clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store)
Clears an EGO-store, wipes its content and deallocates its memory.
void create_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier)
Creates a new EGO which will be registered to a store under a specific identifier.
void unbind_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier, void *handle)
Binds an EGO which was registered to a store under a specific identifier to a given handle
static void callback_ego_lookup(void *cls, struct GNUNET_IDENTITY_Ego *ego)
static void callback_ego_delete(void *cls, const char *emsg)
void init_ego_store(struct GNUNET_MESSENGER_EgoStore *store, const struct GNUNET_CONFIGURATION_Handle *config)
Initializes an EGO-store as fully empty.
static void callback_ego_rename(void *cls, const char *emsg)
void rename_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *old_identifier, const char *new_identifier)
Updates the location of a registered EGO in a store to a different one under a specific new_identifie...
static void callback_update_ego(void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, const char *identifier)
GNUnet MESSENGER service.
void(* GNUNET_MESSENGER_EgoLookupCallback)(void *cls, const char *identifier, const struct GNUNET_MESSENGER_Ego *ego)
void set_srv_handle_ego(struct GNUNET_MESSENGER_SrvHandle *handle, const struct GNUNET_MESSENGER_Ego *ego)
Sets the EGO used by a given handle.
GNUnet MESSENGER service.
static const struct GNUNET_CONFIGURATION_Handle * config
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition: crypto_hash.c:41
int GNUNET_CONTAINER_multihashmap_get_multiple(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map that match a particular key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_contains_value(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Check if the map contains the given value under the given key.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from the map.
enum GNUNET_GenericReturnValue GNUNET_CONTAINER_multihashmap_put(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_CONTAINER_MultiHashMap * GNUNET_CONTAINER_multihashmap_create(unsigned int len, int do_not_copy_keys)
Create a multi hash map.
int GNUNET_CONTAINER_multihashmap_iterate(struct GNUNET_CONTAINER_MultiHashMap *map, GNUNET_CONTAINER_MulitHashMapIteratorCallback it, void *it_cls)
Iterate over all entries in the map.
void GNUNET_CONTAINER_multihashmap_destroy(struct GNUNET_CONTAINER_MultiHashMap *map)
Destroy a hash map.
void * GNUNET_CONTAINER_multihashmap_get(const struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key)
Given a key find a value in the map matching the key.
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST
, ' bother checking if a value already exists (faster than GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE...
@ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE
Allow multiple values with the same key.
const struct GNUNET_IDENTITY_PrivateKey * GNUNET_IDENTITY_ego_get_private_key(const struct GNUNET_IDENTITY_Ego *ego)
Obtain the ECC key associated with a ego.
Definition: identity_api.c:639
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_rename(struct GNUNET_IDENTITY_Handle *h, const char *old_name, const char *new_name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Renames an existing identity.
Definition: identity_api.c:810
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:175
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_create(struct GNUNET_IDENTITY_Handle *h, const char *name, const struct GNUNET_IDENTITY_PrivateKey *privkey, enum GNUNET_IDENTITY_KeyType ktype, GNUNET_IDENTITY_CreateContinuation cont, void *cont_cls)
Create a new ego with the given name.
Definition: identity_api.c:757
void GNUNET_IDENTITY_cancel(struct GNUNET_IDENTITY_Operation *op)
Cancel an identity operation.
Definition: identity_api.c:904
void GNUNET_IDENTITY_ego_lookup_cancel(struct GNUNET_IDENTITY_EgoLookup *el)
Abort ego lookup attempt.
struct GNUNET_IDENTITY_Handle * GNUNET_IDENTITY_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_IDENTITY_Callback cb, void *cb_cls)
Connect to the identity service.
Definition: identity_api.c:610
void GNUNET_IDENTITY_disconnect(struct GNUNET_IDENTITY_Handle *h)
Disconnect from identity service.
Definition: identity_api.c:921
struct GNUNET_IDENTITY_EgoLookup * GNUNET_IDENTITY_ego_lookup(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *name, GNUNET_IDENTITY_EgoCallback cb, void *cb_cls)
Lookup an ego by name.
struct GNUNET_IDENTITY_Operation * GNUNET_IDENTITY_delete(struct GNUNET_IDENTITY_Handle *h, const char *name, GNUNET_IDENTITY_Continuation cb, void *cb_cls)
Delete an existing identity.
Definition: identity_api.c:863
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
#define GNUNET_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:99
@ GNUNET_YES
@ GNUNET_NO
Definition: gnunet_common.h:98
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
A 512-bit hashcode.
Handle for an ego.
Definition: identity.h:37
A private key for an identity as per LSD0001.
struct GNUNET_IDENTITY_EgoLookup * lookup
struct GNUNET_MESSENGER_EgoStore * store
GNUNET_MESSENGER_EgoLookupCallback cb
struct GNUNET_MESSENGER_EgoStore * store
struct GNUNET_IDENTITY_Operation * operation
struct GNUNET_CONTAINER_MultiHashMap * handles
struct GNUNET_MESSENGER_EgoLookup * lu_end
const struct GNUNET_CONFIGURATION_Handle * cfg
struct GNUNET_MESSENGER_EgoLookup * lu_start
struct GNUNET_IDENTITY_Handle * identity
struct GNUNET_CONTAINER_MultiHashMap * egos
struct GNUNET_MESSENGER_EgoOperation * op_end
struct GNUNET_MESSENGER_EgoOperation * op_start
struct GNUNET_IDENTITY_PublicKey pub
struct GNUNET_IDENTITY_PrivateKey priv