Merge branch 'master' into credentials
[oweals/gnunet.git] / src / credential / gnunet-credential.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2012-2013 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  * @file gnunet-credential.c
22  * @brief command line tool to access command line Credential service
23  * @author Adnan Husain
24  */
25 #include "platform.h"
26 #include <gnunet_util_lib.h>
27 #include <gnunet_identity_service.h>
28 #include <gnunet_credential_service.h>
29
30 /**
31  * Configuration we are using.
32  */
33 static const struct GNUNET_CONFIGURATION_Handle *cfg;
34
35 /**
36  * Handle to Credential service.
37  */
38 static struct GNUNET_CREDENTIAL_Handle *credential;
39
40 /**
41  * Desired timeout for the lookup (default is no timeout).
42  */
43 static struct GNUNET_TIME_Relative timeout;
44
45 /**
46  * Credential to lookup. (-u option)
47  */
48 static char *lookup_credential;
49
50 /**
51  * Handle to lookup request
52  */
53 static struct GNUNET_CREDENTIAL_LookupRequest *lookup_request;
54
55 /**
56  * Lookup an ego with the identity service.
57  */
58 static struct GNUNET_IDENTITY_EgoLookup *el;
59
60 /**
61  * Handle for identity service.
62  */
63 static struct GNUNET_IDENTITY_Handle *identity;
64
65 /**
66  * Active operation on identity service.
67  */
68 static struct GNUNET_IDENTITY_Operation *id_op;
69
70 /**
71  * Task scheduled to handle timeout.
72  */
73 static struct GNUNET_SCHEDULER_Task *tt;
74
75 /**
76  * Subject pubkey string
77  */
78 static char *subject_key;
79
80 /**
81  * Subject pubkey string
82  */
83 static char *issuer_key;
84
85 /*
86  * Credential flags
87  */
88 static int credential_flags;
89
90 /*
91  * Maximum delegation depth
92  */
93 static int max_delegation_depth;
94
95
96
97 /**
98  * Identity of the zone to use for the lookup (-z option)
99  */
100 static char *zone_ego_name;
101
102
103 /**
104  * Task run on shutdown.  Cleans up everything.
105  *
106  * @param cls unused
107  */
108 static void
109 do_shutdown (void *cls)
110 {
111   if (NULL != el)
112   {
113     GNUNET_IDENTITY_ego_lookup_cancel (el);
114     el = NULL;
115   }
116   if (NULL != id_op)
117   {
118     GNUNET_IDENTITY_cancel (id_op);
119     id_op = NULL;
120   }
121   if (NULL != lookup_request)
122   {
123     GNUNET_CREDENTIAL_lookup_cancel (lookup_request);
124     lookup_request = NULL;
125   }
126   if (NULL != identity)
127   {
128     GNUNET_IDENTITY_disconnect (identity);
129     identity = NULL;
130   }
131   if (NULL != credential)
132   {
133     GNUNET_CREDENTIAL_disconnect (credential);
134     credential = NULL;
135   }
136   if (NULL != tt)
137   {
138     GNUNET_SCHEDULER_cancel (tt);
139     tt = NULL;
140   }
141 }
142
143
144 /**
145  * Task run on timeout. Triggers shutdown.
146  *
147  * @param cls unused
148  */
149 static void
150 do_timeout (void *cls)
151 {
152   tt = NULL;
153   GNUNET_SCHEDULER_shutdown ();
154 }
155
156
157 /**
158  * Function called with the result of a Credential lookup.
159  *
160  * @param cls the 'const char *' name that was resolved
161  * @param cd_count number of records returned
162  * @param cd array of @a cd_count records with the results
163  */
164 static void
165 handle_lookup_result (void *cls,
166                                 struct GNUNET_IDENTITY_Ego *issuer,
167                 uint16_t issuer_len,
168                                 const struct GNUNET_CREDENTIAL_RecordData *data)
169 {
170   
171
172   lookup_request = NULL;
173   if (0 == issuer_len)
174     printf ("No results.\n");
175   else
176         printf ("%u\n",
177           issuer_len);
178
179   
180   GNUNET_SCHEDULER_shutdown ();
181 }
182
183
184
185
186 /**
187  * Perform the actual resolution, with the subject pkey and
188  * the issuer public key
189  *
190  * @param pkey public key to use for the zone, can be NULL
191  * @param shorten_key private key used for shortening, can be NULL
192  */
193 static void
194 lookup_credentials (struct GNUNET_IDENTITY_Ego *ego)
195 {
196   
197   struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey;
198   struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey;
199
200   if (NULL != subject_key && NULL != issuer_key && NULL != lookup_credential)
201   {
202     if (GNUNET_OK !=
203         GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key,
204                                                     strlen (subject_key),
205                                                     &subject_pkey))
206     {
207       fprintf (stderr,
208                _("Subject public key `%s' is not well-formed\n"),
209                subject_key);
210       GNUNET_SCHEDULER_shutdown ();
211       return;
212     }
213
214     if (GNUNET_OK !=
215         GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key,
216                                                     strlen (issuer_key),
217                                                     &issuer_pkey))
218     {
219       fprintf (stderr,
220                _("Authority public key `%s' is not well-formed\n"),
221                issuer_key);
222       GNUNET_SCHEDULER_shutdown ();
223       return;
224     }
225     
226   lookup_request = GNUNET_CREDENTIAL_lookup(credential,
227                     lookup_credential,
228                     ego,
229                     &subject_pkey,
230                     &issuer_pkey,
231                     credential_flags,
232                     max_delegation_depth,
233                     &handle_lookup_result,
234                     NULL);
235    return;
236   }
237   else
238   {
239     fprintf (stderr,
240        _("Please specify name to lookup, subject key and issuer key!\n"));
241     GNUNET_SCHEDULER_shutdown ();
242     return;
243   }
244 }
245
246
247 /**
248  * Method called to with the ego we are to use for the lookup,
249  * when the ego is the one for the default master zone.
250  *
251  * @param cls closure (NULL, unused)
252  * @param ego ego handle, NULL if not found
253  * @param ctx context for application to store data for this ego
254  *                 (during the lifetime of this process, initially NULL)
255  * @param name name assigned by the user for this ego,
256  *                   NULL if the user just deleted the ego and it
257  *                   must thus no longer be used
258  */
259 static void
260 identity_master_cb (void *cls,
261                     struct GNUNET_IDENTITY_Ego *ego,
262                     void **ctx,
263                     const char *name)
264 {
265   
266   id_op = NULL;
267   if (NULL == ego)
268   {
269     fprintf (stderr,
270              _("Ego for `gns-master' not found, cannot perform lookup.  Did you run gnunet-gns-import.sh?\n"));
271     GNUNET_SCHEDULER_shutdown ();
272     return;
273   }
274
275   lookup_credentials(ego);
276
277   
278 }
279
280
281 /**
282  * Main function that will be run.
283  *
284  * @param cls closure
285  * @param args remaining command-line arguments
286  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
287  * @param c configuration
288  */
289 static void
290 run (void *cls,
291      char *const *args,
292      const char *cfgfile,
293      const struct GNUNET_CONFIGURATION_Handle *c)
294 {
295   
296   cfg = c;
297   credential = GNUNET_CREDENTIAL_connect (cfg);
298   identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
299
300  
301
302   
303   if (NULL == credential)
304   {
305     fprintf (stderr,
306              _("Failed to connect to CREDENTIAL\n"));
307     return;
308   }
309   if (NULL == identity)
310   {
311     fprintf (stderr,
312              _("Failed to connect to IDENTITY\n"));
313     return;
314   }
315   tt = GNUNET_SCHEDULER_add_delayed (timeout,
316                                      &do_timeout, NULL);
317   GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
318   
319
320   
321         GNUNET_break (NULL == id_op);
322         id_op = GNUNET_IDENTITY_get (identity,
323                          "gns-master",//# TODO: Create credential-master
324                          &identity_master_cb,
325                          cls);
326         GNUNET_assert (NULL != id_op);
327
328
329  
330
331 }
332
333
334 /**
335  * The main function for gnunet-gns.
336  *
337  * @param argc number of arguments from the command line
338  * @param argv command line arguments
339  * @return 0 ok, 1 on error
340  */
341 int
342 main (int argc, char *const *argv)
343 {
344   static const struct GNUNET_GETOPT_CommandLineOption options[] = {
345     {'u', "lookup", "CREDENTIAL",
346       gettext_noop ("Lookup a record for the given credential"), 1,
347       &GNUNET_GETOPT_set_string, &lookup_credential},
348    /** { 'T', "timeout", "DELAY",
349       gettext_noop ("Specify timeout for the lookup"), 1,
350       &GNUNET_GETOPT_set_relative_time, &timeout },
351     {'t', "type", "TYPE",
352       gettext_noop ("Specify the type of the record to lookup"), 1,
353     &GNUNET_GETOPT_set_string, &lookup_type},**/
354     {'z', "zone", "NAME",
355     gettext_noop ("Specify the name of the ego of the zone to lookup the record in"), 1,
356     &GNUNET_GETOPT_set_string, &zone_ego_name},
357     {'s', "subject", "PKEY",
358       gettext_noop ("Specify the public key of the subject to lookup the credential for"), 1,
359       &GNUNET_GETOPT_set_string, &subject_key},
360     {'i', "issuer", "PKEY",
361       gettext_noop ("Specify the public key of the authority to verify the credential against"), 1,
362       &GNUNET_GETOPT_set_string, &issuer_key},
363     GNUNET_GETOPT_OPTION_END
364   };
365   int ret;
366
367   timeout = GNUNET_TIME_UNIT_FOREVER_REL;
368   if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
369     return 2;
370
371   GNUNET_log_setup ("gnunet-credential", "WARNING", NULL);
372   ret =
373       (GNUNET_OK ==
374        GNUNET_PROGRAM_run (argc, argv, "gnunet-credential",
375                            _("GNUnet credential resolver tool"),
376                            options,
377                            &run, NULL)) ? 0 : 1;
378   GNUNET_free ((void*) argv);
379   return ret;
380 }
381
382 /* end of gnunet-credential.c */