- rework issue api
[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  * Ego name
61  */
62 static char* ego_name;
63
64 /**
65  * Identity handle
66  */
67 static struct GNUNET_IDENTITY_Handle *identity_handle;
68
69 /**
70  * IdP handle
71  */
72 static struct GNUNET_IDENTITY_PROVIDER_Handle *idp_handle;
73
74 /**
75  * IdP operation
76  */
77 static struct GNUNET_IDENTITY_PROVIDER_Operation *idp_op;
78
79 /**
80  * Attribute iterator
81  */
82 static struct GNUNET_IDENTITY_PROVIDER_AttributeIterator *attr_iterator;
83
84 /**
85  * Master ABE key
86  */
87 static struct GNUNET_CRYPTO_AbeMasterKey *abe_key;
88
89 /**
90  * ego private key
91  */
92 static const struct GNUNET_CRYPTO_EcdsaPrivateKey *pkey;
93
94 /**
95  * rp public key
96  */
97 static struct GNUNET_CRYPTO_EcdsaPublicKey rp_key;
98
99
100 /**
101  * Attribute list
102  */
103 static struct GNUNET_IDENTITY_PROVIDER_AttributeList *attr_list;
104
105 static void
106 do_cleanup(void *cls)
107 {
108   if (NULL != attr_iterator)
109     GNUNET_IDENTITY_PROVIDER_get_attributes_stop (attr_iterator);
110   if (NULL != idp_handle)
111     GNUNET_IDENTITY_PROVIDER_disconnect (idp_handle);
112   if (NULL != identity_handle)
113     GNUNET_IDENTITY_disconnect (identity_handle);
114   if (NULL != abe_key)
115     GNUNET_free (abe_key);
116   if (NULL != attr_list)
117     GNUNET_free (attr_list);
118 }
119
120 static void
121 ticket_issue_cb (void* cls,
122                  const struct GNUNET_IDENTITY_PROVIDER_Ticket2 *ticket)
123 {
124   char* ticket_str;
125   if (NULL != ticket) {
126     ticket_str = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
127                                     sizeof (uint64_t));
128     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
129                 "Got ticket, %s\n",
130                 ticket_str);
131     GNUNET_free (ticket_str);
132   }
133   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
134 }
135
136 static void
137 store_attr_cont (void *cls,
138                  int32_t success,
139                  const char*emsg)
140 {
141   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
142               "Store continuation\n");
143
144   if (GNUNET_SYSERR == success) {
145     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
146                 "%s\n", emsg);
147   } else {
148     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
149                 "Sucessfully added identity attribute %s=%s\n",
150                 attr_name, attr_value);
151   }
152   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
153 }
154
155 static void
156 iter_error (void *cls)
157 {
158   attr_iterator = NULL;
159   GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
160               "Failed to iterate over attributes\n");
161   GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
162 }
163
164 static void
165 iter_finished (void *cls)
166 {
167   struct GNUNET_IDENTITY_PROVIDER_Attribute *attr;
168
169   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
170               "Attribute collection finished!\n");
171   attr_iterator = NULL;
172   if (list) {
173     GNUNET_SCHEDULER_add_now (&do_cleanup, NULL);
174     return;
175   }
176
177   if (issue_attrs) {
178     idp_op = GNUNET_IDENTITY_PROVIDER_idp_ticket_issue (idp_handle,
179                                                         pkey,
180                                                         &rp_key,
181                                                         attr_list,
182                                                         &ticket_issue_cb,
183                                                         NULL);
184     return;
185   }
186   attr = GNUNET_IDENTITY_PROVIDER_attribute_new (attr_name,
187                                                  GNUNET_IDENTITY_PROVIDER_AT_STRING,
188                                                  attr_value,
189                                                  strlen (attr_value));
190   GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
191               "Adding attribute\n");
192
193   idp_op = GNUNET_IDENTITY_PROVIDER_attribute_store (idp_handle,
194                                                      pkey,
195                                                      attr,
196                                                      &store_attr_cont,
197                                                      NULL);
198
199
200 }
201
202 static void
203 iter_cb (void *cls,
204          const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity,
205          const struct GNUNET_IDENTITY_PROVIDER_Attribute *attr)
206 {
207   struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry *le;
208   char *attrs_tmp;
209   char *attr_str;
210
211   if (issue_attrs)
212   {
213     attrs_tmp = GNUNET_strdup (issue_attrs);
214     attr_str = strtok (attrs_tmp, ",");
215     while (NULL != attr_str) {
216       if (0 != strcmp (attr_str, attr->name)) {
217         attr_str = strtok (NULL, ",");
218         continue;
219       }
220       le = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeListEntry);
221       le->attribute = GNUNET_IDENTITY_PROVIDER_attribute_new (attr->name,
222                                                               attr->attribute_type,
223                                                               attr->data,
224                                                               attr->data_size);
225       GNUNET_CONTAINER_DLL_insert (attr_list->list_head,
226                                    attr_list->list_tail,
227                                    le);
228       break;
229     }
230     GNUNET_free (attrs_tmp);
231   } else {
232     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
233                 "%s: %s\n", attr->name, (char*)attr->data);
234   }
235   GNUNET_IDENTITY_PROVIDER_get_attributes_next (attr_iterator);
236 }
237
238 static void
239 ego_cb (void *cls,
240         struct GNUNET_IDENTITY_Ego *ego,
241         void **ctx,
242         const char *name)
243 {
244   if (NULL == name)
245     return;
246   if (0 != strcmp (name, ego_name))
247     return;
248   pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
249
250   if (NULL != rp)
251     GNUNET_CRYPTO_ecdsa_public_key_from_string (rp,
252                                                 strlen (rp),
253                                                 &rp_key);
254
255   attr_list = GNUNET_new (struct GNUNET_IDENTITY_PROVIDER_AttributeList);
256
257   attr_iterator = GNUNET_IDENTITY_PROVIDER_get_attributes_start (idp_handle,
258                                                                  pkey,
259                                                                  &iter_error,
260                                                                  NULL,
261                                                                  &iter_cb,
262                                                                  NULL,
263                                                                  &iter_finished,
264                                                                  NULL);
265
266
267 }
268
269 static void
270 run (void *cls,
271      char *const *args,
272      const char *cfgfile,
273      const struct GNUNET_CONFIGURATION_Handle *c)
274 {
275
276   if (NULL == ego_name)
277   {
278     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
279                 _("Ego is required\n"));
280     return;
281   } 
282
283   idp_handle = GNUNET_IDENTITY_PROVIDER_connect (c);
284   //Get Ego
285   identity_handle = GNUNET_IDENTITY_connect (c,
286                                              &ego_cb,
287                                              NULL);
288
289
290 }
291
292
293 int
294 main(int argc, char *const argv[])
295 {
296   struct GNUNET_GETOPT_CommandLineOption options[] = {
297
298     GNUNET_GETOPT_option_string ('a',
299                                  "add",
300                                  NULL,
301                                  gettext_noop ("Add attribute"),
302                                  &attr_name),
303
304     GNUNET_GETOPT_option_string ('V',
305                                  "value",
306                                  NULL,
307                                  gettext_noop ("Attribute value"),
308                                  &attr_value),
309     GNUNET_GETOPT_option_string ('e',
310                                  "ego",
311                                  NULL,
312                                  gettext_noop ("Ego"),
313                                  &ego_name),
314     GNUNET_GETOPT_option_string ('r',
315                                  "rp",
316                                  NULL,
317                                  gettext_noop ("Audience (relying party)"),
318                                  &rp),
319     GNUNET_GETOPT_option_flag ('D',
320                                "dump",
321                                gettext_noop ("List attributes for Ego"),
322                                &list),
323     GNUNET_GETOPT_option_string ('i',
324                                  "issue",
325                                  NULL,
326                                  gettext_noop ("Issue a ticket"),
327                                  &issue_attrs),
328     GNUNET_GETOPT_OPTION_END
329   };
330   return GNUNET_PROGRAM_run (argc, argv, "ct",
331                              "ct", options,
332                              &run, NULL);
333 }