fix ego not found
[oweals/gnunet.git] / src / reclaim / gnunet-reclaim.c
1 /*
2    This file is part of GNUnet.
3    Copyright (C) 2012-2015 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 /**
19  * @author Martin Schanzenbach
20  * @file src/reclaim/gnunet-reclaim.c
21  * @brief Identity Provider utility
22  *
23  */
24
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_namestore_service.h"
28 #include "gnunet_reclaim_service.h"
29 #include "gnunet_identity_service.h"
30 #include "gnunet_signatures.h"
31
32 /**
33  * return value
34  */
35 static int ret;
36
37 /**
38  * List attribute flag
39  */
40 static int list;
41
42 /**
43  * Relying party
44  */
45 static char* rp;
46
47 /**
48  * The attribute
49  */
50 static char* attr_name;
51
52 /**
53  * Attribute value
54  */
55 static char* attr_value;
56
57 /**
58  * Attributes to issue
59  */
60 static char* issue_attrs;
61
62 /**
63  * Ticket to consume
64  */
65 static char* consume_ticket;
66
67 /**
68  * Attribute type
69  */
70 static char* type_str;
71
72 /**
73  * Ticket to revoke
74  */
75 static char* revoke_ticket;
76
77 /**
78  * Ego name
79  */
80 static char* ego_name;
81
82 /**
83  * Identity handle
84  */
85 static struct GNUNET_IDENTITY_Handle *identity_handle;
86
87 /**
88  * reclaim handle
89  */
90 static struct GNUNET_RECLAIM_Handle *reclaim_handle;
91
92 /**
93  * reclaim operation
94  */
95 static struct GNUNET_RECLAIM_Operation *reclaim_op;
96
97 /**
98  * Attribute iterator
99  */
100 static struct GNUNET_RECLAIM_AttributeIterator *attr_iterator;
101
102 /**
103  * Master ABE key
104  */
105 static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
106
107 /**
108  * ego private key
109  */
110 static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
111
112 /**
113  * rp public key
114  */
115 static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
116
117 /**
118  * Ticket to consume
119  */
120 static struct GNUNET_RECLAIM_Ticket ticket;
121
122 /**
123  * Attribute list
124  */
125 static struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
126
127 /**
128  * Attribute expiration interval
129  */
130 static struct GNUNET_TIME_Relative exp_interval;
131
132 /**
133  * Timeout task
134  */
135 static struct GNUNET_SCHEDULER_Task *timeout;
136
137 static void
138 do_cleanup(void *cls)
139 {
140   if (NULL != timeout)
141     GNUNET_SCHEDULER_cancel (timeout);
142   if (NULL != reclaim_op)
143     GNUNET_RECLAIM_cancel (reclaim_op);
144   if (NULL != attr_iterator)
145     GNUNET_RECLAIM_get_attributes_stop (attr_iterator);
146   if (NULL != reclaim_handle)
147     GNUNET_RECLAIM_disconnect (reclaim_handle);
148   if (NULL != identity_handle)
149     GNUNET_IDENTITY_disconnect (identity_handle);
150   if (NULL != abe_key)
151     GNUNET_free (abe_key);
152   if (NULL != attr_list)
153     GNUNET_free (attr_list);
154 }
155
156 static void
157 ticket_issue_cb (void* cls,
158                  const struct GNUNET_RECLAIM_Ticket *ticket)
159 {
160   char* ticket_str;
161   reclaim_op = NULL;
162   if (NULL != ticket) {
163     ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
164                                                       sizeof (struct GNUNET_RECLAIM_Ticket));
165     printf("%s\n",
166            ticket_str);
167     GNUNET_free (ticket_str);
168   }
169   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
170 }
171
172 static void
173 store_attr_cont (void *cls,
174                  int32_t success,
175                  const char*emsg)
176 {
177   reclaim_op = NULL;
178   if (GNUNET_SYSERR == success) {
179     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
180                 "%s\n", emsg);
181   }
182   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
183 }
184
185 static void
186 process_attrs (void *cls,
187          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
188          const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
189 {
190   char *value_str;
191   if (NULL == identity)
192   {
193     reclaim_op = NULL;
194     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
195     return;
196   }
197   if (NULL == attr)
198   {
199     ret = 1;
200     return;
201   }
202   value_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
203                                                         attr->data,
204                                                         attr->data_size);
205   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
206               "%s: %s\n", attr->name, value_str);
207 }
208
209
210 static void
211 iter_error (void *cls)
212 {
213   attr_iterator = NULL;
214   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
215               "Failed to iterate over attributes\n");
216   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
217 }
218
219 static void
220 timeout_task (void *cls)
221 {
222   timeout = NULL;
223   ret = 1;
224   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
225               "Timeout\n");
226   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
227 }
228
229 static void
230 process_rvk (void *cls, int success, const char* msg)
231 {
232   reclaim_op = NULL;
233   if (GNUNET_OK != success)
234   {
235     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
236                 "Revocation failed.\n");
237     ret = 1;
238   }
239   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
240 }
241
242 static void
243 iter_finished (void *cls)
244 {
245   struct GNUNET_RECLAIM_ATTRIBUTE_Claim *claim;
246   char *data;
247   size_t data_size;
248   int type;
249
250   attr_iterator = NULL;
251   if (list)
252   {
253     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
254     return;
255   }
256
257   if (issue_attrs)
258   {
259     reclaim_op = GNUNET_RECLAIM_ticket_issue (reclaim_handle,
260                                               pkey,
261                                               &rp_key,
262                                               attr_list,
263                                               &ticket_issue_cb,
264                                               NULL);
265     return;
266   }
267   if (consume_ticket)
268   {
269     reclaim_op = GNUNET_RECLAIM_ticket_consume (reclaim_handle,
270                                                 pkey,
271                                                 &ticket,
272                                                 &process_attrs,
273                                                 NULL);
274     timeout = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 10),
275                                             &timeout_task,
276                                             NULL);
277     return;
278   }
279   if (revoke_ticket)
280   {
281     reclaim_op = GNUNET_RECLAIM_ticket_revoke (reclaim_handle,
282                                                pkey,
283                                                &ticket,
284                                                &process_rvk,
285                                                NULL);
286     return;
287   }
288   if (attr_name)
289   {
290     if (NULL == type_str)
291       type = GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING;
292     else
293       type = GNUNET_RECLAIM_ATTRIBUTE_typename_to_number (type_str);
294
295     GNUNET_assert (GNUNET_SYSERR != GNUNET_RECLAIM_ATTRIBUTE_string_to_value (type,
296                                                                               attr_value,
297                                                                               (void**)&data,
298                                                                               &data_size));
299     claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr_name,
300                                                  type,
301                                                  data,
302                                                  data_size);
303     reclaim_op = GNUNET_RECLAIM_attribute_store (reclaim_handle,
304                                                  pkey,
305                                                  claim,
306                                                  &exp_interval,
307                                                  &store_attr_cont,
308                                                  NULL);
309     return;
310   }
311   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
312 }
313
314 static void
315 iter_cb (void *cls,
316          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
317          const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
318 {
319   struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
320   char *attrs_tmp;
321   char *attr_str;
322
323   if (issue_attrs)
324   {
325     attrs_tmp = GNUNET_strdup (issue_attrs);
326     attr_str = strtok (attrs_tmp, ",");
327     while (NULL != attr_str) {
328       if (0 != strcmp (attr_str, attr->name)) {
329         attr_str = strtok (NULL, ",");
330         continue;
331       }
332       le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
333       le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name,
334                                                       attr->type,
335                                                       attr->data,
336                                                       attr->data_size);
337       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
338                                    attr_list->list_tail,
339                                    le);
340       break;
341     }
342     GNUNET_free (attrs_tmp);
343   } else if (list) {
344     attr_str = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
345                                                          attr->data,
346                                                          attr->data_size);
347     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
348                 "%s: %s\n", attr->name, attr_str);
349   }
350   GNUNET_RECLAIM_get_attributes_next (attr_iterator);
351 }
352
353 static void
354 ego_iter_finished (void *cls)
355 {
356   if (NULL == pkey)
357   {
358     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
359                 "Ego %s not found\n", ego_name);
360     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
361     return;
362   }
363
364   if (NULL != rp)
365     GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
366                                                 strlen (rp),
367                                                 &rp_key);
368   if (NULL != consume_ticket)
369     GNUNET_STRINGS_string_to_data (consume_ticket,
370                                    strlen (consume_ticket),
371                                    &ticket,
372                                    sizeof (struct GNUNET_RECLAIM_Ticket));
373   if (NULL != revoke_ticket)
374     GNUNET_STRINGS_string_to_data (revoke_ticket,
375                                    strlen (revoke_ticket),
376                                    &ticket,
377                                    sizeof (struct GNUNET_RECLAIM_Ticket));
378
379
380   attr_list = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
381
382   attr_iterator = GNUNET_RECLAIM_get_attributes_start (reclaim_handle,
383                                                        pkey,
384                                                        &iter_error,
385                                                        NULL,
386                                                        &iter_cb,
387                                                        NULL,
388                                                        &iter_finished,
389                                                        NULL);
390
391
392 }
393
394 static int init = GNUNET_YES;
395
396 static void
397 ego_cb (void *cls,
398         struct GNUNET_IDENTITY_Ego *ego,
399         void **ctx,
400         const char *name)
401 {
402   if (NULL == name) {
403     if (GNUNET_YES == init) {
404       init = GNUNET_NO;
405       GNUNET_SCHEDULER_add_now (&ego_iter_finished, NULL);
406     }
407     return;
408   }
409   if (0 != strcmp (name, ego_name))
410     return;
411   pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
412 }
413
414
415 static void
416 run (void *cls,
417      char *const *args,
418      const char *cfgfile,
419      const struct GNUNET_CONFIGURATION_Handle *c)
420 {
421   ret = 0;
422   if (NULL == ego_name)
423   {
424     ret = 1;
425     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
426                 _("Ego is required\n"));
427     return;
428   }
429
430   if ( (NULL == attr_value) && (NULL != attr_name) )
431   {
432     ret = 1;
433     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
434                 _("Attribute value missing!\n"));
435     return;
436   }
437
438   if ( (NULL == rp) && (NULL != issue_attrs) )
439   {
440     ret = 1;
441     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
442                 _("Requesting party key is required!\n"));
443     return;
444   }
445
446   reclaim_handle = GNUNET_RECLAIM_connect (c);
447   //Get Ego
448   identity_handle = GNUNET_IDENTITY_connect (c,
449                                              &ego_cb,
450                                              NULL);
451
452
453 }
454
455
456 int
457 main(int argc, char *const argv[])
458 {
459   exp_interval = GNUNET_TIME_UNIT_HOURS;
460   struct GNUNET_GETOPT_CommandLineOption options[] = {
461
462     GNUNET_GETOPT_option_string ('a',
463                                  "add",
464                                  NULL,
465                                  gettext_noop ("Add attribute"),
466                                  &attr_name),
467
468     GNUNET_GETOPT_option_string ('V',
469                                  "value",
470                                  NULL,
471                                  gettext_noop ("Attribute value"),
472                                  &attr_value),
473     GNUNET_GETOPT_option_string ('e',
474                                  "ego",
475                                  NULL,
476                                  gettext_noop ("Ego"),
477                                  &ego_name),
478     GNUNET_GETOPT_option_string ('r',
479                                  "rp",
480                                  NULL,
481                                  gettext_noop ("Audience (relying party)"),
482                                  &rp),
483     GNUNET_GETOPT_option_flag ('D',
484                                "dump",
485                                gettext_noop ("List attributes for Ego"),
486                                &list),
487     GNUNET_GETOPT_option_string ('i',
488                                  "issue",
489                                  NULL,
490                                  gettext_noop ("Issue a ticket"),
491                                  &issue_attrs),
492     GNUNET_GETOPT_option_string ('C',
493                                  "consume",
494                                  NULL,
495                                  gettext_noop ("Consume a ticket"),
496                                  &consume_ticket),
497     GNUNET_GETOPT_option_string ('R',
498                                  "revoke",
499                                  NULL,
500                                  gettext_noop ("Revoke a ticket"),
501                                  &revoke_ticket),
502     GNUNET_GETOPT_option_string ('t',
503                                  "type",
504                                  NULL,
505                                  gettext_noop ("Type of attribute"),
506                                  &type_str),
507     GNUNET_GETOPT_option_relative_time ('E',
508                                         "expiration",
509                                         NULL,
510                                         gettext_noop ("Expiration interval of the attribute"),
511                                         &exp_interval),
512
513     GNUNET_GETOPT_OPTION_END
514   };
515   if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "ct",
516                                        "ct", options,
517                                        &run, NULL))
518     return 1;
519   else
520     return ret;
521 }