GNUnet  0.11.x
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--2021 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 ((!ego) || (!identifier))
37  return;
38 
39  struct GNUNET_MESSENGER_EgoStore *store = cls;
40 
41  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", identifier);
42 
43  update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key (ego));
44 }
45 
46 void
48  const struct GNUNET_CONFIGURATION_Handle *config)
49 {
50  GNUNET_assert ((store) && (config));
51 
52  store->cfg = config;
55 
56  store->lu_start = NULL;
57  store->lu_end = NULL;
58 
59  store->op_start = NULL;
60  store->op_end = NULL;
61 }
62 
63 
64 static int
66  const struct GNUNET_HashCode *key,
67  void *value)
68 {
69  struct GNUNET_MESSENGER_Ego *ego = value;
70  GNUNET_free(ego);
71  return GNUNET_YES;
72 }
73 
74 void
76 {
77  GNUNET_assert (store);
78 
80 
81  while (store->op_start)
82  {
83  op = store->op_start;
84 
85  GNUNET_IDENTITY_cancel (op->operation);
87 
88  if (op->identifier)
89  GNUNET_free (op->identifier);
90 
91  GNUNET_free (op);
92  }
93 
94  struct GNUNET_MESSENGER_EgoLookup *lu;
95 
96  while (store->lu_start)
97  {
98  lu = store->lu_start;
99 
102 
103  if (lu->identifier)
104  GNUNET_free(lu->identifier);
105 
106  GNUNET_free (lu);
107  }
108 
111 
112  if (store->identity)
113  {
115 
116  store->identity = NULL;
117  }
118 }
119 
120 static void
122  const struct GNUNET_IDENTITY_PrivateKey *key,
123  const char *emsg)
124 {
125  struct GNUNET_MESSENGER_EgoOperation *element = cls;
126  struct GNUNET_MESSENGER_EgoStore *store = element->store;
127 
128  GNUNET_assert(element->identifier);
129 
130  if (emsg)
131  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
132 
133  if (key)
134  {
135  struct GNUNET_MESSENGER_SrvHandle *handle = element->handle;
136 
137  struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store, element->identifier, key);
138 
139  set_handle_ego (handle, msg_ego);
140  }
141  else
142  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n");
143 
144  GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
145  GNUNET_free (element->identifier);
146  GNUNET_free (element);
147 }
148 
149 void
151  const char *identifier,
152  void *handle)
153 {
154  GNUNET_assert ((store) && (identifier));
155 
157 
158  element->store = store;
159  element->handle = handle;
160 
161  element->identifier = GNUNET_strdup (identifier);
162 
165 
167 }
168 
169 static void
171  struct GNUNET_IDENTITY_Ego *ego)
172 {
173  struct GNUNET_MESSENGER_EgoLookup *element = cls;
174  struct GNUNET_MESSENGER_EgoStore *store = element->store;
175 
176  GNUNET_assert(element->identifier);
177 
178  struct GNUNET_MESSENGER_Ego *msg_ego;
179 
180  if (ego)
181  msg_ego = update_store_ego (
182  store, element->identifier, GNUNET_IDENTITY_ego_get_private_key(ego)
183  );
184  else
185  msg_ego = NULL;
186 
187  if (element->cb)
188  element->cb(element->cls, element->identifier, msg_ego);
189 
190  GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, element);
191  GNUNET_free (element->identifier);
192  GNUNET_free (element);
193 }
194 
195 void
197  const char *identifier,
199  void *cls)
200 {
201  GNUNET_assert (store);
202 
203  if (!identifier)
204  {
205  lookup(cls, identifier, NULL);
206  return;
207  }
208 
209  struct GNUNET_HashCode hash;
210  GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
211 
212  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
213 
214  if (ego)
215  lookup(cls, identifier, ego);
216  else
217  {
219 
220  element->store = store;
221 
222  element->cb = lookup;
223  element->cls = cls;
224 
225  element->identifier = GNUNET_strdup (identifier);
226 
228 
230  }
231 }
232 
233 struct GNUNET_MESSENGER_Ego*
235  const char *identifier,
236  const struct GNUNET_IDENTITY_PrivateKey *key)
237 {
238  GNUNET_assert ((store) && (identifier) && (key));
239 
240  struct GNUNET_HashCode hash;
241  GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash);
242 
243  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
244 
245  if (!ego)
246  {
247  ego = GNUNET_new(struct GNUNET_MESSENGER_Ego);
249  }
250 
251  GNUNET_memcpy(&(ego->priv), key, sizeof(*key));
252 
254  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n");
255 
256  return ego;
257 }
258 
259 static void
261  const char *emsg)
262 {
263  struct GNUNET_MESSENGER_EgoOperation *element = cls;
264  struct GNUNET_MESSENGER_EgoStore *store = element->store;
265 
266  GNUNET_assert(element->identifier);
267 
268  if (emsg)
269  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg);
270 
271  struct GNUNET_HashCode hash;
272  GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash);
273 
274  struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash);
275 
276  if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego))
277  {
278  GNUNET_CRYPTO_hash ((char*) element->handle, strlen ((char*) element->handle), &hash);
279 
280  GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego,
282  }
283  else
284  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n");
285 
286  GNUNET_free (element->handle);
287 
288  GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element);
289  GNUNET_free (element->identifier);
290  GNUNET_free (element);
291 }
292 
293 void
295  const char *old_identifier,
296  const char *new_identifier)
297 {
298  GNUNET_assert ((store) && (old_identifier) && (new_identifier));
299 
301 
302  element->store = store;
303  element->handle = GNUNET_strdup (new_identifier);
304 
305  element->identifier = GNUNET_strdup (old_identifier);
306 
307  element->operation = GNUNET_IDENTITY_rename (store->identity, old_identifier, new_identifier, callback_ego_rename, element);
308 
310 }
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 create_store_ego(struct GNUNET_MESSENGER_EgoStore *store, const char *identifier, void *handle)
Creates a new EGO which will be registered to a store under a specific identifier.
static void callback_ego_create(void *cls, const struct GNUNET_IDENTITY_PrivateKey *key, const char *emsg)
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.
static void callback_ego_lookup(void *cls, struct GNUNET_IDENTITY_Ego *ego)
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_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_log(kind,...)
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
#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_remove(struct GNUNET_CONTAINER_MultiHashMap *map, const struct GNUNET_HashCode *key, const void *value)
Remove the given key-value pair from 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_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.
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...
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.
@ GNUNET_IDENTITY_TYPE_ECDSA
The identity type.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_WARNING
@ 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_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