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