tests: Fix memory leak.
[gpgme.git] / tests / run-keylist.c
1 /* run-keylist.c  - Helper to show a key listing.
2    Copyright (C) 2008, 2009 g10 Code GmbH
3
4    This file is part of GPGME.
5
6    GPGME is free software; you can redistribute it and/or modify it
7    under the terms of the GNU Lesser General Public License as
8    published by the Free Software Foundation; either version 2.1 of
9    the License, or (at your option) any later version.
10
11    GPGME is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this program; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 /* We need to include config.h so that we know whether we are building
21    with large file system (LFS) support. */
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29
30 #include <gpgme.h>
31
32 #define PGM "run-keylist"
33
34 #include "run-support.h"
35
36
37 static int verbose;
38
39
40 static int
41 show_usage (int ex)
42 {
43   fputs ("usage: " PGM " [options] [USERID]\n\n"
44          "Options:\n"
45          "  --verbose        run in verbose mode\n"
46          "  --openpgp        use the OpenPGP protocol (default)\n"
47          "  --cms            use the CMS protocol\n"
48          "  --secret         list only secret keys\n"
49          "  --local          use GPGME_KEYLIST_MODE_LOCAL\n"
50          "  --extern         use GPGME_KEYLIST_MODE_EXTERN\n"
51          "  --sigs           use GPGME_KEYLIST_MODE_SIGS\n"
52          "  --sig-notations  use GPGME_KEYLIST_MODE_SIG_NOTATIONS\n"
53          "  --ephemeral      use GPGME_KEYLIST_MODE_EPHEMERAL\n"
54          "  --validate       use GPGME_KEYLIST_MODE_VALIDATE\n"
55          "  --import         import all keys\n"
56          "  --offline        use offline mode\n"
57          , stderr);
58   exit (ex);
59 }
60
61
62 int
63 main (int argc, char **argv)
64 {
65   int last_argc = -1;
66   gpgme_error_t err;
67   gpgme_ctx_t ctx;
68   gpgme_keylist_mode_t mode = 0;
69   gpgme_key_t key;
70   gpgme_subkey_t subkey;
71   gpgme_keylist_result_t result;
72   int import = 0;
73   gpgme_key_t keyarray[100];
74   int keyidx = 0;
75   gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
76   int only_secret = 0;
77   int offline = 0;
78
79   if (argc)
80     { argc--; argv++; }
81
82   while (argc && last_argc != argc )
83     {
84       last_argc = argc;
85       if (!strcmp (*argv, "--"))
86         {
87           argc--; argv++;
88           break;
89         }
90       else if (!strcmp (*argv, "--help"))
91         show_usage (0);
92       else if (!strcmp (*argv, "--verbose"))
93         {
94           verbose = 1;
95           argc--; argv++;
96         }
97       else if (!strcmp (*argv, "--openpgp"))
98         {
99           protocol = GPGME_PROTOCOL_OpenPGP;
100           argc--; argv++;
101         }
102       else if (!strcmp (*argv, "--cms"))
103         {
104           protocol = GPGME_PROTOCOL_CMS;
105           argc--; argv++;
106         }
107       else if (!strcmp (*argv, "--secret"))
108         {
109           only_secret = 1;
110           argc--; argv++;
111         }
112       else if (!strcmp (*argv, "--local"))
113         {
114           mode |= GPGME_KEYLIST_MODE_LOCAL;
115           argc--; argv++;
116         }
117       else if (!strcmp (*argv, "--extern"))
118         {
119           mode |= GPGME_KEYLIST_MODE_EXTERN;
120           argc--; argv++;
121         }
122       else if (!strcmp (*argv, "--sigs"))
123         {
124           mode |= GPGME_KEYLIST_MODE_SIGS;
125           argc--; argv++;
126         }
127       else if (!strcmp (*argv, "--sig-notations"))
128         {
129           mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS;
130           argc--; argv++;
131         }
132       else if (!strcmp (*argv, "--ephemeral"))
133         {
134           mode |= GPGME_KEYLIST_MODE_EPHEMERAL;
135           argc--; argv++;
136         }
137       else if (!strcmp (*argv, "--validate"))
138         {
139           mode |= GPGME_KEYLIST_MODE_VALIDATE;
140           argc--; argv++;
141         }
142       else if (!strcmp (*argv, "--import"))
143         {
144           import = 1;
145           argc--; argv++;
146         }
147       else if (!strcmp (*argv, "--offline"))
148         {
149           offline = 1;
150           argc--; argv++;
151         }
152       else if (!strncmp (*argv, "--", 2))
153         show_usage (1);
154
155     }
156
157   if (argc > 1)
158     show_usage (1);
159
160   init_gpgme (protocol);
161
162   err = gpgme_new (&ctx);
163   fail_if_err (err);
164   gpgme_set_protocol (ctx, protocol);
165
166   gpgme_set_keylist_mode (ctx, mode);
167
168   gpgme_set_offline (ctx, offline);
169
170   err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, only_secret);
171   fail_if_err (err);
172
173   while (!(err = gpgme_op_keylist_next (ctx, &key)))
174     {
175       gpgme_user_id_t uid;
176       int nuids;
177       int nsub;
178
179       printf ("keyid   : %s\n", key->subkeys?nonnull (key->subkeys->keyid):"?");
180       printf ("fpr     : %s\n", key->subkeys?nonnull (key->subkeys->fpr):"?");
181       if (key->subkeys && key->subkeys->keygrip)
182         printf ("grip    : %s\n", key->subkeys->keygrip);
183       if (key->subkeys && key->subkeys->curve)
184             printf ("curve   : %s\n", key->subkeys->curve);
185       printf ("caps    : %s%s%s%s\n",
186               key->can_encrypt? "e":"",
187               key->can_sign? "s":"",
188               key->can_certify? "c":"",
189               key->can_authenticate? "a":"");
190       printf ("flags   :%s%s%s%s%s%s%s\n",
191               key->secret? " secret":"",
192               key->revoked? " revoked":"",
193               key->expired? " expired":"",
194               key->disabled? " disabled":"",
195               key->invalid? " invalid":"",
196               key->is_qualified? " qualifid":"",
197               key->subkeys && key->subkeys->is_cardkey? " cardkey":"");
198
199       subkey = key->subkeys;
200       if (subkey)
201         subkey = subkey->next;
202       for (nsub=1; subkey; subkey = subkey->next, nsub++)
203         {
204           printf ("fpr   %2d: %s\n", nsub, nonnull (subkey->fpr));
205           if (subkey->keygrip)
206             printf ("grip  %2d: %s\n", nsub, subkey->keygrip);
207           if (subkey->curve)
208             printf ("curve %2d: %s\n", nsub, subkey->curve);
209           printf ("caps  %2d: %s%s%s%s\n",
210                   nsub,
211                   subkey->can_encrypt? "e":"",
212                   subkey->can_sign? "s":"",
213                   subkey->can_certify? "c":"",
214                   subkey->can_authenticate? "a":"");
215           printf ("flags %2d:%s%s%s%s%s%s%s\n",
216                   nsub,
217                   subkey->secret? " secret":"",
218                   subkey->revoked? " revoked":"",
219                   subkey->expired? " expired":"",
220                   subkey->disabled? " disabled":"",
221                   subkey->invalid? " invalid":"",
222                   subkey->is_qualified? " qualifid":"",
223                   subkey->is_cardkey? " cardkey":"");
224         }
225       for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++)
226         {
227           printf ("userid %d: %s\n", nuids, nonnull(uid->uid));
228           printf ("valid  %d: %s\n", nuids,
229                   uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown":
230                   uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined":
231                   uid->validity == GPGME_VALIDITY_NEVER? "never":
232                   uid->validity == GPGME_VALIDITY_MARGINAL? "marginal":
233                   uid->validity == GPGME_VALIDITY_FULL? "full":
234                   uid->validity == GPGME_VALIDITY_ULTIMATE? "ultimate": "[?]");
235         }
236
237
238
239       putchar ('\n');
240
241       if (import)
242         {
243           if (keyidx < DIM (keyarray)-1)
244             keyarray[keyidx++] = key;
245           else
246             {
247               fprintf (stderr, PGM": too many keys in import mode"
248                        "- skipping this key\n");
249               gpgme_key_unref (key);
250             }
251         }
252       else
253         gpgme_key_unref (key);
254     }
255   if (gpgme_err_code (err) != GPG_ERR_EOF)
256     fail_if_err (err);
257   err = gpgme_op_keylist_end (ctx);
258   fail_if_err (err);
259   keyarray[keyidx] = NULL;
260
261   result = gpgme_op_keylist_result (ctx);
262   if (result->truncated)
263     {
264       fprintf (stderr, PGM ": key listing unexpectedly truncated\n");
265       exit (1);
266     }
267
268   if (import)
269     {
270       gpgme_import_result_t impres;
271
272       err = gpgme_op_import_keys (ctx, keyarray);
273       fail_if_err (err);
274       impres = gpgme_op_import_result (ctx);
275       if (!impres)
276         {
277           fprintf (stderr, PGM ": no import result returned\n");
278           exit (1);
279         }
280       print_import_result (impres);
281     }
282
283   for (keyidx=0; keyarray[keyidx]; keyidx++)
284     gpgme_key_unref (keyarray[keyidx]);
285
286   gpgme_release (ctx);
287   return 0;
288 }