See ChangeLog: Wed Mar 17 13:09:03 CET 1999 Werner Koch
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  *      Copyright (C) 1998, 1999 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 #define MAINTAINER_OPTIONS
30
31 #include "packet.h"
32 #include "iobuf.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "main.h"
36 #include "options.h"
37 #include "keydb.h"
38 #include "trustdb.h"
39 #include "mpi.h"
40 #include "cipher.h"
41 #include "filter.h"
42 #include "ttyio.h"
43 #include "i18n.h"
44 #include "status.h"
45 #include "g10defs.h"
46 #include "hkp.h"
47
48 #ifndef IS_G10MAINT
49   #define IS_G10 1
50 #endif
51
52
53 enum cmd_and_opt_values { aNull = 0,
54     oArmor        = 'a',
55     aDetachedSign = 'b',
56     aSym          = 'c',
57     aDecrypt      = 'd',
58     aEncr         = 'e',
59     oKOption      = 'k',
60     oDryRun       = 'n',
61     oOutput       = 'o',
62     oQuiet        = 'q',
63     oRecipient    = 'r',
64     aSign         = 's',
65     oTextmodeShort= 't',
66     oUser         = 'u',
67     oVerbose      = 'v',
68     oCompress     = 'z',
69     oBatch        = 500,
70     aClearsign,
71     aStore,
72     aKeygen,
73     aSignEncr,
74     aSignKey,
75     aListPackets,
76     aEditKey,
77     aDeleteKey,
78     aDeleteSecretKey,
79     aKMode,
80     aKModeC,
81     aImport,
82     aFastImport,
83     aVerify,
84     aListKeys,
85     aListSigs,
86     aListSecretKeys,
87     aSendKeys,
88     aExport,
89     aExportAll,
90     aExportSecret,
91     aCheckKeys,
92     aGenRevoke,
93     aPrimegen,
94     aPrintMD,
95     aPrintMDs,
96     aCheckTrustDB,
97     aUpdateTrustDB,
98     aFixTrustDB,
99     aListTrustDB,
100     aListTrustPath,
101     aExportOwnerTrust,
102     aImportOwnerTrust,
103     aDeArmor,
104     aEnArmor,
105     aGenRandom,
106
107     oTextmode,
108     oFingerprint,
109     oAnswerYes,
110     oAnswerNo,
111     oKeyring,
112     oSecretKeyring,
113     oDefaultKey,
114     oOptions,
115     oDebug,
116     oDebugAll,
117     oStatusFD,
118     oNoComment,
119     oNoVersion,
120     oCompletesNeeded,
121     oMarginalsNeeded,
122     oMaxCertDepth,
123     oLoadExtension,
124     oRFC1991,
125     oCipherAlgo,
126     oDigestAlgo,
127     oCompressAlgo,
128     oPasswdFD,
129     oQuickRandom,
130     oNoVerbose,
131     oTrustDBName,
132     oNoSecmemWarn,
133     oNoArmor,
134     oNoDefKeyring,
135     oNoGreeting,
136     oNoOptions,
137     oNoBatch,
138     oHomedir,
139     oWithColons,
140     oSkipVerify,
141     oCompressKeys,
142     oCompressSigs,
143     oAlwaysTrust,
144     oEmuChecksumBug,
145     oRunAsShmCP,
146     oSetFilename,
147     oComment,
148     oThrowKeyid,
149     oForceV3Sigs,
150     oS2KMode,
151     oS2KDigest,
152     oS2KCipher,
153     oCharset,
154     oNotDashEscaped,
155     oEscapeFrom,
156     oLockOnce,
157     oKeyServer,
158     oEncryptTo,
159     oNoEncryptTo,
160 aTest };
161
162
163 static ARGPARSE_OPTS opts[] = {
164
165     { 300, NULL, 0, N_("@Commands:\n ") },
166
167   #ifdef IS_G10
168     { aSign, "sign",      256, N_("|[file]|make a signature")},
169     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
170     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
171     { aEncr, "encrypt",   256, N_("encrypt data")},
172     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
173     { aStore, "store",     256, N_("store only")},
174     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
175     { aVerify, "verify"   , 256, N_("verify a signature")},
176   #endif
177     { aListKeys, "list-keys", 256, N_("list keys")},
178     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
179     { aCheckKeys, "check-sigs",256, N_("check key signatures")},
180     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
181     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
182   #ifdef IS_G10
183     { aKeygen, "gen-key",   256, N_("generate a new key pair")},
184   #endif
185     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
186   #ifdef IS_G10
187     { aEditKey, "edit-key"  ,256, N_("sign or edit a key")},
188     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
189   #endif
190     { aExport, "export"           , 256, N_("export keys") },
191     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
192     { aExportAll, "export-all"    , 256, "@" },
193     { aExportSecret, "export-secret-keys" , 256, "@" },
194     { aImport, "import",      256     , N_("import/merge keys")},
195     { aFastImport, "fast-import",  256 , "@"},
196     { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
197   #ifdef IS_G10MAINT
198     { aExportOwnerTrust,
199               "export-ownertrust", 256, N_("export the ownertrust values")},
200     { aImportOwnerTrust,
201               "import-ownertrust", 256 , N_("import ownertrust values")},
202     { aUpdateTrustDB,
203               "update-trustdb",0 , N_("|[NAMES]|update the trust database")},
204     { aCheckTrustDB,
205               "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
206     { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
207     { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
208     { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
209     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
210     { aPrintMDs, "print-mds" , 256, N_("print all message digests")},
211     #ifdef MAINTAINER_OPTIONS
212     { aPrimegen, "gen-prime" , 256, "@" },
213     { aGenRandom, "gen-random" , 256, "@" },
214     #endif
215   #endif
216
217     { 301, NULL, 0, N_("@\nOptions:\n ") },
218
219     { oArmor, "armor",     0, N_("create ascii armored output")},
220     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
221     { oRecipient, "remote-user", 2, "@"},  /* old option name */
222     { oEncryptTo, "encrypt-to", 2, "@" },
223     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
224   #ifdef IS_G10
225     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
226     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
227     { oTextmodeShort, NULL,   0, "@"},
228     { oTextmode, "textmode",  0, N_("use canonical text mode")},
229   #endif
230     { oOutput, "output",    2, N_("use as output file")},
231     { oVerbose, "verbose",   0, N_("verbose") },
232     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
233     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
234     { oDryRun, "dry-run",   0, N_("do not make any changes") },
235     { oBatch, "batch",     0, N_("batch mode: never ask")},
236     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
237     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
238     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
239     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
240     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
241     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
242     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
243     { oOptions, "options"   , 2, N_("read options from file")},
244
245     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
246     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
247     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
248     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
249     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
250     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
251     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
252     { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
253     { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
254     { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
255     { oS2KDigest, "s2k-digest-algo",2,
256                 N_("|NAME|use message digest algorithm NAME for passphrases")},
257     { oS2KCipher, "s2k-cipher-algo",2,
258                 N_("|NAME|use cipher algorithm NAME for passphrases")},
259   #ifdef IS_G10
260     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
261     { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
262     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
263     { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
264   #else /* some dummies */
265     { oCipherAlgo, "cipher-algo", 2 , "@"},
266     { oDigestAlgo, "digest-algo", 2 , "@"},
267     { oCompressAlgo, "compress-algo", 1 , "@"},
268   #endif
269
270   #ifdef IS_G10
271     { 302, NULL, 0, N_("@\nExamples:\n\n"
272     " -se -r Bob [file]          sign and encrypt for user Bob\n"
273     " --clearsign [file]         make a clear text signature\n"
274     " --detach-sign [file]       make a detached signature\n"
275     " --list-keys [names]        show keys\n"
276     " --fingerprint [names]      show fingerprints\n"  ) },
277   #endif
278
279   /* hidden options */
280   #ifdef IS_G10MAINT
281     { aExportOwnerTrust, "list-ownertrust",0 , "@"},  /* alias */
282     { aListTrustDB, "list-trustdb",0 , "@"},
283     { aListTrustPath, "list-trust-path",0, "@"},
284   #endif
285   #ifdef IS_G10
286     { oKOption, NULL,    0, "@"},
287     { oPasswdFD, "passphrase-fd",1, "@" },
288     { aSignKey, "sign-key"  ,256, "@" }, /* alias for edit-key */
289   #endif
290     { aDeleteSecretKey, "delete-secret-key",0, "@" },
291     { oQuickRandom, "quick-random", 0, "@"},
292     { oNoVerbose, "no-verbose", 0, "@"},
293     { oTrustDBName, "trustdb-name", 2, "@" },
294     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
295     { oNoArmor, "no-armor",   0, "@"},
296     { oNoDefKeyring, "no-default-keyring", 0, "@" },
297     { oNoGreeting, "no-greeting", 0, "@" },
298     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
299     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
300     { oNoBatch, "no-batch", 0, "@" },
301     { oWithColons, "with-colons", 0, "@"},
302     { aListKeys, "list-key", 0, "@" }, /* alias */
303     { aListSigs, "list-sig", 0, "@" }, /* alias */
304     { aCheckKeys, "check-sig",0, "@" }, /* alias */
305     { oSkipVerify, "skip-verify",0, "@" },
306     { oCompressKeys, "compress-keys",0, "@"},
307     { oCompressSigs, "compress-sigs",0, "@"},
308     { oAlwaysTrust, "always-trust", 0, "@"},
309     { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"},
310     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
311     { oSetFilename, "set-filename", 2, "@" },
312     { oComment, "comment", 2, "@" },
313     { oNoVersion, "no-version", 0,   "@"},
314     { oNotDashEscaped, "not-dash-escaped", 0, "@" },
315     { oEscapeFrom, "escape-from-lines", 0, "@" },
316     { oLockOnce, "lock-once", 0, "@" },
317 {0} };
318
319
320
321 int g10_errors_seen = 0;
322
323
324 static int maybe_setuid = 1;
325
326 static char *build_list( const char *text,
327                          const char *(*mapf)(int), int (*chkf)(int) );
328 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
329                         enum cmd_and_opt_values new_cmd );
330 #ifdef IS_G10MAINT
331 static void print_hex( byte *p, size_t n );
332 static void print_mds( const char *fname, int algo );
333 #endif
334
335 const char *
336 strusage( int level )
337 {
338   static char *digests, *pubkeys, *ciphers;
339     const char *p;
340     switch( level ) {
341       case 11: p =
342           #ifdef IS_G10MAINT
343             "gpgm (GnuPG)";
344           #else
345             "gpg (GnuPG)";
346           #endif
347         break;
348       case 13: p = VERSION; break;
349       case 17: p = PRINTABLE_OS_NAME; break;
350       case 19: p =
351             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
352         break;
353       case 1:
354       case 40:  p =
355           #ifdef IS_G10MAINT
356             _("Usage: gpgm [options] [files] (-h for help)");
357           #else
358             _("Usage: gpg [options] [files] (-h for help)");
359           #endif
360         break;
361       case 41:  p =
362           #ifdef IS_G10MAINT
363             _("Syntax: gpgm [options] [files]\n"
364               "GnuPG maintenance utility\n");
365           #else
366             _("Syntax: gpg [options] [files]\n"
367               "sign, check, encrypt or decrypt\n"
368               "default operation depends on the input data\n");
369           #endif
370         break;
371
372       case 31: p = _("\nSupported algorithms:\n"); break;
373       case 32:
374         if( !ciphers )
375             ciphers = build_list("Cipher: ", cipher_algo_to_string,
376                                                         check_cipher_algo );
377         p = ciphers;
378         break;
379       case 33:
380         if( !pubkeys )
381             pubkeys = build_list("Pubkey: ", pubkey_algo_to_string,
382                                                         check_pubkey_algo );
383         p = pubkeys;
384         break;
385       case 34:
386         if( !digests )
387             digests = build_list("Hash: ", digest_algo_to_string,
388                                                         check_digest_algo );
389         p = digests;
390         break;
391
392       default:  p = default_strusage(level);
393     }
394     return p;
395 }
396
397
398 static char *
399 build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
400 {
401     int i;
402     const char *s;
403     size_t n=strlen(text)+2;
404     char *list, *p;
405
406     if( maybe_setuid )
407         secmem_init( 0 );    /* drop setuid */
408
409     for(i=1; i < 110; i++ )
410         if( !chkf(i) && (s=mapf(i)) )
411             n += strlen(s) + 2;
412     list = m_alloc( 21 + n ); *list = 0;
413     for(p=NULL, i=1; i < 110; i++ ) {
414         if( !chkf(i) && (s=mapf(i)) ) {
415             if( !p )
416                 p = stpcpy( list, text );
417             else
418                 p = stpcpy( p, ", ");
419             p = stpcpy(p, s );
420         }
421     }
422     if( p )
423         p = stpcpy(p, "\n" );
424     return list;
425 }
426
427
428 static void
429 i18n_init(void)
430 {
431   #ifdef ENABLE_NLS
432     #ifdef HAVE_LC_MESSAGES
433        setlocale( LC_TIME, "" );
434        setlocale( LC_MESSAGES, "" );
435     #else
436        setlocale( LC_ALL, "" );
437     #endif
438     bindtextdomain( PACKAGE, G10_LOCALEDIR );
439     textdomain( PACKAGE );
440   #endif
441 }
442
443 static void
444 wrong_args( const char *text)
445 {
446   #ifdef IS_G10MAINT
447     fputs(_("usage: gpgm [options] "),stderr);
448   #else
449     fputs(_("usage: gpg [options] "),stderr);
450   #endif
451     fputs(text,stderr);
452     putc('\n',stderr);
453     g10_exit(2);
454 }
455
456 static void
457 set_debug(void)
458 {
459     if( opt.debug & DBG_MEMORY_VALUE )
460         memory_debug_mode = 1;
461     if( opt.debug & DBG_MEMSTAT_VALUE )
462         memory_stat_debug_mode = 1;
463     if( opt.debug & DBG_MPI_VALUE )
464         mpi_debug_mode = 1;
465     if( opt.debug & DBG_CIPHER_VALUE )
466         g10c_debug_mode = 1;
467     if( opt.debug & DBG_IOBUF_VALUE )
468         iobuf_debug_mode = 1;
469
470 }
471
472
473 static void
474 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
475 {
476     enum cmd_and_opt_values cmd = *ret_cmd;
477
478     if( !cmd || cmd == new_cmd )
479         cmd = new_cmd;
480     else if( cmd == aSign && new_cmd == aEncr )
481         cmd = aSignEncr;
482     else if( cmd == aEncr && new_cmd == aSign )
483         cmd = aSignEncr;
484     else if( cmd == aKMode && new_cmd == aSym )
485         cmd = aKModeC;
486     else if(    ( cmd == aSign     && new_cmd == aClearsign )
487              || ( cmd == aClearsign && new_cmd == aSign )  )
488         cmd = aClearsign;
489     else {
490         log_error(_("conflicting commands\n"));
491         g10_exit(2);
492     }
493
494     *ret_cmd = cmd;
495 }
496
497
498
499 int
500 main( int argc, char **argv )
501 {
502     ARGPARSE_ARGS pargs;
503     IOBUF a;
504     int rc=0;
505     int orig_argc;
506     char **orig_argv;
507     const char *fname;
508     STRLIST sl, remusr= NULL, locusr=NULL;
509     STRLIST nrings=NULL, sec_nrings=NULL;
510     armor_filter_context_t afx;
511     int detached_sig = 0;
512     FILE *configfp = NULL;
513     char *configname = NULL;
514     unsigned configlineno;
515     int parse_debug = 0;
516     int default_config =1;
517     int default_keyring = 1;
518     int greeting = 1;
519     enum cmd_and_opt_values cmd = 0;
520     const char *trustdb_name = NULL;
521     char *def_cipher_string = NULL;
522     char *def_digest_string = NULL;
523     char *s2k_cipher_string = NULL;
524     char *s2k_digest_string = NULL;
525     int pwfd = -1;
526   #ifdef USE_SHM_COPROCESSING
527     ulong requested_shm_size=0;
528   #endif
529
530     trap_unaligned();
531     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
532   #ifdef IS_G10MAINT
533     secmem_init( 0 );      /* disable use of secmem */
534     maybe_setuid = 0;
535     log_set_name("gpgm");
536   #else
537     /* Please note that we may running SUID(ROOT), so be very CAREFUL
538      * when adding any stuff between here and the call to
539      * secmem_init()  somewhere after the option parsing
540      */
541     log_set_name("gpg");
542     secure_random_alloc(); /* put random number into secure memory */
543     disable_core_dumps();
544   #endif
545     init_signals();
546     create_dotlock(NULL); /* register locking cleanup */
547     i18n_init();
548     opt.compress = -1; /* defaults to standard compress level */
549     /* fixme: set the next two to zero and decide where used */
550     opt.def_cipher_algo = 0;
551     opt.def_digest_algo = 0;
552     opt.def_compress_algo = 2;
553     opt.s2k_mode = 1; /* salted */
554     opt.s2k_digest_algo = DIGEST_ALGO_RMD160;
555     opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
556     opt.completes_needed = 1;
557     opt.marginals_needed = 3;
558     opt.max_cert_depth = 5;
559     opt.homedir = getenv("GNUPGHOME");
560     if( !opt.homedir || !*opt.homedir ) {
561       #ifdef HAVE_DRIVE_LETTERS
562         opt.homedir = "c:/gnupg";
563       #else
564         opt.homedir = "~/.gnupg";
565       #endif
566     }
567
568     /* check whether we have a config file on the commandline */
569     orig_argc = argc;
570     orig_argv = argv;
571     pargs.argc = &argc;
572     pargs.argv = &argv;
573     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
574     while( arg_parse( &pargs, opts) ) {
575         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
576             parse_debug++;
577         else if( pargs.r_opt == oOptions ) {
578             /* yes there is one, so we do not try the default one, but
579              * read the option file when it is encountered at the commandline
580              */
581             default_config = 0;
582         }
583         else if( pargs.r_opt == oNoOptions )
584             default_config = 0; /* --no-options */
585         else if( pargs.r_opt == oHomedir )
586             opt.homedir = pargs.r.ret_str;
587       #ifdef USE_SHM_COPROCESSING
588         else if( pargs.r_opt == oRunAsShmCP ) {
589             /* does not make sense in a options file, we do it here,
590              * so that we are the able to drop setuid as soon as possible */
591             opt.shm_coprocess = 1;
592             requested_shm_size = pargs.r.ret_ulong;
593         }
594       #endif
595     }
596
597
598   #ifdef USE_SHM_COPROCESSING
599     if( opt.shm_coprocess ) {
600       #ifdef IS_G10
601         init_shm_coprocessing(requested_shm_size, 1 );
602       #else
603         init_shm_coprocessing(requested_shm_size, 0 );
604       #endif
605     }
606   #endif
607   #ifdef IS_G10
608     /* initialize the secure memory. */
609     secmem_init( 16384 );
610     maybe_setuid = 0;
611     /* Okay, we are now working under our real uid */
612   #endif
613
614     if( default_config )
615         configname = make_filename(opt.homedir, "options", NULL );
616
617     argc = orig_argc;
618     argv = orig_argv;
619     pargs.argc = &argc;
620     pargs.argv = &argv;
621     pargs.flags=  1;  /* do not remove the args */
622   next_pass:
623     if( configname ) {
624         configlineno = 0;
625         configfp = fopen( configname, "r" );
626         if( !configfp ) {
627             if( default_config ) {
628                 if( parse_debug )
629                     log_info(_("NOTE: no default option file `%s'\n"),
630                                                             configname );
631             }
632             else {
633                 log_error(_("option file `%s': %s\n"),
634                                     configname, strerror(errno) );
635                 g10_exit(2);
636             }
637             m_free(configname); configname = NULL;
638         }
639         if( parse_debug && configname )
640             log_info(_("reading options from `%s'\n"), configname );
641         default_config = 0;
642     }
643
644     while( optfile_parse( configfp, configname, &configlineno,
645                                                 &pargs, opts) ) {
646         switch( pargs.r_opt ) {
647           case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
648           case aListPackets: set_cmd( &cmd, aListPackets); break;
649           case aImport: set_cmd( &cmd, aImport); break;
650           case aFastImport: set_cmd( &cmd, aFastImport); break;
651           case aSendKeys: set_cmd( &cmd, aSendKeys); break;
652           case aExport: set_cmd( &cmd, aExport); break;
653           case aExportAll: set_cmd( &cmd, aExportAll); break;
654           case aListKeys: set_cmd( &cmd, aListKeys); break;
655           case aListSigs: set_cmd( &cmd, aListSigs); break;
656           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
657           case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); break;
658           case aDeleteKey: set_cmd( &cmd, aDeleteKey); break;
659
660         #ifdef IS_G10
661           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
662           case aSym: set_cmd( &cmd, aSym); break;
663           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
664           case aEncr: set_cmd( &cmd, aEncr); break;
665           case aSign: set_cmd( &cmd, aSign );  break;
666           case aKeygen: set_cmd( &cmd, aKeygen); break;
667           case aSignKey: set_cmd( &cmd, aSignKey); break;
668           case aStore: set_cmd( &cmd, aStore); break;
669           case aEditKey: set_cmd( &cmd, aEditKey); break;
670           case aClearsign: set_cmd( &cmd, aClearsign); break;
671           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
672           case aVerify: set_cmd( &cmd, aVerify); break;
673         #else
674           #ifdef MAINTAINER_OPTIONS
675             case aPrimegen: set_cmd( &cmd, aPrimegen); break;
676             case aGenRandom: set_cmd( &cmd, aGenRandom); break;
677           #endif
678           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
679           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
680           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
681           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
682           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
683           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
684           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
685           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
686           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
687           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
688           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
689         #endif /* IS_G10MAINT */
690
691
692
693           case oArmor: opt.armor = 1; opt.no_armor=0; break;
694           case oOutput: opt.outfile = pargs.r.ret_str; break;
695           case oQuiet: opt.quiet = 1; break;
696           case oDryRun: opt.dry_run = 1; break;
697           case oVerbose: g10_opt_verbose++;
698                     opt.verbose++; opt.list_sigs=1; break;
699           case oKOption: set_cmd( &cmd, aKMode ); break;
700
701           case oBatch: opt.batch = 1; greeting = 0; break;
702           case oAnswerYes: opt.answer_yes = 1; break;
703           case oAnswerNo: opt.answer_no = 1; break;
704           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
705           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
706           case oDebugAll: opt.debug = ~0; break;
707           case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
708           case oFingerprint: opt.fingerprint++; break;
709           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
710           case oOptions:
711             /* config files may not be nested (silently ignore them) */
712             if( !configfp ) {
713                 m_free(configname);
714                 configname = m_strdup(pargs.r.ret_str);
715                 goto next_pass;
716             }
717             break;
718           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
719           case oNoDefKeyring: default_keyring = 0; break;
720           case oNoGreeting: greeting = 0; break;
721           case oNoVerbose: g10_opt_verbose = 0;
722                            opt.verbose = 0; opt.list_sigs=0; break;
723           case oQuickRandom: quick_random_gen(1); break;
724           case oNoComment: opt.no_comment=1; break;
725           case oNoVersion: opt.no_version=1; break;
726           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
727           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
728           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
729           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
730           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
731           case oNoOptions: break; /* no-options */
732           case oHomedir: opt.homedir = pargs.r.ret_str; break;
733           case oNoBatch: opt.batch = 0; break;
734           case oWithColons: opt.with_colons=':'; break;
735
736           case oSkipVerify: opt.skip_verify=1; break;
737           case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break;
738           case oCompressKeys: opt.compress_keys = 1; break;
739           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
740           case oAlwaysTrust: opt.always_trust = 1; break;
741           case oLoadExtension:
742             register_cipher_extension(orig_argc? *orig_argv:NULL,
743                                       pargs.r.ret_str);
744             break;
745           case oRFC1991:
746             opt.rfc1991 = 1;
747             opt.no_comment = 1;
748             opt.escape_from = 1;
749             break;
750           case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
751           case oCompressSigs: opt.compress_sigs = 1; break;
752           case oRunAsShmCP:
753           #ifndef USE_SHM_COPROCESSING
754             /* not possible in the option file,
755              * but we print the warning here anyway */
756             log_error("shared memory coprocessing is not available\n");
757           #endif
758             break;
759           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
760           case oComment: opt.comment_string = pargs.r.ret_str; break;
761           case oThrowKeyid: opt.throw_keyid = 1; break;
762           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
763           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
764           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
765           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
766
767           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
768           case oEncryptTo: /* store the recipient in the second list */
769             sl = add_to_strlist( &remusr, pargs.r.ret_str );
770             sl->flags = 1;
771             break;
772         #ifdef IS_G10
773           case oRecipient: /* store the recipient */
774             add_to_strlist( &remusr, pargs.r.ret_str );
775             break;
776           case oTextmodeShort: opt.textmode = 2; break;
777           case oTextmode: opt.textmode=1;  break;
778           case oUser: /* store the local users */
779             add_to_strlist( &locusr, pargs.r.ret_str );
780             break;
781           case oCompress: opt.compress = pargs.r.ret_int; break;
782           case oPasswdFD: pwfd = pargs.r.ret_int; break;
783           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
784           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
785           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
786         #else
787           case oCipherAlgo:
788           case oDigestAlgo:
789           case oNoSecmemWarn:
790             break;  /* dummies */
791         #endif
792           case oCharset:
793             if( set_native_charset( pargs.r.ret_str ) )
794                 log_error(_("%s is not a valid character set\n"),
795                                                     pargs.r.ret_str);
796             break;
797           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
798           case oEscapeFrom: opt.escape_from = 1; break;
799           case oLockOnce: opt.lock_once = 1; break;
800           case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
801
802           default : pargs.err = configfp? 1:2; break;
803         }
804     }
805     if( configfp ) {
806         fclose( configfp );
807         configfp = NULL;
808         m_free(configname); configname = NULL;
809         goto next_pass;
810     }
811     m_free( configname ); configname = NULL;
812     if( log_get_errorcount(0) )
813         g10_exit(2);
814
815     if( greeting ) {
816         fprintf(stderr, "%s %s; %s\n",
817                         strusage(11), strusage(13), strusage(14) );
818         fprintf(stderr, "%s\n", strusage(15) );
819       #ifdef IS_DEVELOPMENT_VERSION
820         log_info("NOTE: this is a development version!\n");
821       #endif
822     }
823
824     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
825
826     set_debug();
827     g10_opt_homedir = opt.homedir;
828
829     /* must do this after dropping setuid, because string_to...
830      * may try to load an module */
831     if( def_cipher_string ) {
832         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
833         m_free(def_cipher_string); def_cipher_string = NULL;
834         if( check_cipher_algo(opt.def_cipher_algo) )
835             log_error(_("selected cipher algorithm is invalid\n"));
836     }
837     if( def_digest_string ) {
838         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
839         m_free(def_digest_string); def_digest_string = NULL;
840         if( check_digest_algo(opt.def_digest_algo) )
841             log_error(_("selected digest algorithm is invalid\n"));
842     }
843     if( s2k_cipher_string ) {
844         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
845         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
846         if( check_cipher_algo(opt.s2k_cipher_algo) )
847             log_error(_("selected cipher algorithm is invalid\n"));
848     }
849     if( s2k_digest_string ) {
850         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
851         m_free(s2k_digest_string); s2k_digest_string = NULL;
852         if( check_digest_algo(opt.s2k_digest_algo) )
853             log_error(_("selected digest algorithm is invalid\n"));
854     }
855     if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
856         log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
857     if( opt.completes_needed < 1 )
858         log_error(_("completes-needed must be greater than 0\n"));
859     if( opt.marginals_needed < 2 )
860         log_error(_("marginals-needed must be greater than 1\n"));
861     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
862         log_error(_("max-cert-depth must be in range 1 to 255\n"));
863     switch( opt.s2k_mode ) {
864       case 0:
865         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
866         break;
867       case 1: case 3: break;
868       default:
869         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
870     }
871
872
873     if( log_get_errorcount(0) )
874         g10_exit(2);
875
876     if( !cmd && opt.fingerprint )
877         set_cmd( &cmd, aListKeys);
878
879     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
880         if( cmd == aKModeC ) {
881             opt.fingerprint = 1;
882             cmd = aKMode;
883         }
884         opt.list_sigs = 0;
885         if( opt.verbose > 2 )
886             opt.check_sigs++;
887         if( opt.verbose > 1 )
888             opt.list_sigs++;
889
890         opt.verbose = opt.verbose > 1;
891         g10_opt_verbose = opt.verbose;
892     }
893
894
895     /* kludge to let -sat generate a clear text signature */
896     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
897         cmd = aClearsign;
898
899     if( opt.verbose > 1 )
900         set_packet_list_mode(1);
901
902     /* add the keyrings, but not for some special commands and
903      * not in case of "-kvv userid keyring" */
904     if( cmd != aDeArmor && cmd != aEnArmor
905         && !(cmd == aKMode && argc == 2 ) ) {
906
907         if( !sec_nrings || default_keyring )  /* add default secret rings */
908             add_keyblock_resource("secring.gpg", 0, 1);
909         for(sl = sec_nrings; sl; sl = sl->next )
910             add_keyblock_resource( sl->d, 0, 1 );
911         if( !nrings || default_keyring )  /* add default ring */
912             add_keyblock_resource("pubring.gpg", 0, 0);
913         for(sl = nrings; sl; sl = sl->next )
914             add_keyblock_resource( sl->d, 0, 0 );
915     }
916     FREE_STRLIST(nrings);
917     FREE_STRLIST(sec_nrings);
918
919
920     if( pwfd != -1 )  /* read the passphrase now. */
921         read_passphrase_from_fd( pwfd );
922
923     fname = argc? *argv : NULL;
924
925     switch( cmd ) {
926       case aPrimegen:
927       case aPrintMD:
928       case aPrintMDs:
929       case aGenRandom:
930       case aDeArmor:
931       case aEnArmor:
932       case aFixTrustDB:
933         break;
934       case aKMode:
935       case aListKeys:
936       case aListSecretKeys:
937       case aCheckKeys:
938         if( opt.with_colons ) /* need this to list the trust */
939             rc = setup_trustdb(1, trustdb_name );
940         break;
941       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
942       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
943       default: rc = setup_trustdb(1, trustdb_name ); break;
944     }
945     if( rc )
946         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
947
948
949     switch( cmd ) {
950       case aStore: /* only store the file */
951         if( argc > 1 )
952             wrong_args(_("--store [filename]"));
953         if( (rc = encode_store(fname)) )
954             log_error_f( print_fname_stdin(fname),
955                         "store failed: %s\n", g10_errstr(rc) );
956         break;
957     #ifdef IS_G10
958       case aSym: /* encrypt the given file only with the symmetric cipher */
959         if( argc > 1 )
960             wrong_args(_("--symmetric [filename]"));
961         if( (rc = encode_symmetric(fname)) )
962             log_error_f(print_fname_stdin(fname),
963                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
964         break;
965
966       case aEncr: /* encrypt the given file */
967         if( argc > 1 )
968             wrong_args(_("--encrypt [filename]"));
969         if( (rc = encode_crypt(fname,remusr)) )
970             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
971         break;
972
973       case aSign: /* sign the given file */
974         sl = NULL;
975         if( detached_sig ) { /* sign all files */
976             for( ; argc; argc--, argv++ )
977                 add_to_strlist( &sl, *argv );
978         }
979         else {
980             if( argc > 1 )
981                 wrong_args(_("--sign [filename]"));
982             if( argc ) {
983                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
984                 strcpy(sl->d, fname);
985             }
986         }
987         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
988             log_error("signing failed: %s\n", g10_errstr(rc) );
989         free_strlist(sl);
990         break;
991
992       case aSignEncr: /* sign and encrypt the given file */
993         if( argc > 1 )
994             wrong_args(_("--sign --encrypt [filename]"));
995         if( argc ) {
996             sl = m_alloc_clear( sizeof *sl + strlen(fname));
997             strcpy(sl->d, fname);
998         }
999         else
1000             sl = NULL;
1001         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1002             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1003         free_strlist(sl);
1004         break;
1005
1006       case aClearsign: /* make a clearsig */
1007         if( argc > 1 )
1008             wrong_args(_("--clearsign [filename]"));
1009         if( (rc = clearsign_file(fname, locusr, NULL)) )
1010             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1011         break;
1012
1013       case aVerify:
1014         if( (rc = verify_signatures( argc, argv ) ))
1015             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
1016         break;
1017
1018       case aDecrypt:
1019         if( argc > 1 )
1020             wrong_args(_("--decrypt [filename]"));
1021         if( (rc = decrypt_message( fname ) ))
1022             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
1023         break;
1024
1025
1026       case aSignKey: /* sign the key given as argument */
1027       case aEditKey: /* Edit a key signature */
1028         if( !argc )
1029             wrong_args(_("--edit-key username [commands]"));
1030         if( argc > 1 ) {
1031             sl = NULL;
1032             for( argc--, argv++ ; argc; argc--, argv++ )
1033                 append_to_strlist( &sl, *argv );
1034             keyedit_menu( fname, locusr, sl );
1035             free_strlist(sl);
1036         }
1037         else
1038             keyedit_menu(fname, locusr, NULL );
1039         break;
1040
1041       #endif /* IS_G10 */
1042
1043       case aDeleteSecretKey:
1044         if( argc != 1 )
1045             wrong_args(_("--delete-secret-key username"));
1046       case aDeleteKey:
1047         if( argc != 1 )
1048             wrong_args(_("--delete-key username"));
1049         /* note: fname is the user id! */
1050         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
1051             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1052         break;
1053
1054
1055       case aCheckKeys:
1056         opt.check_sigs = 1;
1057       case aListSigs:
1058         opt.list_sigs = 1;
1059       case aListKeys:
1060         public_key_list( argc, argv );
1061         break;
1062       case aListSecretKeys:
1063         secret_key_list( argc, argv );
1064         break;
1065
1066       case aKMode: /* list keyring */
1067         if( argc < 2 )  /* -kv [userid] */
1068             public_key_list( (argc && **argv)? 1:0, argv );
1069         else if( argc == 2 ) { /* -kv userid keyring */
1070             if( access( argv[1], R_OK ) ) {
1071                 log_error(_("can't open %s: %s\n"),
1072                                print_fname_stdin(argv[1]), strerror(errno));
1073             }
1074             else {
1075                 /* add keyring (default keyrings are not registered in this
1076                  * special case */
1077                 add_keyblock_resource( argv[1], 0, 0 );
1078                 public_key_list( **argv?1:0, argv );
1079             }
1080         }
1081         else
1082             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
1083         break;
1084
1085     #ifdef IS_G10
1086       case aKeygen: /* generate a key (interactive) */
1087         if( argc )
1088             wrong_args("--gen-key");
1089         generate_keypair();
1090         break;
1091     #endif
1092
1093       case aFastImport:
1094       case aImport:
1095         if( !argc  ) {
1096             rc = import_keys( NULL, (cmd == aFastImport) );
1097             if( rc )
1098                 log_error("import failed: %s\n", g10_errstr(rc) );
1099         }
1100         for( ; argc; argc--, argv++ ) {
1101             rc = import_keys( *argv, (cmd == aFastImport) );
1102             if( rc )
1103                 log_error("import from `%s' failed: %s\n",
1104                                                 *argv, g10_errstr(rc) );
1105         }
1106         break;
1107
1108       case aExport:
1109       case aExportAll:
1110       case aSendKeys:
1111         sl = NULL;
1112         for( ; argc; argc--, argv++ )
1113             add_to_strlist( &sl, *argv );
1114         if( cmd == aSendKeys )
1115             hkp_export( sl );
1116         else
1117             export_pubkeys( sl, (cmd == aExport) );
1118         free_strlist(sl);
1119         break;
1120
1121       case aExportSecret:
1122         sl = NULL;
1123         for( ; argc; argc--, argv++ )
1124             add_to_strlist( &sl, *argv );
1125         export_seckeys( sl );
1126         free_strlist(sl);
1127         break;
1128
1129     #ifdef IS_G10
1130       case aGenRevoke:
1131         if( argc != 1 )
1132             wrong_args("--gen-revoke user-id");
1133         gen_revoke( *argv );
1134         break;
1135     #endif
1136
1137     #ifdef IS_G10MAINT
1138       case aDeArmor:
1139         if( argc > 1 )
1140             wrong_args("--dearmor [file]");
1141         rc = dearmor_file( argc? *argv: NULL );
1142         if( rc )
1143             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
1144         break;
1145
1146       case aEnArmor:
1147         if( argc > 1 )
1148             wrong_args("--enarmor [file]");
1149         rc = enarmor_file( argc? *argv: NULL );
1150         if( rc )
1151             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
1152         break;
1153
1154
1155      #ifdef MAINTAINER_OPTIONS
1156       case aPrimegen:
1157         if( argc == 1 ) {
1158             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
1159             putchar('\n');
1160         }
1161         else if( argc == 2 ) {
1162             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1163                                                    atoi(argv[1]), NULL,NULL ), 1);
1164             putchar('\n');
1165         }
1166         else if( argc == 3 ) {
1167             MPI g = mpi_alloc(1);
1168             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1169                                                    atoi(argv[1]), g, NULL ), 1);
1170             printf("\nGenerator: ");
1171             mpi_print( stdout, g, 1 );
1172             putchar('\n');
1173             mpi_free(g);
1174         }
1175         else if( argc == 4 ) {
1176             mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
1177                                                    atoi(argv[1]), NULL,NULL ), 1);
1178             putchar('\n');
1179         }
1180         else
1181             usage(1);
1182         break;
1183       #endif /* MAINTAINER OPTIONS */
1184
1185       #ifdef MAINTAINER_OPTIONS
1186       case aGenRandom:
1187         if( argc < 1 || argc > 2 )
1188             wrong_args("--gen-random level [hex]");
1189         {
1190             int c;
1191             int level = atoi(*argv);
1192             for(;;) {
1193                 byte *p;
1194                 if( argc == 2 ) {
1195                     p = get_random_bits( 8, level, 0);
1196                     printf("%02x", *p );
1197                     fflush(stdout);
1198                 }
1199                 else {
1200                     p = get_random_bits( 800, level, 0);
1201                     for(c=0; c < 100; c++ )
1202                         putchar( p[c] );
1203                 }
1204                 m_free(p);
1205             }
1206         }
1207         break;
1208       #endif /* MAINTAINER OPTIONS */
1209
1210       case aPrintMD:
1211         if( argc < 1)
1212             wrong_args("--print-md algo [file]");
1213         else {
1214             int algo = string_to_digest_algo(*argv);
1215
1216             if( !algo )
1217                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
1218             else {
1219                 argc--; argv++;
1220                 if( !argc )
1221                     print_mds(NULL, algo);
1222                 else {
1223                     for(; argc; argc--, argv++ )
1224                         print_mds(*argv, algo);
1225                 }
1226             }
1227         }
1228         break;
1229
1230       case aPrintMDs:
1231         if( !argc )
1232             print_mds(NULL,0);
1233         else {
1234             for(; argc; argc--, argv++ )
1235                 print_mds(*argv,0);
1236         }
1237         break;
1238
1239       case aListTrustDB:
1240         if( !argc )
1241             list_trustdb(NULL);
1242         else {
1243             for( ; argc; argc--, argv++ )
1244                 list_trustdb( *argv );
1245         }
1246         break;
1247
1248       case aUpdateTrustDB:
1249         if( argc )
1250             wrong_args("--update-trustdb");
1251         update_trustdb();
1252         break;
1253
1254       case aCheckTrustDB:
1255         if( !argc )
1256             check_trustdb(NULL);
1257         else {
1258             for( ; argc; argc--, argv++ )
1259                 check_trustdb( *argv );
1260         }
1261         break;
1262
1263       case aFixTrustDB:
1264         log_error("this command ist not yet implemented.\"\n");
1265         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
1266         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
1267         break;
1268
1269       case aListTrustPath:
1270         if( !argc )
1271             wrong_args("--list-trust-path <usernames>");
1272         for( ; argc; argc--, argv++ )
1273             list_trust_path( *argv );
1274         break;
1275
1276       case aExportOwnerTrust:
1277         if( argc )
1278             wrong_args("--export-ownertrust");
1279         export_ownertrust();
1280         break;
1281
1282       case aImportOwnerTrust:
1283         if( argc > 1 )
1284             wrong_args("--import-ownertrust [file]");
1285         import_ownertrust( argc? *argv:NULL );
1286         break;
1287
1288      #endif /* IS_G10MAINT */
1289
1290
1291       case aListPackets:
1292         opt.list_packets=1;
1293       default:
1294         /* fixme: g10maint should do regular maintenace tasks here */
1295         if( argc > 1 )
1296             wrong_args(_("[filename]"));
1297         /* Issue some output for the unix newbie */
1298         if( !fname && !opt.outfile && isatty( fileno(stdin) )
1299                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
1300             log_info(_("Go ahead and type your message ...\n"));
1301
1302         if( !(a = iobuf_open(fname)) )
1303             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
1304         else {
1305
1306             if( !opt.no_armor ) {
1307                 if( use_armor_filter( a ) ) {
1308                     memset( &afx, 0, sizeof afx);
1309                     iobuf_push_filter( a, armor_filter, &afx );
1310                 }
1311             }
1312             if( cmd == aListPackets ) {
1313                 set_packet_list_mode(1);
1314                 opt.list_packets=1;
1315             }
1316             proc_packets( a );
1317             iobuf_close(a);
1318         }
1319         break;
1320     }
1321
1322     /* cleanup */
1323     FREE_STRLIST(remusr);
1324     FREE_STRLIST(locusr);
1325     g10_exit(0);
1326     return 8; /*NEVER REACHED*/
1327 }
1328
1329
1330 void
1331 g10_exit( int rc )
1332 {
1333     if( opt.debug & DBG_MEMSTAT_VALUE )
1334         m_print_stats("on exit");
1335     if( opt.debug )
1336         secmem_dump_stats();
1337     secmem_term();
1338     rc = rc? rc : log_get_errorcount(0)? 2 :
1339                         g10_errors_seen? 1 : 0;
1340     /*write_status( STATUS_LEAVE );*/
1341     exit(rc );
1342 }
1343
1344
1345
1346
1347 #ifdef IS_G10MAINT
1348 static void
1349 print_hex( byte *p, size_t n )
1350 {
1351     int i;
1352
1353     if( n == 20 ) {
1354         for(i=0; i < n ; i++, i++, p += 2 ) {
1355             if( i )
1356                 putchar(' ');
1357             if( i == 10 )
1358                 putchar(' ');
1359             printf("%02X%02X", *p, p[1] );
1360         }
1361     }
1362     else if( n == 24 ) {
1363         for(i=0; i < n ; i += 4, p += 4 ) {
1364             if( i )
1365                 putchar(' ');
1366             if( i == 12 )
1367                 putchar(' ');
1368             printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
1369         }
1370     }
1371     else {
1372         for(i=0; i < n ; i++, p++ ) {
1373             if( i )
1374                 putchar(' ');
1375             if( i && !(i%8) )
1376                 putchar(' ');
1377             printf("%02X", *p );
1378         }
1379     }
1380 }
1381
1382 static void
1383 print_mds( const char *fname, int algo )
1384 {
1385     FILE *fp;
1386     char buf[1024];
1387     size_t n;
1388     MD_HANDLE md;
1389     char *pname;
1390
1391     if( !fname ) {
1392         fp = stdin;
1393         pname = m_strdup("[stdin]: ");
1394     }
1395     else {
1396         pname = m_alloc(strlen(fname)+3);
1397         strcpy(stpcpy(pname,fname),": ");
1398         fp = fopen( fname, "rb" );
1399     }
1400     if( !fp ) {
1401         log_error("%s%s\n", pname, strerror(errno) );
1402         m_free(pname);
1403         return;
1404     }
1405
1406     md = md_open( 0, 0 );
1407     if( algo )
1408         md_enable( md, algo );
1409     else {
1410         md_enable( md, DIGEST_ALGO_MD5 );
1411         md_enable( md, DIGEST_ALGO_SHA1 );
1412         md_enable( md, DIGEST_ALGO_RMD160 );
1413         if( !check_digest_algo(DIGEST_ALGO_TIGER) )
1414             md_enable( md, DIGEST_ALGO_TIGER );
1415     }
1416
1417     while( (n=fread( buf, 1, DIM(buf), fp )) )
1418         md_write( md, buf, n );
1419     if( ferror(fp) )
1420         log_error("%s%s\n", pname, strerror(errno) );
1421     else {
1422         md_final(md);
1423         if( algo ) {
1424             if( fname )
1425                 fputs( pname, stdout );
1426             print_hex(md_read(md, algo), md_digest_length(algo) );
1427         }
1428         else {
1429             printf(  "%s   MD5 = ", fname?pname:"" );
1430                             print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1431             printf("\n%s  SHA1 = ", fname?pname:""  );
1432                             print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1433             printf("\n%sRMD160 = ", fname?pname:""  );
1434                             print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1435             if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
1436                 printf("\n%s TIGER = ", fname?pname:""  );
1437                             print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
1438             }
1439         }
1440         putchar('\n');
1441     }
1442     md_close(md);
1443
1444     if( fp != stdin )
1445         fclose(fp);
1446 }
1447
1448
1449
1450 #endif /* IS_G10MAINT */
1451