aboutsummaryrefslogtreecommitdiff
path: root/src/fs/fs_namespace.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-08-22 17:57:31 +0000
committerChristian Grothoff <christian@grothoff.org>2009-08-22 17:57:31 +0000
commit2ae973618f3b51fa9bbf5532eaa1352cafc24ecc (patch)
treeea8bb13a4c7d390f88318b61bc6caf50ea6cf400 /src/fs/fs_namespace.c
parent9a10e9c06a3b08c8ab73edb7d2093a6d452ecc05 (diff)
downloadgnunet-2ae973618f3b51fa9bbf5532eaa1352cafc24ecc.tar.gz
gnunet-2ae973618f3b51fa9bbf5532eaa1352cafc24ecc.zip
stuff
Diffstat (limited to 'src/fs/fs_namespace.c')
-rw-r--r--src/fs/fs_namespace.c729
1 files changed, 729 insertions, 0 deletions
diff --git a/src/fs/fs_namespace.c b/src/fs/fs_namespace.c
new file mode 100644
index 000000000..fb45d99e9
--- /dev/null
+++ b/src/fs/fs_namespace.c
@@ -0,0 +1,729 @@
1/*
2 This file is part of GNUnet
3 (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file fs/fs_namespace.c
23 * @brief create and destroy namespaces
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_fs_service.h"
28
29
30/**
31 * Publish an advertismement for a namespace.
32 *
33 * @param h handle to the file sharing subsystem
34 * @param namespace handle for the namespace that should be advertised
35 * @param meta meta-data for the namespace advertisement
36 * @param anonymity for the namespace advertismement
37 * @param priority for the namespace advertisement
38 * @param expiration for the namespace advertisement
39 * @param advertisementURI the keyword (!) URI to advertise the
40 * namespace under (we will create a GNUNET_EC_KNBlock)
41 * @param rootEntry name of the root entry in the namespace (for
42 * the namespace advertisement)
43 *
44 * @return uri of the advertisement
45 */
46struct GNUNET_FS_Uri *
47GNUNET_FS_namespace_advertise (struct GNUNET_FS_Handle *h,
48 struct GNUNET_FS_Namespace *namespace,
49 const struct GNUNET_MetaData *meta,
50 unsigned int anonymity,
51 unsigned int priority,
52 struct GNUNET_TIME_Absolute expiration,
53 const struct GNUNET_FS_Uri *advertisementURI,
54 const char *rootEntry)
55{
56 return NULL;
57}
58
59
60/**
61 * Create a namespace with the given name; if one already
62 * exists, return a handle to the existing namespace.
63 *
64 * @param h handle to the file sharing subsystem
65 * @param name name to use for the namespace
66 * @return handle to the namespace, NULL on error
67 */
68struct GNUNET_FS_Namespace *
69GNUNET_FS_namespace_create (struct GNUNET_FS_Handle *h,
70 const char *name)
71{
72 return NULL;
73}
74
75
76/**
77 * Delete a namespace handle. Can be used for a clean shutdown (free
78 * memory) or also to freeze the namespace to prevent further
79 * insertions by anyone.
80 *
81 * @param namespace handle to the namespace that should be deleted / freed
82 * @param freeze prevents future insertions; creating a namespace
83 * with the same name again will create a fresh namespace instead
84 *
85 * @return GNUNET_OK on success, GNUNET_SYSERR on error
86 */
87int
88GNUNET_FS_namespace_delete (struct GNUNET_FS_Namespace *namespace,
89 int freeze)
90{
91 return GNUNET_SYSERR;
92}
93
94
95/**
96 * Build a list of all available local (!) namespaces The returned
97 * names are only the nicknames since we only iterate over the local
98 * namespaces.
99 *
100 * @param h handle to the file sharing subsystem
101 * @param cb function to call on each known namespace
102 * @param cb_cls closure for cb
103 */
104void
105GNUNET_FS_namespace_list (struct GNUNET_FS_Handle *h,
106 GNUNET_FS_NamespaceInfoProcessor cb,
107 void *cb_cls)
108{
109}
110
111/* end of fs_namespace.c */
112
113#if 0
114/*
115 This file is part of GNUnet
116 (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
117
118 GNUnet is free software; you can redistribute it and/or modify
119 it under the terms of the GNU General Public License as published
120 by the Free Software Foundation; either version 2, or (at your
121 option) any later version.
122
123 GNUnet is distributed in the hope that it will be useful, but
124 WITHOUT ANY WARRANTY; without even the implied warranty of
125 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
126 General Public License for more details.
127
128 You should have received a copy of the GNU General Public License
129 along with GNUnet; see the file COPYING. If not, write to the
130 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
131 Boston, MA 02111-1307, USA.
132*/
133
134/**
135 * @file applications/fs/ecrs/namespace.c
136 * @brief creation, deletion and advertising of namespaces
137 * @author Christian Grothoff
138 */
139
140#include "platform.h"
141#include "gnunet_directories.h"
142#include "gnunet_protocols.h"
143#include "gnunet_ecrs_lib.h"
144#include "gnunet_fs_lib.h"
145#include "ecrs_core.h"
146#include "ecrs.h"
147
148#define PSEUDODIR "data/namespace/keys/"
149#define INITVALUE "GNUnet!!"
150#define MAX_SBLOCK_SIZE 32000
151
152static char *
153getPseudonymFileName (struct GNUNET_GE_Context *ectx,
154 struct GNUNET_GC_Configuration *cfg,
155 const GNUNET_HashCode * pid)
156{
157 char *gnHome;
158 char *fileName;
159 GNUNET_EncName enc;
160
161 GNUNET_GC_get_configuration_value_filename (cfg,
162 "GNUNET",
163 "GNUNET_HOME",
164 GNUNET_DEFAULT_HOME_DIRECTORY,
165 &fileName);
166 gnHome = GNUNET_expand_file_name (ectx, fileName);
167 GNUNET_free (fileName);
168 fileName =
169 GNUNET_malloc (strlen (gnHome) + strlen (PSEUDODIR) +
170 sizeof (GNUNET_EncName) + 2);
171 strcpy (fileName, gnHome);
172 GNUNET_free (gnHome);
173 strcat (fileName, DIR_SEPARATOR_STR);
174 strcat (fileName, PSEUDODIR);
175 GNUNET_disk_directory_create (ectx, fileName);
176 if (pid != NULL)
177 {
178 GNUNET_hash_to_enc (pid, &enc);
179 strcat (fileName, (char *) &enc);
180 }
181 return fileName;
182}
183
184
185/**
186 * Check if the given namespace exists (locally).
187 *
188 * @return GNUNET_OK if the namespace exists, GNUNET_SYSERR if not
189 */
190int
191GNUNET_ECRS_namespace_test_exists (struct GNUNET_GE_Context *ectx,
192 struct GNUNET_GC_Configuration *cfg,
193 const GNUNET_HashCode * pid)
194{
195 char *fileName;
196 int ret;
197
198 fileName = getPseudonymFileName (ectx, cfg, pid);
199 ret = GNUNET_disk_file_test (ectx, fileName);
200 GNUNET_free (fileName);
201 return ret;
202}
203
204/**
205 * Delete a local namespace.
206 *
207 * @return GNUNET_OK on success, GNUNET_SYSERR on error
208 */
209int
210GNUNET_ECRS_namespace_delete (struct GNUNET_GE_Context *ectx,
211 struct GNUNET_GC_Configuration *cfg,
212 const GNUNET_HashCode * pid)
213{
214 char *fileName;
215
216 fileName = getPseudonymFileName (ectx, cfg, pid);
217 if (GNUNET_YES != GNUNET_disk_file_test (ectx, fileName))
218 {
219 GNUNET_free (fileName);
220 return GNUNET_SYSERR; /* no such namespace */
221 }
222 if (0 != UNLINK (fileName))
223 {
224 GNUNET_GE_LOG_STRERROR_FILE (ectx,
225 GNUNET_GE_WARNING | GNUNET_GE_USER |
226 GNUNET_GE_BULK, "unlink", fileName);
227 GNUNET_free (fileName);
228 return GNUNET_SYSERR;
229 }
230 GNUNET_free (fileName);
231 return GNUNET_OK;
232}
233
234/**
235 * Write the private key of the namespace to a file.
236 */
237static int
238write_namespace_key (struct GNUNET_GC_Configuration *cfg,
239 const struct GNUNET_RSA_PrivateKey *key)
240{
241 GNUNET_RSA_PrivateKeyEncoded *namespace_priv_key_encoded;
242 char *fileName;
243 GNUNET_RSA_PublicKey pubk;
244 GNUNET_HashCode pid;
245
246 GNUNET_RSA_get_public_key (key, &pubk);
247 GNUNET_hash (&pubk, sizeof (GNUNET_RSA_PublicKey), &pid);
248 fileName = getPseudonymFileName (NULL, cfg, &pid);
249 if (GNUNET_YES == GNUNET_disk_file_test (NULL, fileName))
250 {
251 GNUNET_GE_BREAK (NULL, 0); /* hash collision!? */
252 GNUNET_free (fileName);
253 return GNUNET_SYSERR;
254 }
255 namespace_priv_key_encoded = GNUNET_RSA_encode_key (key);
256 GNUNET_disk_file_write (NULL, fileName,
257 (const char *) namespace_priv_key_encoded,
258 ntohs (namespace_priv_key_encoded->len), "600");
259 GNUNET_free (fileName);
260 GNUNET_free (namespace_priv_key_encoded);
261 return GNUNET_OK;
262}
263
264/**
265 * Create a new namespace (and publish an advertismement).
266 * This publishes both an GNUNET_EC_NBlock in the namespace itself
267 * as well as KNBlocks under all keywords specified in
268 * the advertisementURI.
269 *
270 * @param anonymity_level for the namespace advertismement
271 * @param priority for the namespace advertisement
272 * @param expiration for the namespace advertisement
273 * @param advertisementURI the keyword (!) URI to advertise the
274 * namespace under (GNUNET_EC_KNBlock)
275 * @param meta meta-data for the namespace advertisement
276 * (will be used to derive a name)
277 * @param rootEntry name of the root entry in the namespace (for
278 * the namespace advertisement)
279 * @param rootURI set to the URI of the namespace, NULL if
280 * no advertisement was created
281 *
282 * @return URI on success, NULL on error
283 */
284struct GNUNET_ECRS_URI *
285GNUNET_ECRS_namespace_create (struct GNUNET_GE_Context *ectx,
286 struct GNUNET_GC_Configuration *cfg,
287 const struct GNUNET_MetaData *meta,
288 unsigned int anonymityLevel,
289 unsigned int priority,
290 GNUNET_CronTime expiration,
291 const struct GNUNET_ECRS_URI *advertisementURI,
292 const char *rootEntry)
293{
294 struct GNUNET_ECRS_URI *rootURI;
295 struct GNUNET_RSA_PrivateKey *namespace_priv_key;
296 GNUNET_HashCode hc;
297 struct GNUNET_ClientServerConnection *sock;
298 GNUNET_DatastoreValue *value;
299 GNUNET_DatastoreValue *knvalue;
300 unsigned int size;
301 unsigned int mdsize;
302 struct GNUNET_RSA_PrivateKey *pk;
303 GNUNET_EC_SBlock *sb;
304 GNUNET_EC_KSBlock *ksb;
305 char **keywords;
306 const char *keyword;
307 unsigned int keywordCount;
308 int i;
309 char *cpy;
310 char *rtgt;
311
312 if ((advertisementURI != NULL)
313 && (!GNUNET_ECRS_uri_test_ksk (advertisementURI)))
314 {
315 GNUNET_GE_BREAK (ectx, 0);
316 return NULL;
317 }
318 namespace_priv_key = GNUNET_RSA_create_key ();
319 if (GNUNET_OK != write_namespace_key (cfg, namespace_priv_key))
320 {
321 GNUNET_RSA_free_key (namespace_priv_key);
322 return NULL;
323 }
324
325 /* create advertisements */
326 mdsize = GNUNET_meta_data_get_serialized_size (meta, GNUNET_SERIALIZE_PART);
327 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2;
328 if (size > MAX_SBLOCK_SIZE)
329 {
330 size = MAX_SBLOCK_SIZE;
331 mdsize = size - sizeof (GNUNET_EC_SBlock) - strlen (rootEntry) - 2;
332 }
333 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
334 memset (value, 0, sizeof (GNUNET_DatastoreValue) + size);
335 sb = (GNUNET_EC_SBlock *) & value[1];
336 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
337 GNUNET_RSA_get_public_key (namespace_priv_key, &sb->subspace);
338 rtgt = (char *) &sb[1];
339 memcpy (rtgt, rootEntry, strlen (rootEntry) + 1);
340 mdsize = GNUNET_meta_data_serialize (ectx,
341 meta,
342 &rtgt[strlen (rootEntry) + 2],
343 mdsize, GNUNET_SERIALIZE_PART);
344 if (mdsize == -1)
345 {
346 GNUNET_GE_BREAK (ectx, 0);
347 GNUNET_RSA_free_key (namespace_priv_key);
348 GNUNET_free (value);
349 return NULL;
350 }
351 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2;
352 GNUNET_GE_ASSERT (ectx,
353 GNUNET_OK == GNUNET_RSA_sign (namespace_priv_key,
354 size
355 -
356 sizeof
357 (GNUNET_RSA_Signature) -
358 sizeof
359 (GNUNET_RSA_PublicKey) -
360 sizeof (unsigned int),
361 &sb->identifier,
362 &sb->signature));
363 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
364 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
365 value->priority = htonl (priority);
366 value->anonymity_level = htonl (anonymityLevel);
367 value->expiration_time = GNUNET_htonll (expiration);
368 sock = GNUNET_client_connection_create (ectx, cfg);
369 if (sock == NULL)
370 {
371 GNUNET_free (value);
372 GNUNET_RSA_free_key (namespace_priv_key);
373 return NULL;
374 }
375 if (GNUNET_OK != GNUNET_FS_insert (sock, value))
376 {
377 GNUNET_free (value);
378 GNUNET_client_connection_destroy (sock);
379 GNUNET_RSA_free_key (namespace_priv_key);
380 return NULL;
381 }
382
383
384 /* publish KNBlocks */
385 size += sizeof (GNUNET_EC_KSBlock) - sizeof (GNUNET_EC_SBlock);
386 knvalue = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
387 *knvalue = *value;
388 knvalue->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED);
389 knvalue->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
390 ksb = (GNUNET_EC_KSBlock *) & knvalue[1];
391 ksb->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED);
392 memcpy (&ksb->sblock,
393 sb, sizeof (GNUNET_EC_SBlock) + mdsize + strlen (rootEntry) + 2);
394
395 if (advertisementURI != NULL)
396 {
397 keywords = advertisementURI->data.ksk.keywords;
398 keywordCount = advertisementURI->data.ksk.keywordCount;
399 cpy =
400 GNUNET_malloc (size - sizeof (GNUNET_EC_KBlock) -
401 sizeof (unsigned int));
402 memcpy (cpy,
403 &ksb->sblock,
404 size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int));
405 for (i = 0; i < keywordCount; i++)
406 {
407 keyword = keywords[i];
408 /* first character of keyword indicates
409 mandatory or not -- ignore for hashing! */
410 GNUNET_hash (&keyword[1], strlen (&keyword[1]), &hc);
411 pk = GNUNET_RSA_create_key_from_hash (&hc);
412 GNUNET_RSA_get_public_key (pk, &ksb->kblock.keyspace);
413 GNUNET_GE_ASSERT (ectx,
414 size - sizeof (GNUNET_EC_KBlock) -
415 sizeof (unsigned int) ==
416 sizeof (GNUNET_EC_SBlock) + mdsize +
417 strlen (rootEntry) + 2);
418 GNUNET_ECRS_encryptInPlace (&hc, &ksb->sblock,
419 size - sizeof (GNUNET_EC_KBlock) -
420 sizeof (unsigned int));
421
422 GNUNET_GE_ASSERT (ectx,
423 GNUNET_OK == GNUNET_RSA_sign (pk,
424 size -
425 sizeof
426 (GNUNET_EC_KBlock) -
427 sizeof (unsigned
428 int),
429 &ksb->sblock,
430 &ksb->
431 kblock.signature));
432 /* extra check: verify sig */
433 GNUNET_RSA_free_key (pk);
434 if (GNUNET_OK != GNUNET_FS_insert (sock, knvalue))
435 {
436 GNUNET_GE_BREAK (ectx, 0);
437 GNUNET_free (cpy);
438 GNUNET_free (knvalue);
439 GNUNET_free (value);
440 GNUNET_client_connection_destroy (sock);
441 GNUNET_RSA_free_key (namespace_priv_key);
442 return NULL;
443 }
444 /* restore nblock to avoid re-encryption! */
445 memcpy (&ksb->sblock,
446 cpy,
447 size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int));
448 }
449 GNUNET_free (cpy);
450 }
451 rootURI = GNUNET_malloc (sizeof (URI));
452 rootURI->type = sks;
453 GNUNET_hash (&sb->subspace,
454 sizeof (GNUNET_RSA_PublicKey), &rootURI->data.sks.namespace);
455 rootURI->data.sks.identifier = GNUNET_strdup (rootEntry);
456 GNUNET_free (knvalue);
457 GNUNET_free (value);
458 GNUNET_client_connection_destroy (sock);
459 GNUNET_RSA_free_key (namespace_priv_key);
460
461 return rootURI;
462}
463
464static struct GNUNET_RSA_PrivateKey *
465read_namespace_key (struct GNUNET_GC_Configuration *cfg,
466 const GNUNET_HashCode * pid)
467{
468 char *fileName;
469 GNUNET_RSA_PrivateKeyEncoded *hke;
470 struct GNUNET_RSA_PrivateKey *hk;
471 char *dst;
472 unsigned long long len;
473
474 fileName = getPseudonymFileName (NULL, cfg, pid);
475 if (GNUNET_OK != GNUNET_disk_file_size (NULL, fileName, &len, GNUNET_YES))
476 {
477 GNUNET_free (fileName);
478 return NULL;
479 }
480 if (len < 2)
481 {
482 GNUNET_GE_LOG (NULL, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
483 _("File `%s' does not contain a pseudonym.\n"),
484 fileName);
485 GNUNET_free (fileName);
486 return NULL;
487 }
488 dst = GNUNET_malloc (len);
489 len = GNUNET_disk_file_read (NULL, fileName, len, dst);
490 hke = (GNUNET_RSA_PrivateKeyEncoded *) dst;
491 if (ntohs (hke->len) != len)
492 {
493 GNUNET_GE_LOG (NULL, GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
494 _("Format of pseudonym `%s' is invalid.\n"), fileName);
495 GNUNET_free (fileName);
496 GNUNET_free (hke);
497 return NULL;
498 }
499 GNUNET_free (fileName);
500 hk = GNUNET_RSA_decode_key (hke);
501 GNUNET_free (hke);
502 return hk;
503}
504
505
506/**
507 * Add an entry into a namespace.
508 *
509 * @param dstU to which URI should the namespace entry refer?
510 * @param md what meta-data should be associated with the
511 * entry?
512 * @param thisId name of this entry in the namespace (keyword/identifier)
513 * @param nextId name of the update for this entry (to be published in
514 * the future; maybe NULL)
515 * @param pid unique identifier of the namespace/pseudonym
516 * @return URI on success, NULL on error
517 */
518struct GNUNET_ECRS_URI *
519GNUNET_ECRS_namespace_add_content (struct GNUNET_GE_Context *ectx,
520 struct GNUNET_GC_Configuration *cfg,
521 const GNUNET_HashCode * pid,
522 unsigned int anonymityLevel,
523 unsigned int priority,
524 GNUNET_CronTime expiration,
525 const char *thisId,
526 const char *nextId,
527 const struct GNUNET_ECRS_URI *dstU,
528 const struct GNUNET_MetaData *md)
529{
530 struct GNUNET_ECRS_URI *uri;
531 struct GNUNET_ClientServerConnection *sock;
532 GNUNET_DatastoreValue *value;
533 unsigned int size;
534 unsigned int mdsize;
535 struct GNUNET_RSA_PrivateKey *hk;
536 GNUNET_EC_SBlock *sb;
537 char *dstURI;
538 char *destPos;
539 GNUNET_HashCode hc; /* hash of thisId = key */
540 GNUNET_HashCode hc2; /* hash of hc = identifier */
541 int ret;
542 unsigned int nidlen;
543
544 hk = read_namespace_key (cfg, pid);
545 if (hk == NULL)
546 return NULL;
547
548 /* THEN: construct GNUNET_EC_SBlock */
549 dstURI = GNUNET_ECRS_uri_to_string (dstU);
550 mdsize = GNUNET_meta_data_get_serialized_size (md, GNUNET_SERIALIZE_PART);
551 if (nextId == NULL)
552 nextId = "";
553 nidlen = strlen (nextId) + 1;
554 size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen;
555 if (size > MAX_SBLOCK_SIZE)
556 {
557 size = MAX_SBLOCK_SIZE;
558 mdsize =
559 size - (sizeof (GNUNET_EC_SBlock) + strlen (dstURI) + 1 + nidlen);
560 }
561 value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size);
562 sb = (GNUNET_EC_SBlock *) & value[1];
563 sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
564 destPos = (char *) &sb[1];
565 memcpy (destPos, nextId, nidlen);
566 destPos += nidlen;
567 memcpy (destPos, dstURI, strlen (dstURI) + 1);
568 destPos += strlen (dstURI) + 1;
569 mdsize = GNUNET_meta_data_serialize (ectx,
570 md,
571 destPos,
572 mdsize, GNUNET_SERIALIZE_PART);
573 if (mdsize == -1)
574 {
575 GNUNET_GE_BREAK (ectx, 0);
576 GNUNET_free (dstURI);
577 GNUNET_RSA_free_key (hk);
578 GNUNET_free (value);
579 return NULL;
580 }
581 size = sizeof (GNUNET_EC_SBlock) + mdsize + strlen (dstURI) + 1 + nidlen;
582 value->size = htonl (sizeof (GNUNET_DatastoreValue) + size);
583 value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED);
584 value->priority = htonl (priority);
585 value->anonymity_level = htonl (anonymityLevel);
586 value->expiration_time = GNUNET_htonll (expiration);
587 GNUNET_hash (thisId, strlen (thisId), &hc);
588 GNUNET_hash (&hc, sizeof (GNUNET_HashCode), &hc2);
589 uri = GNUNET_malloc (sizeof (URI));
590 uri->type = sks;
591 GNUNET_RSA_get_public_key (hk, &sb->subspace);
592 GNUNET_hash (&sb->subspace,
593 sizeof (GNUNET_RSA_PublicKey), &uri->data.sks.namespace);
594 GNUNET_GE_BREAK (ectx, 0 == memcmp (&uri->data.sks.namespace,
595 pid, sizeof (GNUNET_HashCode)));
596 uri->data.sks.identifier = GNUNET_strdup (thisId);
597 GNUNET_hash_xor (&hc2, &uri->data.sks.namespace, &sb->identifier);
598 GNUNET_ECRS_encryptInPlace (&hc, &sb[1], size - sizeof (GNUNET_EC_SBlock));
599 GNUNET_GE_ASSERT (ectx,
600 GNUNET_OK == GNUNET_RSA_sign (hk,
601 size
602 -
603 sizeof
604 (GNUNET_RSA_Signature) -
605 sizeof
606 (GNUNET_RSA_PublicKey) -
607 sizeof (unsigned int),
608 &sb->identifier,
609 &sb->signature));
610 GNUNET_RSA_free_key (hk);
611 sock = GNUNET_client_connection_create (ectx, cfg);
612 ret = GNUNET_FS_insert (sock, value);
613 if (ret != GNUNET_OK)
614 {
615 GNUNET_free (uri);
616 uri = NULL;
617 }
618 GNUNET_client_connection_destroy (sock);
619 GNUNET_free (value);
620 GNUNET_free (dstURI);
621
622 return uri;
623}
624
625struct lNCLS
626{
627 struct GNUNET_GE_Context *ectx;
628 struct GNUNET_GC_Configuration *cfg;
629 GNUNET_ECRS_NamespaceInfoProcessor cb;
630 void *cls;
631 int cnt;
632};
633
634static int
635processFile_ (void *cls, const char *fileName)
636{
637 struct lNCLS *c = cls;
638 struct GNUNET_RSA_PrivateKey *hk;
639 GNUNET_RSA_PrivateKeyEncoded *hke;
640 char *dst;
641 unsigned long long len;
642 GNUNET_HashCode namespace;
643 GNUNET_RSA_PublicKey pk;
644 const char *name;
645
646 if (GNUNET_OK !=
647 GNUNET_disk_file_size (c->ectx, fileName, &len, GNUNET_YES))
648 return GNUNET_OK;
649 if (len < 2)
650 {
651 GNUNET_GE_LOG (c->ectx,
652 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
653 _("Format of file `%s' is invalid, trying to remove.\n"),
654 fileName);
655 UNLINK (fileName);
656 return GNUNET_OK;
657 }
658 dst = GNUNET_malloc (len);
659 len = GNUNET_disk_file_read (c->ectx, fileName, len, dst);
660 hke = (GNUNET_RSA_PrivateKeyEncoded *) dst;
661 if (ntohs (hke->len) != len)
662 {
663 GNUNET_GE_LOG (c->ectx,
664 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
665 _("Format of file `%s' is invalid, trying to remove.\n"),
666 fileName);
667 UNLINK (fileName);
668 GNUNET_free (hke);
669 return GNUNET_OK;
670 }
671 hk = GNUNET_RSA_decode_key (hke);
672 GNUNET_free (hke);
673 if (hk == NULL)
674 {
675 GNUNET_GE_LOG (c->ectx,
676 GNUNET_GE_ERROR | GNUNET_GE_BULK | GNUNET_GE_USER,
677 _("Format of file `%s' is invalid, trying to remove.\n"),
678 fileName);
679 UNLINK (fileName);
680 GNUNET_GE_BREAK (c->ectx, 0);
681 return GNUNET_SYSERR;
682 }
683 GNUNET_RSA_get_public_key (hk, &pk);
684 GNUNET_RSA_free_key (hk);
685 GNUNET_hash (&pk, sizeof (GNUNET_RSA_PublicKey), &namespace);
686 if (NULL != c->cb)
687 {
688 name = fileName;
689 while (NULL != strstr (name, DIR_SEPARATOR_STR))
690 name = 1 + strstr (name, DIR_SEPARATOR_STR);
691 if (GNUNET_OK == c->cb (&namespace, name, c->cls))
692 c->cnt++;
693 else
694 c->cnt = GNUNET_SYSERR;
695 }
696 else
697 c->cnt++;
698 return GNUNET_OK;
699}
700
701/**
702 * Build a list of all available namespaces
703 *
704 * @param list where to store the names (is allocated, caller frees)
705 * @return GNUNET_SYSERR on error, otherwise the number of pseudonyms in list
706 */
707int
708GNUNET_ECRS_get_namespaces (struct GNUNET_GE_Context *ectx,
709 struct GNUNET_GC_Configuration *cfg,
710 GNUNET_ECRS_NamespaceInfoProcessor cb, void *cls)
711{
712 char *dirName;
713 struct lNCLS myCLS;
714
715 myCLS.cls = cls;
716 myCLS.cb = cb;
717 myCLS.cnt = 0;
718 myCLS.ectx = ectx;
719 myCLS.cfg = cfg;
720 dirName = getPseudonymFileName (ectx, cfg, NULL);
721 GNUNET_disk_directory_scan (ectx, dirName, &processFile_, &myCLS);
722 GNUNET_free (dirName);
723 return myCLS.cnt;
724}
725
726
727
728/* end of namespace.c */
729#endif