📄 namespace.c
字号:
/* This file is part of GNUnet (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*//** * @file applications/fs/ecrs/namespace.c * @brief creation, deletion and advertising of namespaces * @author Christian Grothoff */#include "platform.h"#include "gnunet_directories.h"#include "gnunet_protocols.h"#include "gnunet_ecrs_lib.h"#include "gnunet_fs_lib.h"#include "ecrs_core.h"#include "ecrs.h"#define PSEUDODIR "data/namespace/keys/"#define INITVALUE "GNUnet!!"#define MAX_SBLOCK_SIZE 32000static char *getPseudonymFileName (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const GNUNET_HashCode * pid){ char *gnHome; char *fileName; GNUNET_EncName enc; GNUNET_GC_get_configuration_value_filename (cfg, "GNUNET", "GNUNET_HOME", GNUNET_DEFAULT_HOME_DIRECTORY, &fileName); gnHome = GNUNET_expand_file_name (ectx, fileName); GNUNET_free (fileName); fileName = GNUNET_malloc (strlen (gnHome) + strlen (PSEUDODIR) + sizeof (GNUNET_EncName) + 2); strcpy (fileName, gnHome); GNUNET_free (gnHome); strcat (fileName, DIR_SEPARATOR_STR); strcat (fileName, PSEUDODIR); GNUNET_disk_directory_create (ectx, fileName); if (pid != NULL) { GNUNET_hash_to_enc (pid, &enc); strcat (fileName, (char *) &enc); } return fileName;}/** * Check if the given namespace exists (locally). * * @return GNUNET_OK if the namespace exists, GNUNET_SYSERR if not */intGNUNET_ECRS_namespace_test_exists (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const GNUNET_HashCode * pid){ char *fileName; int ret; fileName = getPseudonymFileName (ectx, cfg, pid); ret = GNUNET_disk_file_test (ectx, fileName); GNUNET_free (fileName); return ret;}/** * Delete a local namespace. * * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_ECRS_namespace_delete (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const GNUNET_HashCode * pid){ char *fileName; fileName = getPseudonymFileName (ectx, cfg, pid); if (GNUNET_YES != GNUNET_disk_file_test (ectx, fileName)) { GNUNET_free (fileName); return GNUNET_SYSERR; /* no such namespace */ } if (0 != UNLINK (fileName)) { GNUNET_GE_LOG_STRERROR_FILE (ectx, GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK, "unlink", fileName); GNUNET_free (fileName); return GNUNET_SYSERR; } GNUNET_free (fileName); return GNUNET_OK;}/** * Write the private key of the namespace to a file. */static intwrite_namespace_key (struct GNUNET_GC_Configuration *cfg, const struct GNUNET_RSA_PrivateKey *key){ GNUNET_RSA_PrivateKeyEncoded *namespace_priv_key_encoded; char *fileName; GNUNET_RSA_PublicKey pubk; GNUNET_HashCode pid; GNUNET_RSA_get_public_key (key, &pubk); GNUNET_hash (&pubk, sizeof (GNUNET_RSA_PublicKey), &pid); fileName = getPseudonymFileName (NULL, cfg, &pid); if (GNUNET_YES == GNUNET_disk_file_test (NULL, fileName)) { GNUNET_GE_BREAK (NULL, 0); /* hash collision!? */ GNUNET_free (fileName); return GNUNET_SYSERR; } namespace_priv_key_encoded = GNUNET_RSA_encode_key (key); GNUNET_disk_file_write (NULL, fileName, (const char *) namespace_priv_key_encoded, ntohs (namespace_priv_key_encoded->len), "600"); GNUNET_free (fileName); GNUNET_free (namespace_priv_key_encoded); return GNUNET_OK;}/** * Create a new namespace (and publish an advertismement). * This publishes both an GNUNET_EC_NBlock in the namespace itself * as well as KNBlocks under all keywords specified in * the advertisementURI. * * @param anonymity_level for the namespace advertismement * @param priority for the namespace advertisement * @param expiration for the namespace advertisement * @param advertisementURI the keyword (!) URI to advertise the * namespace under (GNUNET_EC_KNBlock) * @param meta meta-data for the namespace advertisement * (will be used to derive a name) * @param rootEntry name of the root entry in the namespace (for * the namespace advertisement) * @param rootURI set to the URI of the namespace, NULL if * no advertisement was created * * @return URI on success, NULL on error */struct GNUNET_ECRS_URI *GNUNET_ECRS_namespace_create (struct GNUNET_GE_Context *ectx, struct GNUNET_GC_Configuration *cfg, const struct GNUNET_MetaData *meta, unsigned int anonymityLevel, unsigned int priority, GNUNET_CronTime expiration, const struct GNUNET_ECRS_URI *advertisementURI, const char *rootEntry){ struct GNUNET_ECRS_URI *rootURI; struct GNUNET_RSA_PrivateKey *namespace_priv_key; GNUNET_HashCode hc; struct GNUNET_ClientServerConnection *sock; GNUNET_DatastoreValue *value; GNUNET_DatastoreValue *knvalue; unsigned int size; unsigned int mdsize; struct GNUNET_RSA_PrivateKey *pk; GNUNET_EC_SBlock *sb; GNUNET_EC_KSBlock *ksb; char **keywords; const char *keyword; unsigned int keywordCount; int i; char *cpy; char *rtgt; if ((advertisementURI != NULL) && (!GNUNET_ECRS_uri_test_ksk (advertisementURI))) { GNUNET_GE_BREAK (ectx, 0); return NULL; } namespace_priv_key = GNUNET_RSA_create_key (); if (GNUNET_OK != write_namespace_key (cfg, namespace_priv_key)) { GNUNET_RSA_free_key (namespace_priv_key); return NULL; } /* create advertisements */ mdsize = GNUNET_meta_data_get_serialized_size (meta, GNUNET_SERIALIZE_PART); size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2; if (size > MAX_SBLOCK_SIZE) { size = MAX_SBLOCK_SIZE; mdsize = size - sizeof (GNUNET_EC_SBlock) - strlen (rootEntry) - 2; } value = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size); memset (value, 0, sizeof (GNUNET_DatastoreValue) + size); sb = (GNUNET_EC_SBlock *) & value[1]; sb->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED); GNUNET_RSA_get_public_key (namespace_priv_key, &sb->subspace); rtgt = (char *) &sb[1]; memcpy (rtgt, rootEntry, strlen (rootEntry) + 1); mdsize = GNUNET_meta_data_serialize (ectx, meta, &rtgt[strlen (rootEntry) + 2], mdsize, GNUNET_SERIALIZE_PART); if (mdsize == -1) { GNUNET_GE_BREAK (ectx, 0); GNUNET_RSA_free_key (namespace_priv_key); GNUNET_free (value); return NULL; } size = mdsize + sizeof (GNUNET_EC_SBlock) + strlen (rootEntry) + 2; GNUNET_GE_ASSERT (ectx, GNUNET_OK == GNUNET_RSA_sign (namespace_priv_key, size - sizeof (GNUNET_RSA_Signature) - sizeof (GNUNET_RSA_PublicKey) - sizeof (unsigned int), &sb->identifier, &sb->signature)); value->size = htonl (sizeof (GNUNET_DatastoreValue) + size); value->type = htonl (GNUNET_ECRS_BLOCKTYPE_SIGNED); value->priority = htonl (priority); value->anonymity_level = htonl (anonymityLevel); value->expiration_time = GNUNET_htonll (expiration); sock = GNUNET_client_connection_create (ectx, cfg); if (GNUNET_OK != GNUNET_FS_insert (sock, value)) { GNUNET_GE_BREAK (ectx, 0); GNUNET_free (value); GNUNET_client_connection_destroy (sock); GNUNET_RSA_free_key (namespace_priv_key); return NULL; } /* publish KNBlocks */ size += sizeof (GNUNET_EC_KSBlock) - sizeof (GNUNET_EC_SBlock); knvalue = GNUNET_malloc (sizeof (GNUNET_DatastoreValue) + size); *knvalue = *value; knvalue->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED); knvalue->size = htonl (sizeof (GNUNET_DatastoreValue) + size); ksb = (GNUNET_EC_KSBlock *) & knvalue[1]; ksb->type = htonl (GNUNET_ECRS_BLOCKTYPE_KEYWORD_SIGNED); memcpy (&ksb->sblock, sb, sizeof (GNUNET_EC_SBlock) + mdsize + strlen (rootEntry) + 2); if (advertisementURI != NULL) { keywords = advertisementURI->data.ksk.keywords; keywordCount = advertisementURI->data.ksk.keywordCount; cpy = GNUNET_malloc (size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int)); memcpy (cpy, &ksb->sblock, size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int)); for (i = 0; i < keywordCount; i++) { keyword = keywords[i]; /* first character of keyword indicates mandatory or not -- ignore for hashing! */ GNUNET_hash (&keyword[1], strlen (&keyword[1]), &hc); pk = GNUNET_RSA_create_key_from_hash (&hc); GNUNET_RSA_get_public_key (pk, &ksb->kblock.keyspace); GNUNET_GE_ASSERT (ectx, size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int) == sizeof (GNUNET_EC_SBlock) + mdsize + strlen (rootEntry) + 2); GNUNET_ECRS_encryptInPlace (&hc, &ksb->sblock, size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned int)); GNUNET_GE_ASSERT (ectx, GNUNET_OK == GNUNET_RSA_sign (pk, size - sizeof (GNUNET_EC_KBlock) - sizeof (unsigned
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -