Update head to match stable 1.0
[gnupg.git] / g10 / kbxutil.c
1 /* gpg.c - The GnuPG utility (main for gpg)
2  *      Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28
29 #include <gcrypt.h>
30
31 #include "packet.h"
32 #include "iobuf.h"
33 #include "util.h"
34 #include "main.h"
35 #include "options.h"
36 #include "keydb.h"
37 #include "filter.h"
38 #include "ttyio.h"
39 #include "i18n.h"
40 #include "gnupg-defs.h"
41 #include "kbx.h"
42
43
44 enum cmd_and_opt_values { aNull = 0,
45     oArmor        = 'a',
46     aDetachedSign = 'b',
47     aSym          = 'c',
48     aDecrypt      = 'd',
49     aEncr         = 'e',
50     oInteractive  = 'i',
51     oKOption      = 'k',
52     oDryRun       = 'n',
53     oOutput       = 'o',
54     oQuiet        = 'q',
55     oRecipient    = 'r',
56     aSign         = 's',
57     oTextmodeShort= 't',
58     oUser         = 'u',
59     oVerbose      = 'v',
60     oCompress     = 'z',
61     oNotation     = 'N',
62     oBatch        = 500,
63     aClearsign,
64     aStore,
65     aKeygen,
66     aSignEncr,
67     aSignKey,
68     aLSignKey,
69     aListPackets,
70     aEditKey,
71     aDeleteKey,
72     aDeleteSecretKey,
73     aKMode,
74     aKModeC,
75     aImport,
76     aFastImport,
77     aVerify,
78     aListKeys,
79     aListSigs,
80     aListSecretKeys,
81     aSendKeys,
82     aRecvKeys,
83     aExport,
84     aExportAll,
85     aExportSecret,
86     aCheckKeys,
87     aGenRevoke,
88     aPrimegen,
89     aPrintMD,
90     aPrintHMAC,
91     aPrintMDs,
92     aCheckTrustDB,
93     aUpdateTrustDB,
94     aFixTrustDB,
95     aListTrustDB,
96     aListTrustPath,
97     aExportOwnerTrust,
98     aImportOwnerTrust,
99     aDeArmor,
100     aEnArmor,
101     aGenRandom,
102
103     oTextmode,
104     oFingerprint,
105     oWithFingerprint,
106     oAnswerYes,
107     oAnswerNo,
108     oKeyring,
109     oSecretKeyring,
110     oDefaultKey,
111     oDefRecipient,
112     oDefRecipientSelf,
113     oNoDefRecipient,
114     oOptions,
115     oDebug,
116     oDebugAll,
117     oStatusFD,
118     oNoComment,
119     oNoVersion,
120     oEmitVersion,
121     oCompletesNeeded,
122     oMarginalsNeeded,
123     oMaxCertDepth,
124     oLoadExtension,
125     oRFC1991,
126     oOpenPGP,
127     oCipherAlgo,
128     oDigestAlgo,
129     oCompressAlgo,
130     oPasswdFD,
131     oNoVerbose,
132     oTrustDBName,
133     oNoSecmemWarn,
134     oNoArmor,
135     oNoDefKeyring,
136     oNoGreeting,
137     oNoTTY,
138     oNoOptions,
139     oNoBatch,
140     oHomedir,
141     oWithColons,
142     oWithKeyData,
143     oSkipVerify,
144     oCompressKeys,
145     oCompressSigs,
146     oAlwaysTrust,
147     oEmuChecksumBug,
148     oRunAsShmCP,
149     oSetFilename,
150     oSetPolicyURL,
151     oUseEmbeddedFilename,
152     oComment,
153     oDefaultComment,
154     oThrowKeyid,
155     oForceV3Sigs,
156     oForceMDC,
157     oS2KMode,
158     oS2KDigest,
159     oS2KCipher,
160     oCharset,
161     oNotDashEscaped,
162     oEscapeFrom,
163     oLockOnce,
164     oLockMultiple,
165     oKeyServer,
166     oEncryptTo,
167     oNoEncryptTo,
168     oLoggerFD,
169     oUtf8Strings,
170     oNoUtf8Strings,
171     oDisableCipherAlgo,
172     oDisablePubkeyAlgo,
173     oAllowNonSelfsignedUID,
174     oNoLiteral,
175     oSetFilesize,
176     oEntropyDLLName,
177
178     aFindByFpr,
179     aFindByKid,
180     aFindByUid,
181 aTest };
182
183
184 static ARGPARSE_OPTS opts[] = {
185
186     { 300, NULL, 0, N_("@Commands:\n ") },
187
188     { aFindByFpr,  "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" },
189     { aFindByKid,  "find-by-kid", 0, "|KID| find key using it's keyid" },
190     { aFindByUid,  "find-by-uid", 0, "|NAME| find key by user name" },
191
192     { 301, NULL, 0, N_("@\nOptions:\n ") },
193
194     { oArmor, "armor",     0, N_("create ascii armored output")},
195     { oArmor, "armour",     0, "@" },
196     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
197     { oOutput, "output",    2, N_("use as output file")},
198     { oVerbose, "verbose",   0, N_("verbose") },
199     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
200     { oDryRun, "dry-run",   0, N_("do not make any changes") },
201     { oOptions, "options"   , 2, N_("read options from file")},
202
203     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
204     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
205
206
207 {0} };
208
209
210
211 int gpg_errors_seen = 0;
212
213
214 static const char *
215 my_strusage( int level )
216 {
217     const char *p;
218     switch( level ) {
219       case 11: p = "kbxutil (GnuPG)";
220         break;
221       case 13: p = VERSION; break;
222       case 17: p = PRINTABLE_OS_NAME; break;
223       case 19: p =
224             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
225         break;
226       case 1:
227       case 40:  p =
228             _("Usage: kbxutil [options] [files] (-h for help)");
229         break;
230       case 41:  p =
231             _("Syntax: kbxutil [options] [files]\n"
232               "list, export, import KBX data\n");
233         break;
234
235
236       default:  p = NULL;
237     }
238     return p;
239 }
240
241
242 static void
243 i18n_init(void)
244 {
245   #ifdef USE_SIMPLE_GETTEXT
246     set_gettext_file( PACKAGE );
247   #else
248   #ifdef ENABLE_NLS
249     #ifdef HAVE_LC_MESSAGES
250        setlocale( LC_TIME, "" );
251        setlocale( LC_MESSAGES, "" );
252     #else
253        setlocale( LC_ALL, "" );
254     #endif
255     bindtextdomain( PACKAGE, GNUPG_LOCALEDIR );
256     textdomain( PACKAGE );
257   #endif
258   #endif
259 }
260
261
262 static void
263 wrong_args( const char *text )
264 {
265     log_error("usage: kbxutil %s\n", text);
266     gpg_exit ( 1 );
267 }
268
269
270 static int
271 hextobyte( const byte *s )
272 {
273     int c;
274
275     if( *s >= '0' && *s <= '9' )
276         c = 16 * (*s - '0');
277     else if( *s >= 'A' && *s <= 'F' )
278         c = 16 * (10 + *s - 'A');
279     else if( *s >= 'a' && *s <= 'f' )
280         c = 16 * (10 + *s - 'a');
281     else
282         return -1;
283     s++;
284     if( *s >= '0' && *s <= '9' )
285         c += *s - '0';
286     else if( *s >= 'A' && *s <= 'F' )
287         c += 10 + *s - 'A';
288     else if( *s >= 'a' && *s <= 'f' )
289         c += 10 + *s - 'a';
290     else
291         return -1;
292     return c;
293 }
294
295 static char *
296 format_fingerprint ( const char *s )
297 {
298     int i, c;
299     byte fpr[20];
300
301     for (i=0; i < 20 && *s; ) {
302         if ( *s == ' ' || *s == '\t' ) {
303             s++;
304             continue;
305         }
306         c = hextobyte(s);
307         if (c == -1) {
308             return NULL;
309         }
310         fpr[i++] = c;
311         s += 2;
312     }
313     return gcry_xstrdup ( fpr );
314 }
315
316 static int
317 format_keyid ( const char *s, u32 *kid )
318 {
319     char helpbuf[9];
320     switch ( strlen ( s ) ) {
321       case 8:
322         kid[0] = 0;
323         kid[1] = strtoul( s, NULL, 16 );
324         return 10;
325
326       case 16:
327         mem2str( helpbuf, s, 9 );
328         kid[0] = strtoul( helpbuf, NULL, 16 );
329         kid[1] = strtoul( s+8, NULL, 16 );
330         return 11;
331     }
332     return 0; /* error */
333 }
334
335
336
337 int
338 main( int argc, char **argv )
339 {
340     ARGPARSE_ARGS pargs;
341     enum cmd_and_opt_values cmd = 0;
342
343     set_strusage( my_strusage );
344     log_set_name("kbxutil");
345     /* check that the libraries are suitable.  Do it here because
346      * the option parse may need services of the library */
347     if ( !gcry_check_version ( "1.1.0a" ) ) {
348         log_fatal(_("libgcrypt is too old (need %s, have %s)\n"),
349                                 VERSION, gcry_check_version(NULL) );
350     }
351
352     create_dotlock(NULL); /* register locking cleanup */
353     i18n_init();
354
355
356     pargs.argc = &argc;
357     pargs.argv = &argv;
358     pargs.flags=  1;  /* do not remove the args */
359     while( arg_parse( &pargs, opts) ) {
360         switch( pargs.r_opt ) {
361           case oVerbose:
362                 opt.verbose++;
363                 gcry_control( GCRYCTL_SET_VERBOSITY, (int)opt.verbose );
364                 break;
365           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
366           case oDebugAll: opt.debug = ~0; break;
367
368           case aFindByFpr:
369           case aFindByKid:
370           case aFindByUid:
371             cmd = pargs.r_opt;
372             break;
373
374           default : pargs.err = 2; break;
375         }
376     }
377     if( log_get_errorcount(0) )
378         gpg_exit(2);
379
380     if ( !cmd ) { /* default is to list a KBX file */
381         if( !argc ) {
382             print_kbxfile( NULL );
383         }
384         else {
385             for ( ; argc; argc--, argv++ ) {
386                 print_kbxfile( *argv );
387             }
388         }
389     }
390     else if ( cmd == aFindByFpr ) {
391         char *fpr;
392         if ( argc != 2 )
393             wrong_args ("kbxfile foingerprint");
394         fpr = format_fingerprint ( argv[1] );
395         if ( !fpr )
396             log_error ("invalid formatted fingerprint\n");
397         else {
398             kbxfile_search_by_fpr ( argv[0], fpr );
399             gcry_free ( fpr );
400         }
401     }
402     else if ( cmd == aFindByKid ) {
403         u32 kid[2];
404         int mode;
405
406         if ( argc != 2 )
407             wrong_args ("kbxfile short-or-long-keyid");
408         mode = format_keyid ( argv[1], kid );
409         if ( !mode )
410             log_error ("invalid formatted keyID\n");
411         else {
412             kbxfile_search_by_kid ( argv[0], kid, mode );
413         }
414     }
415     else if ( cmd == aFindByUid ) {
416         if ( argc != 2 )
417             wrong_args ("kbxfile userID");
418         kbxfile_search_by_uid ( argv[0], argv[1] );
419     }
420     else
421         log_error ("unsupported action\n");
422
423     gpg_exit(0);
424     return 8; /*NEVER REACHED*/
425 }
426
427
428 void
429 gpg_exit( int rc )
430 {
431     if( opt.debug & DBG_MEMSTAT_VALUE ) {
432         gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
433         gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
434     }
435     if( opt.debug )
436         gcry_control( GCRYCTL_DUMP_SECMEM_STATS );
437     rc = rc? rc : log_get_errorcount(0)? 2 :
438                         gpg_errors_seen? 1 : 0;
439     exit(rc );
440 }
441
442