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