diff options
Diffstat (limited to 'src/util/pseudonym.c')
-rw-r--r-- | src/util/pseudonym.c | 669 |
1 files changed, 452 insertions, 217 deletions
diff --git a/src/util/pseudonym.c b/src/util/pseudonym.c index fa48e19e3..02600cd6d 100644 --- a/src/util/pseudonym.c +++ b/src/util/pseudonym.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2003, 2004, 2005, 2006, 2007, 2008 Christian Grothoff (and other contributing authors) | 3 | (C) 2003, 2004, 2005, 2006, 2007, 2008, 2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -17,19 +17,22 @@ | |||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | |||
21 | /** | 20 | /** |
22 | * @file util/pseudonym.c | 21 | * @file util/pseudonym.c |
23 | * @brief helper functions | 22 | * @brief helper functions |
24 | * @author Christian Grothoff | 23 | * @author Christian Grothoff |
24 | * | ||
25 | * TODO: | ||
26 | * - all cryptographic operations are currently NOT implemented and | ||
27 | * provided by stubs that merely pretend to work! | ||
25 | */ | 28 | */ |
26 | |||
27 | #include "platform.h" | 29 | #include "platform.h" |
28 | #include "gnunet_common.h" | 30 | #include "gnunet_common.h" |
29 | #include "gnunet_container_lib.h" | 31 | #include "gnunet_container_lib.h" |
30 | #include "gnunet_disk_lib.h" | 32 | #include "gnunet_disk_lib.h" |
31 | #include "gnunet_pseudonym_lib.h" | 33 | #include "gnunet_pseudonym_lib.h" |
32 | #include "gnunet_bio_lib.h" | 34 | #include "gnunet_bio_lib.h" |
35 | #include <gcrypt.h> | ||
33 | 36 | ||
34 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) | 37 | #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) |
35 | 38 | ||
@@ -38,12 +41,12 @@ | |||
38 | /** | 41 | /** |
39 | * Name of the directory which stores meta data for pseudonym | 42 | * Name of the directory which stores meta data for pseudonym |
40 | */ | 43 | */ |
41 | #define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms" DIR_SEPARATOR_STR "metadata" DIR_SEPARATOR_STR | 44 | #define PS_METADATA_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym" DIR_SEPARATOR_STR "metadata" DIR_SEPARATOR_STR |
42 | 45 | ||
43 | /** | 46 | /** |
44 | * Name of the directory which stores names for pseudonyms | 47 | * Name of the directory which stores names for pseudonyms |
45 | */ | 48 | */ |
46 | #define PS_NAMES_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonyms" DIR_SEPARATOR_STR "names" DIR_SEPARATOR_STR | 49 | #define PS_NAMES_DIR DIR_SEPARATOR_STR "data" DIR_SEPARATOR_STR "pseudonym" DIR_SEPARATOR_STR "names" DIR_SEPARATOR_STR |
47 | 50 | ||
48 | 51 | ||
49 | /** | 52 | /** |
@@ -52,16 +55,22 @@ | |||
52 | #define GNUNET_CLIENT_SERVICE_NAME "client" | 55 | #define GNUNET_CLIENT_SERVICE_NAME "client" |
53 | 56 | ||
54 | 57 | ||
58 | /* ************************* Disk operations (pseudonym data mgmt) **************** */ | ||
55 | 59 | ||
56 | /** | 60 | /** |
57 | * Registered callbacks for discovery of pseudonyms. | 61 | * Registered callbacks for discovery of pseudonyms. |
58 | */ | 62 | */ |
59 | struct DiscoveryCallback | 63 | struct GNUNET_PSEUDONYM_DiscoveryHandle |
60 | { | 64 | { |
61 | /** | 65 | /** |
62 | * This is a linked list. | 66 | * This is a doubly linked list. |
63 | */ | 67 | */ |
64 | struct DiscoveryCallback *next; | 68 | struct GNUNET_PSEUDONYM_DiscoveryHandle *next; |
69 | |||
70 | /** | ||
71 | * This is a doubly linked list. | ||
72 | */ | ||
73 | struct GNUNET_PSEUDONYM_DiscoveryHandle *prev; | ||
65 | 74 | ||
66 | /** | 75 | /** |
67 | * Function to call each time a pseudonym is discovered. | 76 | * Function to call each time a pseudonym is discovered. |
@@ -71,7 +80,7 @@ struct DiscoveryCallback | |||
71 | /** | 80 | /** |
72 | * Closure for callback. | 81 | * Closure for callback. |
73 | */ | 82 | */ |
74 | void *closure; | 83 | void *callback_cls; |
75 | }; | 84 | }; |
76 | 85 | ||
77 | 86 | ||
@@ -79,28 +88,33 @@ struct DiscoveryCallback | |||
79 | * Head of the linked list of functions to call when | 88 | * Head of the linked list of functions to call when |
80 | * new pseudonyms are added. | 89 | * new pseudonyms are added. |
81 | */ | 90 | */ |
82 | static struct DiscoveryCallback *head; | 91 | static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_head; |
92 | |||
93 | /** | ||
94 | * Tail of the linked list of functions to call when | ||
95 | * new pseudonyms are added. | ||
96 | */ | ||
97 | static struct GNUNET_PSEUDONYM_DiscoveryHandle *disco_tail; | ||
98 | |||
83 | 99 | ||
84 | /** | 100 | /** |
85 | * Internal notification about new tracked URI. | 101 | * Internal notification about new tracked URI. |
86 | * @param id a point to the hash code of pseudonym | 102 | * |
103 | * @param pseudonym public key of the pseudonym | ||
87 | * @param md meta data to be written | 104 | * @param md meta data to be written |
88 | * @param rating rating of pseudonym | 105 | * @param rating rating of pseudonym |
89 | */ | 106 | */ |
90 | static void | 107 | static void |
91 | internal_notify (const struct GNUNET_HashCode * id, | 108 | internal_notify (const struct GNUNET_PseudonymIdentifier *pseudonym, |
92 | const struct GNUNET_CONTAINER_MetaData *md, int rating) | 109 | const struct GNUNET_CONTAINER_MetaData *md, int rating) |
93 | { | 110 | { |
94 | struct DiscoveryCallback *pos; | 111 | struct GNUNET_PSEUDONYM_DiscoveryHandle *pos; |
95 | 112 | ||
96 | pos = head; | 113 | for (pos = disco_head; NULL != pos; pos = pos->next) |
97 | while (pos != NULL) | 114 | pos->callback (pos->callback_cls, pseudonym, NULL, NULL, md, rating); |
98 | { | ||
99 | pos->callback (pos->closure, id, NULL, NULL, md, rating); | ||
100 | pos = pos->next; | ||
101 | } | ||
102 | } | 115 | } |
103 | 116 | ||
117 | |||
104 | /** | 118 | /** |
105 | * Register callback to be invoked whenever we discover | 119 | * Register callback to be invoked whenever we discover |
106 | * a new pseudonym. | 120 | * a new pseudonym. |
@@ -109,164 +123,197 @@ internal_notify (const struct GNUNET_HashCode * id, | |||
109 | * | 123 | * |
110 | * @param cfg configuration to use | 124 | * @param cfg configuration to use |
111 | * @param iterator iterator over pseudonym | 125 | * @param iterator iterator over pseudonym |
112 | * @param closure point to a closure | 126 | * @param iterator_cls point to a closure |
127 | * @return registration handle | ||
113 | */ | 128 | */ |
114 | int | 129 | struct GNUNET_PSEUDONYM_DiscoveryHandle * |
115 | GNUNET_PSEUDONYM_discovery_callback_register (const struct | 130 | GNUNET_PSEUDONYM_discovery_callback_register (const struct |
116 | GNUNET_CONFIGURATION_Handle *cfg, | 131 | GNUNET_CONFIGURATION_Handle *cfg, |
117 | GNUNET_PSEUDONYM_Iterator | 132 | GNUNET_PSEUDONYM_Iterator iterator, |
118 | iterator, void *closure) | 133 | void *iterator_cls) |
119 | { | 134 | { |
120 | struct DiscoveryCallback *list; | 135 | struct GNUNET_PSEUDONYM_DiscoveryHandle *dh; |
121 | 136 | ||
122 | list = GNUNET_malloc (sizeof (struct DiscoveryCallback)); | 137 | dh = GNUNET_malloc (sizeof (struct GNUNET_PSEUDONYM_DiscoveryHandle)); |
123 | list->callback = iterator; | 138 | dh->callback = iterator; |
124 | list->closure = closure; | 139 | dh->callback_cls = iterator_cls; |
125 | list->next = head; | 140 | GNUNET_CONTAINER_DLL_insert (disco_head, disco_tail, dh); |
126 | head = list; | 141 | GNUNET_PSEUDONYM_list_all (cfg, iterator, iterator_cls); |
127 | GNUNET_PSEUDONYM_list_all (cfg, iterator, closure); | 142 | return dh; |
128 | return GNUNET_OK; | ||
129 | } | 143 | } |
130 | 144 | ||
145 | |||
131 | /** | 146 | /** |
132 | * Unregister pseudonym discovery callback. | 147 | * Unregister pseudonym discovery callback. |
133 | * @param iterator iterator over pseudonym | 148 | * |
134 | * @param closure point to a closure | 149 | * @param dh registration to unregister |
135 | */ | 150 | */ |
136 | int | 151 | void |
137 | GNUNET_PSEUDONYM_discovery_callback_unregister (GNUNET_PSEUDONYM_Iterator | 152 | GNUNET_PSEUDONYM_discovery_callback_unregister (struct GNUNET_PSEUDONYM_DiscoveryHandle *dh) |
138 | iterator, void *closure) | ||
139 | { | 153 | { |
140 | struct DiscoveryCallback *prev; | 154 | GNUNET_CONTAINER_DLL_remove (disco_head, disco_tail, dh); |
141 | struct DiscoveryCallback *pos; | 155 | GNUNET_free (dh); |
142 | |||
143 | prev = NULL; | ||
144 | pos = head; | ||
145 | while ((pos != NULL) && | ||
146 | ((pos->callback != iterator) || (pos->closure != closure))) | ||
147 | { | ||
148 | prev = pos; | ||
149 | pos = pos->next; | ||
150 | } | ||
151 | if (pos == NULL) | ||
152 | return GNUNET_SYSERR; | ||
153 | if (prev == NULL) | ||
154 | head = pos->next; | ||
155 | else | ||
156 | prev->next = pos->next; | ||
157 | GNUNET_free (pos); | ||
158 | return GNUNET_OK; | ||
159 | } | 156 | } |
160 | 157 | ||
161 | 158 | ||
162 | /** | 159 | /** |
163 | * Get the filename (or directory name) for the given | 160 | * Get the filename (or directory name) for the given |
164 | * pseudonym identifier and directory prefix. | 161 | * pseudonym identifier and directory prefix. |
162 | * | ||
165 | * @param cfg configuration to use | 163 | * @param cfg configuration to use |
166 | * @param prefix path components to append to the private directory name | 164 | * @param prefix path components to append to the private directory name |
167 | * @param psid hash code of pseudonym, can be NULL | 165 | * @param pseudonym the pseudonym, can be NULL |
168 | * @return filename of the pseudonym (if psid != NULL) or directory with the data (if psid == NULL) | 166 | * @return filename of the pseudonym (if pseudonym != NULL) or directory with the data (if pseudonym == NULL) |
169 | */ | 167 | */ |
170 | static char * | 168 | static char * |
171 | get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, | 169 | get_data_filename (const struct GNUNET_CONFIGURATION_Handle *cfg, |
172 | const char *prefix, const struct GNUNET_HashCode * psid) | 170 | const char *prefix, |
171 | const struct GNUNET_PseudonymIdentifier *pseudonym) | ||
173 | { | 172 | { |
174 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; | 173 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; |
174 | struct GNUNET_HashCode psid; | ||
175 | 175 | ||
176 | if (psid != NULL) | 176 | if (NULL != pseudonym) |
177 | GNUNET_CRYPTO_hash_to_enc (psid, &enc); | 177 | { |
178 | return GNUNET_DISK_get_home_filename (cfg, GNUNET_CLIENT_SERVICE_NAME, prefix, | 178 | GNUNET_CRYPTO_hash (pseudonym, |
179 | (psid == | 179 | sizeof (struct GNUNET_PseudonymIdentifier), |
180 | NULL) ? NULL : (const char *) &enc, | 180 | &psid); |
181 | GNUNET_CRYPTO_hash_to_enc (&psid, &enc); | ||
182 | } | ||
183 | return GNUNET_DISK_get_home_filename (cfg, | ||
184 | GNUNET_CLIENT_SERVICE_NAME, prefix, | ||
185 | (NULL == pseudonym) | ||
186 | ? NULL | ||
187 | : (const char *) &enc, | ||
181 | NULL); | 188 | NULL); |
182 | } | 189 | } |
183 | 190 | ||
184 | 191 | ||
185 | /** | 192 | /** |
186 | * Write the pseudonym infomation into a file | 193 | * Get the filename (or directory name) for the given |
194 | * hash code and directory prefix. | ||
195 | * | ||
187 | * @param cfg configuration to use | 196 | * @param cfg configuration to use |
188 | * @param nsid hash code of a pseudonym | 197 | * @param prefix path components to append to the private directory name |
189 | * @param meta meta data to be written into a file | 198 | * @param hc some hash code |
190 | * @param ranking ranking of a pseudonym | 199 | * @return filename of the pseudonym (if hc != NULL) or directory with the data (if hc == NULL) |
191 | * @param ns_name non-unique name of a pseudonym | ||
192 | */ | 200 | */ |
193 | static void | 201 | static char * |
194 | write_pseudonym_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | 202 | get_data_filename_hash (const struct GNUNET_CONFIGURATION_Handle *cfg, |
195 | const struct GNUNET_HashCode * nsid, | 203 | const char *prefix, |
196 | const struct GNUNET_CONTAINER_MetaData *meta, | 204 | const struct GNUNET_HashCode *hc) |
197 | int32_t ranking, const char *ns_name) | 205 | { |
206 | struct GNUNET_CRYPTO_HashAsciiEncoded enc; | ||
207 | |||
208 | if (NULL != hc) | ||
209 | GNUNET_CRYPTO_hash_to_enc (hc, &enc); | ||
210 | return GNUNET_DISK_get_home_filename (cfg, | ||
211 | GNUNET_CLIENT_SERVICE_NAME, prefix, | ||
212 | (NULL == hc) | ||
213 | ? NULL | ||
214 | : (const char *) &enc, | ||
215 | NULL); | ||
216 | } | ||
217 | |||
218 | |||
219 | /** | ||
220 | * Set the pseudonym metadata, rank and name. | ||
221 | * Writes the pseudonym infomation into a file | ||
222 | * | ||
223 | * @param cfg overall configuration | ||
224 | * @param nsid id of the pseudonym | ||
225 | * @param name name to set. Must be the non-unique version of it. | ||
226 | * May be NULL, in which case it erases pseudonym's name! | ||
227 | * @param md metadata to set | ||
228 | * May be NULL, in which case it erases pseudonym's metadata! | ||
229 | * @param rank rank to assign | ||
230 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
231 | */ | ||
232 | int | ||
233 | GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
234 | const struct GNUNET_PseudonymIdentifier *pseudonym, | ||
235 | const char *name, | ||
236 | const struct GNUNET_CONTAINER_MetaData *md, | ||
237 | int32_t rank) | ||
198 | { | 238 | { |
199 | char *fn; | 239 | char *fn; |
200 | struct GNUNET_BIO_WriteHandle *fileW; | 240 | struct GNUNET_BIO_WriteHandle *fileW; |
201 | 241 | ||
202 | fn = get_data_filename (cfg, PS_METADATA_DIR, nsid); | 242 | fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym); |
203 | GNUNET_assert (fn != NULL); | 243 | if (NULL == (fileW = GNUNET_BIO_write_open (fn))) |
204 | fileW = GNUNET_BIO_write_open (fn); | ||
205 | if (NULL != fileW) | ||
206 | { | 244 | { |
207 | if ((GNUNET_OK != GNUNET_BIO_write_int32 (fileW, ranking)) || | 245 | GNUNET_free (fn); |
208 | (GNUNET_OK != GNUNET_BIO_write_string (fileW, ns_name)) || | 246 | return GNUNET_SYSERR; |
209 | (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, meta))) | ||
210 | { | ||
211 | (void) GNUNET_BIO_write_close (fileW); | ||
212 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); | ||
213 | GNUNET_free (fn); | ||
214 | return; | ||
215 | } | ||
216 | if (GNUNET_OK != GNUNET_BIO_write_close (fileW)) | ||
217 | { | ||
218 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); | ||
219 | GNUNET_free (fn); | ||
220 | return; | ||
221 | } | ||
222 | } | 247 | } |
248 | if ((GNUNET_OK != GNUNET_BIO_write (fileW, pseudonym, | ||
249 | sizeof (struct GNUNET_PseudonymIdentifier))) || | ||
250 | (GNUNET_OK != GNUNET_BIO_write_int32 (fileW, rank)) || | ||
251 | (GNUNET_OK != GNUNET_BIO_write_string (fileW, name)) || | ||
252 | (GNUNET_OK != GNUNET_BIO_write_meta_data (fileW, md))) | ||
253 | { | ||
254 | (void) GNUNET_BIO_write_close (fileW); | ||
255 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); | ||
256 | GNUNET_free (fn); | ||
257 | return GNUNET_SYSERR; | ||
258 | } | ||
259 | if (GNUNET_OK != GNUNET_BIO_write_close (fileW)) | ||
260 | { | ||
261 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fn)); | ||
262 | GNUNET_free (fn); | ||
263 | return GNUNET_SYSERR; | ||
264 | } | ||
223 | GNUNET_free (fn); | 265 | GNUNET_free (fn); |
224 | /* create entry for pseudonym name in names */ | 266 | /* create entry for pseudonym name in names */ |
225 | if (ns_name != NULL) | 267 | if (NULL != name) |
226 | GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, nsid, ns_name, | 268 | GNUNET_free_non_null (GNUNET_PSEUDONYM_name_uniquify (cfg, pseudonym, |
227 | NULL)); | 269 | name, NULL)); |
270 | return GNUNET_OK; | ||
228 | } | 271 | } |
229 | 272 | ||
230 | 273 | ||
231 | /** | 274 | /** |
232 | * read the pseudonym infomation from a file | 275 | * Read pseudonym infomation from a file |
276 | * | ||
233 | * @param cfg configuration to use | 277 | * @param cfg configuration to use |
234 | * @param nsid hash code of a pseudonym | 278 | * @param nsid hash code of a pseudonym |
235 | * @param meta meta data to be read from a file | 279 | * @param meta meta data to be read from a file |
236 | * @param ranking ranking of a pseudonym | 280 | * @param rank rank of a pseudonym |
237 | * @param ns_name name of a pseudonym | 281 | * @param ns_name name of a pseudonym |
282 | * @return GNUNET_OK on success, GNUNET_SYSERR on error | ||
238 | */ | 283 | */ |
239 | static int | 284 | static int |
240 | read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | 285 | read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, |
241 | const struct GNUNET_HashCode * nsid, | 286 | const struct GNUNET_PseudonymIdentifier *pseudonym, |
242 | struct GNUNET_CONTAINER_MetaData **meta, int32_t * ranking, | 287 | struct GNUNET_CONTAINER_MetaData **meta, |
288 | int32_t *rank, | ||
243 | char **ns_name) | 289 | char **ns_name) |
244 | { | 290 | { |
291 | struct GNUNET_PseudonymIdentifier pd; | ||
245 | char *fn; | 292 | char *fn; |
246 | char *emsg; | 293 | char *emsg; |
247 | struct GNUNET_BIO_ReadHandle *fileR; | 294 | struct GNUNET_BIO_ReadHandle *fileR; |
248 | 295 | ||
249 | fn = get_data_filename (cfg, PS_METADATA_DIR, nsid); | 296 | fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym); |
250 | GNUNET_assert (fn != NULL); | ||
251 | if (GNUNET_YES != | 297 | if (GNUNET_YES != |
252 | GNUNET_DISK_file_test (fn)) | 298 | GNUNET_DISK_file_test (fn)) |
253 | { | 299 | { |
254 | GNUNET_free (fn); | 300 | GNUNET_free (fn); |
255 | return GNUNET_SYSERR; | 301 | return GNUNET_SYSERR; |
256 | } | 302 | } |
257 | fileR = GNUNET_BIO_read_open (fn); | 303 | if (NULL == (fileR = GNUNET_BIO_read_open (fn))) |
258 | if (fileR == NULL) | ||
259 | { | 304 | { |
260 | GNUNET_free (fn); | 305 | GNUNET_free (fn); |
261 | return GNUNET_SYSERR; | 306 | return GNUNET_SYSERR; |
262 | } | 307 | } |
263 | emsg = NULL; | 308 | emsg = NULL; |
264 | *ns_name = NULL; | 309 | *ns_name = NULL; |
265 | if ((GNUNET_OK != GNUNET_BIO_read_int32 (fileR, ranking)) || | 310 | if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) || |
266 | (GNUNET_OK != | 311 | (0 != memcmp (&pd, pseudonym, sizeof (pd))) || |
267 | GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) || | 312 | (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, rank)) || |
268 | (GNUNET_OK != | 313 | (GNUNET_OK != |
269 | GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta))) | 314 | GNUNET_BIO_read_string (fileR, "Read string error!", ns_name, 200)) || |
315 | (GNUNET_OK != | ||
316 | GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", meta)) ) | ||
270 | { | 317 | { |
271 | (void) GNUNET_BIO_read_close (fileR, &emsg); | 318 | (void) GNUNET_BIO_read_close (fileR, &emsg); |
272 | GNUNET_free_non_null (emsg); | 319 | GNUNET_free_non_null (emsg); |
@@ -296,12 +343,11 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
296 | 343 | ||
297 | 344 | ||
298 | /** | 345 | /** |
299 | * Return unique variant of the namespace name. | 346 | * Return unique variant of the namespace name. Use it after |
300 | * Use it after GNUNET_PSEUDONYM_get_info() to make sure | 347 | * GNUNET_PSEUDONYM_get_info() to make sure that name is unique. |
301 | * that name is unique. | ||
302 | * | 348 | * |
303 | * @param cfg configuration | 349 | * @param cfg configuration |
304 | * @param nsid cryptographic ID of the namespace | 350 | * @param pseudonym public key of the pseudonym |
305 | * @param name name to uniquify | 351 | * @param name name to uniquify |
306 | * @param suffix if not NULL, filled with the suffix value | 352 | * @param suffix if not NULL, filled with the suffix value |
307 | * @return NULL on failure (should never happen), name on success. | 353 | * @return NULL on failure (should never happen), name on success. |
@@ -309,9 +355,12 @@ read_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
309 | */ | 355 | */ |
310 | char * | 356 | char * |
311 | GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | 357 | GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, |
312 | const struct GNUNET_HashCode * nsid, const char *name, unsigned int *suffix) | 358 | const struct GNUNET_PseudonymIdentifier *pseudonym, |
359 | const char *name, | ||
360 | unsigned int *suffix) | ||
313 | { | 361 | { |
314 | struct GNUNET_HashCode nh; | 362 | struct GNUNET_HashCode nh; |
363 | struct GNUNET_PseudonymIdentifier pi; | ||
315 | uint64_t len; | 364 | uint64_t len; |
316 | char *fn; | 365 | char *fn; |
317 | struct GNUNET_DISK_FileHandle *fh; | 366 | struct GNUNET_DISK_FileHandle *fh; |
@@ -321,9 +370,7 @@ GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
321 | struct stat sbuf; | 370 | struct stat sbuf; |
322 | 371 | ||
323 | GNUNET_CRYPTO_hash (name, strlen (name), &nh); | 372 | GNUNET_CRYPTO_hash (name, strlen (name), &nh); |
324 | fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); | 373 | fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh); |
325 | GNUNET_assert (fn != NULL); | ||
326 | |||
327 | len = 0; | 374 | len = 0; |
328 | if (0 == STAT (fn, &sbuf)) | 375 | if (0 == STAT (fn, &sbuf)) |
329 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES)); | 376 | GNUNET_break (GNUNET_OK == GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES)); |
@@ -334,11 +381,11 @@ GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
334 | GNUNET_DISK_PERM_USER_WRITE); | 381 | GNUNET_DISK_PERM_USER_WRITE); |
335 | i = 0; | 382 | i = 0; |
336 | idx = -1; | 383 | idx = -1; |
337 | while ((len >= sizeof (struct GNUNET_HashCode)) && | 384 | while ((len >= sizeof (struct GNUNET_PseudonymIdentifier)) && |
338 | (sizeof (struct GNUNET_HashCode) == | 385 | (sizeof (struct GNUNET_PseudonymIdentifier) == |
339 | GNUNET_DISK_file_read (fh, &nh, sizeof (struct GNUNET_HashCode)))) | 386 | GNUNET_DISK_file_read (fh, &pi, sizeof (struct GNUNET_PseudonymIdentifier)))) |
340 | { | 387 | { |
341 | if (0 == memcmp (&nh, nsid, sizeof (struct GNUNET_HashCode))) | 388 | if (0 == memcmp (&pi, pseudonym, sizeof (struct GNUNET_PseudonymIdentifier))) |
342 | { | 389 | { |
343 | idx = i; | 390 | idx = i; |
344 | break; | 391 | break; |
@@ -346,11 +393,11 @@ GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
346 | i++; | 393 | i++; |
347 | len -= sizeof (struct GNUNET_HashCode); | 394 | len -= sizeof (struct GNUNET_HashCode); |
348 | } | 395 | } |
349 | if (idx == -1) | 396 | if (-1 == idx) |
350 | { | 397 | { |
351 | idx = i; | 398 | idx = i; |
352 | if (sizeof (struct GNUNET_HashCode) != | 399 | if (sizeof (struct GNUNET_PseudonymIdentifier) != |
353 | GNUNET_DISK_file_write (fh, nsid, sizeof (struct GNUNET_HashCode))) | 400 | GNUNET_DISK_file_write (fh, pseudonym, sizeof (struct GNUNET_PseudonymIdentifier))) |
354 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); | 401 | LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "write", fn); |
355 | } | 402 | } |
356 | GNUNET_DISK_file_close (fh); | 403 | GNUNET_DISK_file_close (fh); |
@@ -362,13 +409,14 @@ GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
362 | return ret; | 409 | return ret; |
363 | } | 410 | } |
364 | 411 | ||
412 | |||
365 | /** | 413 | /** |
366 | * Get namespace name, metadata and rank | 414 | * Get namespace name, metadata and rank |
367 | * This is a wrapper around internal read_info() call, and ensures that | 415 | * This is a wrapper around internal read_info() call, and ensures that |
368 | * returned data is not invalid (not NULL). | 416 | * returned data is not invalid (not NULL). |
369 | * | 417 | * |
370 | * @param cfg configuration | 418 | * @param cfg configuration |
371 | * @param nsid cryptographic ID of the namespace | 419 | * @param pseudonym public key of the pseudonym |
372 | * @param ret_meta a location to store metadata pointer. NULL, if metadata | 420 | * @param ret_meta a location to store metadata pointer. NULL, if metadata |
373 | * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). | 421 | * is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy(). |
374 | * @param ret_rank a location to store rank. NULL, if rank not needed. | 422 | * @param ret_rank a location to store rank. NULL, if rank not needed. |
@@ -382,8 +430,11 @@ GNUNET_PSEUDONYM_name_uniquify (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
382 | */ | 430 | */ |
383 | int | 431 | int |
384 | GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | 432 | GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, |
385 | const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta, | 433 | const struct GNUNET_PseudonymIdentifier *pseudonym, |
386 | int32_t *ret_rank, char **ret_name, int *name_is_a_dup) | 434 | struct GNUNET_CONTAINER_MetaData **ret_meta, |
435 | int32_t *ret_rank, | ||
436 | char **ret_name, | ||
437 | int *name_is_a_dup) | ||
387 | { | 438 | { |
388 | struct GNUNET_CONTAINER_MetaData *meta; | 439 | struct GNUNET_CONTAINER_MetaData *meta; |
389 | char *name; | 440 | char *name; |
@@ -391,7 +442,7 @@ GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
391 | 442 | ||
392 | meta = NULL; | 443 | meta = NULL; |
393 | name = NULL; | 444 | name = NULL; |
394 | if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name)) | 445 | if (GNUNET_OK == read_info (cfg, pseudonym, &meta, &rank, &name)) |
395 | { | 446 | { |
396 | if ((meta != NULL) && (name == NULL)) | 447 | if ((meta != NULL) && (name == NULL)) |
397 | name = | 448 | name = |
@@ -446,17 +497,19 @@ GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
446 | return GNUNET_SYSERR; | 497 | return GNUNET_SYSERR; |
447 | } | 498 | } |
448 | 499 | ||
500 | |||
449 | /** | 501 | /** |
450 | * Get the namespace ID belonging to the given namespace name. | 502 | * Get the namespace ID belonging to the given namespace name. |
451 | * | 503 | * |
452 | * @param cfg configuration to use | 504 | * @param cfg configuration to use |
453 | * @param ns_uname unique (!) human-readable name for the namespace | 505 | * @param ns_uname unique (!) human-readable name for the namespace |
454 | * @param nsid set to namespace ID based on 'ns_uname' | 506 | * @param pseudonym set to public key of pseudonym based on 'ns_uname' |
455 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | 507 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure |
456 | */ | 508 | */ |
457 | int | 509 | int |
458 | GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, | 510 | GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, |
459 | const char *ns_uname, struct GNUNET_HashCode * nsid) | 511 | const char *ns_uname, |
512 | struct GNUNET_PseudonymIdentifier *pseudonym) | ||
460 | { | 513 | { |
461 | size_t slen; | 514 | size_t slen; |
462 | uint64_t len; | 515 | uint64_t len; |
@@ -470,19 +523,18 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
470 | slen = strlen (ns_uname); | 523 | slen = strlen (ns_uname); |
471 | while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx))) | 524 | while ((slen > 0) && (1 != SSCANF (&ns_uname[slen - 1], "-%u", &idx))) |
472 | slen--; | 525 | slen--; |
473 | if (slen == 0) | 526 | if (0 == slen) |
474 | return GNUNET_SYSERR; | 527 | return GNUNET_SYSERR; |
475 | name = GNUNET_strdup (ns_uname); | 528 | name = GNUNET_strdup (ns_uname); |
476 | name[slen - 1] = '\0'; | 529 | name[slen - 1] = '\0'; |
477 | 530 | ||
478 | GNUNET_CRYPTO_hash (name, strlen (name), &nh); | 531 | GNUNET_CRYPTO_hash (name, strlen (name), &nh); |
479 | GNUNET_free (name); | 532 | GNUNET_free (name); |
480 | fn = get_data_filename (cfg, PS_NAMES_DIR, &nh); | 533 | fn = get_data_filename_hash (cfg, PS_NAMES_DIR, &nh); |
481 | GNUNET_assert (fn != NULL); | ||
482 | 534 | ||
483 | if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || | 535 | if ((GNUNET_OK != GNUNET_DISK_file_test (fn) || |
484 | (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || | 536 | (GNUNET_OK != GNUNET_DISK_file_size (fn, &len, GNUNET_YES, GNUNET_YES))) || |
485 | ((idx + 1) * sizeof (struct GNUNET_HashCode) > len)) | 537 | ((idx + 1) * sizeof (struct GNUNET_PseudonymIdentifier) > len)) |
486 | { | 538 | { |
487 | GNUNET_free (fn); | 539 | GNUNET_free (fn); |
488 | return GNUNET_SYSERR; | 540 | return GNUNET_SYSERR; |
@@ -494,14 +546,14 @@ GNUNET_PSEUDONYM_name_to_id (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
494 | GNUNET_DISK_PERM_USER_WRITE); | 546 | GNUNET_DISK_PERM_USER_WRITE); |
495 | GNUNET_free (fn); | 547 | GNUNET_free (fn); |
496 | if (GNUNET_SYSERR == | 548 | if (GNUNET_SYSERR == |
497 | GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_HashCode), | 549 | GNUNET_DISK_file_seek (fh, idx * sizeof (struct GNUNET_PseudonymIdentifier), |
498 | GNUNET_DISK_SEEK_SET)) | 550 | GNUNET_DISK_SEEK_SET)) |
499 | { | 551 | { |
500 | GNUNET_DISK_file_close (fh); | 552 | GNUNET_DISK_file_close (fh); |
501 | return GNUNET_SYSERR; | 553 | return GNUNET_SYSERR; |
502 | } | 554 | } |
503 | if (sizeof (struct GNUNET_HashCode) != | 555 | if (sizeof (struct GNUNET_PseudonymIdentifier) != |
504 | GNUNET_DISK_file_read (fh, nsid, sizeof (struct GNUNET_HashCode))) | 556 | GNUNET_DISK_file_read (fh, pseudonym, sizeof (struct GNUNET_PseudonymIdentifier))) |
505 | { | 557 | { |
506 | GNUNET_DISK_file_close (fh); | 558 | GNUNET_DISK_file_close (fh); |
507 | return GNUNET_SYSERR; | 559 | return GNUNET_SYSERR; |
@@ -526,7 +578,7 @@ struct ListPseudonymClosure | |||
526 | /** | 578 | /** |
527 | * Closure for iterator. | 579 | * Closure for iterator. |
528 | */ | 580 | */ |
529 | void *closure; | 581 | void *iterator_cls; |
530 | 582 | ||
531 | /** | 583 | /** |
532 | * Configuration to use. | 584 | * Configuration to use. |
@@ -537,47 +589,59 @@ struct ListPseudonymClosure | |||
537 | 589 | ||
538 | 590 | ||
539 | /** | 591 | /** |
540 | * the help function to list all available pseudonyms | 592 | * Helper function to list all available pseudonyms |
593 | * | ||
541 | * @param cls point to a struct ListPseudonymClosure | 594 | * @param cls point to a struct ListPseudonymClosure |
542 | * @param fullname name of pseudonym | 595 | * @param fullname name of pseudonym |
543 | */ | 596 | */ |
544 | static int | 597 | static int |
545 | list_pseudonym_helper (void *cls, const char *fullname) | 598 | list_pseudonym_helper (void *cls, const char *fullname) |
546 | { | 599 | { |
547 | struct ListPseudonymClosure *c = cls; | 600 | struct ListPseudonymClosure *lpc = cls; |
548 | int ret; | 601 | struct GNUNET_PseudonymIdentifier pd; |
549 | struct GNUNET_HashCode id; | 602 | char *emsg; |
550 | int32_t rating; | 603 | struct GNUNET_BIO_ReadHandle *fileR; |
604 | int32_t rank; | ||
605 | char *ns_name; | ||
551 | struct GNUNET_CONTAINER_MetaData *meta; | 606 | struct GNUNET_CONTAINER_MetaData *meta; |
552 | const char *fn; | 607 | int ret; |
553 | char *str; | ||
554 | char *name_unique; | 608 | char *name_unique; |
555 | 609 | ||
556 | if (strlen (fullname) < sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) | 610 | if (NULL == (fileR = GNUNET_BIO_read_open (fullname))) |
557 | return GNUNET_OK; | 611 | return GNUNET_SYSERR; |
558 | fn = &fullname[strlen (fullname) + 1 - | 612 | emsg = NULL; |
559 | sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)]; | 613 | ns_name = NULL; |
560 | if (fn[-1] != DIR_SEPARATOR) | 614 | if ( (GNUNET_OK != GNUNET_BIO_read (fileR, "pseudonym", &pd, sizeof (pd))) || |
561 | return GNUNET_OK; | 615 | (GNUNET_OK != GNUNET_BIO_read_int32 (fileR, &rank)) || |
562 | ret = GNUNET_OK; | 616 | (GNUNET_OK != |
563 | if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string (fn, &id)) | 617 | GNUNET_BIO_read_string (fileR, "Read string error!", &ns_name, 200)) || |
564 | return GNUNET_OK; /* invalid name */ | 618 | (GNUNET_OK != |
565 | str = NULL; | 619 | GNUNET_BIO_read_meta_data (fileR, "Read meta data error!", &meta)) ) |
566 | if (GNUNET_OK != GNUNET_PSEUDONYM_get_info (c->cfg, &id, &meta, &rating, | ||
567 | &str, NULL)) | ||
568 | { | 620 | { |
569 | /* ignore entry. FIXME: Why? Lack of data about a pseudonym is not a reason | 621 | (void) GNUNET_BIO_read_close (fileR, &emsg); |
570 | * to ignore it... So yeah, it will have placeholders instead of name, | 622 | GNUNET_free_non_null (emsg); |
571 | * empty metadata container and a default rank == -1, so what? We know | 623 | GNUNET_free_non_null (ns_name); |
572 | * its nsid - that's all we really need. Right? */ | 624 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname)); |
573 | GNUNET_free (str); | 625 | return GNUNET_SYSERR; |
626 | } | ||
627 | if (NULL == ns_name) | ||
628 | ns_name = GNUNET_strdup (_("no-name")); | ||
629 | if (GNUNET_OK != GNUNET_BIO_read_close (fileR, &emsg)) | ||
630 | { | ||
631 | LOG (GNUNET_ERROR_TYPE_WARNING, | ||
632 | _("Failed to parse metadata about pseudonym from file `%s': %s\n"), fullname, | ||
633 | emsg); | ||
634 | GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove (fullname)); | ||
574 | GNUNET_CONTAINER_meta_data_destroy (meta); | 635 | GNUNET_CONTAINER_meta_data_destroy (meta); |
575 | return GNUNET_OK; | 636 | GNUNET_free (ns_name); |
637 | GNUNET_free_non_null (emsg); | ||
638 | return GNUNET_SYSERR; | ||
576 | } | 639 | } |
577 | name_unique = GNUNET_PSEUDONYM_name_uniquify (c->cfg, &id, str, NULL); | 640 | ret = GNUNET_OK; |
578 | if (c->iterator != NULL) | 641 | name_unique = GNUNET_PSEUDONYM_name_uniquify (lpc->cfg, &pd, ns_name, NULL); |
579 | ret = c->iterator (c->closure, &id, str, name_unique, meta, rating); | 642 | if (NULL != lpc->iterator) |
580 | GNUNET_free_non_null (str); | 643 | ret = lpc->iterator (lpc->iterator_cls, &pd, ns_name, name_unique, meta, rank); |
644 | GNUNET_free (ns_name); | ||
581 | GNUNET_free_non_null (name_unique); | 645 | GNUNET_free_non_null (name_unique); |
582 | GNUNET_CONTAINER_meta_data_destroy (meta); | 646 | GNUNET_CONTAINER_meta_data_destroy (meta); |
583 | return ret; | 647 | return ret; |
@@ -589,19 +653,20 @@ list_pseudonym_helper (void *cls, const char *fullname) | |||
589 | * | 653 | * |
590 | * @param cfg overall configuration | 654 | * @param cfg overall configuration |
591 | * @param iterator function to call for each pseudonym | 655 | * @param iterator function to call for each pseudonym |
592 | * @param closure closure for iterator | 656 | * @param iterator_cls closure for iterator |
593 | * @return number of pseudonyms found | 657 | * @return number of pseudonyms found |
594 | */ | 658 | */ |
595 | int | 659 | int |
596 | GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg, | 660 | GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg, |
597 | GNUNET_PSEUDONYM_Iterator iterator, void *closure) | 661 | GNUNET_PSEUDONYM_Iterator iterator, |
662 | void *iterator_cls) | ||
598 | { | 663 | { |
599 | struct ListPseudonymClosure cls; | 664 | struct ListPseudonymClosure cls; |
600 | char *fn; | 665 | char *fn; |
601 | int ret; | 666 | int ret; |
602 | 667 | ||
603 | cls.iterator = iterator; | 668 | cls.iterator = iterator; |
604 | cls.closure = closure; | 669 | cls.iterator_cls = iterator_cls; |
605 | cls.cfg = cfg; | 670 | cls.cfg = cfg; |
606 | fn = get_data_filename (cfg, PS_METADATA_DIR, NULL); | 671 | fn = get_data_filename (cfg, PS_METADATA_DIR, NULL); |
607 | GNUNET_assert (fn != NULL); | 672 | GNUNET_assert (fn != NULL); |
@@ -613,60 +678,35 @@ GNUNET_PSEUDONYM_list_all (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
613 | 678 | ||
614 | 679 | ||
615 | /** | 680 | /** |
616 | * Change the ranking of a pseudonym. | 681 | * Change the rank of a pseudonym. |
617 | * | 682 | * |
618 | * @param cfg overall configuration | 683 | * @param cfg overall configuration |
619 | * @param nsid id of the pseudonym | 684 | * @param pseudonym the pseudonym |
620 | * @param delta by how much should the rating be | 685 | * @param delta by how much should the rating be changed? |
621 | * changed? | ||
622 | * @return new rating of the pseudonym | 686 | * @return new rating of the pseudonym |
623 | */ | 687 | */ |
624 | int | 688 | int |
625 | GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, | 689 | GNUNET_PSEUDONYM_rank (const struct GNUNET_CONFIGURATION_Handle *cfg, |
626 | const struct GNUNET_HashCode * nsid, int delta) | 690 | const struct GNUNET_PseudonymIdentifier *pseudonym, |
691 | int32_t delta) | ||
627 | { | 692 | { |
628 | struct GNUNET_CONTAINER_MetaData *meta; | 693 | struct GNUNET_CONTAINER_MetaData *meta; |
629 | int ret; | 694 | int ret; |
630 | int32_t ranking; | 695 | int32_t rank; |
631 | char *name; | 696 | char *name; |
632 | 697 | ||
633 | name = NULL; | 698 | name = NULL; |
634 | ret = read_info (cfg, nsid, &meta, &ranking, &name); | 699 | ret = read_info (cfg, pseudonym, &meta, &rank, &name); |
635 | if (ret == GNUNET_SYSERR) | 700 | if (ret == GNUNET_SYSERR) |
636 | { | 701 | { |
637 | ranking = 0; | 702 | rank = 0; |
638 | meta = GNUNET_CONTAINER_meta_data_create (); | 703 | meta = GNUNET_CONTAINER_meta_data_create (); |
639 | } | 704 | } |
640 | ranking += delta; | 705 | rank += delta; |
641 | write_pseudonym_info (cfg, nsid, meta, ranking, name); | 706 | GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, meta, rank); |
642 | GNUNET_CONTAINER_meta_data_destroy (meta); | 707 | GNUNET_CONTAINER_meta_data_destroy (meta); |
643 | GNUNET_free_non_null (name); | 708 | GNUNET_free_non_null (name); |
644 | return ranking; | 709 | return rank; |
645 | } | ||
646 | |||
647 | |||
648 | /** | ||
649 | * Set the pseudonym metadata, rank and name. | ||
650 | * | ||
651 | * @param cfg overall configuration | ||
652 | * @param nsid id of the pseudonym | ||
653 | * @param name name to set. Must be the non-unique version of it. | ||
654 | * May be NULL, in which case it erases pseudonym's name! | ||
655 | * @param md metadata to set | ||
656 | * May be NULL, in which case it erases pseudonym's metadata! | ||
657 | * @param rank rank to assign | ||
658 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
659 | */ | ||
660 | int | ||
661 | GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
662 | const struct GNUNET_HashCode * nsid, const char *name, | ||
663 | const struct GNUNET_CONTAINER_MetaData *md, int rank) | ||
664 | { | ||
665 | GNUNET_assert (cfg != NULL); | ||
666 | GNUNET_assert (nsid != NULL); | ||
667 | |||
668 | write_pseudonym_info (cfg, nsid, md, rank, name); | ||
669 | return GNUNET_OK; | ||
670 | } | 710 | } |
671 | 711 | ||
672 | 712 | ||
@@ -676,38 +716,233 @@ GNUNET_PSEUDONYM_set_info (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
676 | * FS should automatically call this function. | 716 | * FS should automatically call this function. |
677 | * | 717 | * |
678 | * @param cfg overall configuration | 718 | * @param cfg overall configuration |
679 | * @param id the pseudonym identifier | 719 | * @param pseudonym the pseudonym to add |
680 | * @param meta metadata for the pseudonym | 720 | * @param meta metadata for the pseudonym |
721 | * @return GNUNET_OK on success, GNUNET_SYSERR on failure | ||
681 | */ | 722 | */ |
682 | void | 723 | int |
683 | GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg, | 724 | GNUNET_PSEUDONYM_add (const struct GNUNET_CONFIGURATION_Handle *cfg, |
684 | const struct GNUNET_HashCode * id, | 725 | const struct GNUNET_PseudonymIdentifier *pseudonym, |
685 | const struct GNUNET_CONTAINER_MetaData *meta) | 726 | const struct GNUNET_CONTAINER_MetaData *meta) |
686 | { | 727 | { |
687 | char *name; | 728 | char *name; |
688 | int32_t ranking; | 729 | int32_t rank; |
689 | struct GNUNET_CONTAINER_MetaData *old; | 730 | struct GNUNET_CONTAINER_MetaData *old; |
690 | char *fn; | 731 | char *fn; |
691 | struct stat sbuf; | 732 | struct stat sbuf; |
733 | int ret; | ||
692 | 734 | ||
693 | ranking = 0; | 735 | rank = 0; |
694 | fn = get_data_filename (cfg, PS_METADATA_DIR, id); | 736 | fn = get_data_filename (cfg, PS_METADATA_DIR, pseudonym); |
695 | GNUNET_assert (fn != NULL); | 737 | GNUNET_assert (fn != NULL); |
696 | 738 | ||
697 | if ((0 == STAT (fn, &sbuf)) && | 739 | if ((0 == STAT (fn, &sbuf)) && |
698 | (GNUNET_OK == read_info (cfg, id, &old, &ranking, &name))) | 740 | (GNUNET_OK == read_info (cfg, pseudonym, &old, &rank, &name))) |
699 | { | 741 | { |
700 | GNUNET_CONTAINER_meta_data_merge (old, meta); | 742 | GNUNET_CONTAINER_meta_data_merge (old, meta); |
701 | write_pseudonym_info (cfg, id, old, ranking, name); | 743 | ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, name, old, rank); |
702 | GNUNET_CONTAINER_meta_data_destroy (old); | 744 | GNUNET_CONTAINER_meta_data_destroy (old); |
703 | GNUNET_free_non_null (name); | 745 | GNUNET_free_non_null (name); |
704 | } | 746 | } |
705 | else | 747 | else |
706 | { | 748 | { |
707 | write_pseudonym_info (cfg, id, meta, ranking, NULL); | 749 | ret = GNUNET_PSEUDONYM_set_info (cfg, pseudonym, NULL, meta, rank); |
708 | } | 750 | } |
709 | GNUNET_free (fn); | 751 | GNUNET_free (fn); |
710 | internal_notify (id, meta, ranking); | 752 | internal_notify (pseudonym, meta, rank); |
753 | return ret; | ||
754 | } | ||
755 | |||
756 | |||
757 | /* ***************************** cryptographic operations ************************* */ | ||
758 | |||
759 | /** | ||
760 | * Handle for a pseudonym (private key). | ||
761 | */ | ||
762 | struct GNUNET_PseudonymHandle | ||
763 | { | ||
764 | /** | ||
765 | * FIXME. | ||
766 | */ | ||
767 | char data[42]; | ||
768 | }; | ||
769 | |||
770 | |||
771 | /** | ||
772 | * Create a pseudonym. | ||
773 | * | ||
774 | * @param filename name of the file to use for storage, NULL for in-memory only | ||
775 | * @return handle to the private key of the pseudonym | ||
776 | */ | ||
777 | struct GNUNET_PseudonymHandle * | ||
778 | GNUNET_PSEUDONYM_create (const char *filename) | ||
779 | { | ||
780 | struct GNUNET_PseudonymHandle *ph; | ||
781 | ssize_t ret; | ||
782 | |||
783 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); | ||
784 | if (NULL != filename) | ||
785 | { | ||
786 | ret = GNUNET_DISK_fn_read (filename, ph, | ||
787 | sizeof (struct GNUNET_PseudonymHandle)); | ||
788 | if (sizeof (struct GNUNET_PseudonymHandle) == ret) | ||
789 | return ph; | ||
790 | } | ||
791 | GNUNET_break (0); // not implemented... | ||
792 | gcry_randomize (ph, sizeof (struct GNUNET_PseudonymHandle), | ||
793 | GCRY_STRONG_RANDOM); | ||
794 | if (NULL != filename) | ||
795 | { | ||
796 | ret = GNUNET_DISK_fn_write (filename, ph, sizeof (struct GNUNET_PseudonymHandle), | ||
797 | GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
798 | if (sizeof (struct GNUNET_PseudonymHandle) != ret) | ||
799 | { | ||
800 | GNUNET_free (ph); | ||
801 | return NULL; | ||
802 | } | ||
803 | } | ||
804 | return ph; | ||
805 | } | ||
806 | |||
807 | |||
808 | /** | ||
809 | * Create a pseudonym, from a file that must already exist. | ||
810 | * | ||
811 | * @param filename name of the file to use for storage, NULL for in-memory only | ||
812 | * @return handle to the private key of the pseudonym | ||
813 | */ | ||
814 | struct GNUNET_PseudonymHandle * | ||
815 | GNUNET_PSEUDONYM_create_from_existing_file (const char *filename) | ||
816 | { | ||
817 | struct GNUNET_PseudonymHandle *ph; | ||
818 | ssize_t ret; | ||
819 | |||
820 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); | ||
821 | ret = GNUNET_DISK_fn_read (filename, ph, | ||
822 | sizeof (struct GNUNET_PseudonymHandle)); | ||
823 | if (sizeof (struct GNUNET_PseudonymHandle) == ret) | ||
824 | return ph; | ||
825 | GNUNET_free (ph); | ||
826 | return NULL; | ||
827 | } | ||
828 | |||
829 | |||
830 | /** | ||
831 | * Get the handle for the 'anonymous' pseudonym shared by all users. | ||
832 | * That pseudonym uses a fixed 'secret' for the private key; this | ||
833 | * construction is useful to make anonymous and pseudonymous APIs | ||
834 | * (and packets) indistinguishable on the network. See #2564. | ||
835 | * | ||
836 | * @return handle to the (non-secret) private key of the 'anonymous' pseudonym | ||
837 | */ | ||
838 | struct GNUNET_PseudonymHandle * | ||
839 | GNUNET_PSEUDONYM_get_anonymous_pseudonym_handle () | ||
840 | { | ||
841 | struct GNUNET_PseudonymHandle *ph; | ||
842 | |||
843 | ph = GNUNET_malloc (sizeof (struct GNUNET_PseudonymHandle)); | ||
844 | GNUNET_break (0); | ||
845 | return ph; | ||
846 | } | ||
847 | |||
848 | |||
849 | /** | ||
850 | * Destroy a pseudonym handle. Does NOT remove the private key from | ||
851 | * the disk. | ||
852 | * | ||
853 | * @param ph pseudonym handle to destroy | ||
854 | */ | ||
855 | void | ||
856 | GNUNET_PSEUDONYM_destroy (struct GNUNET_PseudonymHandle *ph) | ||
857 | { | ||
858 | GNUNET_free (ph); | ||
859 | } | ||
860 | |||
861 | |||
862 | /** | ||
863 | * Cryptographically sign some data with the pseudonym. | ||
864 | * | ||
865 | * @param ph private key used for signing (corresponds to 'x' in #2564) | ||
866 | * @param purpose data to sign | ||
867 | * @param seed hash of the plaintext of the data that we are signing, | ||
868 | * used for deterministic PRNG for anonymous signing; | ||
869 | * corresponds to 'k' in section 2.7 of #2564 | ||
870 | * @param signing_key modifier to apply to the private key for signing; | ||
871 | * corresponds to 'h' in section 2.3 of #2564. | ||
872 | * @param signature where to store the signature | ||
873 | */ | ||
874 | void | ||
875 | GNUNET_PSEUDONYM_sign (struct GNUNET_PseudonymHandle *ph, | ||
876 | const struct GNUNET_PseudonymSignaturePurpose *purpose, | ||
877 | const struct GNUNET_HashCode *seed, | ||
878 | const struct GNUNET_HashCode *signing_key, | ||
879 | struct GNUNET_PseudonymSignature *signature) | ||
880 | { | ||
881 | memset (signature, 0, sizeof (struct GNUNET_PseudonymSignature)); | ||
882 | GNUNET_break (0); | ||
883 | } | ||
884 | |||
885 | |||
886 | /** | ||
887 | * Given a pseudonym and a signing key, derive the corresponding public | ||
888 | * key that would be used to verify the resulting signature. | ||
889 | * | ||
890 | * @param pseudonym the public key (g^x) | ||
891 | * @param signing_key input to derive 'h' (see section 2.4 of #2564) | ||
892 | * @param verification_key resulting public key to verify the signature | ||
893 | * created from the 'ph' of 'pseudonym' and the 'signing_key'; | ||
894 | * the value stored here can then be given to GNUNET_PSEUDONYM_verify. | ||
895 | */ | ||
896 | void | ||
897 | GNUNET_PSEUDONYM_derive_verification_key (struct GNUNET_PseudonymIdentifier *pseudonym, | ||
898 | const struct GNUNET_HashCode *signing_key, | ||
899 | struct GNUNET_PseudonymIdentifier *verification_key) | ||
900 | { | ||
901 | struct GNUNET_HashCode hc; | ||
902 | struct GNUNET_HashCode x; | ||
903 | |||
904 | GNUNET_break (0); | ||
905 | GNUNET_CRYPTO_hash (pseudonym, sizeof (*pseudonym), &hc); | ||
906 | GNUNET_CRYPTO_hash_xor (&hc, signing_key, &x); | ||
907 | memset (verification_key, 0, sizeof (struct GNUNET_PseudonymIdentifier)); | ||
908 | memcpy (verification_key, &x, GNUNET_MIN (sizeof (x), sizeof (*verification_key))); | ||
909 | } | ||
910 | |||
911 | |||
912 | /** | ||
913 | * Verify a signature made with a pseudonym. | ||
914 | * | ||
915 | * @param purpose data that was signed | ||
916 | * @param signature signature to verify | ||
917 | * @param verification_key public key to use for checking the signature; | ||
918 | * corresponds to 'g^(x+h)' in section 2.4 of #2564. | ||
919 | * @return GNUNET_OK on success (signature valid, 'pseudonym' set), | ||
920 | * GNUNET_SYSERR if the signature is invalid | ||
921 | */ | ||
922 | int | ||
923 | GNUNET_PSEUDONYM_verify (const struct GNUNET_PseudonymSignaturePurpose *purpose, | ||
924 | const struct GNUNET_PseudonymSignature *signature, | ||
925 | const struct GNUNET_PseudonymIdentifier *verification_key) | ||
926 | { | ||
927 | GNUNET_break (0); | ||
928 | return GNUNET_OK; | ||
929 | } | ||
930 | |||
931 | |||
932 | /** | ||
933 | * Get the identifier (public key) of a pseudonym. | ||
934 | * | ||
935 | * @param ph pseudonym handle with the private key | ||
936 | * @param pseudonym pseudonym identifier (set based on 'ph') | ||
937 | */ | ||
938 | void | ||
939 | GNUNET_PSEUDONYM_get_identifier (struct GNUNET_PseudonymHandle *ph, | ||
940 | struct GNUNET_PseudonymIdentifier *pseudonym) | ||
941 | { | ||
942 | GNUNET_break (0); | ||
943 | memcpy (pseudonym, ph, | ||
944 | GNUNET_MIN (sizeof (struct GNUNET_PseudonymIdentifier), | ||
945 | sizeof (*ph))); | ||
711 | } | 946 | } |
712 | 947 | ||
713 | 948 | ||