-refactored
[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   if (NULL == identity)
172   {
173     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
174     return;
175   }
176   if (NULL == attr)
177   {
178     ret = 1;
179     return;
180   }
181   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
182               "%s: %s\n", attr->name, (char*)attr->data);
183 }
184
185
186 static void
187 iter_error (void *cls)
188 {
189   attr_iterator = NULL;
190   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
191               "Failed to iterate over attributes\n");
192   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
193 }
194
195 static void
196 process_rvk (void *cls, int success, const char* msg)
197 {
198   if (GNUNET_OK != success)
199   {
200     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
201                 "Revocation failed.\n");
202     ret = 1;
203   }
204   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
205 }
206
207 static void
208 iter_finished (void *cls)
209 {
210   struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr;
211
212   attr_iterator = NULL;
213   if (list)
214   {
215     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
216     return;
217   }
218
219   if (issue_attrs)
220   {
221     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (idp_handle,
222                                                     pkey,
223                                                     &rp_key,
224                                                     attr_list,
225                                                     &ticket_issue_cb,
226                                                     NULL);
227     return;
228   }
229   if (consume_ticket)
230   {
231     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_consume (idp_handle,
232                                                       pkey,
233                                                       &ticket,
234                                                       &process_attrs,
235                                                       NULL);
236     return;
237   }
238   if (revoke_ticket)
239   {
240     idp_op = GNUNET_IDENTITY_PROVIDER_ticket_revoke (idp_handle,
241                                                      pkey,
242                                                      &ticket,
243                                                      &process_rvk,
244                                                      NULL);
245     return;
246   }
247   attr = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr_name,
248                                                  GNUNET_IDENTITY_ATTRIBUTE_TYPE_STRING,
249                                                  attr_value,
250                                                  strlen (attr_value) + 1);
251   idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
252                                                      pkey,
253                                                      attr,
254                                                      &store_attr_cont,
255                                                      NULL);
256
257
258 }
259
260 static void
261 iter_cb (void *cls,
262          const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
263          const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
264 {
265   struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
266   char *attrs_tmp;
267   char *attr_str;
268
269   if (issue_attrs)
270   {
271     attrs_tmp = GNUNET_strdup (issue_attrs);
272     attr_str = strtok (attrs_tmp, ",");
273     while (NULL != attr_str) {
274       if (0 != strcmp (attr_str, attr->name)) {
275         attr_str = strtok (NULL, ",");
276         continue;
277       }
278       le = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
279       le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr->name,
280                                                        attr->type,
281                                                        attr->data,
282                                                        attr->data_size);
283       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
284                                    attr_list->list_tail,
285                                    le);
286       break;
287     }
288     GNUNET_free (attrs_tmp);
289   } else if (list) {
290     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
291                 "%s: %s\n", attr->name, (char*)attr->data);
292   }
293   GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
294 }
295
296 static void
297 ego_cb (void *cls,
298         struct GNUNET_IDENTITY_Ego *ego,
299         void **ctx,
300         const char *name)
301 {
302   if (NULL == name)
303     return;
304   if (0 != strcmp (name, ego_name))
305     return;
306   pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
307
308   if (NULL != rp)
309     GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
310                                                 strlen (rp),
311                                                 &rp_key);
312   if (NULL != consume_ticket)
313     GNUNET_STRINGS_string_to_data (consume_ticket,
314                                    strlen (consume_ticket),
315                                    &ticket,
316                                    sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
317   if (NULL != revoke_ticket)
318     GNUNET_STRINGS_string_to_data (revoke_ticket,
319                                    strlen (revoke_ticket),
320                                    &ticket,
321                                    sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
322
323
324   attr_list = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
325
326   attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
327                                                                  pkey,
328                                                                  &iter_error,
329                                                                  NULL,
330                                                                  &iter_cb,
331                                                                  NULL,
332                                                                  &iter_finished,
333                                                                  NULL);
334
335
336 }
337
338 static void
339 run (void *cls,
340      char *const *args,
341      const char *cfgfile,
342      const struct GNUNET_CONFIGURATION_Handle *c)
343 {
344   ret = 0;
345   if (NULL == ego_name)
346   {
347     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
348                 _("Ego is required\n"));
349     return;
350   } 
351
352   idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c);
353   //Get Ego
354   identity_handle = GNUNET_IDENTITY_connect (c,
355                                              &ego_cb,
356                                              NULL);
357
358
359 }
360
361
362 int
363 main(int argc, char *const argv[])
364 {
365   struct GNUNET_GETOPT_CommandLineOption options[] = {
366
367     GNUNET_GETOPT_option_string ('a',
368                                  "add",
369                                  NULL,
370                                  gettext_noop ("Add attribute"),
371                                  &attr_name),
372
373     GNUNET_GETOPT_option_string ('V',
374                                  "value",
375                                  NULL,
376                                  gettext_noop ("Attribute value"),
377                                  &attr_value),
378     GNUNET_GETOPT_option_string ('e',
379                                  "ego",
380                                  NULL,
381                                  gettext_noop ("Ego"),
382                                  &ego_name),
383     GNUNET_GETOPT_option_string ('r',
384                                  "rp",
385                                  NULL,
386                                  gettext_noop ("Audience (relying party)"),
387                                  &rp),
388     GNUNET_GETOPT_option_flag ('D',
389                                "dump",
390                                gettext_noop ("List attributes for Ego"),
391                                &list),
392     GNUNET_GETOPT_option_string ('i',
393                                  "issue",
394                                  NULL,
395                                  gettext_noop ("Issue a ticket"),
396                                  &issue_attrs),
397     GNUNET_GETOPT_option_string ('C',
398                                  "consume",
399                                  NULL,
400                                  gettext_noop ("Consume a ticket"),
401                                  &consume_ticket),
402     GNUNET_GETOPT_option_string ('R',
403                                  "revoke",
404                                  NULL,
405                                  gettext_noop ("Revoke a ticket"),
406                                  &revoke_ticket),
407     GNUNET_GETOPT_OPTION_END
408   };
409   GNUNET_PROGRAM_run (argc, argv, "ct",
410                       "ct", options,
411                       &run, NULL);
412   return ret;
413 }