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