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