-merge
[oweals/gnunet.git] / src / identity-provider / gnunet-idp.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
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., 51 Franklin Street, Fifth Floor,
18    Boston, MA 02110-1301, USA.
19    */
20 /**
21  * @author Martin Schanzenbach
22  * @file src/identity-provider/gnunet-idp.c
23  * @brief Identity Provider utility
24  *
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_namestore_service.h"
30 #include "gnunet_identity_provider_service.h"
31 #include "gnunet_identity_service.h"
32 #include "gnunet_signatures.h"
33
34 /**
35  * return value
36  */
37 static int ret;
38
39 /**
40  * List attribute flag
41  */
42 static int list;
43
44 /**
45  * Relying party
46  */
47 static char* rp;
48
49 /**
50  * The attribute
51  */
52 static char* attr_name;
53
54 /**
55  * Attribute value
56  */
57 static char* attr_value;
58
59 /**
60  * Attributes to issue
61  */
62 static char* issue_attrs;
63
64 /**
65  * Ticket to consume
66  */
67 static char* consume_ticket;
68
69 /**
70  * Attribute type
71  */
72 static char* type_str;
73
74 /**
75  * Ticket to revoke
76  */
77 static char* revoke_ticket;
78
79 /**
80  * Ego name
81  */
82 static char* ego_name;
83
84 /**
85  * Identity handle
86  */
87 static struct GNUNET_IDENTITY_Handle *identity_handle;
88
89 /**
90  * IdP handle
91  */
92 static struct GNUNET_IDENTITY_PROVIDER_Handle *idp_handle;
93
94 /**
95  * IdP operation
96  */
97 static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op;
98
99 /**
100  * Attribute iterator
101  */
102 static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator;
103
104 /**
105  * Master ABE key
106  */
107 static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
108
109 /**
110  * ego private key
111  */
112 static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
113
114 /**
115  * rp public key
116  */
117 static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
118
119 /**
120  * Ticket to consume
121  */
122 static struct GNUNET_IDENTITY_PROVIDER_Ticket ticket;
123
124 /**
125  * Attribute list
126  */
127 static struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attr_list;
128
129 static void
130 do_cleanup(void *cls)
131 {
132   if (NULL != attr_iterator)
133     GNUNET_IDENTITY_PROVIDER_get_attributes_stop (attr_iterator);
134   if (NULL != idp_handle)
135     GNUNET_IDENTITY_PROVIDER_disconnect (idp_handle);
136   if (NULL != identity_handle)
137     GNUNET_IDENTITY_disconnect (identity_handle);
138   if (NULL != abe_key)
139     GNUNET_free (abe_key);
140   if (NULL != attr_list)
141     GNUNET_free (attr_list);
142 }
143
144 static void
145 ticket_issue_cb (void* cls,
146                  const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
147 {
148   char* ticket_str;
149   if (NULL != ticket) {
150     ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
151                                                       sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
152     printf("%s\n",
153            ticket_str);
154     GNUNET_free (ticket_str);
155   }
156   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
157 }
158
159 static void
160 store_attr_cont (void *cls,
161                  int32_t success,
162                  const char*emsg)
163 {
164   if (GNUNET_SYSERR == success) {
165     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
166                 "%s\n", emsg);
167   }
168   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
169 }
170
171 static void
172 process_attrs (void *cls,
173          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
174          const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
175 {
176   char *value_str;
177   if (NULL == identity)
178   {
179     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
180     return;
181   }
182   if (NULL == attr)
183   {
184     ret = 1;
185     return;
186   }
187   value_str = GNUNET_IDENTITY_ATTRIBUTE_value_to_string (attr->type,
188                                                      attr->data,
189                                                      attr->data_size);
190   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
191               "%s: %s\n", attr->name, value_str);
192 }
193
194
195 static void
196 iter_error (void *cls)
197 {
198   attr_iterator = NULL;
199   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
200               "Failed to iterate over attributes\n");
201   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
202 }
203
204 static void
205 process_rvk (void *cls, int success, const char* msg)
206 {
207   if (GNUNET_OK != success)
208   {
209     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
210                 "Revocation failed.\n");
211     ret = 1;
212   }
213   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
214 }
215
216 static void
217 iter_finished (void *cls)
218 {
219   struct GNUNET_IDENTITY_ATTRIBUTE_Claim *claim;
220   char *data;
221   size_t data_size;
222   int type;
223
224   attr_iterator = NULL;
225   if (list)
226   {
227     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
228     return;
229   }
230
231   if (issue_attrs)
232   {
233     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (idp_handle,
234                                                     pkey,
235                                                     &rp_key,
236                                                     attr_list,
237                                                     &ticket_issue_cb,
238                                                     NULL);
239     return;
240   }
241   if (consume_ticket)
242   {
243     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (idp_handle,
244                                                       pkey,
245                                                       &ticket,
246                                                       &process_attrs,
247                                                       NULL);
248     return;
249   }
250   if (revoke_ticket)
251   {
252     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (idp_handle,
253                                                      pkey,
254                                                      &ticket,
255                                                      &process_rvk,
256                                                      NULL);
257     return;
258   }
259   if (NULL == type_str)
260     type = GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING;
261   else
262     type = GNUNET_IDENTITY_ATTRIBUTE_typename_to_number (type_str);
263
264   GNUNET_assert (GNUNET_SYSERR != GNUNET_IDENTITY_ATTRIBUTE_string_to_value (type,
265                                              attr_value,
266                                              (void**)&data,
267                                              &data_size));
268   claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name,
269                                                type,
270                                                data,
271                                                data_size);
272   idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
273                                                      pkey,
274                                                      claim,
275                                                      &store_attr_cont,
276                                                      NULL);
277
278
279 }
280
281 static void
282 iter_cb (void *cls,
283          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
284          const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
285 {
286   struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
287   char *attrs_tmp;
288   char *attr_str;
289
290   if (issue_attrs)
291   {
292     attrs_tmp = GNUNET_strdup (issue_attrs);
293     attr_str = strtok (attrs_tmp, ",");
294     while (NULL != attr_str) {
295       if (0 != strcmp (attr_str, attr->name)) {
296         attr_str = strtok (NULL, ",");
297         continue;
298       }
299       le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
300       le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr->name,
301                                                        attr->type,
302                                                        attr->data,
303                                                        attr->data_size);
304       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
305                                    attr_list->list_tail,
306                                    le);
307       break;
308     }
309     GNUNET_free (attrs_tmp);
310   } else if (list) {
311     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
312                 "%s: %s\n", attr->name, (char*)attr->data);
313   }
314   GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
315 }
316
317 static void
318 ego_cb (void *cls,
319         struct GNUNET_IDENTITY_Ego *ego,
320         void **ctx,
321         const char *name)
322 {
323   if (NULL == name)
324     return;
325   if (0 != strcmp (name, ego_name))
326     return;
327   pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
328
329   if (NULL != rp)
330     GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
331                                                 strlen (rp),
332                                                 &rp_key);
333   if (NULL != consume_ticket)
334     GNUNET_STRINGS_string_to_data (consume_ticket,
335                                    strlen (consume_ticket),
336                                    &ticket,
337                                    sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
338   if (NULL != revoke_ticket)
339     GNUNET_STRINGS_string_to_data (revoke_ticket,
340                                    strlen (revoke_ticket),
341                                    &ticket,
342                                    sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
343
344
345   attr_list = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
346
347   attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
348                                                                  pkey,
349                                                                  &iter_error,
350                                                                  NULL,
351                                                                  &iter_cb,
352                                                                  NULL,
353                                                                  &iter_finished,
354                                                                  NULL);
355
356
357 }
358
359 static void
360 run (void *cls,
361      char *const *args,
362      const char *cfgfile,
363      const struct GNUNET_CONFIGURATION_Handle *c)
364 {
365   ret = 0;
366   if (NULL == ego_name)
367   {
368     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
369                 _("Ego is required\n"));
370     return;
371   } 
372
373   idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c);
374   //Get Ego
375   identity_handle = GNUNET_IDENTITY_connect (c,
376                                              &ego_cb,
377                                              NULL);
378
379
380 }
381
382
383 int
384 main(int argc, char *const argv[])
385 {
386   struct GNUNET_GETOPT_CommandLineOption options[] = {
387
388     GNUNET_GETOPT_option_string ('a',
389                                  "add",
390                                  NULL,
391                                  gettext_noop ("Add attribute"),
392                                  &attr_name),
393
394     GNUNET_GETOPT_option_string ('V',
395                                  "value",
396                                  NULL,
397                                  gettext_noop ("Attribute value"),
398                                  &attr_value),
399     GNUNET_GETOPT_option_string ('e',
400                                  "ego",
401                                  NULL,
402                                  gettext_noop ("Ego"),
403                                  &ego_name),
404     GNUNET_GETOPT_option_string ('r',
405                                  "rp",
406                                  NULL,
407                                  gettext_noop ("Audience (relying party)"),
408                                  &rp),
409     GNUNET_GETOPT_option_flag ('D',
410                                "dump",
411                                gettext_noop ("List attributes for Ego"),
412                                &list),
413     GNUNET_GETOPT_option_string ('i',
414                                  "issue",
415                                  NULL,
416                                  gettext_noop ("Issue a ticket"),
417                                  &issue_attrs),
418     GNUNET_GETOPT_option_string ('C',
419                                  "consume",
420                                  NULL,
421                                  gettext_noop ("Consume a ticket"),
422                                  &consume_ticket),
423     GNUNET_GETOPT_option_string ('R',
424                                  "revoke",
425                                  NULL,
426                                  gettext_noop ("Revoke a ticket"),
427                                  &revoke_ticket),
428     GNUNET_GETOPT_option_string ('t',
429                                  "type",
430                                  NULL,
431                                  gettext_noop ("Type of attribute"),
432                                  &type_str),
433     GNUNET_GETOPT_OPTION_END
434   };
435   GNUNET_PROGRAM_run (argc, argv, "ct",
436                       "ct", options,
437                       &run, NULL);
438   return ret;
439 }