From 2768306ebbaee4936fdd57398f2f54e7e4018b1f Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 1 Mar 2012 08:24:17 +0000 Subject: [PATCH] LRN: updates to pseudonym API from #1952, change pseudonym management --- src/chat/gnunet-chat.c | 96 ++++++++++++-- src/fs/fs_uri.c | 12 +- src/fs/gnunet-pseudonym.c | 23 +++- src/include/gnunet_pseudonym_lib.h | 72 ++++++++++- src/util/pseudonym.c | 201 +++++++++++++++++++++-------- src/util/test_pseudonym.c | 30 ++++- 6 files changed, 344 insertions(+), 90 deletions(-) diff --git a/src/chat/gnunet-chat.c b/src/chat/gnunet-chat.c index 4abc58c9f..fb958d98a 100644 --- a/src/chat/gnunet-chat.c +++ b/src/chat/gnunet-chat.c @@ -114,14 +114,27 @@ receive_cb (void *cls, struct GNUNET_CHAT_Room *room, const char *message, struct GNUNET_TIME_Absolute timestamp, enum GNUNET_CHAT_MsgOptions options) { + char *non_unique_nick; char *nick; + int nick_is_a_dup; char *time; const char *fmt; - if (NULL != sender) - nick = GNUNET_PSEUDONYM_id_to_name (cfg, sender); - else + if (NULL == sender) nick = GNUNET_strdup (_("anonymous")); + else + { + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + sender, NULL, NULL, &non_unique_nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (non_unique_nick); + non_unique_nick = GNUNET_strdup (_("anonymous")); + } + nick = GNUNET_PSEUDONYM_name_uniquify (cfg, sender, non_unique_nick, NULL); + GNUNET_free (non_unique_nick); + } + fmt = NULL; switch ((int) options) { @@ -188,9 +201,20 @@ confirmation_cb (void *cls, struct GNUNET_CHAT_Room *room, const GNUNET_HashCode * receiver) { char *nick; + char *unique_nick; + int nick_is_a_dup; - nick = GNUNET_PSEUDONYM_id_to_name (cfg, receiver); - FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), nick, orig_seq_number); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + receiver, NULL, NULL, &nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (nick); + nick = GNUNET_strdup (_("anonymous")); + } + unique_nick = GNUNET_PSEUDONYM_name_uniquify (cfg, receiver, nick, NULL); + GNUNET_free (nick); + FPRINTF (stdout, _("'%s' acknowledged message #%d\n"), unique_nick, orig_seq_number); + GNUNET_free (unique_nick); return GNUNET_OK; } @@ -210,7 +234,8 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *member_id, enum GNUNET_CHAT_MsgOptions options) { - char *nick; + char *nick, *non_unique_nick; + int nick_is_a_dup; GNUNET_HashCode id; struct UserList *pos; struct UserList *prev; @@ -218,7 +243,16 @@ member_list_cb (void *cls, const struct GNUNET_CONTAINER_MetaData *member_info, GNUNET_CRYPTO_hash (member_id, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &id); - nick = GNUNET_PSEUDONYM_id_to_name (cfg, &id); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &id, NULL, NULL, &non_unique_nick, &nick_is_a_dup) + || (nick_is_a_dup == GNUNET_YES)) + { + GNUNET_free (non_unique_nick); + non_unique_nick = GNUNET_strdup (_("anonymous")); + } + nick = GNUNET_PSEUDONYM_name_uniquify (cfg, &id, non_unique_nick, NULL); + GNUNET_free (non_unique_nick); + FPRINTF (stdout, member_info != NULL ? _("`%s' entered the room\n") : _("`%s' left the room\n"), @@ -267,6 +301,7 @@ static int do_join (const char *arg, const void *xtra) { char *my_name; + int my_name_is_a_dup; GNUNET_HashCode me; if (arg[0] == '#') @@ -284,7 +319,16 @@ do_join (const char *arg, const void *xtra) FPRINTF (stdout, "%s", _("Could not change username\n")); return GNUNET_SYSERR; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } + /* Don't uniquify our own name - other people will have a different + * suffix for our own name anyway. + */ FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); GNUNET_free (my_name); @@ -296,6 +340,7 @@ static int do_nick (const char *msg, const void *xtra) { char *my_name; + int my_name_is_a_dup; GNUNET_HashCode me; GNUNET_CHAT_leave_room (room); @@ -316,7 +361,13 @@ do_nick (const char *msg, const void *xtra) FPRINTF (stdout, "%s", _("Could not change username\n")); return GNUNET_SYSERR; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } FPRINTF (stdout, _("Changed username to `%s'\n"), my_name); GNUNET_free (my_name); return GNUNET_OK; @@ -327,6 +378,8 @@ static int do_names (const char *msg, const void *xtra) { char *name; + char *unique_name; + int name_is_a_dup; struct UserList *pos; GNUNET_HashCode pid; @@ -337,9 +390,17 @@ do_names (const char *msg, const void *xtra) GNUNET_CRYPTO_hash (&pos->pkey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pid); - name = GNUNET_PSEUDONYM_id_to_name (cfg, &pid); - FPRINTF (stdout, "`%s' ", name); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &pid, NULL, NULL, &name, &name_is_a_dup) + || (name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (name); + name = GNUNET_strdup (_("anonymous")); + } + unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &pid, name, NULL); GNUNET_free (name); + FPRINTF (stdout, "`%s' ", unique_name); + GNUNET_free (unique_name); pos = pos->next; } FPRINTF (stdout, "%s", "\n"); @@ -376,7 +437,9 @@ do_send_pm (const char *msg, const void *xtra) msg += strlen (user) + 1; if (GNUNET_OK != GNUNET_PSEUDONYM_name_to_id (cfg, user, &uid)) { - FPRINTF (stderr, _("Unknown user `%s'\n"), user); + FPRINTF (stderr, + _("Unknown user `%s'. Make sure you specify its numeric suffix, if any.\n"), + user); GNUNET_free (user); return GNUNET_OK; } @@ -598,6 +661,7 @@ run (void *cls, char *const *args, const char *cfgfile, { GNUNET_HashCode me; char *my_name; + int my_name_is_a_dup; cfg = c; /* check arguments */ @@ -626,7 +690,13 @@ run (void *cls, char *const *args, const char *cfgfile, ret = -1; return; } - my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); + if ((GNUNET_OK != GNUNET_PSEUDONYM_get_info (cfg, + &me, NULL, NULL, &my_name, &my_name_is_a_dup)) || + (my_name_is_a_dup == GNUNET_YES)) + { + GNUNET_free (my_name); + my_name = GNUNET_strdup (_("anonymous")); + } FPRINTF (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); GNUNET_free (my_name); diff --git a/src/fs/fs_uri.c b/src/fs/fs_uri.c index 5dfdcb54d..43cf2c5bd 100644 --- a/src/fs/fs_uri.c +++ b/src/fs/fs_uri.c @@ -1377,15 +1377,17 @@ GNUNET_FS_uri_sks_to_string_fancy (struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_FS_Uri *uri) { char *ret; - char *name; + char *name, *unique_name; + int getinfo_result; if (uri->type != sks) return NULL; - name = GNUNET_PSEUDONYM_id_to_name (cfg, &uri->data.sks.namespace); - if (name == NULL) - return GNUNET_FS_uri_to_string (uri); - GNUNET_asprintf (&ret, "%s: %s", name, uri->data.sks.identifier); + getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, &uri->data.sks.namespace, + NULL, NULL, &name, NULL); + unique_name = GNUNET_PSEUDONYM_name_uniquify (cfg, &uri->data.sks.namespace, name, NULL); GNUNET_free (name); + GNUNET_asprintf (&ret, "%s: %s", unique_name, uri->data.sks.identifier); + GNUNET_free (unique_name); return ret; } diff --git a/src/fs/gnunet-pseudonym.c b/src/fs/gnunet-pseudonym.c index 412ddd2b0..247a5a0d8 100644 --- a/src/fs/gnunet-pseudonym.c +++ b/src/fs/gnunet-pseudonym.c @@ -106,20 +106,28 @@ ns_printer (void *cls, const char *name, const GNUNET_HashCode * id) static int pseudo_printer (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { - char *id; - - id = GNUNET_PSEUDONYM_id_to_name (cfg, pseudonym); - if (id == NULL) + char *id, *unique_id; + int getinfo_result; + + /* While we get a name from the caller, it might be NULL. + * GNUNET_PSEUDONYM_get_info () never returns NULL. + */ + getinfo_result = GNUNET_PSEUDONYM_get_info (cfg, pseudonym, + NULL, NULL, &id, NULL); + if (getinfo_result != GNUNET_OK) { GNUNET_break (0); return GNUNET_OK; } - FPRINTF (stdout, "%s (%d):\n", id, rating); + unique_id = GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym, id, NULL); + GNUNET_free (id); + FPRINTF (stdout, "%s (%d):\n", unique_id, rating); GNUNET_CONTAINER_meta_data_iterate (md, &EXTRACTOR_meta_data_print, stdout); FPRINTF (stdout, "%s", "\n"); - GNUNET_free (id); + GNUNET_free (unique_id); return GNUNET_OK; } @@ -162,7 +170,8 @@ post_advertising (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg) } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Namespace `%s' unknown.\n"), + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + ("Namespace `%s' unknown. Make sure you specify its numeric suffix, if any.\n"), rating_change); } } diff --git a/src/include/gnunet_pseudonym_lib.h b/src/include/gnunet_pseudonym_lib.h index bde98ef8f..8fd938da8 100644 --- a/src/include/gnunet_pseudonym_lib.h +++ b/src/include/gnunet_pseudonym_lib.h @@ -44,12 +44,16 @@ extern "C" * * @param cls closure * @param pseudonym hash code of public key of pseudonym + * @param name name of the pseudonym (might be NULL) + * @param unique_name unique name of the pseudonym (might be NULL) * @param md meta data known about the pseudonym * @param rating the local rating of the pseudonym * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort */ typedef int (*GNUNET_PSEUDONYM_Iterator) (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, + const char *unique_name, const struct GNUNET_CONTAINER_MetaData * md, int rating); @@ -110,22 +114,76 @@ GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator iterator, void *closure); /** - * Return the unique, human readable name for the given pseudonym. + * Return unique variant of the namespace name. + * Use after GNUNET_PSEUDONYM_id_to_name() to make sure + * that name is unique. * - * @return NULL on failure (should never happen) + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param name name to uniquify + * @param suffix if not NULL, filled with the suffix value + * @return NULL on failure (should never happen), name on success. + * Free the name with GNUNET_free(). */ char * -GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, - const GNUNET_HashCode * pseudo); +GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix); /** - * Get the pseudonym ID belonging to the given human readable name. + * Get namespace name, metadata and rank + * This is a wrapper around internal read_info() call, and ensures that + * returned data is not invalid (not NULL). + * Writing back information returned by this function will give + * a name "no-name" to pseudonyms that have no name. This side-effect is + * unavoidable, but hardly harmful. * - * @return GNUNET_OK on success + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param ret_meta a location to store metadata pointer. NULL, if metadata + * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). + * @param ret_rank a location to store rank. NULL, if rank not needed. + * @param ret_name a location to store human-readable name. Name is not unique. + * NULL, if name is not needed. Free with GNUNET_free(). + * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with + * a duplicate of a "no-name" placeholder + * @return GNUNET_OK on success. GNUENT_SYSERR if the data was + * unobtainable (in that case ret_* are filled with placeholders - + * empty metadata container, rank -1 and a "no-name" name). + */ +int +GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, + int32_t *ret_rank, char **ret_name, int *name_is_a_dup); + + +/** + * Get the namespace ID belonging to the given namespace name. + * + * @param cfg configuration to use + * @param ns_uname unique (!) human-readable name for the namespace + * @param nsid set to namespace ID based on 'ns_uname' + * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *hname, GNUNET_HashCode * psid); + const char *ns_uname, GNUNET_HashCode * nsid); + +/** + * Set the pseudonym metadata, rank and name. + * + * @param cfg overall configuration + * @param nsid id of the pseudonym + * @param name name to set. Must be the non-unique version of it. + * May be NULL, in which case it erases pseudonym's name! + * @param md metadata to set + * May be NULL, in which case it erases pseudonym's metadata! + * @param rank rank to assign + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, + const struct GNUNET_CONTAINER_MetaData *md, int rank); #if 0 /* keep Emacsens' auto-indent happy */ diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c index 782a405fc..dd8ad08b3 100644 --- a/src/util/pseudonym.c +++ b/src/util/pseudonym.c @@ -96,7 +96,7 @@ internal_notify (const GNUNET_HashCode * id, pos = head; while (pos != NULL) { - pos->callback (pos->closure, id, md, rating); + pos->callback (pos->closure, id, NULL, NULL, md, rating); pos = pos->next; } } @@ -104,6 +104,9 @@ internal_notify (const GNUNET_HashCode * id, /** * Register callback to be invoked whenever we discover * a new pseudonym. + * Will immediately call provided iterator callback for all + * already discovered pseudonyms. + * * @param cfg configuration to use * @param iterator iterator over pseudonym * @param closure point to a closure @@ -185,7 +188,7 @@ get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, * @param nsid hash code of a pseudonym * @param meta meta data to be written into a file * @param ranking ranking of a pseudonym - * @param ns_name name of a pseudonym + * @param ns_name non-unique name of a pseudonym */ static void write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, @@ -219,9 +222,9 @@ write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, } GNUNET_free (fn); /* create entry for pseudonym name in names */ - /* FIXME: 90% of what this call does is not needed - * here => refactor code to only create the entry! */ - GNUNET_free_non_null (GNUNET_PSEUDONYM_id_to_name (cfg, nsid)); + if (ns_name != NULL) + GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name, + NULL)); } @@ -285,57 +288,31 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_OK; } - - /** - * Return the unique, human readable name for the given namespace. + * Return unique variant of the namespace name. + * Use it after GNUNET_PSEUDONYM_get_info() to make sure + * that name is unique. * * @param cfg configuration * @param nsid cryptographic ID of the namespace - * @return NULL on failure (should never happen) + * @param name name to uniquify + * @param suffix if not NULL, filled with the suffix value + * @return NULL on failure (should never happen), name on success. + * Free the name with GNUNET_free(). */ char * -GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, - const GNUNET_HashCode * nsid) +GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, unsigned int *suffix) { - struct GNUNET_CONTAINER_MetaData *meta; - char *name; GNUNET_HashCode nh; - char *fn; uint64_t len; + char *fn; struct GNUNET_DISK_FileHandle *fh; unsigned int i; unsigned int idx; char *ret; struct stat sbuf; - int32_t temp = 0; - int32_t *rank = &temp; - meta = NULL; - name = NULL; - if (GNUNET_OK == read_info (cfg, nsid, &meta, rank, &name)) - { - if ((meta != NULL) && (name == NULL)) - name = - GNUNET_CONTAINER_meta_data_get_first_by_types (meta, - EXTRACTOR_METATYPE_TITLE, - EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, - EXTRACTOR_METATYPE_FILENAME, - EXTRACTOR_METATYPE_DESCRIPTION, - EXTRACTOR_METATYPE_SUBJECT, - EXTRACTOR_METATYPE_PUBLISHER, - EXTRACTOR_METATYPE_AUTHOR_NAME, - EXTRACTOR_METATYPE_COMMENT, - EXTRACTOR_METATYPE_SUMMARY, - -1); - if (meta != NULL) - { - GNUNET_CONTAINER_meta_data_destroy (meta); - meta = NULL; - } - } - if (name == NULL) - name = GNUNET_strdup (_("no-name")); GNUNET_CRYPTO_hash (name, strlen (name), &nh); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); GNUNET_assert (fn != NULL); @@ -372,22 +349,107 @@ GNUNET_PSEUDONYM_id_to_name (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_DISK_file_close (fh); ret = GNUNET_malloc (strlen (name) + 32); GNUNET_snprintf (ret, strlen (name) + 32, "%s-%u", name, idx); - GNUNET_free (name); + if (suffix != NULL) + *suffix = idx; GNUNET_free (fn); return ret; } +/** + * Get namespace name, metadata and rank + * This is a wrapper around internal read_info() call, and ensures that + * returned data is not invalid (not NULL). + * + * @param cfg configuration + * @param nsid cryptographic ID of the namespace + * @param ret_meta a location to store metadata pointer. NULL, if metadata + * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). + * @param ret_rank a location to store rank. NULL, if rank not needed. + * @param ret_name a location to store human-readable name. Name is not unique. + * NULL, if name is not needed. Free with GNUNET_free(). + * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with + * a duplicate of a "no-name" placeholder + * @return GNUNET_OK on success. GNUENT_SYSERR if the data was + * unobtainable (in that case ret_* are filled with placeholders - + * empty metadata container, rank -1 and a "no-name" name). + */ +int +GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, + int32_t *ret_rank, char **ret_name, int *name_is_a_dup) +{ + struct GNUNET_CONTAINER_MetaData *meta; + char *name; + int32_t rank = -1; + + meta = NULL; + name = NULL; + if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name)) + { + if ((meta != NULL) && (name == NULL)) + name = + GNUNET_CONTAINER_meta_data_get_first_by_types (meta, + EXTRACTOR_METATYPE_TITLE, + EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME, + EXTRACTOR_METATYPE_FILENAME, + EXTRACTOR_METATYPE_DESCRIPTION, + EXTRACTOR_METATYPE_SUBJECT, + EXTRACTOR_METATYPE_PUBLISHER, + EXTRACTOR_METATYPE_AUTHOR_NAME, + EXTRACTOR_METATYPE_COMMENT, + EXTRACTOR_METATYPE_SUMMARY, + -1); + if (ret_name != NULL) + { + if (name == NULL) + { + name = GNUNET_strdup (_("no-name")); + if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_YES; + } + else if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_NO; + *ret_name = name; + } + else if (name != NULL) + GNUNET_free (name); + + if (ret_meta != NULL) + { + if (meta == NULL) + meta = GNUNET_CONTAINER_meta_data_create (); + *ret_meta = meta; + } + else if (meta != NULL) + GNUNET_CONTAINER_meta_data_destroy (meta); + + if (ret_rank != NULL) + *ret_rank = rank; + + return GNUNET_OK; + } + if (ret_name != NULL) + *ret_name = GNUNET_strdup (_("no-name")); + if (ret_meta != NULL) + *ret_meta = GNUNET_CONTAINER_meta_data_create (); + if (ret_rank != NULL) + *ret_rank = -1; + if (name_is_a_dup != NULL) + *name_is_a_dup = GNUNET_YES; + return GNUNET_SYSERR; +} + /** * Get the namespace ID belonging to the given namespace name. * * @param cfg configuration to use - * @param ns_uname human-readable name for the namespace + * @param ns_uname unique (!) human-readable name for the namespace * @param nsid set to namespace ID based on 'ns_uname' - * @return GNUNET_OK on success + * @return GNUNET_OK on success, GNUNET_SYSERR on failure */ int GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *ns_uname, GNUNET_HashCode * nsid) + const char *ns_uname, GNUNET_HashCode * nsid) { size_t slen; uint64_t len; @@ -405,6 +467,7 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, return GNUNET_SYSERR; name = GNUNET_strdup (ns_uname); name[slen - 1] = '\0'; + GNUNET_CRYPTO_hash (name, strlen (name), &nh); GNUNET_free (name); fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); @@ -472,10 +535,10 @@ list_pseudonym_helper (void *cls, const char *fullname) struct ListPseudonymClosure *c = cls; int ret; GNUNET_HashCode id; - int rating; + int32_t rating; struct GNUNET_CONTAINER_MetaData *meta; const char *fn; - char *str; + char *str, *name_unique; if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) return GNUNET_OK; @@ -487,11 +550,22 @@ list_pseudonym_helper (void *cls, const char *fullname) if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id)) return GNUNET_OK; /* invalid name */ str = NULL; - if (GNUNET_OK != read_info (c->cfg, &id, &meta, &rating, &str)) - return GNUNET_OK; /* ignore entry */ - GNUNET_free_non_null (str); + if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating, + &str, NULL)) + { + /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason + * to ignore it... So yeah, it will have placeholders instead of name, + * empty metadata container and a default rank == -1, so what? We know + * its nsid - that's all we really need. Right? */ + GNUNET_free (str); + GNUNET_CONTAINER_meta_data_destroy (meta); + return GNUNET_OK; + } + name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL); if (c->iterator != NULL) - ret = c->iterator (c->closure, &id, meta, rating); + ret = c->iterator (c->closure, &id, str, name_unique, meta, rating); + GNUNET_free_non_null (str); + GNUNET_free_non_null (name_unique); GNUNET_CONTAINER_meta_data_destroy (meta); return ret; } @@ -558,6 +632,31 @@ GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, } +/** + * Set the pseudonym metadata, rank and name. + * + * @param cfg overall configuration + * @param nsid id of the pseudonym + * @param name name to set. Must be the non-unique version of it. + * May be NULL, in which case it erases pseudonym's name! + * @param md metadata to set + * May be NULL, in which case it erases pseudonym's metadata! + * @param rank rank to assign + * @return GNUNET_OK on success, GNUNET_SYSERR on failure + */ +int +GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, + const GNUNET_HashCode * nsid, const char *name, + const struct GNUNET_CONTAINER_MetaData *md, int rank) +{ + GNUNET_assert (cfg != NULL); + GNUNET_assert (nsid != NULL); + + write_pseudonym_info (cfg, nsid, md, rank, name); + return GNUNET_OK; +} + + /** * Add a pseudonym to the set of known pseudonyms. * For all pseudonym advertisements that we discover diff --git a/src/util/test_pseudonym.c b/src/util/test_pseudonym.c index 20a3d3d96..4ce8b3853 100644 --- a/src/util/test_pseudonym.c +++ b/src/util/test_pseudonym.c @@ -39,6 +39,7 @@ static GNUNET_HashCode id1; static int iter (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ok = cls; @@ -54,6 +55,7 @@ iter (void *cls, const GNUNET_HashCode * pseudonym, static int noti_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ret = cls; @@ -64,6 +66,7 @@ noti_callback (void *cls, const GNUNET_HashCode * pseudonym, static int fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { int *ret = cls; @@ -74,6 +77,7 @@ fake_noti_callback (void *cls, const GNUNET_HashCode * pseudonym, static int false_callback (void *cls, const GNUNET_HashCode * pseudonym, + const char *name, const char *unique_name, const struct GNUNET_CONTAINER_MetaData *md, int rating) { return GNUNET_OK; @@ -95,7 +99,10 @@ main (int argc, char *argv[]) char *name1; char *name2; char *name3; + char *name1_unique; + char *name2_unique; char *noname; + int noname_is_a_dup; int notiCount, fakenotiCount; int count; static char m[1024 * 1024 * 10]; @@ -152,15 +159,21 @@ main (int argc, char *argv[]) strlen (m) + 1)); GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &id3); GNUNET_PSEUDONYM_add (cfg, &id3, meta); - name3 = GNUNET_PSEUDONYM_id_to_name (cfg, &id3); - name2 = GNUNET_PSEUDONYM_id_to_name (cfg, &id2); + GNUNET_PSEUDONYM_get_info (cfg, &id3, NULL, NULL, &name3, NULL); + CHECK (name3 != NULL); + GNUNET_PSEUDONYM_get_info (cfg, &id2, NULL, NULL, &name2, NULL); CHECK (name2 != NULL); - name1 = GNUNET_PSEUDONYM_id_to_name (cfg, &id1); + GNUNET_PSEUDONYM_get_info (cfg, &id1, NULL, NULL, &name1, NULL); CHECK (name1 != NULL); - CHECK (0 != strcmp (name1, name2)); + CHECK (0 == strcmp (name1, name2)); + name1_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id1, name1, NULL); + name2_unique = GNUNET_PSEUDONYM_name_uniquify (cfg, &id2, name2, NULL); + CHECK (0 != strcmp (name1_unique, name2_unique)); CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, "fake", &rid2)); - CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); - CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); + CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name2, &rid2)); + CHECK (GNUNET_SYSERR == GNUNET_PSEUDONYM_name_to_id (cfg, name1, &rid1)); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name2_unique, &rid2)); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_name_to_id (cfg, name1_unique, &rid1)); CHECK (0 == memcmp (&id1, &rid1, sizeof (GNUNET_HashCode))); CHECK (0 == memcmp (&id2, &rid2, sizeof (GNUNET_HashCode))); @@ -168,14 +181,17 @@ main (int argc, char *argv[]) GNUNET_log_skip (1, GNUNET_NO); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &fid, 0)); GNUNET_log_skip (0, GNUNET_YES); - noname = GNUNET_PSEUDONYM_id_to_name (cfg, &fid); + CHECK (GNUNET_OK == GNUNET_PSEUDONYM_get_info (cfg, &fid, NULL, NULL, &noname, &noname_is_a_dup)); CHECK (noname != NULL); + CHECK (noname_is_a_dup == GNUNET_YES); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 0)); CHECK (5 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); CHECK (-5 == GNUNET_PSEUDONYM_rank (cfg, &id1, -10)); CHECK (0 == GNUNET_PSEUDONYM_rank (cfg, &id1, 5)); GNUNET_free (name1); GNUNET_free (name2); + GNUNET_free (name1_unique); + GNUNET_free (name2_unique); GNUNET_free (name3); GNUNET_free (noname); /* END OF TEST CODE */ -- 2.25.1