See ChangeLog: Tue Feb 16 14:10:02 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 "mpi.h"
39 #include "cipher.h"
40 #include "filter.h"
41 #include "trustdb.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     oTrustedKey,
115     oOptions,
116     oDebug,
117     oDebugAll,
118     oStatusFD,
119     oNoComment,
120     oNoVersion,
121     oCompletesNeeded,
122     oMarginalsNeeded,
123     oMaxCertDepth,
124     oLoadExtension,
125     oRFC1991,
126     oCipherAlgo,
127     oDigestAlgo,
128     oCompressAlgo,
129     oPasswdFD,
130     oQuickRandom,
131     oNoVerbose,
132     oTrustDBName,
133     oNoSecmemWarn,
134     oNoArmor,
135     oNoDefKeyring,
136     oNoGreeting,
137     oNoOptions,
138     oNoBatch,
139     oHomedir,
140     oWithColons,
141     oSkipVerify,
142     oCompressKeys,
143     oCompressSigs,
144     oAlwaysTrust,
145     oEmuChecksumBug,
146     oRunAsShmCP,
147     oSetFilename,
148     oComment,
149     oThrowKeyid,
150     oForceV3Sigs,
151     oS2KMode,
152     oS2KDigest,
153     oS2KCipher,
154     oCharset,
155     oNotDashEscaped,
156     oEscapeFrom,
157     oLockOnce,
158     oKeyServer,
159     oEncryptTo,
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   #ifdef IS_G10
224     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
225     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
226     { oTextmodeShort, NULL,   0, "@"},
227     { oTextmode, "textmode",  0, N_("use canonical text mode")},
228   #endif
229     { oOutput, "output",    2, N_("use as output file")},
230     { oVerbose, "verbose",   0, N_("verbose") },
231     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
232     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
233  /* { oDryRun, "dry-run",   0, N_("do not make any changes") }, */
234     { oBatch, "batch",     0, N_("batch mode: never ask")},
235     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
236     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
237     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
238     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
239     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
240     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
241     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
242     { oOptions, "options"   , 2, N_("read options from file")},
243
244     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
245     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
246     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
247     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
248     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
249     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
250     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
251     { oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
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 oVerbose: g10_opt_verbose++;
697                     opt.verbose++; opt.list_sigs=1; break;
698           case oKOption: set_cmd( &cmd, aKMode ); break;
699
700           case oBatch: opt.batch = 1; greeting = 0; break;
701           case oAnswerYes: opt.answer_yes = 1; break;
702           case oAnswerNo: opt.answer_no = 1; break;
703           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
704           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
705           case oDebugAll: opt.debug = ~0; break;
706           case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
707           case oFingerprint: opt.fingerprint++; break;
708           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
709           case oOptions:
710             /* config files may not be nested (silently ignore them) */
711             if( !configfp ) {
712                 m_free(configname);
713                 configname = m_strdup(pargs.r.ret_str);
714                 goto next_pass;
715             }
716             break;
717           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
718           case oNoDefKeyring: default_keyring = 0; break;
719           case oNoGreeting: greeting = 0; break;
720           case oNoVerbose: g10_opt_verbose = 0;
721                            opt.verbose = 0; opt.list_sigs=0; break;
722           case oQuickRandom: quick_random_gen(1); break;
723           case oNoComment: opt.no_comment=1; break;
724           case oNoVersion: opt.no_version=1; break;
725           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
726           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
727           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
728           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
729           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
730           case oTrustedKey: register_trusted_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 oEncryptTo: /* store the recipient in the second list */
768             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
769             strcpy(sl->d, pargs.r.ret_str);
770             sl->flags = 1;
771             sl->next = remusr;
772             remusr = sl;
773             break;
774         #ifdef IS_G10
775           case oRecipient: /* store the recipient */
776             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
777             strcpy(sl->d, pargs.r.ret_str);
778             sl->next = remusr;
779             remusr = sl;
780             break;
781           case oTextmodeShort: opt.textmode = 2; break;
782           case oTextmode: opt.textmode=1;  break;
783           case oUser: /* store the local users */
784             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
785             strcpy(sl->d, pargs.r.ret_str);
786             sl->next = locusr;
787             locusr = sl;
788             break;
789           case oCompress: opt.compress = pargs.r.ret_int; break;
790           case oPasswdFD: pwfd = pargs.r.ret_int; break;
791           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
792           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
793           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
794         #else
795           case oCipherAlgo:
796           case oDigestAlgo:
797           case oNoSecmemWarn:
798             break;  /* dummies */
799         #endif
800           case oCharset:
801             if( set_native_charset( pargs.r.ret_str ) )
802                 log_error(_("%s is not a valid character set\n"),
803                                                     pargs.r.ret_str);
804             break;
805           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
806           case oEscapeFrom: opt.escape_from = 1; break;
807           case oLockOnce: opt.lock_once = 1; break;
808           case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
809
810           default : pargs.err = configfp? 1:2; break;
811         }
812     }
813     if( configfp ) {
814         fclose( configfp );
815         configfp = NULL;
816         m_free(configname); configname = NULL;
817         goto next_pass;
818     }
819     m_free( configname ); configname = NULL;
820     if( log_get_errorcount(0) )
821         g10_exit(2);
822
823     if( greeting ) {
824         tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
825         tty_printf("%s\n", strusage(15) );
826       #ifdef IS_DEVELOPMENT_VERSION
827         log_info("NOTE: this is a development version!\n");
828       #endif
829     }
830
831     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
832
833     set_debug();
834
835     /* must do this after dropping setuid, because string_to...
836      * may try to load an module */
837     if( def_cipher_string ) {
838         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
839         m_free(def_cipher_string); def_cipher_string = NULL;
840         if( check_cipher_algo(opt.def_cipher_algo) )
841             log_error(_("selected cipher algorithm is invalid\n"));
842     }
843     if( def_digest_string ) {
844         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
845         m_free(def_digest_string); def_digest_string = NULL;
846         if( check_digest_algo(opt.def_digest_algo) )
847             log_error(_("selected digest algorithm is invalid\n"));
848     }
849     if( s2k_cipher_string ) {
850         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
851         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
852         if( check_cipher_algo(opt.s2k_cipher_algo) )
853             log_error(_("selected cipher algorithm is invalid\n"));
854     }
855     if( s2k_digest_string ) {
856         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
857         m_free(s2k_digest_string); s2k_digest_string = NULL;
858         if( check_digest_algo(opt.s2k_digest_algo) )
859             log_error(_("selected digest algorithm is invalid\n"));
860     }
861     if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
862         log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
863     if( opt.completes_needed < 1 )
864         log_error(_("completes-needed must be greater than 0\n"));
865     if( opt.marginals_needed < 2 )
866         log_error(_("marginals-needed must be greater than 1\n"));
867     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
868         log_error(_("max-cert-depth must be in range 1 to 255\n"));
869     switch( opt.s2k_mode ) {
870       case 0:
871         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
872         break;
873       case 1: case 3: break;
874       default:
875         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
876     }
877
878
879     if( log_get_errorcount(0) )
880         g10_exit(2);
881
882     if( !cmd && opt.fingerprint )
883         set_cmd( &cmd, aListKeys);
884
885     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
886         if( cmd == aKModeC ) {
887             opt.fingerprint = 1;
888             cmd = aKMode;
889         }
890         opt.list_sigs = 0;
891         if( opt.verbose > 2 )
892             opt.check_sigs++;
893         if( opt.verbose > 1 )
894             opt.list_sigs++;
895
896         opt.verbose = opt.verbose > 1;
897         g10_opt_verbose = opt.verbose;
898     }
899
900
901     /* kludge to let -sat generate a clear text signature */
902     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
903         cmd = aClearsign;
904
905     if( opt.verbose > 1 )
906         set_packet_list_mode(1);
907
908     /* add the keyrings, but not for some special commands and
909      * not in case of "-kvv userid keyring" */
910     if( cmd != aDeArmor && cmd != aEnArmor
911         && !(cmd == aKMode && argc == 2 ) ) {
912
913         if( !sec_nrings || default_keyring )  /* add default secret rings */
914             add_keyblock_resource("secring.gpg", 0, 1);
915         for(sl = sec_nrings; sl; sl = sl->next )
916             add_keyblock_resource( sl->d, 0, 1 );
917         if( !nrings || default_keyring )  /* add default ring */
918             add_keyblock_resource("pubring.gpg", 0, 0);
919         for(sl = nrings; sl; sl = sl->next )
920             add_keyblock_resource( sl->d, 0, 0 );
921     }
922     FREE_STRLIST(nrings);
923     FREE_STRLIST(sec_nrings);
924
925
926     if( pwfd != -1 )  /* read the passphrase now. */
927         read_passphrase_from_fd( pwfd );
928
929     fname = argc? *argv : NULL;
930
931     switch( cmd ) {
932       case aPrimegen:
933       case aPrintMD:
934       case aPrintMDs:
935       case aGenRandom:
936       case aDeArmor:
937       case aEnArmor:
938       case aFixTrustDB:
939         break;
940       case aKMode:
941       case aListKeys:
942       case aListSecretKeys:
943       case aCheckKeys:
944         if( opt.with_colons ) /* need this to list the trust */
945             rc = init_trustdb(1, trustdb_name );
946         break;
947       case aExportOwnerTrust: rc = init_trustdb( 0, trustdb_name ); break;
948       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
949       default: rc = init_trustdb(1, trustdb_name ); break;
950     }
951     if( rc )
952         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
953
954
955     switch( cmd ) {
956       case aStore: /* only store the file */
957         if( argc > 1 )
958             wrong_args(_("--store [filename]"));
959         if( (rc = encode_store(fname)) )
960             log_error_f( print_fname_stdin(fname),
961                         "store failed: %s\n", g10_errstr(rc) );
962         break;
963     #ifdef IS_G10
964       case aSym: /* encrypt the given file only with the symmetric cipher */
965         if( argc > 1 )
966             wrong_args(_("--symmetric [filename]"));
967         if( (rc = encode_symmetric(fname)) )
968             log_error_f(print_fname_stdin(fname),
969                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
970         break;
971
972       case aEncr: /* encrypt the given file */
973         if( argc > 1 )
974             wrong_args(_("--encrypt [filename]"));
975         if( (rc = encode_crypt(fname,remusr)) )
976             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
977         break;
978
979       case aSign: /* sign the given file */
980         sl = NULL;
981         if( detached_sig ) { /* sign all files */
982             for( ; argc; argc--, argv++ )
983                 add_to_strlist( &sl, *argv );
984         }
985         else {
986             if( argc > 1 )
987                 wrong_args(_("--sign [filename]"));
988             if( argc ) {
989                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
990                 strcpy(sl->d, fname);
991             }
992         }
993         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
994             log_error("signing failed: %s\n", g10_errstr(rc) );
995         free_strlist(sl);
996         break;
997
998       case aSignEncr: /* sign and encrypt the given file */
999         if( argc > 1 )
1000             wrong_args(_("--sign --encrypt [filename]"));
1001         if( argc ) {
1002             sl = m_alloc_clear( sizeof *sl + strlen(fname));
1003             strcpy(sl->d, fname);
1004         }
1005         else
1006             sl = NULL;
1007         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1008             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1009         free_strlist(sl);
1010         break;
1011
1012       case aClearsign: /* make a clearsig */
1013         if( argc > 1 )
1014             wrong_args(_("--clearsign [filename]"));
1015         if( (rc = clearsign_file(fname, locusr, NULL)) )
1016             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1017         break;
1018
1019       case aVerify:
1020         if( (rc = verify_signatures( argc, argv ) ))
1021             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
1022         break;
1023
1024       case aDecrypt:
1025         if( argc > 1 )
1026             wrong_args(_("--decrypt [filename]"));
1027         if( (rc = decrypt_message( fname ) ))
1028             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
1029         break;
1030
1031
1032       case aSignKey: /* sign the key given as argument */
1033       case aEditKey: /* Edit a key signature */
1034         if( !argc )
1035             wrong_args(_("--edit-key username [commands]"));
1036         if( argc > 1 ) {
1037             sl = NULL;
1038             for( argc--, argv++ ; argc; argc--, argv++ )
1039                 append_to_strlist( &sl, *argv );
1040             keyedit_menu( fname, locusr, sl );
1041             free_strlist(sl);
1042         }
1043         else
1044             keyedit_menu(fname, locusr, NULL );
1045         break;
1046
1047       #endif /* IS_G10 */
1048
1049       case aDeleteSecretKey:
1050         if( argc != 1 )
1051             wrong_args(_("--delete-secret-key username"));
1052       case aDeleteKey:
1053         if( argc != 1 )
1054             wrong_args(_("--delete-key username"));
1055         /* note: fname is the user id! */
1056         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
1057             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1058         break;
1059
1060
1061       case aCheckKeys:
1062         opt.check_sigs = 1;
1063       case aListSigs:
1064         opt.list_sigs = 1;
1065       case aListKeys:
1066         public_key_list( argc, argv );
1067         break;
1068       case aListSecretKeys:
1069         secret_key_list( argc, argv );
1070         break;
1071
1072       case aKMode: /* list keyring */
1073         if( argc < 2 )  /* -kv [userid] */
1074             public_key_list( (argc && **argv)? 1:0, argv );
1075         else if( argc == 2 ) { /* -kv userid keyring */
1076             if( access( argv[1], R_OK ) ) {
1077                 log_error(_("can't open %s: %s\n"),
1078                                print_fname_stdin(argv[1]), strerror(errno));
1079             }
1080             else {
1081                 /* add keyring (default keyrings are not registered in this
1082                  * special case */
1083                 add_keyblock_resource( argv[1], 0, 0 );
1084                 public_key_list( **argv?1:0, argv );
1085             }
1086         }
1087         else
1088             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
1089         break;
1090
1091     #ifdef IS_G10
1092       case aKeygen: /* generate a key (interactive) */
1093         if( argc )
1094             wrong_args("--gen-key");
1095         generate_keypair();
1096         break;
1097     #endif
1098
1099       case aFastImport:
1100       case aImport:
1101         if( !argc  ) {
1102             rc = import_keys( NULL, (cmd == aFastImport) );
1103             if( rc )
1104                 log_error("import failed: %s\n", g10_errstr(rc) );
1105         }
1106         for( ; argc; argc--, argv++ ) {
1107             rc = import_keys( *argv, (cmd == aFastImport) );
1108             if( rc )
1109                 log_error("import from `%s' failed: %s\n",
1110                                                 *argv, g10_errstr(rc) );
1111         }
1112         break;
1113
1114       case aExport:
1115       case aExportAll:
1116       case aSendKeys:
1117         sl = NULL;
1118         for( ; argc; argc--, argv++ )
1119             add_to_strlist( &sl, *argv );
1120         if( cmd == aSendKeys )
1121             hkp_export( sl );
1122         else
1123             export_pubkeys( sl, (cmd == aExport) );
1124         free_strlist(sl);
1125         break;
1126
1127       case aExportSecret:
1128         sl = NULL;
1129         for( ; argc; argc--, argv++ )
1130             add_to_strlist( &sl, *argv );
1131         export_seckeys( sl );
1132         free_strlist(sl);
1133         break;
1134
1135     #ifdef IS_G10
1136       case aGenRevoke:
1137         if( argc != 1 )
1138             wrong_args("--gen-revoke user-id");
1139         gen_revoke( *argv );
1140         break;
1141     #endif
1142
1143     #ifdef IS_G10MAINT
1144       case aDeArmor:
1145         if( argc > 1 )
1146             wrong_args("--dearmor [file]");
1147         rc = dearmor_file( argc? *argv: NULL );
1148         if( rc )
1149             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
1150         break;
1151
1152       case aEnArmor:
1153         if( argc > 1 )
1154             wrong_args("--enarmor [file]");
1155         rc = enarmor_file( argc? *argv: NULL );
1156         if( rc )
1157             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
1158         break;
1159
1160
1161      #ifdef MAINTAINER_OPTIONS
1162       case aPrimegen:
1163         if( argc == 1 ) {
1164             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
1165             putchar('\n');
1166         }
1167         else if( argc == 2 ) {
1168             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1169                                                    atoi(argv[1]), NULL,NULL ), 1);
1170             putchar('\n');
1171         }
1172         else if( argc == 3 ) {
1173             MPI g = mpi_alloc(1);
1174             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1175                                                    atoi(argv[1]), g, NULL ), 1);
1176             printf("\nGenerator: ");
1177             mpi_print( stdout, g, 1 );
1178             putchar('\n');
1179             mpi_free(g);
1180         }
1181         else if( argc == 4 ) {
1182             mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
1183                                                    atoi(argv[1]), NULL,NULL ), 1);
1184             putchar('\n');
1185         }
1186         else
1187             usage(1);
1188         break;
1189       #endif /* MAINTAINER OPTIONS */
1190
1191       #ifdef MAINTAINER_OPTIONS
1192       case aGenRandom:
1193         if( argc < 1 || argc > 2 )
1194             wrong_args("--gen-random level [hex]");
1195         {
1196             int c;
1197             int level = atoi(*argv);
1198             for(;;) {
1199                 byte *p;
1200                 if( argc == 2 ) {
1201                     p = get_random_bits( 8, level, 0);
1202                     printf("%02x", *p );
1203                     fflush(stdout);
1204                 }
1205                 else {
1206                     p = get_random_bits( 800, level, 0);
1207                     for(c=0; c < 100; c++ )
1208                         putchar( p[c] );
1209                 }
1210                 m_free(p);
1211             }
1212         }
1213         break;
1214       #endif /* MAINTAINER OPTIONS */
1215
1216       case aPrintMD:
1217         if( argc < 1)
1218             wrong_args("--print-md algo [file]");
1219         else {
1220             int algo = string_to_digest_algo(*argv);
1221
1222             if( !algo )
1223                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
1224             else {
1225                 argc--; argv++;
1226                 if( !argc )
1227                     print_mds(NULL, algo);
1228                 else {
1229                     for(; argc; argc--, argv++ )
1230                         print_mds(*argv, algo);
1231                 }
1232             }
1233         }
1234         break;
1235
1236       case aPrintMDs:
1237         if( !argc )
1238             print_mds(NULL,0);
1239         else {
1240             for(; argc; argc--, argv++ )
1241                 print_mds(*argv,0);
1242         }
1243         break;
1244
1245       case aListTrustDB:
1246         if( !argc )
1247             list_trustdb(NULL);
1248         else {
1249             for( ; argc; argc--, argv++ )
1250                 list_trustdb( *argv );
1251         }
1252         break;
1253
1254       case aUpdateTrustDB:
1255         if( argc )
1256             wrong_args("--update-trustdb");
1257         update_trustdb();
1258         break;
1259
1260       case aCheckTrustDB:
1261         if( !argc )
1262             check_trustdb(NULL);
1263         else {
1264             for( ; argc; argc--, argv++ )
1265                 check_trustdb( *argv );
1266         }
1267         break;
1268
1269       case aFixTrustDB:
1270         log_error("this command ist not yet implemented.\"\n");
1271         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
1272         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
1273         break;
1274
1275       case aListTrustPath:
1276         if( !argc )
1277             wrong_args("--list-trust-path <usernames>");
1278         for( ; argc; argc--, argv++ )
1279             list_trust_path( *argv );
1280         break;
1281
1282       case aExportOwnerTrust:
1283         if( argc )
1284             wrong_args("--export-ownertrust");
1285         export_ownertrust();
1286         break;
1287
1288       case aImportOwnerTrust:
1289         if( argc > 1 )
1290             wrong_args("--import-ownertrust [file]");
1291         import_ownertrust( argc? *argv:NULL );
1292         break;
1293
1294      #endif /* IS_G10MAINT */
1295
1296
1297       case aListPackets:
1298         opt.list_packets=1;
1299       default:
1300         /* fixme: g10maint should do regular maintenace tasks here */
1301         if( argc > 1 )
1302             wrong_args(_("[filename]"));
1303         /* Issue some output for the unix newbie */
1304         if( !fname && !opt.outfile && isatty( fileno(stdin) )
1305                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
1306             log_info(_("Go ahead and type your message ...\n"));
1307
1308         if( !(a = iobuf_open(fname)) )
1309             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
1310         else {
1311
1312             if( !opt.no_armor ) {
1313                 if( use_armor_filter( a ) ) {
1314                     memset( &afx, 0, sizeof afx);
1315                     iobuf_push_filter( a, armor_filter, &afx );
1316                 }
1317             }
1318             if( cmd == aListPackets ) {
1319                 set_packet_list_mode(1);
1320                 opt.list_packets=1;
1321             }
1322             proc_packets( a );
1323             iobuf_close(a);
1324         }
1325         break;
1326     }
1327
1328     /* cleanup */
1329     FREE_STRLIST(remusr);
1330     FREE_STRLIST(locusr);
1331     g10_exit(0);
1332     return 8; /*NEVER REACHED*/
1333 }
1334
1335
1336 void
1337 g10_exit( int rc )
1338 {
1339     if( opt.debug & DBG_MEMSTAT_VALUE )
1340         m_print_stats("on exit");
1341     if( opt.debug )
1342         secmem_dump_stats();
1343     secmem_term();
1344     rc = rc? rc : log_get_errorcount(0)? 2 :
1345                         g10_errors_seen? 1 : 0;
1346     /*write_status( STATUS_LEAVE );*/
1347     exit(rc );
1348 }
1349
1350
1351
1352
1353 #ifdef IS_G10MAINT
1354 static void
1355 print_hex( byte *p, size_t n )
1356 {
1357     int i;
1358
1359     if( n == 20 ) {
1360         for(i=0; i < n ; i++, i++, p += 2 ) {
1361             if( i )
1362                 putchar(' ');
1363             if( i == 10 )
1364                 putchar(' ');
1365             printf("%02X%02X", *p, p[1] );
1366         }
1367     }
1368     else if( n == 24 ) {
1369         for(i=0; i < n ; i += 4, p += 4 ) {
1370             if( i )
1371                 putchar(' ');
1372             if( i == 12 )
1373                 putchar(' ');
1374             printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
1375         }
1376     }
1377     else {
1378         for(i=0; i < n ; i++, p++ ) {
1379             if( i )
1380                 putchar(' ');
1381             if( i && !(i%8) )
1382                 putchar(' ');
1383             printf("%02X", *p );
1384         }
1385     }
1386 }
1387
1388 static void
1389 print_mds( const char *fname, int algo )
1390 {
1391     FILE *fp;
1392     char buf[1024];
1393     size_t n;
1394     MD_HANDLE md;
1395     char *pname;
1396
1397     if( !fname ) {
1398         fp = stdin;
1399         pname = m_strdup("[stdin]: ");
1400     }
1401     else {
1402         pname = m_alloc(strlen(fname)+3);
1403         strcpy(stpcpy(pname,fname),": ");
1404         fp = fopen( fname, "rb" );
1405     }
1406     if( !fp ) {
1407         log_error("%s%s\n", pname, strerror(errno) );
1408         m_free(pname);
1409         return;
1410     }
1411
1412     md = md_open( 0, 0 );
1413     if( algo )
1414         md_enable( md, algo );
1415     else {
1416         md_enable( md, DIGEST_ALGO_MD5 );
1417         md_enable( md, DIGEST_ALGO_SHA1 );
1418         md_enable( md, DIGEST_ALGO_RMD160 );
1419         if( !check_digest_algo(DIGEST_ALGO_TIGER) )
1420             md_enable( md, DIGEST_ALGO_TIGER );
1421     }
1422
1423     while( (n=fread( buf, 1, DIM(buf), fp )) )
1424         md_write( md, buf, n );
1425     if( ferror(fp) )
1426         log_error("%s%s\n", pname, strerror(errno) );
1427     else {
1428         md_final(md);
1429         if( algo ) {
1430             if( fname )
1431                 fputs( pname, stdout );
1432             print_hex(md_read(md, algo), md_digest_length(algo) );
1433         }
1434         else {
1435             printf(  "%s   MD5 = ", fname?pname:"" );
1436                             print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1437             printf("\n%s  SHA1 = ", fname?pname:""  );
1438                             print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1439             printf("\n%sRMD160 = ", fname?pname:""  );
1440                             print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1441             if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
1442                 printf("\n%s TIGER = ", fname?pname:""  );
1443                             print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
1444             }
1445         }
1446         putchar('\n');
1447     }
1448     md_close(md);
1449
1450     if( fp != stdin )
1451         fclose(fp);
1452 }
1453
1454
1455
1456 #endif /* IS_G10MAINT */
1457