--armor does now produce PEM format.
[gnupg.git] / sm / gpgsm.c
1 /* gpgsm.c - GnuPG for S/MIME 
2  *      Copyright (C) 2001 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 #include <fcntl.h>
29
30 #include <gcrypt.h>
31 #include "gpgsm.h"
32 #include "../assuan/assuan.h" /* malloc hooks */
33 #include "../kbx/keybox.h" /* malloc hooks */
34 #include "i18n.h"
35 #include "keydb.h"
36
37 enum cmd_and_opt_values {
38   aNull = 0,
39   oArmor          = 'a',
40   aDetachedSign = 'b',
41   aSym    = 'c',
42   aDecrypt        = 'd',
43   aEncr   = 'e',
44   oInteractive  = 'i',
45   oKOption        = 'k',
46   oDryRun         = 'n',
47   oOutput         = 'o',
48   oQuiet          = 'q',
49   oRecipient      = 'r',
50   aSign   = 's',
51   oTextmodeShort= 't',
52   oUser   = 'u',
53   oVerbose        = 'v',
54   oCompress       = 'z',
55   oNotation       = 'N',
56   oBatch          = 500,
57   aClearsign,
58   aStore,
59   aKeygen,
60   aSignEncr,
61   aSignKey,
62   aLSignKey,
63   aListPackets,
64   aEditKey,
65   aDeleteKey,
66   aImport,
67   aVerify,
68   aVerifyFiles,
69   aListKeys,
70   aListSigs,
71   aListSecretKeys,
72   aSendKeys,
73   aRecvKeys,
74   aExport,
75   aExportAll,
76   aCheckKeys,
77   aServer,                        
78
79   oEnableSpecialFilenames,
80   oAgentProgram,
81
82   oTextmode,
83   oFingerprint,
84   oWithFingerprint,
85   oAnswerYes,
86   oAnswerNo,
87   oKeyring,
88   oSecretKeyring,
89   oDefaultKey,
90   oDefRecipient,
91   oDefRecipientSelf,
92   oNoDefRecipient,
93   oOptions,
94   oDebug,
95   oDebugAll,
96   oStatusFD,
97   oNoComment,
98   oNoVersion,
99   oEmitVersion,
100   oCompletesNeeded,
101   oMarginalsNeeded,
102   oMaxCertDepth,
103   oLoadExtension,
104   oRFC1991,
105   oOpenPGP,
106   oCipherAlgo,
107   oDigestAlgo,
108   oCompressAlgo,
109   oPasswdFD,
110   oCommandFD,
111   oNoVerbose,
112   oTrustDBName,
113   oNoSecmemWarn,
114   oNoArmor,
115   oNoDefKeyring,
116   oNoGreeting,
117   oNoTTY,
118   oNoOptions,
119   oNoBatch,
120   oHomedir,
121   oWithColons,
122   oWithKeyData,
123   oSkipVerify,
124   oCompressKeys,
125   oCompressSigs,
126   oAlwaysTrust,
127   oRunAsShmCP,
128   oSetFilename,
129   oSetPolicyURL,
130   oUseEmbeddedFilename,
131   oComment,
132   oDefaultComment,
133   oThrowKeyid,
134   oForceV3Sigs,
135   oForceMDC,
136   oS2KMode,
137   oS2KDigest,
138   oS2KCipher,
139   oCharset,
140   oNotDashEscaped,
141   oEscapeFrom,
142   oLockOnce,
143   oLockMultiple,
144   oLockNever,
145   oKeyServer,
146   oEncryptTo,
147   oNoEncryptTo,
148   oLoggerFD,
149   oUtf8Strings,
150   oNoUtf8Strings,
151   oDisableCipherAlgo,
152   oDisablePubkeyAlgo,
153   oAllowNonSelfsignedUID,
154   oAllowFreeformUID,
155   oNoLiteral,
156   oSetFilesize,
157   oHonorHttpProxy,
158   oFastListMode,
159   oListOnly,
160   oIgnoreTimeConflict,
161   oNoRandomSeedFile,
162   oNoAutoKeyRetrieve,
163   oUseAgent,
164   oMergeOnly,
165   oTryAllSecrets,
166   oTrustedKey,
167   oEmuMDEncodeBug,
168   aTest
169  };
170
171
172 static ARGPARSE_OPTS opts[] = {
173
174     { 300, NULL, 0, N_("@Commands:\n ") },
175
176     { aSign, "sign",      256, N_("|[file]|make a signature")},
177     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
178     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
179     { aEncr, "encrypt",   256, N_("encrypt data")},
180     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
181     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
182     { aVerify, "verify"   , 256, N_("verify a signature")},
183     { aVerifyFiles, "verify-files" , 256, "@" },
184     { aListKeys, "list-keys", 256, N_("list keys")},
185     { aListKeys, "list-public-keys", 256, "@" },
186     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
187     { aCheckKeys, "check-sigs",256, N_("check key signatures")},
188     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
189     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
190     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
191     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
192     { aExport, "export"           , 256, N_("export keys") },
193     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
194     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
195     { aImport, "import",      256     , N_("import/merge keys")},
196     { aServer, "server",      256, N_("run in server mode")},
197     
198
199     { 301, NULL, 0, N_("@\nOptions:\n ") },
200
201     { oArmor, "armor",     0, N_("create ascii armored output")},
202     { oArmor, "armour",     0, "@" },
203     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
204     { oRecipient, "remote-user", 2, "@"},  /* old option name */
205     { oDefRecipient, "default-recipient" ,2,
206                                   N_("|NAME|use NAME as default recipient")},
207     { oDefRecipientSelf, "default-recipient-self" ,0,
208                                 N_("use the default key as default recipient")},
209     { oNoDefRecipient, "no-default-recipient", 0, "@" },
210     { oEncryptTo, "encrypt-to", 2, "@" },
211     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
212     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
213     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
214     { oTextmodeShort, NULL,   0, "@"},
215     { oTextmode, "textmode",  0, N_("use canonical text mode")},
216     { oOutput, "output",    2, N_("use as output file")},
217     { oVerbose, "verbose",   0, N_("verbose") },
218     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
219     { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
220     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
221     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
222     { oDryRun, "dry-run",   0, N_("do not make any changes") },
223   /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
224     { oUseAgent, "use-agent",0, N_("use the gpg-agent")},
225     { oBatch, "batch",     0, N_("batch mode: never ask")},
226     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
227     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
228     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
229     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
230     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
231     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
232     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
233     { oOptions, "options"   , 2, N_("read options from file")},
234
235     { oDebug, "debug"     ,4|16, "@"},
236     { oDebugAll, "debug-all" ,0, "@"},
237     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
238     { oNoComment, "no-comment", 0,   "@"},
239     { oCompletesNeeded, "completes-needed", 1, "@"},
240     { oMarginalsNeeded, "marginals-needed", 1, "@"},
241     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
242     { oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
243     { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
244     { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
245     { oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
246     { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
247     { oS2KDigest, "s2k-digest-algo",2,
248                 N_("|NAME|use message digest algorithm NAME for passphrases")},
249     { oS2KCipher, "s2k-cipher-algo",2,
250                 N_("|NAME|use cipher algorithm NAME for passphrases")},
251     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
252     { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
253     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
254     { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
255     { oNotation,   "notation-data", 2, N_("|NAME=VALUE|use this notation data")},
256
257     { 302, NULL, 0, N_(
258   "@\n(See the man page for a complete listing of all commands and options)\n"
259                       )},
260
261     { 303, 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     { oNoVerbose, "no-verbose", 0, "@"},
270
271     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
272
273
274     { oTrustDBName, "trustdb-name", 2, "@" },
275     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
276     { oNoArmor, "no-armor",   0, "@"},
277     { oNoArmor, "no-armour",   0, "@"},
278     { oNoDefKeyring, "no-default-keyring", 0, "@" },
279     { oNoGreeting, "no-greeting", 0, "@" },
280     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
281     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
282     { oAgentProgram, "agent-program", 2 , "@" },
283
284     { oNoBatch, "no-batch", 0, "@" },
285     { oWithColons, "with-colons", 0, "@"},
286     { oWithKeyData,"with-key-data", 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     { oNoVersion, "no-version", 0, "@"},
295     { oLockOnce, "lock-once", 0, "@" },
296     { oLockMultiple, "lock-multiple", 0, "@" },
297     { oLockNever, "lock-never", 0, "@" },
298     { oLoggerFD, "logger-fd",1, "@" },
299     { oWithFingerprint, "with-fingerprint", 0, "@" },
300     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
301     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
302     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
303     { oListOnly, "list-only", 0, "@"},
304     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
305     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
306 {0} };
307
308
309
310 int gpgsm_errors_seen = 0;
311
312 /* It is possible that we are currentlu running under setuid permissions */
313 static int maybe_setuid = 1;
314
315 /* Option --enable-special-filenames */
316 static int allow_special_filenames;
317
318
319 static char *build_list (const char *text,
320                          const char *(*mapf)(int), int (*chkf)(int));
321 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
322                      enum cmd_and_opt_values new_cmd );
323
324 static int check_special_filename (const char *fname);
325 static int open_read (const char *filename);
326
327
328 static int
329 our_pk_test_algo (int algo)
330 {
331   return 1;
332 }
333
334 static int
335 our_cipher_test_algo (int algo)
336 {
337   return 1;
338 }
339
340 static int
341 our_md_test_algo (int algo)
342 {
343   return 1;
344 }
345
346 static const char *
347 my_strusage( int level )
348 {
349   static char *digests, *pubkeys, *ciphers;
350   const char *p;
351
352   switch (level)
353     {
354     case 11: p = "gpgsm (GnuPG)";
355       break;
356     case 13: p = VERSION; break;
357     case 17: p = PRINTABLE_OS_NAME; break;
358     case 19: p = _("Please report bugs to <bug-gnupg@gnu.org>.\n");
359       break;
360     case 1:
361     case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
362       break;
363     case 41:
364       p = _("Syntax: gpgsm [options] [files]\n"
365             "sign, check, encrypt or decrypt using the S/MIME protocol\n"
366             "default operation depends on the input data\n");
367       break;
368
369     case 31: p = "\nHome: "; break;
370     case 32: p = opt.homedir; break;
371     case 33: p = _("\nSupported algorithms:\n"); break;
372     case 34:
373       if (!ciphers)
374         ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
375                               our_cipher_test_algo );
376       p = ciphers;
377       break;
378     case 35:
379       if (!pubkeys)
380         pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
381                               our_pk_test_algo );
382       p = pubkeys;
383       break;
384     case 36:
385       if (!digests)
386         digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
387       p = digests;
388       break;
389       
390     default: p = NULL; break;
391     }
392   return p;
393 }
394
395
396 static char *
397 build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
398 {
399   int i;
400   size_t n=strlen(text)+2;
401   char *list, *p;
402   
403   if (maybe_setuid) {
404     gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
405   }
406
407   for (i=1; i < 110; i++ )
408     if (!chkf(i))
409       n += strlen(mapf(i)) + 2;
410   list = xmalloc (21 + n);
411   *list = 0;
412   for (p=NULL, i=1; i < 110; i++)
413     {
414       if (!chkf(i))
415         {
416           if( !p )
417             p = stpcpy (list, text );
418           else
419             p = stpcpy (p, ", ");
420           p = stpcpy (p, mapf(i) );
421         }
422     }
423   if (p)
424     p = stpcpy(p, "\n" );
425   return list;
426 }
427
428
429 static void
430 i18n_init(void)
431 {
432 #ifdef USE_SIMPLE_GETTEXT
433   set_gettext_file (PACKAGE);
434 #else
435 # ifdef ENABLE_NLS
436 #  ifdef HAVE_LC_MESSAGES
437   setlocale (LC_TIME, "");
438   setlocale (LC_MESSAGES, "");
439 #  else
440   setlocale (LC_ALL, "" );
441 #  endif
442   bindtextdomain (PACKAGE, GNUPG_LOCALEDIR);
443   textdomain (PACKAGE);
444 # endif
445 #endif
446 }
447
448
449 static void
450 wrong_args (const char *text)
451 {
452   fputs (_("usage: gpgsm [options] "), stderr);
453   fputs (text, stderr);
454   putc ('\n', stderr);
455   gpgsm_exit (2);
456 }
457
458
459 static void
460 set_debug(void)
461 {
462   if (opt.debug & DBG_MPI_VALUE)
463     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
464   if (opt.debug & DBG_CRYPTO_VALUE )
465     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
466 }
467
468
469 static void
470 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
471 {
472   enum cmd_and_opt_values cmd = *ret_cmd;
473
474   if (!cmd || cmd == new_cmd)
475     cmd = new_cmd;
476   else if ( cmd == aSign && new_cmd == aEncr )
477     cmd = aSignEncr;
478   else if ( cmd == aEncr && new_cmd == aSign )
479     cmd = aSignEncr;
480   else if ( (cmd == aSign && new_cmd == aClearsign)
481             || (cmd == aClearsign && new_cmd == aSign) )
482     cmd = aClearsign;
483   else 
484     {
485       log_error(_("conflicting commands\n"));
486       gpgsm_exit(2);
487     }
488
489   *ret_cmd = cmd;
490 }
491
492
493 int
494 main ( int argc, char **argv)
495 {
496   ARGPARSE_ARGS pargs;
497   int orig_argc;
498   char **orig_argv;
499   const char *fname;
500   /*  char *username;*/
501   int may_coredump;
502   STRLIST sl, remusr= NULL, locusr=NULL;
503   STRLIST nrings=NULL;
504   int detached_sig = 0;
505   FILE *configfp = NULL;
506   char *configname = NULL;
507   unsigned configlineno;
508   int parse_debug = 0;
509   int default_config =1;
510   int default_keyring = 1;
511   int greeting = 0;
512   int nogreeting = 0;
513   int use_random_seed = 1;
514   int with_fpr = 0;
515   char *def_cipher_string = NULL;
516   char *def_digest_string = NULL;
517   enum cmd_and_opt_values cmd = 0;
518   struct server_control_s ctrl;
519
520   /* FIXME: trap_unaligned ();*/
521   set_strusage (my_strusage);
522   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
523   /* Please note that we may running SUID(ROOT), so be very CAREFUL
524      when adding any stuff between here and the call to secmem_init()
525      somewhere after the option parsing */
526   /* FIXME: log_set_name ("gpgsm");*/
527   /* check that the libraries are suitable.  Do it here because the
528      option parse may need services of the library */
529   if (!gcry_check_version ( "1.1.4" ) )
530     {
531       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
532                  VERSION, gcry_check_version (NULL) );
533     }
534
535   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
536
537   may_coredump = 0/* FIXME: disable_core_dumps()*/;
538   
539   /* FIXME: init_signals();*/
540   
541   create_dotlock (NULL); /* register locking cleanup */
542   i18n_init();
543
544 #ifdef __MINGW32__
545   opt.homedir = read_w32_registry_string ( NULL,
546                                            "Software\\GNU\\GnuPG", "HomeDir" );
547 #else
548   opt.homedir = getenv ("GNUPGHOME");
549 #endif
550   if (!opt.homedir || !*opt.homedir ) 
551     {
552       opt.homedir = "~/.gnupg-test" /*fixme: GNUPG_HOMEDIR*/;
553     }
554
555   /* first check whether we have a config file on the commandline */
556   orig_argc = argc;
557   orig_argv = argv;
558   pargs.argc = &argc;
559   pargs.argv = &argv;
560   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
561   while (arg_parse( &pargs, opts))
562     {
563       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
564         parse_debug++;
565       else if (pargs.r_opt == oOptions)
566         { /* yes there is one, so we do not try the default one but
567              read the config file when it is encountered at the
568              commandline */
569           default_config = 0;
570         }
571       else if (pargs.r_opt == oNoOptions)
572         default_config = 0; /* --no-options */
573       else if (pargs.r_opt == oHomedir)
574         opt.homedir = pargs.r.ret_str;
575     }
576   
577   
578   /* initialize the secure memory. */
579   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
580   maybe_setuid = 0;
581
582   /* 
583      Now we are now working under our real uid 
584   */
585
586   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
587   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
588   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
589
590   /* Setup a default control structure */
591   memset (&ctrl, 0, sizeof ctrl);
592   ctrl.no_server = 1;
593   ctrl.status_fd = -1; /* not status output */
594   ctrl.autodetect_encoding = 1;
595
596   /* set the default option file */
597   if (default_config )
598     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
599   
600   argc        = orig_argc;
601   argv        = orig_argv;
602   pargs.argc  = &argc;
603   pargs.argv  = &argv;
604   pargs.flags =  1;  /* do not remove the args */
605
606  next_pass:
607   if (configname) {
608     configlineno = 0;
609     configfp = fopen (configname, "r");
610     if (!configfp)
611       {
612         if (default_config)
613           {
614             if (parse_debug)
615               log_info (_("NOTE: no default option file `%s'\n"), configname);
616           }
617         else 
618           {
619             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
620             gpgsm_exit(2);
621           }
622         xfree(configname);
623         configname = NULL;
624       }
625     if (parse_debug && configname)
626       log_info (_("reading options from `%s'\n"), configname);
627     default_config = 0;
628   }
629
630   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
631     {
632       switch (pargs.r_opt)
633         {
634         case aServer: 
635           opt.batch = 1;
636           set_cmd (&cmd, aServer);
637           break;
638
639         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
640         case aImport: set_cmd (&cmd, aImport); break;
641         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
642         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
643         case aExport: set_cmd (&cmd, aExport); break;
644         case aListKeys: set_cmd (&cmd, aListKeys); break;
645
646         case aDeleteKey:
647           set_cmd (&cmd, aDeleteKey);
648           greeting=1;
649           break;
650
651         case aDetachedSign:
652           detached_sig = 1;
653           set_cmd (&cmd, aSign ); 
654           break;
655           
656         case aSym: set_cmd (&cmd, aSym); break;
657         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
658         case aEncr: set_cmd (&cmd, aEncr); break;
659         case aSign: set_cmd (&cmd, aSign );  break;
660         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
661         case aClearsign: set_cmd (&cmd, aClearsign); break;
662         case aVerify: set_cmd (&cmd, aVerify); break;
663
664         case oArmor: opt.armor = 1; opt.no_armor=0; break;
665         case oNoArmor: 
666           ctrl.autodetect_encoding = 0;
667           opt.no_armor=1; opt.armor=0; 
668           break;
669         case oOutput: opt.outfile = pargs.r.ret_str; break;
670         case oQuiet: opt.quiet = 1; break;
671         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
672         case oDryRun: opt.dry_run = 1; break;
673
674         case oVerbose:
675           opt.verbose++;
676           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
677           break;
678         case oNoVerbose:
679           opt.verbose = 0;
680           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
681           break;
682           
683         case oBatch: 
684           opt.batch = 1;
685           greeting = 0;
686           break;
687         case oNoBatch: opt.batch = 0; break;
688           
689         case oAnswerYes: opt.answer_yes = 1; break;
690         case oAnswerNo: opt.answer_no = 1; break;
691
692         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
693
694         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
695         case oDebugAll: opt.debug = ~0; break;
696
697         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
698         case oLoggerFD: /* fixme: log_set_logfile (NULL, pargs.r.ret_int );*/ break;
699         case oWithFingerprint:
700           with_fpr=1; /*fall thru*/
701         case oFingerprint:
702           opt.fingerprint++;
703           break;
704
705         case oOptions:
706           /* config files may not be nested (silently ignore them) */
707           if (!configfp)
708             {
709               xfree(configname);
710               configname = xstrdup (pargs.r.ret_str);
711               goto next_pass;
712             }
713           break;
714         case oNoOptions: break; /* no-options */
715         case oHomedir: opt.homedir = pargs.r.ret_str; break;
716         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
717           
718         case oNoDefKeyring: default_keyring = 0; break;
719         case oNoGreeting: nogreeting = 1; break;
720
721         case oDefaultKey:
722           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
723           break;
724         case oDefRecipient:
725           if (*pargs.r.ret_str)
726             opt.def_recipient = xstrdup (pargs.r.ret_str);
727           break;
728         case oDefRecipientSelf:
729           xfree (opt.def_recipient);
730           opt.def_recipient = NULL;
731           opt.def_recipient_self = 1;
732           break;
733         case oNoDefRecipient:
734           xfree (opt.def_recipient);
735           opt.def_recipient = NULL;
736           opt.def_recipient_self = 0;
737           break;
738
739         case oWithKeyData: opt.with_key_data=1; /* fall thru */
740         case oWithColons: ctrl.with_colons = 1; break;
741
742         case oSkipVerify: opt.skip_verify=1; break;
743
744         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
745         case oEncryptTo: /* store the recipient in the second list */
746           sl = add_to_strlist (&remusr, pargs.r.ret_str);
747           sl->flags = 1;
748           break;
749
750         case oRecipient: /* store the recipient */
751           add_to_strlist ( &remusr, pargs.r.ret_str);
752           break;
753
754         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
755         case oTextmode: /*fixme:opt.textmode=1;*/  break;
756
757         case oUser: /* store the local users */
758           add_to_strlist ( &locusr, pargs.r.ret_str);
759           break;
760
761         case oNoSecmemWarn:
762           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
763           break;
764
765         case oDisableCipherAlgo: 
766           {
767             int algo = gcry_cipher_map_name (pargs.r.ret_str);
768             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
769           }
770           break;
771         case oDisablePubkeyAlgo: 
772           {
773             int algo = gcry_pk_map_name (pargs.r.ret_str);
774             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
775           }
776           break;
777
778         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
779         case oNoRandomSeedFile: use_random_seed = 0; break;
780
781         case oEnableSpecialFilenames: allow_special_filenames =1; break;
782           
783         default: 
784           pargs.err = configfp? 1:2; 
785           break;
786         }
787     }
788
789   if (configfp)
790     {
791       fclose (configfp);
792       configfp = NULL;
793       xfree (configname);
794       configname = NULL;
795       goto next_pass;
796     }
797   
798   xfree (configname);
799   configname = NULL;
800
801   if (log_get_errorcount(0))
802     gpgsm_exit(2);
803   
804   if (nogreeting)
805     greeting = 0;
806   
807   if (greeting)
808     {
809       fprintf(stderr, "%s %s; %s\n",
810               strusage(11), strusage(13), strusage(14) );
811       fprintf(stderr, "%s\n", strusage(15) );
812     }
813 #  ifdef IS_DEVELOPMENT_VERSION
814   if (!opt.batch)
815     {
816       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
817       log_info ("It is only intended for test purposes and should NOT be\n");
818       log_info ("used in a production environment or with production keys!\n");
819     }
820 #  endif
821
822   if (may_coredump && !opt.quiet)
823     log_info (_("WARNING: program may create a core file!\n"));
824   
825 /*FIXME    if (opt.batch) */
826 /*      tty_batchmode (1); */
827
828   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
829
830   set_debug ();
831
832   /* FIXME: should set filenames of libgcrypt explicitly
833    * gpg_opt_homedir = opt.homedir; */
834
835   /* must do this after dropping setuid, because string_to...
836    * may try to load an module */
837   if (def_cipher_string) 
838     {
839       opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string);
840       xfree (def_cipher_string);
841       def_cipher_string = NULL;
842       if ( our_cipher_test_algo (opt.def_cipher_algo) )
843         log_error (_("selected cipher algorithm is invalid\n"));
844     }
845   if (def_digest_string)
846     {
847       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
848       xfree (def_digest_string);
849       def_digest_string = NULL;
850       if (our_md_test_algo(opt.def_digest_algo) )
851         log_error (_("selected digest algorithm is invalid\n"));
852     }
853
854   if (log_get_errorcount(0))
855     gpgsm_exit(2);
856   
857   /* set the random seed file */
858   if (use_random_seed) {
859     char *p = make_filename (opt.homedir, "random_seed", NULL);
860 #if 0
861 #warning set_random_seed_file not yet available in Libgcrypt
862     set_random_seed_file(p);
863 #endif
864     xfree(p);
865   }
866
867   if (opt.armor)
868     ctrl.create_pem = 1;
869
870   if (!cmd && opt.fingerprint && !with_fpr)
871     set_cmd (&cmd, aListKeys);
872   
873   if (!nrings && default_keyring)  /* add default keybox */
874     keydb_add_resource ("pubcerts.kbx", 0, 0);
875   for (sl = nrings; sl; sl = sl->next)
876     keydb_add_resource (sl->d, 0, 0);
877   FREE_STRLIST(nrings);
878   
879   fname = argc? *argv : NULL;
880   
881   switch (cmd)
882     {
883     case aServer:
884       gpgsm_server ();
885       break;
886
887     case aEncr: /* encrypt the given file */
888 #if 0
889       if (argc > 1)
890         wrong_args(_("--encrypt [filename]"));
891       if ((rc = encode_crypt(fname,remusr)) )
892         log_error ("%s: encryption failed: %s\n",
893                    print_fname_stdin(fname), gpg_errstr(rc) );
894       break;
895 #endif
896
897     case aSign: /* sign the given file */
898       /* FIXME: we can only do detached sigs for now and we don't
899          handle --output yet. We should also allow to concatenate
900          multiple files for signins because that is what gpg does.*/
901       if (!argc)
902         gpgsm_sign (&ctrl, 0, 1, stdout); /* create from stdin */
903       else if (argc == 1)
904         gpgsm_sign (&ctrl, open_read (*argv), 1, stdout); /* from file */
905       else
906         wrong_args (_("--sign [datafile]"));
907       break;
908 #if 0
909       sl = NULL;
910       if (detached_sig)
911         { /* sign all files */
912           for (; argc; argc--, argv++ )
913             add_to_strlist ( &sl, *argv );
914         }
915       else
916         {
917           if (argc > 1 )
918             wrong_args (_("--sign [filename]"));
919           if (argc)
920             {
921               sl = xcalloc (1, sizeof *sl + strlen(fname));
922               strcpy(sl->d, fname);
923             }
924         }
925       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
926         log_error ("signing failed: %s\n", gpg_errstr(rc) );
927       free_strlist(sl);
928 #endif
929       break;
930         
931     case aSignEncr: /* sign and encrypt the given file */
932 #if 0
933       if (argc > 1)
934         wrong_args(_("--sign --encrypt [filename]"));
935       if (argc)
936         {
937           sl = xcalloc( 1, sizeof *sl + strlen(fname));
938           strcpy(sl->d, fname);
939         }
940       else
941         sl = NULL;
942
943       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
944         log_error ("%s: sign+encrypt failed: %s\n",
945                    print_fname_stdin(fname), gpg_errstr(rc) );
946       free_strlist(sl);
947 #endif
948       break;
949
950     case aClearsign: /* make a clearsig */
951 #if 0
952       if (argc > 1)
953         wrong_args (_("--clearsign [filename]"));
954       if ( (rc = clearsign_file(fname, locusr, NULL)) )
955         log_error ("%s: clearsign failed: %s\n",
956                    print_fname_stdin(fname), gpg_errstr(rc) );
957 #endif
958       break;
959
960     case aVerify:
961       if (!argc)
962         gpgsm_verify (&ctrl, 0, -1); /* normal signature from stdin */
963       else if (argc == 1)
964         gpgsm_verify (&ctrl, open_read (*argv), -1); /* normal signature */
965       else if (argc == 2) /* detached signature (sig, detached) */
966         gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1])); 
967       else
968         wrong_args (_("--verify [signature [detached_data]]"));
969       break;
970
971     case aVerifyFiles:
972 /*        if ((rc = verify_files( argc, argv ))) */
973 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
974       break;
975
976     case aDecrypt:
977 /*        if (argc > 1) */
978 /*          wrong_args (_("--decrypt [filename]")); */
979 /*        if ((rc = decrypt_message( fname ) )) */
980 /*          log_error ("decrypt_message failed: %s\n", gpg_errstr(rc) ); */
981       break;
982
983     case aDeleteKey:
984       if (argc != 1)
985         wrong_args(_("--delete-key user-id"));
986 /*        username = make_username (fname); */
987 /*        if( (rc = delete_key(username)) ) */
988 /*          log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */
989 /*        xfree(username); */
990       break;
991
992     case aListKeys:
993       for (sl=NULL; argc; argc--, argv++)
994         add_to_strlist (&sl, *argv);
995       gpgsm_list_keys (&ctrl, sl, stdout);
996       free_strlist(sl);
997       break;
998
999     case aListSecretKeys:
1000       sl = NULL;
1001       for( ; argc; argc--, argv++ )
1002         add_to_strlist (&sl, *argv);
1003 /*        secret_key_list ( sl ); */
1004       free_strlist(sl);
1005       break;
1006
1007     case aKeygen: /* generate a key */
1008 /*        if (opt.batch) */
1009 /*          { */
1010 /*            if (argc > 1) */
1011 /*              wrong_args("--gen-key [parameterfile]"); */
1012 /*            generate_keypair (argc? *argv : NULL); */
1013 /*      } */
1014 /*        else */
1015 /*          { */
1016 /*            if (argc) */
1017 /*              wrong_args ("--gen-key"); */
1018 /*            generate_keypair(NULL); */
1019 /*      } */
1020       break;
1021
1022     case aImport:
1023       if (!argc)
1024         gpgsm_import (&ctrl, 0);
1025       else
1026         {
1027           for (; argc; argc--, argv++)
1028             gpgsm_import (&ctrl, open_read (*argv));
1029         }
1030       break;
1031       
1032     case aExport:
1033     case aSendKeys:
1034     case aRecvKeys:
1035 /*        sl = NULL; */
1036 /*        for ( ; argc; argc--, argv++ ) */
1037 /*          add_to_strlist (&sl, *argv); */
1038 /*        if ( cmd == aSendKeys ) */
1039 /*          ldap_export (sl); */
1040 /*        else if (cmd == aRecvKeys ) */
1041 /*          ldap_import (sl); */
1042 /*        else */
1043 /*          export_pubkeys (sl, (cmd == aExport)); */
1044 /*        free_strlist (sl); */
1045       break;
1046
1047       default:
1048         if (argc > 1)
1049           wrong_args(_("[filename]"));
1050         /* Issue some output for the unix newbie */
1051         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1052             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1053           log_info (_("Go ahead and type your message ...\n"));
1054         
1055 #if 0
1056         if ( !(a = iobuf_open(fname)) )
1057           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1058         else
1059           {
1060             if (!opt.no_armor) 
1061               iobuf_close(a);
1062         }
1063 #endif
1064         break;
1065     }
1066   
1067   /* cleanup */
1068   FREE_STRLIST(remusr);
1069   FREE_STRLIST(locusr);
1070   gpgsm_exit(0);
1071   return 8; /*NEVER REACHED*/
1072 }
1073
1074
1075 void
1076 gpgsm_exit (int rc)
1077 {
1078   #if 0
1079 #warning no update_random_seed_file
1080   update_random_seed_file();
1081   #endif
1082 #if 0
1083   /* at this time a bit annoying */
1084   if (opt.debug & DBG_MEMSTAT_VALUE)
1085     {
1086       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1087       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1088     }
1089   if (opt.debug)
1090     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1091 #endif
1092   gcry_control (GCRYCTL_TERM_SECMEM );
1093   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1094   exit (rc);
1095 }
1096
1097
1098 /* Check whether the filename has the form "-&nnnn", where n is a
1099    non-zero number.  Returns this number or -1 if it is not the case.  */
1100 static int
1101 check_special_filename (const char *fname)
1102 {
1103   if (allow_special_filenames
1104       && fname && *fname == '-' && fname[1] == '&' ) {
1105     int i;
1106     
1107     fname += 2;
1108     for (i=0; isdigit (fname[i]); i++ )
1109       ;
1110     if ( !fname[i] ) 
1111       return atoi (fname);
1112   }
1113   return -1;
1114 }
1115
1116
1117
1118 /* Open the FILENAME for read and return the fieldescriptor.  Stop
1119    with an error message in case of problems.  "-" denotes stdin and
1120    if special filenames are allowed the given fd is opend instead. */
1121 static int 
1122 open_read (const char *filename)
1123 {
1124   int fd;
1125
1126   if (filename[0] == '-' && !filename[1])
1127     return 0; /* stdin */
1128   fd = check_special_filename (filename);
1129   if (fd != -1)
1130     return fd;
1131   fd = open (filename, O_RDONLY);
1132   if (fd == -1)
1133     {
1134       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1135       gpgsm_exit (2);
1136     }
1137   return fd;
1138 }