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