daf50d450b896a4d8d7f81d00801b532dfa230ae
[oweals/gnunet.git] / src / identity / gnunet-service-identity.c
1 /*
2   This file is part of GNUnet.
3   (C) 2013 Christian Grothoff (and other contributing authors)
4
5   GNUnet is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published
7   by the Free Software Foundation; either version 3, or (at your
8   option) any later version.
9
10   GNUnet is distributed in the hope that it will be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with GNUnet; see the file COPYING.  If not, write to the
17   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18   Boston, MA 02111-1307, USA.
19  */
20
21 /**
22  * @file 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 #include "platform.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_constants.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_statistics_service.h"
34 #include "gnunet_identity_service.h"
35 #include "identity.h"
36
37
38 /**
39  * Information we keep about each ego.
40  */
41 struct Ego
42 {
43
44   /**
45    * We keep egos in a DLL.
46    */ 
47   struct Ego *next;
48
49   /**
50    * We keep egos in a DLL.
51    */ 
52   struct Ego *prev;
53
54   /**
55    * Private key of the ego.
56    */
57   struct GNUNET_CRYPTO_EccPrivateKey *pk;
58
59   /**
60    * String identifier for the ego.
61    */
62   char *identifier;
63
64 };
65
66
67 /**
68  * Handle to our current configuration.
69  */
70 static const struct GNUNET_CONFIGURATION_Handle *cfg;
71
72 /**
73  * Handle to subsystem configuration which for each subsystem contains
74  * the name of the default ego.
75  */
76 static struct GNUNET_CONFIGURATION_Handle *subsystem_cfg;
77
78 /**
79  * Handle to the statistics service.
80  */
81 static struct GNUNET_STATISTICS_Handle *stats;
82
83 /**
84  * Notification context, simplifies client broadcasts.
85  */
86 static struct GNUNET_SERVER_NotificationContext *nc;
87
88 /**
89  * Directory where we store the identities.
90  */
91 static char *ego_directory;
92
93 /**
94  * Configuration file name where subsystem information is kept.
95  */
96 static char *subsystem_cfg_file;
97
98 /**
99  * Head of DLL of all egos.
100  */
101 static struct Ego *ego_head;
102
103 /**
104  * Tail of DLL of all egos.
105  */
106 static struct Ego *ego_tail;
107
108
109 /**
110  * Task run during shutdown.
111  *
112  * @param cls unused
113  * @param tc unused
114  */
115 static void
116 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
117 {
118   struct Ego *e;
119
120   if (NULL != nc)
121   {
122     GNUNET_SERVER_notification_context_destroy (nc);
123     nc = NULL;
124   }
125   if (NULL != stats)
126   {
127     GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
128     stats = NULL;
129   }
130   GNUNET_CONFIGURATION_destroy (subsystem_cfg);
131   subsystem_cfg = NULL;
132   GNUNET_free (subsystem_cfg_file);
133   subsystem_cfg_file = NULL;
134   GNUNET_free (ego_directory);
135   ego_directory = NULL;
136   while (NULL != (e = ego_head))
137   {
138     GNUNET_CONTAINER_DLL_remove (ego_head, ego_tail, e);
139     GNUNET_CRYPTO_ecc_key_free (e->pk);
140     GNUNET_free (e);
141   }
142 }
143
144
145 /**
146  * Handler for START message from client, sends information
147  * about all identities to the client immediately and 
148  * adds the client to the notification context for future
149  * updates.
150  *
151  * @param cls unused
152  * @param client who sent the message
153  * @param message the message received
154  */
155 static void
156 handle_start_message (void *cls, struct GNUNET_SERVER_Client *client,
157                       const struct GNUNET_MessageHeader *message)
158 {
159   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
160               "Received START message from client\n");
161   GNUNET_SERVER_notification_context_add (nc, client);
162   GNUNET_break (0); // not implemented!
163   // setup_estimate_message (&em);
164   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
165   GNUNET_SERVER_receive_done (client, GNUNET_OK);
166 }
167
168
169 /**
170  * Handler for GET_DEFAULT message from client, returns
171  * default identity for some service.
172  *
173  * @param cls unused
174  * @param client who sent the message
175  * @param message the message received
176  */
177 static void
178 handle_get_default_message (void *cls, struct GNUNET_SERVER_Client *client,
179                             const struct GNUNET_MessageHeader *message)
180 {
181   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
182               "Received GET_DEFAULT message from client\n");
183   // setup_estimate_message (&em);
184   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
185   GNUNET_break (0); // not implemented!
186   GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
187 }
188
189
190 /**
191  * Handler for SET_DEFAULT message from client, updates
192  * default identity for some service.
193  *
194  * @param cls unused
195  * @param client who sent the message
196  * @param message the message received
197  */
198 static void
199 handle_set_default_message (void *cls, struct GNUNET_SERVER_Client *client,
200                             const struct GNUNET_MessageHeader *message)
201 {
202   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
203               "Received SET_DEFAULT message from client\n");
204   // setup_estimate_message (&em);
205   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
206   GNUNET_break (0); // not implemented!
207   GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
208 }
209
210
211 /**
212  * Handler for CREATE message from client, creates
213  * new identity.
214  *
215  * @param cls unused
216  * @param client who sent the message
217  * @param message the message received
218  */
219 static void
220 handle_create_message (void *cls, struct GNUNET_SERVER_Client *client,
221                        const struct GNUNET_MessageHeader *message)
222 {
223   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
224               "Received CREATE message from client\n");
225   // setup_estimate_message (&em);
226   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
227   GNUNET_break (0); // not implemented!
228   GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
229 }
230
231
232
233 /**
234  * Handler for RENAME message from client, creates
235  * new identity.
236  *
237  * @param cls unused
238  * @param client who sent the message
239  * @param message the message received
240  */
241 static void
242 handle_rename_message (void *cls, struct GNUNET_SERVER_Client *client,
243                        const struct GNUNET_MessageHeader *message)
244 {
245   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
246               "Received RENAME message from client\n");
247   // setup_estimate_message (&em);
248   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
249   GNUNET_break (0); // not implemented!
250   GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
251 }
252
253
254 /**
255  * Handler for DELETE message from client, creates
256  * new identity.
257  *
258  * @param cls unused
259  * @param client who sent the message
260  * @param message the message received
261  */
262 static void
263 handle_delete_message (void *cls, struct GNUNET_SERVER_Client *client,
264                        const struct GNUNET_MessageHeader *message)
265 {
266   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 
267               "Received DELETE message from client\n");
268   // setup_estimate_message (&em);
269   // GNUNET_SERVER_notification_context_unicast (nc, client, &em.header, GNUNET_YES);
270   GNUNET_break (0); // not implemented!
271   GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
272 }
273
274
275 /**
276  * Handle network size estimate clients.
277  *
278  * @param cls closure
279  * @param server the initialized server
280  * @param c configuration to use
281  */
282 static void
283 run (void *cls, 
284      struct GNUNET_SERVER_Handle *server,
285      const struct GNUNET_CONFIGURATION_Handle *c)
286 {
287   static const struct GNUNET_SERVER_MessageHandler handlers[] = {
288     {&handle_start_message, NULL,
289      GNUNET_MESSAGE_TYPE_IDENTITY_START, sizeof (struct GNUNET_MessageHeader)},
290     {&handle_get_default_message, NULL,
291      GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT, 0},
292     {&handle_set_default_message, NULL,
293      GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT, 0},
294     {&handle_create_message, NULL,
295      GNUNET_MESSAGE_TYPE_IDENTITY_CREATE, 0},
296     {&handle_rename_message, NULL,
297      GNUNET_MESSAGE_TYPE_IDENTITY_RENAME, 0},
298     {&handle_delete_message, NULL,
299      GNUNET_MESSAGE_TYPE_IDENTITY_DELETE, 0},
300     {NULL, NULL, 0, 0}
301   };
302
303   cfg = c;
304   if (GNUNET_OK !=
305       GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
306                                                "EGODIR",
307                                                &ego_directory))
308   {
309     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "EGODIR");
310     GNUNET_SCHEDULER_shutdown ();
311     return;
312   }
313   if (GNUNET_OK !=
314       GNUNET_CONFIGURATION_get_value_filename (cfg, "identity",
315                                                "SUBSYSTEM_CFG",
316                                                &subsystem_cfg_file))
317   {
318     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "identity", "SUBSYSTEM_CFG");
319     GNUNET_SCHEDULER_shutdown ();
320     return;
321   }
322   subsystem_cfg = GNUNET_CONFIGURATION_create ();
323   if ( (GNUNET_YES ==
324         GNUNET_DISK_file_test (subsystem_cfg_file)) &&
325        (GNUNET_OK != 
326         GNUNET_CONFIGURATION_parse (subsystem_cfg,
327                                     subsystem_cfg_file)) )
328   {
329     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
330                 _("Failed to parse subsystem identity configuration file `%s'\n"),
331                 subsystem_cfg_file);
332     GNUNET_SCHEDULER_shutdown ();
333     return;
334   }
335   stats = GNUNET_STATISTICS_create ("identity", cfg);
336   GNUNET_SERVER_add_handlers (server, handlers);
337   nc = GNUNET_SERVER_notification_context_create (server, 1);
338   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
339                                 NULL);
340 }
341
342
343 /**
344  * The main function for the network size estimation service.
345  *
346  * @param argc number of arguments from the command line
347  * @param argv command line arguments
348  * @return 0 ok, 1 on error
349  */
350 int
351 main (int argc, char *const *argv)
352 {
353   return (GNUNET_OK ==
354           GNUNET_SERVICE_run (argc, argv, "identity", 
355                               GNUNET_SERVICE_OPTION_NONE,
356                               &run, NULL)) ? 0 : 1;
357 }
358
359
360 /* end of gnunet-service-identity.c */