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