diff options
Diffstat (limited to 'src/identity/gnunet-service-identity.c')
-rw-r--r-- | src/identity/gnunet-service-identity.c | 1253 |
1 files changed, 0 insertions, 1253 deletions
diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c deleted file mode 100644 index 2bb4b0897..000000000 --- a/src/identity/gnunet-service-identity.c +++ /dev/null | |||
@@ -1,1253 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2013 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software: you can redistribute it and/or modify it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
19 | */ | ||
20 | |||
21 | /** | ||
22 | * @file identity/gnunet-service-identity.c | ||
23 | * @brief identity management service | ||
24 | * @author Christian Grothoff | ||
25 | * | ||
26 | * The purpose of this service is to manage private keys that | ||
27 | * represent the various egos/pseudonyms/identities of a GNUnet user. | ||
28 | * | ||
29 | * Todo: | ||
30 | * - auto-initialze default egos; maybe trigger default | ||
31 | * initializations (such as gnunet-gns-import.sh?) | ||
32 | */ | ||
33 | #include "platform.h" | ||
34 | #include "gnunet_util_lib.h" | ||
35 | #include "gnunet_constants.h" | ||
36 | #include "gnunet_protocols.h" | ||
37 | #include "gnunet_statistics_service.h" | ||
38 | #include "gnunet_identity_service.h" | ||
39 | #include "identity.h" | ||
40 | |||
41 | |||
42 | /** | ||
43 | * Information we keep about each ego. | ||
44 | */ | ||
45 | struct Ego | ||
46 | { | ||
47 | /** | ||
48 | * We keep egos in a DLL. | ||
49 | */ | ||
50 | struct Ego *next; | ||
51 | |||
52 | /** | ||
53 | * We keep egos in a DLL. | ||
54 | */ | ||
55 | struct Ego *prev; | ||
56 | |||
57 | /** | ||
58 | * Private key of the ego. | ||
59 | */ | ||
60 | struct GNUNET_IDENTITY_PrivateKey pk; | ||
61 | |||
62 | /** | ||
63 | * String identifier for the ego. | ||
64 | */ | ||
65 | char *identifier; | ||
66 | }; | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Handle to our current configuration. | ||
71 | */ | ||
72 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
73 | |||
74 | /** | ||
75 | * Handle to subsystem configuration which for each subsystem contains | ||
76 | * the name of the default ego. | ||
77 | */ | ||
78 | static struct GNUNET_CONFIGURATION_Handle *subsystem_cfg; | ||
79 | |||
80 | /** | ||
81 | * Handle to the statistics service. | ||
82 | */ | ||
83 | static struct GNUNET_STATISTICS_Handle *stats; | ||
84 | |||
85 | /** | ||
86 | * Notification context, simplifies client broadcasts. | ||
87 | */ | ||
88 | static struct GNUNET_NotificationContext *nc; | ||
89 | |||
90 | /** | ||
91 | * Directory where we store the identities. | ||
92 | */ | ||
93 | static char *ego_directory; | ||
94 | |||
95 | /** | ||
96 | * Configuration file name where subsystem information is kept. | ||
97 | */ | ||
98 | static char *subsystem_cfg_file; | ||
99 | |||
100 | /** | ||
101 | * Head of DLL of all egos. | ||
102 | */ | ||
103 | static struct Ego *ego_head; | ||
104 | |||
105 | /** | ||
106 | * Tail of DLL of all egos. | ||
107 | */ | ||
108 | static struct Ego *ego_tail; | ||
109 | |||
110 | |||
111 | /** | ||
112 | * Get the name of the file we use to store a given ego. | ||
113 | * | ||
114 | * @param ego ego for which we need the filename | ||
115 | * @return full filename for the given ego | ||
116 | */ | ||
117 | static char * | ||
118 | get_ego_filename (struct Ego *ego) | ||
119 | { | ||
120 | char *filename; | ||
121 | |||
122 | GNUNET_asprintf (&filename, | ||
123 | "%s%s%s", | ||
124 | ego_directory, | ||
125 | DIR_SEPARATOR_STR, | ||
126 | ego->identifier); | ||
127 | return filename; | ||
128 | } | ||
129 | |||
130 | |||
131 | /** | ||
132 | * Called whenever a client is disconnected. | ||
133 | * | ||
134 | * @param cls closure | ||
135 | * @param client identification of the client | ||
136 | * @param app_ctx @a client | ||
137 | */ | ||
138 | static void | ||
139 | client_disconnect_cb (void *cls, | ||
140 | struct GNUNET_SERVICE_Client *client, | ||
141 | void *app_ctx) | ||
142 | { | ||
143 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
144 | "Client %p disconnected\n", | ||
145 | client); | ||
146 | } | ||
147 | |||
148 | |||
149 | /** | ||
150 | * Add a client to our list of active clients. | ||
151 | * | ||
152 | * @param cls NULL | ||
153 | * @param client client to add | ||
154 | * @param mq message queue for @a client | ||
155 | * @return internal namestore client structure for this client | ||
156 | */ | ||
157 | static void * | ||
158 | client_connect_cb (void *cls, | ||
159 | struct GNUNET_SERVICE_Client *client, | ||
160 | struct GNUNET_MQ_Handle *mq) | ||
161 | { | ||
162 | return client; | ||
163 | } | ||
164 | |||
165 | |||
166 | /** | ||
167 | * Task run during shutdown. | ||
168 | * | ||
169 | * @param cls unused | ||
170 | */ | ||
171 | static void | ||
172 | shutdown_task (void *cls) | ||
173 | { | ||
174 | struct Ego *e; | ||
175 | |||
176 | if (NULL != nc) | ||
177 | { | ||
178 | GNUNET_notification_context_destroy (nc); | ||
179 | nc = NULL; | ||
180 | } | ||
181 | if (NULL != stats) | ||
182 | { | ||
183 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | ||
184 | stats = NULL; | ||
185 | } | ||
186 | GNUNET_CONFIGURATION_destroy (subsystem_cfg); | ||
187 | subsystem_cfg = NULL; | ||
188 | GNUNET_free (subsystem_cfg_file); | ||
189 | subsystem_cfg_file = NULL; | ||
190 | GNUNET_free (ego_directory); | ||
191 | ego_directory = NULL; | ||
192 | while (NULL != (e = ego_head)) | ||
193 | { | ||
194 | GNUNET_CONTAINER_DLL_remove (ego_head, | ||
195 | ego_tail, | ||
196 | e); | ||
197 | GNUNET_free (e->identifier); | ||
198 | GNUNET_free (e); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | |||
203 | /** | ||
204 | * Send a result code back to the client. | ||
205 | * | ||
206 | * @param client client that should receive the result code | ||
207 | * @param result_code code to transmit | ||
208 | * @param emsg error message to include (or NULL for none) | ||
209 | */ | ||
210 | static void | ||
211 | send_result_code (struct GNUNET_SERVICE_Client *client, | ||
212 | uint32_t result_code, | ||
213 | const char *emsg) | ||
214 | { | ||
215 | struct ResultCodeMessage *rcm; | ||
216 | struct GNUNET_MQ_Envelope *env; | ||
217 | size_t elen; | ||
218 | |||
219 | if (NULL == emsg) | ||
220 | elen = 0; | ||
221 | else | ||
222 | elen = strlen (emsg) + 1; | ||
223 | env = | ||
224 | GNUNET_MQ_msg_extra (rcm, elen, GNUNET_MESSAGE_TYPE_IDENTITY_RESULT_CODE); | ||
225 | rcm->result_code = htonl (result_code); | ||
226 | if (0 < elen) | ||
227 | GNUNET_memcpy (&rcm[1], emsg, elen); | ||
228 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
229 | "Sending result %d (%s) to client\n", | ||
230 | (int) result_code, | ||
231 | emsg); | ||
232 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
233 | } | ||
234 | |||
235 | |||
236 | /** | ||
237 | * Create an update message with information about the current state of an ego. | ||
238 | * | ||
239 | * @param ego ego to create message for | ||
240 | * @return corresponding update message | ||
241 | */ | ||
242 | static struct GNUNET_MQ_Envelope * | ||
243 | create_update_message (struct Ego *ego) | ||
244 | { | ||
245 | struct UpdateMessage *um; | ||
246 | struct GNUNET_MQ_Envelope *env; | ||
247 | size_t name_len; | ||
248 | |||
249 | name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1); | ||
250 | env = GNUNET_MQ_msg_extra (um, name_len, GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); | ||
251 | um->name_len = htons (name_len); | ||
252 | um->end_of_list = htons (GNUNET_NO); | ||
253 | um->private_key = ego->pk; | ||
254 | GNUNET_memcpy (&um[1], ego->identifier, name_len); | ||
255 | return env; | ||
256 | } | ||
257 | |||
258 | |||
259 | /** | ||
260 | * Create a set default message with information about the current state of an ego. | ||
261 | * | ||
262 | * @param ego ego to create message for | ||
263 | * @param servicename name of the service to provide in the message | ||
264 | * @return corresponding set default message | ||
265 | */ | ||
266 | static struct GNUNET_MQ_Envelope * | ||
267 | create_set_default_message (struct Ego *ego, | ||
268 | const char *servicename) | ||
269 | { | ||
270 | struct SetDefaultMessage *sdm; | ||
271 | struct GNUNET_MQ_Envelope *env; | ||
272 | size_t name_len; | ||
273 | |||
274 | name_len = (NULL == servicename) ? 0 : (strlen (servicename) + 1); | ||
275 | env = GNUNET_MQ_msg_extra (sdm, | ||
276 | name_len, | ||
277 | GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT); | ||
278 | sdm->name_len = htons (name_len); | ||
279 | sdm->reserved = htons (0); | ||
280 | sdm->private_key = ego->pk; | ||
281 | GNUNET_memcpy (&sdm[1], servicename, name_len); | ||
282 | return env; | ||
283 | } | ||
284 | |||
285 | |||
286 | /** | ||
287 | * Handler for START message from client, sends information | ||
288 | * about all identities to the client immediately and | ||
289 | * adds the client to the notification context for future | ||
290 | * updates. | ||
291 | * | ||
292 | * @param cls a `struct GNUNET_SERVICE_Client *` | ||
293 | * @param message the message received | ||
294 | */ | ||
295 | static void | ||
296 | handle_start_message (void *cls, | ||
297 | const struct GNUNET_MessageHeader *message) | ||
298 | { | ||
299 | struct GNUNET_SERVICE_Client *client = cls; | ||
300 | |||
301 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
302 | "Received START message from client\n"); | ||
303 | GNUNET_SERVICE_client_mark_monitor (client); | ||
304 | GNUNET_SERVICE_client_disable_continue_warning (client); | ||
305 | GNUNET_notification_context_add (nc, | ||
306 | GNUNET_SERVICE_client_get_mq (client)); | ||
307 | for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next) | ||
308 | { | ||
309 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), | ||
310 | create_update_message (ego)); | ||
311 | } | ||
312 | { | ||
313 | struct UpdateMessage *ume; | ||
314 | struct GNUNET_MQ_Envelope *env; | ||
315 | |||
316 | env = GNUNET_MQ_msg_extra (ume, | ||
317 | 0, | ||
318 | GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); | ||
319 | ume->end_of_list = htons (GNUNET_YES); | ||
320 | ume->name_len = htons (0); | ||
321 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), | ||
322 | env); | ||
323 | } | ||
324 | GNUNET_SERVICE_client_continue (client); | ||
325 | } | ||
326 | |||
327 | |||
328 | /** | ||
329 | * Handler for LOOKUP message from client, sends information | ||
330 | * about ONE identity to the client immediately. | ||
331 | * | ||
332 | * @param cls unused | ||
333 | * @param message the message received | ||
334 | * @return #GNUNET_SYSERR if message was ill-formed | ||
335 | */ | ||
336 | static int | ||
337 | check_lookup_message (void *cls, | ||
338 | const struct LookupMessage *message) | ||
339 | { | ||
340 | GNUNET_MQ_check_zero_termination (message); | ||
341 | return GNUNET_OK; | ||
342 | } | ||
343 | |||
344 | |||
345 | /** | ||
346 | * Handler for LOOKUP message from client, sends information | ||
347 | * about ONE identity to the client immediately. | ||
348 | * | ||
349 | * @param cls a `struct GNUNET_SERVICE_Client *` | ||
350 | * @param message the message received | ||
351 | */ | ||
352 | static void | ||
353 | handle_lookup_message (void *cls, | ||
354 | const struct LookupMessage *message) | ||
355 | { | ||
356 | struct GNUNET_SERVICE_Client *client = cls; | ||
357 | const char *name; | ||
358 | struct GNUNET_MQ_Envelope *env; | ||
359 | struct Ego *ego; | ||
360 | |||
361 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
362 | "Received LOOKUP message from client\n"); | ||
363 | name = (const char *) &message[1]; | ||
364 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
365 | { | ||
366 | if (0 != strcasecmp (name, ego->identifier)) | ||
367 | continue; | ||
368 | env = create_update_message (ego); | ||
369 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
370 | GNUNET_SERVICE_client_continue (client); | ||
371 | return; | ||
372 | } | ||
373 | send_result_code (client, 0, "ego not found"); | ||
374 | GNUNET_SERVICE_client_continue (client); | ||
375 | } | ||
376 | |||
377 | |||
378 | /** | ||
379 | * Handler for LOOKUP message from client, sends information | ||
380 | * about ONE identity to the client immediately. | ||
381 | * | ||
382 | * @param cls unused | ||
383 | * @param message the message received | ||
384 | * @return #GNUNET_SYSERR if message was ill-formed | ||
385 | */ | ||
386 | static int | ||
387 | check_lookup_by_suffix_message (void *cls, | ||
388 | const struct LookupMessage *message) | ||
389 | { | ||
390 | GNUNET_MQ_check_zero_termination (message); | ||
391 | return GNUNET_OK; | ||
392 | } | ||
393 | |||
394 | |||
395 | /** | ||
396 | * Handler for LOOKUP_BY_SUFFIX message from client, sends information | ||
397 | * about ONE identity to the client immediately. | ||
398 | * | ||
399 | * @param cls a `struct GNUNET_SERVICE_Client *` | ||
400 | * @param message the message received | ||
401 | */ | ||
402 | static void | ||
403 | handle_lookup_by_suffix_message (void *cls, | ||
404 | const struct LookupMessage *message) | ||
405 | { | ||
406 | struct GNUNET_SERVICE_Client *client = cls; | ||
407 | const char *name; | ||
408 | struct GNUNET_MQ_Envelope *env; | ||
409 | struct Ego *lprefix; | ||
410 | |||
411 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
412 | "Received LOOKUP_BY_SUFFIX message from client\n"); | ||
413 | name = (const char *) &message[1]; | ||
414 | lprefix = NULL; | ||
415 | for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next) | ||
416 | { | ||
417 | if ((strlen (ego->identifier) <= strlen (name)) && | ||
418 | (0 == strcmp (ego->identifier, | ||
419 | &name[strlen (name) - strlen (ego->identifier)])) && | ||
420 | ((strlen (name) == strlen (ego->identifier)) || | ||
421 | ('.' == name[strlen (name) - strlen (ego->identifier) - 1])) && | ||
422 | ((NULL == lprefix) || | ||
423 | (strlen (ego->identifier) > strlen (lprefix->identifier)))) | ||
424 | { | ||
425 | /* found better match, update! */ | ||
426 | lprefix = ego; | ||
427 | } | ||
428 | } | ||
429 | if (NULL != lprefix) | ||
430 | { | ||
431 | env = create_update_message (lprefix); | ||
432 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
433 | GNUNET_SERVICE_client_continue (client); | ||
434 | return; | ||
435 | } | ||
436 | send_result_code (client, 0, "ego not found"); | ||
437 | GNUNET_SERVICE_client_continue (client); | ||
438 | } | ||
439 | |||
440 | |||
441 | /** | ||
442 | * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT message | ||
443 | * | ||
444 | * @param cls client sending the message | ||
445 | * @param msg message of type `struct GetDefaultMessage` | ||
446 | * @return #GNUNET_OK if @a msg is well-formed | ||
447 | */ | ||
448 | static int | ||
449 | check_get_default_message (void *cls, | ||
450 | const struct GetDefaultMessage *msg) | ||
451 | { | ||
452 | uint16_t size; | ||
453 | uint16_t name_len; | ||
454 | const char *name; | ||
455 | |||
456 | size = ntohs (msg->header.size); | ||
457 | if (size <= sizeof(struct GetDefaultMessage)) | ||
458 | { | ||
459 | GNUNET_break (0); | ||
460 | return GNUNET_SYSERR; | ||
461 | } | ||
462 | name = (const char *) &msg[1]; | ||
463 | name_len = ntohs (msg->name_len); | ||
464 | if ((name_len + sizeof(struct GetDefaultMessage) != size) || | ||
465 | (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1])) | ||
466 | { | ||
467 | GNUNET_break (0); | ||
468 | return GNUNET_SYSERR; | ||
469 | } | ||
470 | return GNUNET_OK; | ||
471 | } | ||
472 | |||
473 | |||
474 | /** | ||
475 | * Handler for GET_DEFAULT message from client, returns | ||
476 | * default identity for some service. | ||
477 | * | ||
478 | * @param cls unused | ||
479 | * @param client who sent the message | ||
480 | * @param message the message received | ||
481 | */ | ||
482 | static void | ||
483 | handle_get_default_message (void *cls, | ||
484 | const struct GetDefaultMessage *gdm) | ||
485 | { | ||
486 | struct GNUNET_MQ_Envelope *env; | ||
487 | struct GNUNET_SERVICE_Client *client = cls; | ||
488 | char *name; | ||
489 | char *identifier; | ||
490 | |||
491 | name = GNUNET_strdup ((const char *) &gdm[1]); | ||
492 | GNUNET_STRINGS_utf8_tolower ((const char *) &gdm[1], | ||
493 | name); | ||
494 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
495 | "Received GET_DEFAULT for service `%s' from client\n", | ||
496 | name); | ||
497 | if (GNUNET_OK != | ||
498 | GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, | ||
499 | name, | ||
500 | "DEFAULT_IDENTIFIER", | ||
501 | &identifier)) | ||
502 | { | ||
503 | send_result_code (client, 1, gettext_noop ("no default known")); | ||
504 | GNUNET_SERVICE_client_continue (client); | ||
505 | GNUNET_free (name); | ||
506 | return; | ||
507 | } | ||
508 | for (struct Ego *ego = ego_head; NULL != ego; ego = ego->next) | ||
509 | { | ||
510 | if (0 == strcmp (ego->identifier, identifier)) | ||
511 | { | ||
512 | env = create_set_default_message (ego, name); | ||
513 | GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client), env); | ||
514 | GNUNET_SERVICE_client_continue (client); | ||
515 | GNUNET_free (identifier); | ||
516 | GNUNET_free (name); | ||
517 | return; | ||
518 | } | ||
519 | } | ||
520 | GNUNET_free (identifier); | ||
521 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
522 | "Failed to find ego `%s'\n", | ||
523 | name); | ||
524 | GNUNET_free (name); | ||
525 | send_result_code (client, | ||
526 | 1, | ||
527 | gettext_noop ( | ||
528 | "default configured, but ego unknown (internal error)")); | ||
529 | GNUNET_SERVICE_client_continue (client); | ||
530 | } | ||
531 | |||
532 | |||
533 | /** | ||
534 | * Compare the given two private keys for equality. | ||
535 | * | ||
536 | * @param pk1 one private key | ||
537 | * @param pk2 another private key | ||
538 | * @return 0 if the keys are equal | ||
539 | */ | ||
540 | static int | ||
541 | key_cmp (const struct GNUNET_IDENTITY_PrivateKey *pk1, | ||
542 | const struct GNUNET_IDENTITY_PrivateKey *pk2) | ||
543 | { | ||
544 | return GNUNET_memcmp (pk1, pk2); | ||
545 | } | ||
546 | |||
547 | |||
548 | /** | ||
549 | * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT message | ||
550 | * | ||
551 | * @param cls client sending the message | ||
552 | * @param msg message of type `struct SetDefaultMessage` | ||
553 | * @return #GNUNET_OK if @a msg is well-formed | ||
554 | */ | ||
555 | static int | ||
556 | check_set_default_message (void *cls, | ||
557 | const struct SetDefaultMessage *msg) | ||
558 | { | ||
559 | uint16_t size; | ||
560 | uint16_t name_len; | ||
561 | const char *str; | ||
562 | |||
563 | size = ntohs (msg->header.size); | ||
564 | if (size <= sizeof(struct SetDefaultMessage)) | ||
565 | { | ||
566 | GNUNET_break (0); | ||
567 | return GNUNET_SYSERR; | ||
568 | } | ||
569 | name_len = ntohs (msg->name_len); | ||
570 | GNUNET_break (0 == ntohs (msg->reserved)); | ||
571 | if (name_len + sizeof(struct SetDefaultMessage) != size) | ||
572 | { | ||
573 | GNUNET_break (0); | ||
574 | return GNUNET_SYSERR; | ||
575 | } | ||
576 | str = (const char *) &msg[1]; | ||
577 | if ('\0' != str[name_len - 1]) | ||
578 | { | ||
579 | GNUNET_break (0); | ||
580 | return GNUNET_SYSERR; | ||
581 | } | ||
582 | return GNUNET_OK; | ||
583 | } | ||
584 | |||
585 | |||
586 | /** | ||
587 | * Handler for SET_DEFAULT message from client, updates | ||
588 | * default identity for some service. | ||
589 | * | ||
590 | * @param cls unused | ||
591 | * @param client who sent the message | ||
592 | * @param message the message received | ||
593 | */ | ||
594 | static void | ||
595 | handle_set_default_message (void *cls, | ||
596 | const struct SetDefaultMessage *sdm) | ||
597 | { | ||
598 | struct Ego *ego; | ||
599 | struct GNUNET_SERVICE_Client *client = cls; | ||
600 | char *str; | ||
601 | |||
602 | str = GNUNET_strdup ((const char *) &sdm[1]); | ||
603 | GNUNET_STRINGS_utf8_tolower ((const char *) &sdm[1], str); | ||
604 | |||
605 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
606 | "Received SET_DEFAULT for service `%s' from client\n", | ||
607 | str); | ||
608 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
609 | { | ||
610 | if (0 == key_cmp (&ego->pk, | ||
611 | &sdm->private_key)) | ||
612 | { | ||
613 | GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, | ||
614 | str, | ||
615 | "DEFAULT_IDENTIFIER", | ||
616 | ego->identifier); | ||
617 | if (GNUNET_OK != | ||
618 | GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) | ||
619 | GNUNET_log ( | ||
620 | GNUNET_ERROR_TYPE_ERROR, | ||
621 | _ ("Failed to write subsystem default identifier map to `%s'.\n"), | ||
622 | subsystem_cfg_file); | ||
623 | send_result_code (client, 0, NULL); | ||
624 | GNUNET_SERVICE_client_continue (client); | ||
625 | GNUNET_free (str); | ||
626 | return; | ||
627 | } | ||
628 | } | ||
629 | send_result_code (client, | ||
630 | 1, | ||
631 | _ ("Unknown ego specified for service (internal error)")); | ||
632 | GNUNET_free (str); | ||
633 | GNUNET_SERVICE_client_continue (client); | ||
634 | } | ||
635 | |||
636 | |||
637 | /** | ||
638 | * Send an updated message for the given ego to all listeners. | ||
639 | * | ||
640 | * @param ego ego to send the update for | ||
641 | */ | ||
642 | static void | ||
643 | notify_listeners (struct Ego *ego) | ||
644 | { | ||
645 | struct UpdateMessage *um; | ||
646 | size_t name_len; | ||
647 | |||
648 | name_len = (NULL == ego->identifier) ? 0 : (strlen (ego->identifier) + 1); | ||
649 | um = GNUNET_malloc (sizeof(struct UpdateMessage) + name_len); | ||
650 | um->header.type = htons (GNUNET_MESSAGE_TYPE_IDENTITY_UPDATE); | ||
651 | um->header.size = htons (sizeof(struct UpdateMessage) + name_len); | ||
652 | um->name_len = htons (name_len); | ||
653 | um->end_of_list = htons (GNUNET_NO); | ||
654 | um->private_key = ego->pk; | ||
655 | GNUNET_memcpy (&um[1], ego->identifier, name_len); | ||
656 | GNUNET_notification_context_broadcast (nc, &um->header, GNUNET_NO); | ||
657 | GNUNET_free (um); | ||
658 | } | ||
659 | |||
660 | |||
661 | /** | ||
662 | * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_CREATE message | ||
663 | * | ||
664 | * @param cls client sending the message | ||
665 | * @param msg message of type `struct CreateRequestMessage` | ||
666 | * @return #GNUNET_OK if @a msg is well-formed | ||
667 | */ | ||
668 | static int | ||
669 | check_create_message (void *cls, | ||
670 | const struct CreateRequestMessage *msg) | ||
671 | { | ||
672 | uint16_t size; | ||
673 | uint16_t name_len; | ||
674 | const char *str; | ||
675 | |||
676 | size = ntohs (msg->header.size); | ||
677 | if (size <= sizeof(struct CreateRequestMessage)) | ||
678 | { | ||
679 | GNUNET_break (0); | ||
680 | return GNUNET_SYSERR; | ||
681 | } | ||
682 | name_len = ntohs (msg->name_len); | ||
683 | GNUNET_break (0 == ntohs (msg->reserved)); | ||
684 | if (name_len + sizeof(struct CreateRequestMessage) != size) | ||
685 | { | ||
686 | GNUNET_break (0); | ||
687 | return GNUNET_SYSERR; | ||
688 | } | ||
689 | str = (const char *) &msg[1]; | ||
690 | if ('\0' != str[name_len - 1]) | ||
691 | { | ||
692 | GNUNET_break (0); | ||
693 | return GNUNET_SYSERR; | ||
694 | } | ||
695 | return GNUNET_OK; | ||
696 | } | ||
697 | |||
698 | |||
699 | /** | ||
700 | * Handler for CREATE message from client, creates new identity. | ||
701 | * | ||
702 | * @param cls unused | ||
703 | * @param client who sent the message | ||
704 | * @param message the message received | ||
705 | */ | ||
706 | static void | ||
707 | handle_create_message (void *cls, | ||
708 | const struct CreateRequestMessage *crm) | ||
709 | { | ||
710 | struct GNUNET_SERVICE_Client *client = cls; | ||
711 | struct Ego *ego; | ||
712 | char *str; | ||
713 | char *fn; | ||
714 | |||
715 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received CREATE message from client\n"); | ||
716 | str = GNUNET_strdup ((const char *) &crm[1]); | ||
717 | GNUNET_STRINGS_utf8_tolower ((const char *) &crm[1], str); | ||
718 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
719 | { | ||
720 | if (0 == strcmp (ego->identifier, str)) | ||
721 | { | ||
722 | send_result_code (client, | ||
723 | 1, | ||
724 | gettext_noop ( | ||
725 | "identifier already in use for another ego")); | ||
726 | GNUNET_SERVICE_client_continue (client); | ||
727 | GNUNET_free (str); | ||
728 | return; | ||
729 | } | ||
730 | } | ||
731 | ego = GNUNET_new (struct Ego); | ||
732 | ego->pk = crm->private_key; | ||
733 | ego->identifier = GNUNET_strdup (str); | ||
734 | GNUNET_CONTAINER_DLL_insert (ego_head, | ||
735 | ego_tail, | ||
736 | ego); | ||
737 | send_result_code (client, 0, NULL); | ||
738 | fn = get_ego_filename (ego); | ||
739 | if (GNUNET_OK != | ||
740 | GNUNET_DISK_fn_write (fn, | ||
741 | &crm->private_key, | ||
742 | sizeof(struct GNUNET_IDENTITY_PrivateKey), | ||
743 | GNUNET_DISK_PERM_USER_READ | ||
744 | | GNUNET_DISK_PERM_USER_WRITE)) | ||
745 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "write", fn); | ||
746 | GNUNET_free (fn); | ||
747 | GNUNET_free (str); | ||
748 | notify_listeners (ego); | ||
749 | GNUNET_SERVICE_client_continue (client); | ||
750 | } | ||
751 | |||
752 | |||
753 | /** | ||
754 | * Closure for 'handle_ego_rename'. | ||
755 | */ | ||
756 | struct RenameContext | ||
757 | { | ||
758 | /** | ||
759 | * Old name. | ||
760 | */ | ||
761 | const char *old_name; | ||
762 | |||
763 | /** | ||
764 | * New name. | ||
765 | */ | ||
766 | const char *new_name; | ||
767 | }; | ||
768 | |||
769 | /** | ||
770 | * An ego was renamed; rename it in all subsystems where it is | ||
771 | * currently set as the default. | ||
772 | * | ||
773 | * @param cls the 'struct RenameContext' | ||
774 | * @param section a section in the configuration to process | ||
775 | */ | ||
776 | static void | ||
777 | handle_ego_rename (void *cls, const char *section) | ||
778 | { | ||
779 | struct RenameContext *rc = cls; | ||
780 | char *id; | ||
781 | |||
782 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, | ||
783 | section, | ||
784 | "DEFAULT_IDENTIFIER", | ||
785 | &id)) | ||
786 | return; | ||
787 | if (0 != strcmp (id, rc->old_name)) | ||
788 | { | ||
789 | GNUNET_free (id); | ||
790 | return; | ||
791 | } | ||
792 | GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, | ||
793 | section, | ||
794 | "DEFAULT_IDENTIFIER", | ||
795 | rc->new_name); | ||
796 | GNUNET_free (id); | ||
797 | } | ||
798 | |||
799 | |||
800 | /** | ||
801 | * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_RENAME message | ||
802 | * | ||
803 | * @param cls client sending the message | ||
804 | * @param msg message of type `struct RenameMessage` | ||
805 | * @return #GNUNET_OK if @a msg is well-formed | ||
806 | */ | ||
807 | static int | ||
808 | check_rename_message (void *cls, const struct RenameMessage *msg) | ||
809 | { | ||
810 | uint16_t size; | ||
811 | uint16_t old_name_len; | ||
812 | uint16_t new_name_len; | ||
813 | const char *old_name; | ||
814 | const char *new_name; | ||
815 | |||
816 | size = ntohs (msg->header.size); | ||
817 | if (size <= sizeof(struct RenameMessage)) | ||
818 | { | ||
819 | GNUNET_break (0); | ||
820 | return GNUNET_SYSERR; | ||
821 | } | ||
822 | old_name_len = ntohs (msg->old_name_len); | ||
823 | new_name_len = ntohs (msg->new_name_len); | ||
824 | old_name = (const char *) &msg[1]; | ||
825 | new_name = &old_name[old_name_len]; | ||
826 | if ((old_name_len + new_name_len + sizeof(struct RenameMessage) != size) || | ||
827 | ('\0' != old_name[old_name_len - 1]) || | ||
828 | ('\0' != new_name[new_name_len - 1])) | ||
829 | { | ||
830 | GNUNET_break (0); | ||
831 | return GNUNET_SYSERR; | ||
832 | } | ||
833 | |||
834 | return GNUNET_OK; | ||
835 | } | ||
836 | |||
837 | |||
838 | /** | ||
839 | * Handler for RENAME message from client, creates | ||
840 | * new identity. | ||
841 | * | ||
842 | * @param cls unused | ||
843 | * @param client who sent the message | ||
844 | * @param message the message received | ||
845 | */ | ||
846 | static void | ||
847 | handle_rename_message (void *cls, const struct RenameMessage *rm) | ||
848 | { | ||
849 | uint16_t old_name_len; | ||
850 | struct Ego *ego; | ||
851 | char *old_name; | ||
852 | char *new_name; | ||
853 | struct RenameContext rename_ctx; | ||
854 | struct GNUNET_SERVICE_Client *client = cls; | ||
855 | char *fn_old; | ||
856 | char *fn_new; | ||
857 | const char *old_name_tmp; | ||
858 | |||
859 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received RENAME message from client\n"); | ||
860 | old_name_len = ntohs (rm->old_name_len); | ||
861 | old_name_tmp = (const char *) &rm[1]; | ||
862 | old_name = GNUNET_strdup (old_name_tmp); | ||
863 | GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name); | ||
864 | new_name = GNUNET_strdup (&old_name_tmp[old_name_len]); | ||
865 | GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name); | ||
866 | |||
867 | /* check if new name is already in use */ | ||
868 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
869 | { | ||
870 | if (0 == strcmp (ego->identifier, new_name)) | ||
871 | { | ||
872 | send_result_code (client, 1, gettext_noop ("target name already exists")); | ||
873 | GNUNET_SERVICE_client_continue (client); | ||
874 | GNUNET_free (old_name); | ||
875 | GNUNET_free (new_name); | ||
876 | return; | ||
877 | } | ||
878 | } | ||
879 | |||
880 | /* locate old name and, if found, perform rename */ | ||
881 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
882 | { | ||
883 | if (0 == strcmp (ego->identifier, old_name)) | ||
884 | { | ||
885 | fn_old = get_ego_filename (ego); | ||
886 | GNUNET_free (ego->identifier); | ||
887 | rename_ctx.old_name = old_name; | ||
888 | rename_ctx.new_name = new_name; | ||
889 | GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, | ||
890 | &handle_ego_rename, | ||
891 | &rename_ctx); | ||
892 | if (GNUNET_OK != | ||
893 | GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) | ||
894 | GNUNET_log ( | ||
895 | GNUNET_ERROR_TYPE_ERROR, | ||
896 | _ ("Failed to write subsystem default identifier map to `%s'.\n"), | ||
897 | subsystem_cfg_file); | ||
898 | ego->identifier = GNUNET_strdup (new_name); | ||
899 | fn_new = get_ego_filename (ego); | ||
900 | if (0 != rename (fn_old, fn_new)) | ||
901 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "rename", fn_old); | ||
902 | GNUNET_free (fn_old); | ||
903 | GNUNET_free (fn_new); | ||
904 | GNUNET_free (old_name); | ||
905 | GNUNET_free (new_name); | ||
906 | notify_listeners (ego); | ||
907 | send_result_code (client, 0, NULL); | ||
908 | GNUNET_SERVICE_client_continue (client); | ||
909 | return; | ||
910 | } | ||
911 | } | ||
912 | |||
913 | /* failed to locate old name */ | ||
914 | send_result_code (client, 1, gettext_noop ("no matching ego found")); | ||
915 | GNUNET_free (old_name); | ||
916 | GNUNET_free (new_name); | ||
917 | GNUNET_SERVICE_client_continue (client); | ||
918 | } | ||
919 | |||
920 | |||
921 | /** | ||
922 | * An ego was removed, remove it from all subsystems where it is | ||
923 | * currently set as the default. | ||
924 | * | ||
925 | * @param cls name of the removed ego (const char *) | ||
926 | * @param section a section in the configuration to process | ||
927 | */ | ||
928 | static void | ||
929 | handle_ego_delete (void *cls, const char *section) | ||
930 | { | ||
931 | const char *identifier = cls; | ||
932 | char *id; | ||
933 | |||
934 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (subsystem_cfg, | ||
935 | section, | ||
936 | "DEFAULT_IDENTIFIER", | ||
937 | &id)) | ||
938 | return; | ||
939 | if (0 != strcmp (id, identifier)) | ||
940 | { | ||
941 | GNUNET_free (id); | ||
942 | return; | ||
943 | } | ||
944 | GNUNET_CONFIGURATION_set_value_string (subsystem_cfg, | ||
945 | section, | ||
946 | "DEFAULT_IDENTIFIER", | ||
947 | NULL); | ||
948 | GNUNET_free (id); | ||
949 | } | ||
950 | |||
951 | |||
952 | /** | ||
953 | * Checks a #GNUNET_MESSAGE_TYPE_IDENTITY_DELETE message | ||
954 | * | ||
955 | * @param cls client sending the message | ||
956 | * @param msg message of type `struct DeleteMessage` | ||
957 | * @return #GNUNET_OK if @a msg is well-formed | ||
958 | */ | ||
959 | static int | ||
960 | check_delete_message (void *cls, const struct DeleteMessage *msg) | ||
961 | { | ||
962 | uint16_t size; | ||
963 | uint16_t name_len; | ||
964 | const char *name; | ||
965 | |||
966 | size = ntohs (msg->header.size); | ||
967 | if (size <= sizeof(struct DeleteMessage)) | ||
968 | { | ||
969 | GNUNET_break (0); | ||
970 | return GNUNET_SYSERR; | ||
971 | } | ||
972 | name = (const char *) &msg[1]; | ||
973 | name_len = ntohs (msg->name_len); | ||
974 | if ((name_len + sizeof(struct DeleteMessage) != size) || | ||
975 | (0 != ntohs (msg->reserved)) || ('\0' != name[name_len - 1])) | ||
976 | { | ||
977 | GNUNET_break (0); | ||
978 | return GNUNET_SYSERR; | ||
979 | } | ||
980 | return GNUNET_OK; | ||
981 | } | ||
982 | |||
983 | |||
984 | /** | ||
985 | * Handler for DELETE message from client, creates | ||
986 | * new identity. | ||
987 | * | ||
988 | * @param cls unused | ||
989 | * @param client who sent the message | ||
990 | * @param message the message received | ||
991 | */ | ||
992 | static void | ||
993 | handle_delete_message (void *cls, const struct DeleteMessage *dm) | ||
994 | { | ||
995 | struct Ego *ego; | ||
996 | char *name; | ||
997 | char *fn; | ||
998 | struct GNUNET_SERVICE_Client *client = cls; | ||
999 | |||
1000 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received DELETE message from client\n"); | ||
1001 | name = GNUNET_strdup ((const char *) &dm[1]); | ||
1002 | GNUNET_STRINGS_utf8_tolower ((const char *) &dm[1], name); | ||
1003 | |||
1004 | for (ego = ego_head; NULL != ego; ego = ego->next) | ||
1005 | { | ||
1006 | if (0 == strcmp (ego->identifier, name)) | ||
1007 | { | ||
1008 | GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, ego); | ||
1009 | GNUNET_CONFIGURATION_iterate_sections (subsystem_cfg, | ||
1010 | &handle_ego_delete, | ||
1011 | ego->identifier); | ||
1012 | if (GNUNET_OK != | ||
1013 | GNUNET_CONFIGURATION_write (subsystem_cfg, subsystem_cfg_file)) | ||
1014 | GNUNET_log ( | ||
1015 | GNUNET_ERROR_TYPE_ERROR, | ||
1016 | _ ("Failed to write subsystem default identifier map to `%s'.\n"), | ||
1017 | subsystem_cfg_file); | ||
1018 | fn = get_ego_filename (ego); | ||
1019 | if (0 != unlink (fn)) | ||
1020 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn); | ||
1021 | GNUNET_free (fn); | ||
1022 | GNUNET_free (ego->identifier); | ||
1023 | ego->identifier = NULL; | ||
1024 | notify_listeners (ego); | ||
1025 | GNUNET_free (ego); | ||
1026 | GNUNET_free (name); | ||
1027 | send_result_code (client, 0, NULL); | ||
1028 | GNUNET_SERVICE_client_continue (client); | ||
1029 | return; | ||
1030 | } | ||
1031 | } | ||
1032 | |||
1033 | send_result_code (client, 1, gettext_noop ("no matching ego found")); | ||
1034 | GNUNET_free (name); | ||
1035 | GNUNET_SERVICE_client_continue (client); | ||
1036 | } | ||
1037 | |||
1038 | |||
1039 | static int | ||
1040 | read_from_file (const char *filename, | ||
1041 | void *buf, | ||
1042 | size_t buf_size) | ||
1043 | { | ||
1044 | int fd; | ||
1045 | struct stat sb; | ||
1046 | |||
1047 | fd = open (filename, | ||
1048 | O_RDONLY); | ||
1049 | if (-1 == fd) | ||
1050 | { | ||
1051 | memset (buf, | ||
1052 | 0, | ||
1053 | buf_size); | ||
1054 | return GNUNET_SYSERR; | ||
1055 | } | ||
1056 | if (0 != fstat (fd, | ||
1057 | &sb)) | ||
1058 | { | ||
1059 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
1060 | "stat", | ||
1061 | filename); | ||
1062 | GNUNET_assert (0 == close (fd)); | ||
1063 | memset (buf, | ||
1064 | 0, | ||
1065 | buf_size); | ||
1066 | return GNUNET_SYSERR; | ||
1067 | } | ||
1068 | if (sb.st_size != buf_size) | ||
1069 | { | ||
1070 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1071 | "File `%s' has wrong size (%llu), expected %llu bytes\n", | ||
1072 | filename, | ||
1073 | (unsigned long long) sb.st_size, | ||
1074 | (unsigned long long) buf_size); | ||
1075 | GNUNET_assert (0 == close (fd)); | ||
1076 | memset (buf, | ||
1077 | 0, | ||
1078 | buf_size); | ||
1079 | return GNUNET_SYSERR; | ||
1080 | } | ||
1081 | if (buf_size != | ||
1082 | read (fd, | ||
1083 | buf, | ||
1084 | buf_size)) | ||
1085 | { | ||
1086 | GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, | ||
1087 | "read", | ||
1088 | filename); | ||
1089 | GNUNET_assert (0 == close (fd)); | ||
1090 | memset (buf, | ||
1091 | 0, | ||
1092 | buf_size); | ||
1093 | return GNUNET_SYSERR; | ||
1094 | } | ||
1095 | GNUNET_assert (0 == close (fd)); | ||
1096 | return GNUNET_OK; | ||
1097 | } | ||
1098 | |||
1099 | |||
1100 | /** | ||
1101 | * Process the given file from the "EGODIR". Parses the file | ||
1102 | * and creates the respective 'struct Ego' in memory. | ||
1103 | * | ||
1104 | * @param cls NULL | ||
1105 | * @param filename name of the file to parse | ||
1106 | * @return #GNUNET_OK to continue to iterate, | ||
1107 | * #GNUNET_NO to stop iteration with no error, | ||
1108 | * #GNUNET_SYSERR to abort iteration with error! | ||
1109 | */ | ||
1110 | static int | ||
1111 | process_ego_file (void *cls, | ||
1112 | const char *filename) | ||
1113 | { | ||
1114 | struct Ego *ego; | ||
1115 | const char *fn; | ||
1116 | |||
1117 | fn = strrchr (filename, (int) DIR_SEPARATOR); | ||
1118 | if (NULL == fn) | ||
1119 | { | ||
1120 | GNUNET_break (0); | ||
1121 | return GNUNET_OK; | ||
1122 | } | ||
1123 | ego = GNUNET_new (struct Ego); | ||
1124 | if (GNUNET_OK != | ||
1125 | read_from_file (filename, | ||
1126 | &ego->pk, | ||
1127 | sizeof (ego->pk))) | ||
1128 | { | ||
1129 | GNUNET_free (ego); | ||
1130 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1131 | _ ("Failed to parse ego information in `%s'\n"), | ||
1132 | filename); | ||
1133 | return GNUNET_OK; | ||
1134 | } | ||
1135 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1136 | "Loaded ego `%s'\n", | ||
1137 | fn + 1); | ||
1138 | ego->identifier = GNUNET_strdup (fn + 1); | ||
1139 | GNUNET_CONTAINER_DLL_insert (ego_head, ego_tail, ego); | ||
1140 | return GNUNET_OK; | ||
1141 | } | ||
1142 | |||
1143 | |||
1144 | /** | ||
1145 | * Handle network size estimate clients. | ||
1146 | * | ||
1147 | * @param cls closure | ||
1148 | * @param server the initialized server | ||
1149 | * @param c configuration to use | ||
1150 | */ | ||
1151 | static void | ||
1152 | run (void *cls, | ||
1153 | const struct GNUNET_CONFIGURATION_Handle *c, | ||
1154 | struct GNUNET_SERVICE_Handle *service) | ||
1155 | { | ||
1156 | cfg = c; | ||
1157 | nc = GNUNET_notification_context_create (1); | ||
1158 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
1159 | "identity", | ||
1160 | "EGODIR", | ||
1161 | &ego_directory)) | ||
1162 | { | ||
1163 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR"); | ||
1164 | GNUNET_SCHEDULER_shutdown (); | ||
1165 | return; | ||
1166 | } | ||
1167 | if (GNUNET_OK != | ||
1168 | GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
1169 | "identity", | ||
1170 | "SUBSYSTEM_CFG", | ||
1171 | &subsystem_cfg_file)) | ||
1172 | { | ||
1173 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
1174 | "identity", | ||
1175 | "SUBSYSTEM_CFG"); | ||
1176 | GNUNET_SCHEDULER_shutdown (); | ||
1177 | return; | ||
1178 | } | ||
1179 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1180 | "Loading subsystem configuration `%s'\n", | ||
1181 | subsystem_cfg_file); | ||
1182 | subsystem_cfg = GNUNET_CONFIGURATION_create (); | ||
1183 | if ((GNUNET_YES == GNUNET_DISK_file_test (subsystem_cfg_file)) && | ||
1184 | (GNUNET_OK != | ||
1185 | GNUNET_CONFIGURATION_parse (subsystem_cfg, subsystem_cfg_file))) | ||
1186 | { | ||
1187 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1188 | _ ( | ||
1189 | "Failed to parse subsystem identity configuration file `%s'\n"), | ||
1190 | subsystem_cfg_file); | ||
1191 | GNUNET_SCHEDULER_shutdown (); | ||
1192 | return; | ||
1193 | } | ||
1194 | stats = GNUNET_STATISTICS_create ("identity", cfg); | ||
1195 | if (GNUNET_OK != GNUNET_DISK_directory_create (ego_directory)) | ||
1196 | { | ||
1197 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1198 | _ ("Failed to create directory `%s' for storing egos\n"), | ||
1199 | ego_directory); | ||
1200 | } | ||
1201 | GNUNET_DISK_directory_scan (ego_directory, | ||
1202 | &process_ego_file, | ||
1203 | NULL); | ||
1204 | GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); | ||
1205 | } | ||
1206 | |||
1207 | |||
1208 | /** | ||
1209 | * Define "main" method using service macro. | ||
1210 | */ | ||
1211 | GNUNET_SERVICE_MAIN ( | ||
1212 | "identity", | ||
1213 | GNUNET_SERVICE_OPTION_NONE, | ||
1214 | &run, | ||
1215 | &client_connect_cb, | ||
1216 | &client_disconnect_cb, | ||
1217 | NULL, | ||
1218 | GNUNET_MQ_hd_fixed_size (start_message, | ||
1219 | GNUNET_MESSAGE_TYPE_IDENTITY_START, | ||
1220 | struct GNUNET_MessageHeader, | ||
1221 | NULL), | ||
1222 | GNUNET_MQ_hd_var_size (lookup_message, | ||
1223 | GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP, | ||
1224 | struct LookupMessage, | ||
1225 | NULL), | ||
1226 | GNUNET_MQ_hd_var_size (lookup_by_suffix_message, | ||
1227 | GNUNET_MESSAGE_TYPE_IDENTITY_LOOKUP_BY_SUFFIX, | ||
1228 | struct LookupMessage, | ||
1229 | NULL), | ||
1230 | GNUNET_MQ_hd_var_size (get_default_message, | ||
1231 | GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, | ||
1232 | struct GetDefaultMessage, | ||
1233 | NULL), | ||
1234 | GNUNET_MQ_hd_var_size (set_default_message, | ||
1235 | GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, | ||
1236 | struct SetDefaultMessage, | ||
1237 | NULL), | ||
1238 | GNUNET_MQ_hd_var_size (create_message, | ||
1239 | GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, | ||
1240 | struct CreateRequestMessage, | ||
1241 | NULL), | ||
1242 | GNUNET_MQ_hd_var_size (rename_message, | ||
1243 | GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, | ||
1244 | struct RenameMessage, | ||
1245 | NULL), | ||
1246 | GNUNET_MQ_hd_var_size (delete_message, | ||
1247 | GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, | ||
1248 | struct DeleteMessage, | ||
1249 | NULL), | ||
1250 | GNUNET_MQ_handler_end ()); | ||
1251 | |||
1252 | |||
1253 | /* end of gnunet-service-identity.c */ | ||