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