2002-04-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / kbxutil.c
blob95fcb9ccea4c8f7d3fb6be3c255ed5ac9db77d20
1 /* gpg.c - The GnuPG utility (main for gpg)
2 * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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
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>
29 #include <gcrypt.h>
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"
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,
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,
178 aFindByFpr,
179 aFindByKid,
180 aFindByUid,
181 aTest };
184 static ARGPARSE_OPTS opts[] = {
186 { 300, NULL, 0, N_("@Commands:\n ") },
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" },
192 { 301, NULL, 0, N_("@\nOptions:\n ") },
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")},
203 { oDebug, "debug" ,4|16, N_("set debugging flags")},
204 { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
207 {0} };
211 int gpg_errors_seen = 0;
214 static const char *
215 my_strusage( int level )
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;
236 default: p = NULL;
238 return p;
242 static void
243 i18n_init(void)
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
262 static void
263 wrong_args( const char *text )
265 log_error("usage: kbxutil %s\n", text);
266 gpg_exit ( 1 );
270 static int
271 hextobyte( const byte *s )
273 int c;
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;
295 static char *
296 format_fingerprint ( const char *s )
298 int i, c;
299 byte fpr[20];
301 for (i=0; i < 20 && *s; ) {
302 if ( *s == ' ' || *s == '\t' ) {
303 s++;
304 continue;
306 c = hextobyte(s);
307 if (c == -1) {
308 return NULL;
310 fpr[i++] = c;
311 s += 2;
313 return gcry_xstrdup ( fpr );
316 static int
317 format_keyid ( const char *s, u32 *kid )
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;
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;
332 return 0; /* error */
338 main( int argc, char **argv )
340 ARGPARSE_ARGS pargs;
341 enum cmd_and_opt_values cmd = 0;
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) );
352 create_dotlock(NULL); /* register locking cleanup */
353 i18n_init();
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;
368 case aFindByFpr:
369 case aFindByKid:
370 case aFindByUid:
371 cmd = pargs.r_opt;
372 break;
374 default : pargs.err = 2; break;
377 if( log_get_errorcount(0) )
378 gpg_exit(2);
380 if ( !cmd ) { /* default is to list a KBX file */
381 if( !argc ) {
382 print_kbxfile( NULL );
384 else {
385 for ( ; argc; argc--, argv++ ) {
386 print_kbxfile( *argv );
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 );
402 else if ( cmd == aFindByKid ) {
403 u32 kid[2];
404 int mode;
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 );
415 else if ( cmd == aFindByUid ) {
416 if ( argc != 2 )
417 wrong_args ("kbxfile userID");
418 kbxfile_search_by_uid ( argv[0], argv[1] );
420 else
421 log_error ("unsupported action\n");
423 gpg_exit(0);
424 return 8; /*NEVER REACHED*/
428 void
429 gpg_exit( int rc )
431 if( opt.debug & DBG_MEMSTAT_VALUE ) {
432 gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
433 gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
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 );