See ChangeLog: Sat Mar 20 11:53:40 CET 1999 Werner Koch
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  *      Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28
29 #define MAINTAINER_OPTIONS
30
31 #include "packet.h"
32 #include "iobuf.h"
33 #include "memory.h"
34 #include "util.h"
35 #include "main.h"
36 #include "options.h"
37 #include "keydb.h"
38 #include "trustdb.h"
39 #include "mpi.h"
40 #include "cipher.h"
41 #include "filter.h"
42 #include "ttyio.h"
43 #include "i18n.h"
44 #include "status.h"
45 #include "g10defs.h"
46 #include "hkp.h"
47
48 #ifndef IS_G10MAINT
49   #define IS_G10 1
50 #endif
51
52
53 enum cmd_and_opt_values { aNull = 0,
54     oArmor        = 'a',
55     aDetachedSign = 'b',
56     aSym          = 'c',
57     aDecrypt      = 'd',
58     aEncr         = 'e',
59     oKOption      = 'k',
60     oDryRun       = 'n',
61     oOutput       = 'o',
62     oQuiet        = 'q',
63     oRecipient    = 'r',
64     aSign         = 's',
65     oTextmodeShort= 't',
66     oUser         = 'u',
67     oVerbose      = 'v',
68     oCompress     = 'z',
69     oBatch        = 500,
70     aClearsign,
71     aStore,
72     aKeygen,
73     aSignEncr,
74     aSignKey,
75     aListPackets,
76     aEditKey,
77     aDeleteKey,
78     aDeleteSecretKey,
79     aKMode,
80     aKModeC,
81     aImport,
82     aFastImport,
83     aVerify,
84     aListKeys,
85     aListSigs,
86     aListSecretKeys,
87     aSendKeys,
88     aRecvKeys,
89     aExport,
90     aExportAll,
91     aExportSecret,
92     aCheckKeys,
93     aGenRevoke,
94     aPrimegen,
95     aPrintMD,
96     aPrintMDs,
97     aCheckTrustDB,
98     aUpdateTrustDB,
99     aFixTrustDB,
100     aListTrustDB,
101     aListTrustPath,
102     aExportOwnerTrust,
103     aImportOwnerTrust,
104     aDeArmor,
105     aEnArmor,
106     aGenRandom,
107
108     oTextmode,
109     oFingerprint,
110     oAnswerYes,
111     oAnswerNo,
112     oKeyring,
113     oSecretKeyring,
114     oDefaultKey,
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     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
194     { aExportAll, "export-all"    , 256, "@" },
195     { aExportSecret, "export-secret-keys" , 256, "@" },
196     { aImport, "import",      256     , N_("import/merge keys")},
197     { aFastImport, "fast-import",  256 , "@"},
198     { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
199   #ifdef IS_G10MAINT
200     { aExportOwnerTrust,
201               "export-ownertrust", 256, N_("export the ownertrust values")},
202     { aImportOwnerTrust,
203               "import-ownertrust", 256 , N_("import ownertrust values")},
204     { aUpdateTrustDB,
205               "update-trustdb",0 , N_("|[NAMES]|update the trust database")},
206     { aCheckTrustDB,
207               "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
208     { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
209     { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
210     { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
211     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
212     { aPrintMDs, "print-mds" , 256, N_("print all message digests")},
213     #ifdef MAINTAINER_OPTIONS
214     { aPrimegen, "gen-prime" , 256, "@" },
215     { aGenRandom, "gen-random" , 256, "@" },
216     #endif
217   #endif
218
219     { 301, NULL, 0, N_("@\nOptions:\n ") },
220
221     { oArmor, "armor",     0, N_("create ascii armored output")},
222     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
223     { oRecipient, "remote-user", 2, "@"},  /* old option name */
224     { oEncryptTo, "encrypt-to", 2, "@" },
225     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
226   #ifdef IS_G10
227     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
228     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
229     { oTextmodeShort, NULL,   0, "@"},
230     { oTextmode, "textmode",  0, N_("use canonical text mode")},
231   #endif
232     { oOutput, "output",    2, N_("use as output file")},
233     { oVerbose, "verbose",   0, N_("verbose") },
234     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
235     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
236     { oDryRun, "dry-run",   0, N_("do not make any changes") },
237     { oBatch, "batch",     0, N_("batch mode: never ask")},
238     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
239     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
240     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
241     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
242     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
243     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
244     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
245     { oOptions, "options"   , 2, N_("read options from file")},
246
247     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
248     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
249     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
250     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
251     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
252     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
253     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
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 aRecvKeys: set_cmd( &cmd, aRecvKeys); break;
655           case aExport: set_cmd( &cmd, aExport); break;
656           case aExportAll: set_cmd( &cmd, aExportAll); break;
657           case aListKeys: set_cmd( &cmd, aListKeys); break;
658           case aListSigs: set_cmd( &cmd, aListSigs); break;
659           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
660           case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); break;
661           case aDeleteKey: set_cmd( &cmd, aDeleteKey); break;
662
663         #ifdef IS_G10
664           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
665           case aSym: set_cmd( &cmd, aSym); break;
666           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
667           case aEncr: set_cmd( &cmd, aEncr); break;
668           case aSign: set_cmd( &cmd, aSign );  break;
669           case aKeygen: set_cmd( &cmd, aKeygen); break;
670           case aSignKey: set_cmd( &cmd, aSignKey); break;
671           case aStore: set_cmd( &cmd, aStore); break;
672           case aEditKey: set_cmd( &cmd, aEditKey); break;
673           case aClearsign: set_cmd( &cmd, aClearsign); break;
674           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
675           case aVerify: set_cmd( &cmd, aVerify); break;
676         #else
677           #ifdef MAINTAINER_OPTIONS
678             case aPrimegen: set_cmd( &cmd, aPrimegen); break;
679             case aGenRandom: set_cmd( &cmd, aGenRandom); break;
680           #endif
681           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
682           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
683           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
684           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
685           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
686           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
687           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
688           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
689           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
690           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
691           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
692         #endif /* IS_G10MAINT */
693
694
695
696           case oArmor: opt.armor = 1; opt.no_armor=0; break;
697           case oOutput: opt.outfile = pargs.r.ret_str; break;
698           case oQuiet: opt.quiet = 1; break;
699           case oDryRun: opt.dry_run = 1; break;
700           case oVerbose: g10_opt_verbose++;
701                     opt.verbose++; opt.list_sigs=1; break;
702           case oKOption: set_cmd( &cmd, aKMode ); break;
703
704           case oBatch: opt.batch = 1; greeting = 0; break;
705           case oAnswerYes: opt.answer_yes = 1; break;
706           case oAnswerNo: opt.answer_no = 1; break;
707           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
708           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
709           case oDebugAll: opt.debug = ~0; break;
710           case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
711           case oFingerprint: opt.fingerprint++; break;
712           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
713           case oOptions:
714             /* config files may not be nested (silently ignore them) */
715             if( !configfp ) {
716                 m_free(configname);
717                 configname = m_strdup(pargs.r.ret_str);
718                 goto next_pass;
719             }
720             break;
721           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
722           case oNoDefKeyring: default_keyring = 0; break;
723           case oNoGreeting: greeting = 0; break;
724           case oNoVerbose: g10_opt_verbose = 0;
725                            opt.verbose = 0; opt.list_sigs=0; break;
726           case oQuickRandom: quick_random_gen(1); break;
727           case oNoComment: opt.no_comment=1; break;
728           case oNoVersion: opt.no_version=1; break;
729           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
730           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
731           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
732           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
733           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
734           case oNoOptions: break; /* no-options */
735           case oHomedir: opt.homedir = pargs.r.ret_str; break;
736           case oNoBatch: opt.batch = 0; break;
737           case oWithColons: opt.with_colons=':'; break;
738
739           case oSkipVerify: opt.skip_verify=1; break;
740           case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break;
741           case oCompressKeys: opt.compress_keys = 1; break;
742           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
743           case oAlwaysTrust: opt.always_trust = 1; break;
744           case oLoadExtension:
745             register_cipher_extension(orig_argc? *orig_argv:NULL,
746                                       pargs.r.ret_str);
747             break;
748           case oRFC1991:
749             opt.rfc1991 = 1;
750             opt.no_comment = 1;
751             opt.escape_from = 1;
752             break;
753           case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
754           case oCompressSigs: opt.compress_sigs = 1; break;
755           case oRunAsShmCP:
756           #ifndef USE_SHM_COPROCESSING
757             /* not possible in the option file,
758              * but we print the warning here anyway */
759             log_error("shared memory coprocessing is not available\n");
760           #endif
761             break;
762           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
763           case oComment: opt.comment_string = pargs.r.ret_str; break;
764           case oThrowKeyid: opt.throw_keyid = 1; break;
765           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
766           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
767           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
768           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
769
770           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
771           case oEncryptTo: /* store the recipient in the second list */
772             sl = add_to_strlist( &remusr, pargs.r.ret_str );
773             sl->flags = 1;
774             break;
775         #ifdef IS_G10
776           case oRecipient: /* store the recipient */
777             add_to_strlist( &remusr, pargs.r.ret_str );
778             break;
779           case oTextmodeShort: opt.textmode = 2; break;
780           case oTextmode: opt.textmode=1;  break;
781           case oUser: /* store the local users */
782             add_to_strlist( &locusr, pargs.r.ret_str );
783             break;
784           case oCompress: opt.compress = pargs.r.ret_int; break;
785           case oPasswdFD: pwfd = pargs.r.ret_int; break;
786           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
787           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
788           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
789         #else
790           case oCipherAlgo:
791           case oDigestAlgo:
792           case oNoSecmemWarn:
793             break;  /* dummies */
794         #endif
795           case oCharset:
796             if( set_native_charset( pargs.r.ret_str ) )
797                 log_error(_("%s is not a valid character set\n"),
798                                                     pargs.r.ret_str);
799             break;
800           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
801           case oEscapeFrom: opt.escape_from = 1; break;
802           case oLockOnce: opt.lock_once = 1; break;
803           case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
804
805           default : pargs.err = configfp? 1:2; break;
806         }
807     }
808     if( configfp ) {
809         fclose( configfp );
810         configfp = NULL;
811         m_free(configname); configname = NULL;
812         goto next_pass;
813     }
814     m_free( configname ); configname = NULL;
815     if( log_get_errorcount(0) )
816         g10_exit(2);
817
818     if( greeting ) {
819         fprintf(stderr, "%s %s; %s\n",
820                         strusage(11), strusage(13), strusage(14) );
821         fprintf(stderr, "%s\n", strusage(15) );
822       #ifdef IS_DEVELOPMENT_VERSION
823         log_info("NOTE: this is a development version!\n");
824       #endif
825     }
826
827     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
828
829     set_debug();
830     g10_opt_homedir = opt.homedir;
831
832     /* must do this after dropping setuid, because string_to...
833      * may try to load an module */
834     if( def_cipher_string ) {
835         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
836         m_free(def_cipher_string); def_cipher_string = NULL;
837         if( check_cipher_algo(opt.def_cipher_algo) )
838             log_error(_("selected cipher algorithm is invalid\n"));
839     }
840     if( def_digest_string ) {
841         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
842         m_free(def_digest_string); def_digest_string = NULL;
843         if( check_digest_algo(opt.def_digest_algo) )
844             log_error(_("selected digest algorithm is invalid\n"));
845     }
846     if( s2k_cipher_string ) {
847         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
848         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
849         if( check_cipher_algo(opt.s2k_cipher_algo) )
850             log_error(_("selected cipher algorithm is invalid\n"));
851     }
852     if( s2k_digest_string ) {
853         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
854         m_free(s2k_digest_string); s2k_digest_string = NULL;
855         if( check_digest_algo(opt.s2k_digest_algo) )
856             log_error(_("selected digest algorithm is invalid\n"));
857     }
858     if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
859         log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
860     if( opt.completes_needed < 1 )
861         log_error(_("completes-needed must be greater than 0\n"));
862     if( opt.marginals_needed < 2 )
863         log_error(_("marginals-needed must be greater than 1\n"));
864     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
865         log_error(_("max-cert-depth must be in range 1 to 255\n"));
866     switch( opt.s2k_mode ) {
867       case 0:
868         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
869         break;
870       case 1: case 3: break;
871       default:
872         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
873     }
874
875
876     if( log_get_errorcount(0) )
877         g10_exit(2);
878
879     if( !cmd && opt.fingerprint )
880         set_cmd( &cmd, aListKeys);
881
882     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
883         if( cmd == aKModeC ) {
884             opt.fingerprint = 1;
885             cmd = aKMode;
886         }
887         opt.list_sigs = 0;
888         if( opt.verbose > 2 )
889             opt.check_sigs++;
890         if( opt.verbose > 1 )
891             opt.list_sigs++;
892
893         opt.verbose = opt.verbose > 1;
894         g10_opt_verbose = opt.verbose;
895     }
896
897
898     /* kludge to let -sat generate a clear text signature */
899     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
900         cmd = aClearsign;
901
902     if( opt.verbose > 1 )
903         set_packet_list_mode(1);
904
905     /* add the keyrings, but not for some special commands and
906      * not in case of "-kvv userid keyring" */
907     if( cmd != aDeArmor && cmd != aEnArmor
908         && !(cmd == aKMode && argc == 2 ) ) {
909
910         if( !sec_nrings || default_keyring )  /* add default secret rings */
911             add_keyblock_resource("secring.gpg", 0, 1);
912         for(sl = sec_nrings; sl; sl = sl->next )
913             add_keyblock_resource( sl->d, 0, 1 );
914         if( !nrings || default_keyring )  /* add default ring */
915             add_keyblock_resource("pubring.gpg", 0, 0);
916         for(sl = nrings; sl; sl = sl->next )
917             add_keyblock_resource( sl->d, 0, 0 );
918     }
919     FREE_STRLIST(nrings);
920     FREE_STRLIST(sec_nrings);
921
922
923     if( pwfd != -1 )  /* read the passphrase now. */
924         read_passphrase_from_fd( pwfd );
925
926     fname = argc? *argv : NULL;
927
928     switch( cmd ) {
929       case aPrimegen:
930       case aPrintMD:
931       case aPrintMDs:
932       case aGenRandom:
933       case aDeArmor:
934       case aEnArmor:
935       case aFixTrustDB:
936         break;
937       case aKMode:
938       case aListKeys:
939       case aListSecretKeys:
940       case aCheckKeys:
941         if( opt.with_colons ) /* need this to list the trust */
942             rc = setup_trustdb(1, trustdb_name );
943         break;
944       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
945       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
946       default: rc = setup_trustdb(1, trustdb_name ); break;
947     }
948     if( rc )
949         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
950
951
952     switch( cmd ) {
953       case aStore: /* only store the file */
954         if( argc > 1 )
955             wrong_args(_("--store [filename]"));
956         if( (rc = encode_store(fname)) )
957             log_error_f( print_fname_stdin(fname),
958                         "store failed: %s\n", g10_errstr(rc) );
959         break;
960     #ifdef IS_G10
961       case aSym: /* encrypt the given file only with the symmetric cipher */
962         if( argc > 1 )
963             wrong_args(_("--symmetric [filename]"));
964         if( (rc = encode_symmetric(fname)) )
965             log_error_f(print_fname_stdin(fname),
966                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
967         break;
968
969       case aEncr: /* encrypt the given file */
970         if( argc > 1 )
971             wrong_args(_("--encrypt [filename]"));
972         if( (rc = encode_crypt(fname,remusr)) )
973             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
974         break;
975
976       case aSign: /* sign the given file */
977         sl = NULL;
978         if( detached_sig ) { /* sign all files */
979             for( ; argc; argc--, argv++ )
980                 add_to_strlist( &sl, *argv );
981         }
982         else {
983             if( argc > 1 )
984                 wrong_args(_("--sign [filename]"));
985             if( argc ) {
986                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
987                 strcpy(sl->d, fname);
988             }
989         }
990         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
991             log_error("signing failed: %s\n", g10_errstr(rc) );
992         free_strlist(sl);
993         break;
994
995       case aSignEncr: /* sign and encrypt the given file */
996         if( argc > 1 )
997             wrong_args(_("--sign --encrypt [filename]"));
998         if( argc ) {
999             sl = m_alloc_clear( sizeof *sl + strlen(fname));
1000             strcpy(sl->d, fname);
1001         }
1002         else
1003             sl = NULL;
1004         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1005             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1006         free_strlist(sl);
1007         break;
1008
1009       case aClearsign: /* make a clearsig */
1010         if( argc > 1 )
1011             wrong_args(_("--clearsign [filename]"));
1012         if( (rc = clearsign_file(fname, locusr, NULL)) )
1013             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1014         break;
1015
1016       case aVerify:
1017         if( (rc = verify_signatures( argc, argv ) ))
1018             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
1019         break;
1020
1021       case aDecrypt:
1022         if( argc > 1 )
1023             wrong_args(_("--decrypt [filename]"));
1024         if( (rc = decrypt_message( fname ) ))
1025             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
1026         break;
1027
1028
1029       case aSignKey: /* sign the key given as argument */
1030       case aEditKey: /* Edit a key signature */
1031         if( !argc )
1032             wrong_args(_("--edit-key username [commands]"));
1033         if( argc > 1 ) {
1034             sl = NULL;
1035             for( argc--, argv++ ; argc; argc--, argv++ )
1036                 append_to_strlist( &sl, *argv );
1037             keyedit_menu( fname, locusr, sl );
1038             free_strlist(sl);
1039         }
1040         else
1041             keyedit_menu(fname, locusr, NULL );
1042         break;
1043
1044       #endif /* IS_G10 */
1045
1046       case aDeleteSecretKey:
1047         if( argc != 1 )
1048             wrong_args(_("--delete-secret-key username"));
1049       case aDeleteKey:
1050         if( argc != 1 )
1051             wrong_args(_("--delete-key username"));
1052         /* note: fname is the user id! */
1053         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
1054             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1055         break;
1056
1057
1058       case aCheckKeys:
1059         opt.check_sigs = 1;
1060       case aListSigs:
1061         opt.list_sigs = 1;
1062       case aListKeys:
1063         public_key_list( argc, argv );
1064         break;
1065       case aListSecretKeys:
1066         secret_key_list( argc, argv );
1067         break;
1068
1069       case aKMode: /* list keyring */
1070         if( argc < 2 )  /* -kv [userid] */
1071             public_key_list( (argc && **argv)? 1:0, argv );
1072         else if( argc == 2 ) { /* -kv userid keyring */
1073             if( access( argv[1], R_OK ) ) {
1074                 log_error(_("can't open %s: %s\n"),
1075                                print_fname_stdin(argv[1]), strerror(errno));
1076             }
1077             else {
1078                 /* add keyring (default keyrings are not registered in this
1079                  * special case */
1080                 add_keyblock_resource( argv[1], 0, 0 );
1081                 public_key_list( **argv?1:0, argv );
1082             }
1083         }
1084         else
1085             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
1086         break;
1087
1088     #ifdef IS_G10
1089       case aKeygen: /* generate a key (interactive) */
1090         if( argc )
1091             wrong_args("--gen-key");
1092         generate_keypair();
1093         break;
1094     #endif
1095
1096       case aFastImport:
1097       case aImport:
1098         if( !argc  ) {
1099             rc = import_keys( NULL, (cmd == aFastImport) );
1100             if( rc )
1101                 log_error("import failed: %s\n", g10_errstr(rc) );
1102         }
1103         for( ; argc; argc--, argv++ ) {
1104             rc = import_keys( *argv, (cmd == aFastImport) );
1105             if( rc )
1106                 log_error("import from `%s' failed: %s\n",
1107                                                 *argv, g10_errstr(rc) );
1108         }
1109         break;
1110
1111       case aExport:
1112       case aExportAll:
1113       case aSendKeys:
1114       case aRecvKeys:
1115         sl = NULL;
1116         for( ; argc; argc--, argv++ )
1117             add_to_strlist( &sl, *argv );
1118         if( cmd == aSendKeys )
1119             hkp_export( sl );
1120         else if( cmd == aRecvKeys )
1121             hkp_import( sl );
1122         else
1123             export_pubkeys( sl, (cmd == aExport) );
1124         free_strlist(sl);
1125         break;
1126
1127       case aExportSecret:
1128         sl = NULL;
1129         for( ; argc; argc--, argv++ )
1130             add_to_strlist( &sl, *argv );
1131         export_seckeys( sl );
1132         free_strlist(sl);
1133         break;
1134
1135     #ifdef IS_G10
1136       case aGenRevoke:
1137         if( argc != 1 )
1138             wrong_args("--gen-revoke user-id");
1139         gen_revoke( *argv );
1140         break;
1141     #endif
1142
1143     #ifdef IS_G10MAINT
1144       case aDeArmor:
1145         if( argc > 1 )
1146             wrong_args("--dearmor [file]");
1147         rc = dearmor_file( argc? *argv: NULL );
1148         if( rc )
1149             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
1150         break;
1151
1152       case aEnArmor:
1153         if( argc > 1 )
1154             wrong_args("--enarmor [file]");
1155         rc = enarmor_file( argc? *argv: NULL );
1156         if( rc )
1157             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
1158         break;
1159
1160
1161      #ifdef MAINTAINER_OPTIONS
1162       case aPrimegen:
1163         if( argc == 1 ) {
1164             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
1165             putchar('\n');
1166         }
1167         else if( argc == 2 ) {
1168             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1169                                                    atoi(argv[1]), NULL,NULL ), 1);
1170             putchar('\n');
1171         }
1172         else if( argc == 3 ) {
1173             MPI g = mpi_alloc(1);
1174             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1175                                                    atoi(argv[1]), g, NULL ), 1);
1176             printf("\nGenerator: ");
1177             mpi_print( stdout, g, 1 );
1178             putchar('\n');
1179             mpi_free(g);
1180         }
1181         else if( argc == 4 ) {
1182             mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
1183                                                    atoi(argv[1]), NULL,NULL ), 1);
1184             putchar('\n');
1185         }
1186         else
1187             usage(1);
1188         break;
1189       #endif /* MAINTAINER OPTIONS */
1190
1191       #ifdef MAINTAINER_OPTIONS
1192       case aGenRandom:
1193         if( argc < 1 || argc > 2 )
1194             wrong_args("--gen-random level [hex]");
1195         {
1196             int c;
1197             int level = atoi(*argv);
1198             for(;;) {
1199                 byte *p;
1200                 if( argc == 2 ) {
1201                     p = get_random_bits( 8, level, 0);
1202                     printf("%02x", *p );
1203                     fflush(stdout);
1204                 }
1205                 else {
1206                     p = get_random_bits( 800, level, 0);
1207                     for(c=0; c < 100; c++ )
1208                         putchar( p[c] );
1209                 }
1210                 m_free(p);
1211             }
1212         }
1213         break;
1214       #endif /* MAINTAINER OPTIONS */
1215
1216       case aPrintMD:
1217         if( argc < 1)
1218             wrong_args("--print-md algo [file]");
1219         else {
1220             int algo = string_to_digest_algo(*argv);
1221
1222             if( !algo )
1223                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
1224             else {
1225                 argc--; argv++;
1226                 if( !argc )
1227                     print_mds(NULL, algo);
1228                 else {
1229                     for(; argc; argc--, argv++ )
1230                         print_mds(*argv, algo);
1231                 }
1232             }
1233         }
1234         break;
1235
1236       case aPrintMDs:
1237         if( !argc )
1238             print_mds(NULL,0);
1239         else {
1240             for(; argc; argc--, argv++ )
1241                 print_mds(*argv,0);
1242         }
1243         break;
1244
1245       case aListTrustDB:
1246         if( !argc )
1247             list_trustdb(NULL);
1248         else {
1249             for( ; argc; argc--, argv++ )
1250                 list_trustdb( *argv );
1251         }
1252         break;
1253
1254       case aUpdateTrustDB:
1255         if( argc )
1256             wrong_args("--update-trustdb");
1257         update_trustdb();
1258         break;
1259
1260       case aCheckTrustDB:
1261         if( !argc )
1262             check_trustdb(NULL);
1263         else {
1264             for( ; argc; argc--, argv++ )
1265                 check_trustdb( *argv );
1266         }
1267         break;
1268
1269       case aFixTrustDB:
1270         log_error("this command ist not yet implemented.\"\n");
1271         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
1272         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
1273         break;
1274
1275       case aListTrustPath:
1276         if( !argc )
1277             wrong_args("--list-trust-path <usernames>");
1278         for( ; argc; argc--, argv++ )
1279             list_trust_path( *argv );
1280         break;
1281
1282       case aExportOwnerTrust:
1283         if( argc )
1284             wrong_args("--export-ownertrust");
1285         export_ownertrust();
1286         break;
1287
1288       case aImportOwnerTrust:
1289         if( argc > 1 )
1290             wrong_args("--import-ownertrust [file]");
1291         import_ownertrust( argc? *argv:NULL );
1292         break;
1293
1294      #endif /* IS_G10MAINT */
1295
1296
1297       case aListPackets:
1298         opt.list_packets=1;
1299       default:
1300         /* fixme: g10maint should do regular maintenace tasks here */
1301         if( argc > 1 )
1302             wrong_args(_("[filename]"));
1303         /* Issue some output for the unix newbie */
1304         if( !fname && !opt.outfile && isatty( fileno(stdin) )
1305                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
1306             log_info(_("Go ahead and type your message ...\n"));
1307
1308         if( !(a = iobuf_open(fname)) )
1309             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
1310         else {
1311
1312             if( !opt.no_armor ) {
1313                 if( use_armor_filter( a ) ) {
1314                     memset( &afx, 0, sizeof afx);
1315                     iobuf_push_filter( a, armor_filter, &afx );
1316                 }
1317             }
1318             if( cmd == aListPackets ) {
1319                 set_packet_list_mode(1);
1320                 opt.list_packets=1;
1321             }
1322             proc_packets( a );
1323             iobuf_close(a);
1324         }
1325         break;
1326     }
1327
1328     /* cleanup */
1329     FREE_STRLIST(remusr);
1330     FREE_STRLIST(locusr);
1331     g10_exit(0);
1332     return 8; /*NEVER REACHED*/
1333 }
1334
1335
1336 void
1337 g10_exit( int rc )
1338 {
1339     if( opt.debug & DBG_MEMSTAT_VALUE )
1340         m_print_stats("on exit");
1341     if( opt.debug )
1342         secmem_dump_stats();
1343     secmem_term();
1344     rc = rc? rc : log_get_errorcount(0)? 2 :
1345                         g10_errors_seen? 1 : 0;
1346     /*write_status( STATUS_LEAVE );*/
1347     exit(rc );
1348 }
1349
1350
1351
1352
1353 #ifdef IS_G10MAINT
1354 static void
1355 print_hex( byte *p, size_t n )
1356 {
1357     int i;
1358
1359     if( n == 20 ) {
1360         for(i=0; i < n ; i++, i++, p += 2 ) {
1361             if( i )
1362                 putchar(' ');
1363             if( i == 10 )
1364                 putchar(' ');
1365             printf("%02X%02X", *p, p[1] );
1366         }
1367     }
1368     else if( n == 24 ) {
1369         for(i=0; i < n ; i += 4, p += 4 ) {
1370             if( i )
1371                 putchar(' ');
1372             if( i == 12 )
1373                 putchar(' ');
1374             printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
1375         }
1376     }
1377     else {
1378         for(i=0; i < n ; i++, p++ ) {
1379             if( i )
1380                 putchar(' ');
1381             if( i && !(i%8) )
1382                 putchar(' ');
1383             printf("%02X", *p );
1384         }
1385     }
1386 }
1387
1388 static void
1389 print_mds( const char *fname, int algo )
1390 {
1391     FILE *fp;
1392     char buf[1024];
1393     size_t n;
1394     MD_HANDLE md;
1395     char *pname;
1396
1397     if( !fname ) {
1398         fp = stdin;
1399         pname = m_strdup("[stdin]: ");
1400     }
1401     else {
1402         pname = m_alloc(strlen(fname)+3);
1403         strcpy(stpcpy(pname,fname),": ");
1404         fp = fopen( fname, "rb" );
1405     }
1406     if( !fp ) {
1407         log_error("%s%s\n", pname, strerror(errno) );
1408         m_free(pname);
1409         return;
1410     }
1411
1412     md = md_open( 0, 0 );
1413     if( algo )
1414         md_enable( md, algo );
1415     else {
1416         md_enable( md, DIGEST_ALGO_MD5 );
1417         md_enable( md, DIGEST_ALGO_SHA1 );
1418         md_enable( md, DIGEST_ALGO_RMD160 );
1419         if( !check_digest_algo(DIGEST_ALGO_TIGER) )
1420             md_enable( md, DIGEST_ALGO_TIGER );
1421     }
1422
1423     while( (n=fread( buf, 1, DIM(buf), fp )) )
1424         md_write( md, buf, n );
1425     if( ferror(fp) )
1426         log_error("%s%s\n", pname, strerror(errno) );
1427     else {
1428         md_final(md);
1429         if( algo ) {
1430             if( fname )
1431                 fputs( pname, stdout );
1432             print_hex(md_read(md, algo), md_digest_length(algo) );
1433         }
1434         else {
1435             printf(  "%s   MD5 = ", fname?pname:"" );
1436                             print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1437             printf("\n%s  SHA1 = ", fname?pname:""  );
1438                             print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1439             printf("\n%sRMD160 = ", fname?pname:""  );
1440                             print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1441             if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
1442                 printf("\n%s TIGER = ", fname?pname:""  );
1443                             print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
1444             }
1445         }
1446         putchar('\n');
1447     }
1448     md_close(md);
1449
1450     if( fp != stdin )
1451         fclose(fp);
1452 }
1453
1454
1455
1456 #endif /* IS_G10MAINT */
1457