0b6b7c237b319dec95aebe4a8ffdb9cae0e5c6ef
[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
595   /* set the default option file */
596   if (default_config )
597     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
598   
599   argc        = orig_argc;
600   argv        = orig_argv;
601   pargs.argc  = &argc;
602   pargs.argv  = &argv;
603   pargs.flags =  1;  /* do not remove the args */
604
605  next_pass:
606   if (configname) {
607     configlineno = 0;
608     configfp = fopen (configname, "r");
609     if (!configfp)
610       {
611         if (default_config)
612           {
613             if (parse_debug)
614               log_info (_("NOTE: no default option file `%s'\n"), configname);
615           }
616         else 
617           {
618             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
619             gpgsm_exit(2);
620           }
621         xfree(configname);
622         configname = NULL;
623       }
624     if (parse_debug && configname)
625       log_info (_("reading options from `%s'\n"), configname);
626     default_config = 0;
627   }
628
629   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
630     {
631       switch (pargs.r_opt)
632         {
633         case aServer: 
634           opt.batch = 1;
635           set_cmd (&cmd, aServer);
636           break;
637
638         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
639         case aImport: set_cmd (&cmd, aImport); break;
640         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
641         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
642         case aExport: set_cmd (&cmd, aExport); break;
643         case aListKeys: set_cmd (&cmd, aListKeys); break;
644
645         case aDeleteKey:
646           set_cmd (&cmd, aDeleteKey);
647           greeting=1;
648           break;
649
650         case aDetachedSign:
651           detached_sig = 1;
652           set_cmd (&cmd, aSign ); 
653           break;
654           
655         case aSym: set_cmd (&cmd, aSym); break;
656         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
657         case aEncr: set_cmd (&cmd, aEncr); break;
658         case aSign: set_cmd (&cmd, aSign );  break;
659         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
660         case aClearsign: set_cmd (&cmd, aClearsign); break;
661         case aVerify: set_cmd (&cmd, aVerify); break;
662
663         case oArmor: opt.armor = 1; opt.no_armor=0; break;
664         case oNoArmor: opt.no_armor=1; opt.armor=0; break;
665         case oOutput: opt.outfile = pargs.r.ret_str; break;
666         case oQuiet: opt.quiet = 1; break;
667         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
668         case oDryRun: opt.dry_run = 1; break;
669
670         case oVerbose:
671           opt.verbose++;
672           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
673           break;
674         case oNoVerbose:
675           opt.verbose = 0;
676           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
677           break;
678           
679         case oBatch: 
680           opt.batch = 1;
681           greeting = 0;
682           break;
683         case oNoBatch: opt.batch = 0; break;
684           
685         case oAnswerYes: opt.answer_yes = 1; break;
686         case oAnswerNo: opt.answer_no = 1; break;
687
688         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
689
690         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
691         case oDebugAll: opt.debug = ~0; break;
692
693         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
694         case oLoggerFD: /* fixme: log_set_logfile (NULL, pargs.r.ret_int );*/ break;
695         case oWithFingerprint:
696           with_fpr=1; /*fall thru*/
697         case oFingerprint:
698           opt.fingerprint++;
699           break;
700
701         case oOptions:
702           /* config files may not be nested (silently ignore them) */
703           if (!configfp)
704             {
705               xfree(configname);
706               configname = xstrdup (pargs.r.ret_str);
707               goto next_pass;
708             }
709           break;
710         case oNoOptions: break; /* no-options */
711         case oHomedir: opt.homedir = pargs.r.ret_str; break;
712         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
713           
714         case oNoDefKeyring: default_keyring = 0; break;
715         case oNoGreeting: nogreeting = 1; break;
716
717         case oDefaultKey:
718           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
719           break;
720         case oDefRecipient:
721           if (*pargs.r.ret_str)
722             opt.def_recipient = xstrdup (pargs.r.ret_str);
723           break;
724         case oDefRecipientSelf:
725           xfree (opt.def_recipient);
726           opt.def_recipient = NULL;
727           opt.def_recipient_self = 1;
728           break;
729         case oNoDefRecipient:
730           xfree (opt.def_recipient);
731           opt.def_recipient = NULL;
732           opt.def_recipient_self = 0;
733           break;
734
735         case oWithKeyData: opt.with_key_data=1; /* fall thru */
736         case oWithColons: ctrl.with_colons = 1; break;
737
738         case oSkipVerify: opt.skip_verify=1; break;
739
740         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
741         case oEncryptTo: /* store the recipient in the second list */
742           sl = add_to_strlist (&remusr, pargs.r.ret_str);
743           sl->flags = 1;
744           break;
745
746         case oRecipient: /* store the recipient */
747           add_to_strlist ( &remusr, pargs.r.ret_str);
748           break;
749
750         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
751         case oTextmode: /*fixme:opt.textmode=1;*/  break;
752
753         case oUser: /* store the local users */
754           add_to_strlist ( &locusr, pargs.r.ret_str);
755           break;
756
757         case oNoSecmemWarn:
758           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
759           break;
760
761         case oDisableCipherAlgo: 
762           {
763             int algo = gcry_cipher_map_name (pargs.r.ret_str);
764             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
765           }
766           break;
767         case oDisablePubkeyAlgo: 
768           {
769             int algo = gcry_pk_map_name (pargs.r.ret_str);
770             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
771           }
772           break;
773
774         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
775         case oNoRandomSeedFile: use_random_seed = 0; break;
776
777         case oEnableSpecialFilenames: allow_special_filenames =1; break;
778           
779         default: 
780           pargs.err = configfp? 1:2; 
781           break;
782         }
783     }
784
785   if (configfp)
786     {
787       fclose (configfp);
788       configfp = NULL;
789       xfree (configname);
790       configname = NULL;
791       goto next_pass;
792     }
793   
794   xfree (configname);
795   configname = NULL;
796
797   if (log_get_errorcount(0))
798     gpgsm_exit(2);
799   
800   if (nogreeting)
801     greeting = 0;
802   
803   if (greeting)
804     {
805       fprintf(stderr, "%s %s; %s\n",
806               strusage(11), strusage(13), strusage(14) );
807       fprintf(stderr, "%s\n", strusage(15) );
808     }
809 #  ifdef IS_DEVELOPMENT_VERSION
810   if (!opt.batch)
811     {
812       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
813       log_info ("It is only intended for test purposes and should NOT be\n");
814       log_info ("used in a production environment or with production keys!\n");
815     }
816 #  endif
817
818   if (may_coredump && !opt.quiet)
819     log_info (_("WARNING: program may create a core file!\n"));
820   
821 /*FIXME    if (opt.batch) */
822 /*      tty_batchmode (1); */
823
824   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
825
826   set_debug ();
827   /* FIXME: should set filenames of libgcrypt explicitly
828    * gpg_opt_homedir = opt.homedir; */
829
830   /* must do this after dropping setuid, because string_to...
831    * may try to load an module */
832   if (def_cipher_string) 
833     {
834       opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string);
835       xfree (def_cipher_string);
836       def_cipher_string = NULL;
837       if ( our_cipher_test_algo (opt.def_cipher_algo) )
838         log_error (_("selected cipher algorithm is invalid\n"));
839     }
840   if (def_digest_string)
841     {
842       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
843       xfree (def_digest_string);
844       def_digest_string = NULL;
845       if (our_md_test_algo(opt.def_digest_algo) )
846         log_error (_("selected digest algorithm is invalid\n"));
847     }
848
849   if (log_get_errorcount(0))
850     gpgsm_exit(2);
851   
852   /* set the random seed file */
853   if (use_random_seed) {
854     char *p = make_filename (opt.homedir, "random_seed", NULL);
855 #if 0
856 #warning set_random_seed_file not yet available in Libgcrypt
857     set_random_seed_file(p);
858 #endif
859     xfree(p);
860   }
861
862   if (!cmd && opt.fingerprint && !with_fpr)
863     set_cmd (&cmd, aListKeys);
864   
865   if (!nrings && default_keyring)  /* add default keybox */
866     keydb_add_resource ("pubcerts.kbx", 0, 0);
867   for (sl = nrings; sl; sl = sl->next)
868     keydb_add_resource (sl->d, 0, 0);
869   FREE_STRLIST(nrings);
870   
871   fname = argc? *argv : NULL;
872   
873   switch (cmd)
874     {
875     case aServer:
876       gpgsm_server ();
877       break;
878
879     case aEncr: /* encrypt the given file */
880 #if 0
881       if (argc > 1)
882         wrong_args(_("--encrypt [filename]"));
883       if ((rc = encode_crypt(fname,remusr)) )
884         log_error ("%s: encryption failed: %s\n",
885                    print_fname_stdin(fname), gpg_errstr(rc) );
886       break;
887 #endif
888
889     case aSign: /* sign the given file */
890       /* FIXME: we can only do detached sigs for now and we don't
891          handle --output yet. We should also allow to concatenate
892          multiple files for signins because that is what gpg does.*/
893       if (!argc)
894         gpgsm_sign (&ctrl, 0, 1, stdout); /* create from stdin */
895       else if (argc == 1)
896         gpgsm_sign (&ctrl, open_read (*argv), 1, stdout); /* from file */
897       else
898         wrong_args (_("--sign [datafile]"));
899       break;
900 #if 0
901       sl = NULL;
902       if (detached_sig)
903         { /* sign all files */
904           for (; argc; argc--, argv++ )
905             add_to_strlist ( &sl, *argv );
906         }
907       else
908         {
909           if (argc > 1 )
910             wrong_args (_("--sign [filename]"));
911           if (argc)
912             {
913               sl = xcalloc (1, sizeof *sl + strlen(fname));
914               strcpy(sl->d, fname);
915             }
916         }
917       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
918         log_error ("signing failed: %s\n", gpg_errstr(rc) );
919       free_strlist(sl);
920 #endif
921       break;
922         
923     case aSignEncr: /* sign and encrypt the given file */
924 #if 0
925       if (argc > 1)
926         wrong_args(_("--sign --encrypt [filename]"));
927       if (argc)
928         {
929           sl = xcalloc( 1, sizeof *sl + strlen(fname));
930           strcpy(sl->d, fname);
931         }
932       else
933         sl = NULL;
934
935       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
936         log_error ("%s: sign+encrypt failed: %s\n",
937                    print_fname_stdin(fname), gpg_errstr(rc) );
938       free_strlist(sl);
939 #endif
940       break;
941
942     case aClearsign: /* make a clearsig */
943 #if 0
944       if (argc > 1)
945         wrong_args (_("--clearsign [filename]"));
946       if ( (rc = clearsign_file(fname, locusr, NULL)) )
947         log_error ("%s: clearsign failed: %s\n",
948                    print_fname_stdin(fname), gpg_errstr(rc) );
949 #endif
950       break;
951
952     case aVerify:
953       if (!argc)
954         gpgsm_verify (&ctrl, 0, -1); /* normal signature from stdin */
955       else if (argc == 1)
956         gpgsm_verify (&ctrl, open_read (*argv), -1); /* normal signature */
957       else if (argc == 2) /* detached signature (sig, detached) */
958         gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1])); 
959       else
960         wrong_args (_("--verify [signature [detached_data]]"));
961       break;
962
963     case aVerifyFiles:
964 /*        if ((rc = verify_files( argc, argv ))) */
965 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
966       break;
967
968     case aDecrypt:
969 /*        if (argc > 1) */
970 /*          wrong_args (_("--decrypt [filename]")); */
971 /*        if ((rc = decrypt_message( fname ) )) */
972 /*          log_error ("decrypt_message failed: %s\n", gpg_errstr(rc) ); */
973       break;
974
975     case aDeleteKey:
976       if (argc != 1)
977         wrong_args(_("--delete-key user-id"));
978 /*        username = make_username (fname); */
979 /*        if( (rc = delete_key(username)) ) */
980 /*          log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */
981 /*        xfree(username); */
982       break;
983
984     case aListKeys:
985       for (sl=NULL; argc; argc--, argv++)
986         add_to_strlist (&sl, *argv);
987       gpgsm_list_keys (&ctrl, sl, stdout);
988       free_strlist(sl);
989       break;
990
991     case aListSecretKeys:
992       sl = NULL;
993       for( ; argc; argc--, argv++ )
994         add_to_strlist (&sl, *argv);
995 /*        secret_key_list ( sl ); */
996       free_strlist(sl);
997       break;
998
999     case aKeygen: /* generate a key */
1000 /*        if (opt.batch) */
1001 /*          { */
1002 /*            if (argc > 1) */
1003 /*              wrong_args("--gen-key [parameterfile]"); */
1004 /*            generate_keypair (argc? *argv : NULL); */
1005 /*      } */
1006 /*        else */
1007 /*          { */
1008 /*            if (argc) */
1009 /*              wrong_args ("--gen-key"); */
1010 /*            generate_keypair(NULL); */
1011 /*      } */
1012       break;
1013
1014     case aImport:
1015       if (!argc)
1016         gpgsm_import (&ctrl, 0);
1017       else
1018         {
1019           for (; argc; argc--, argv++)
1020             gpgsm_import (&ctrl, open_read (*argv));
1021         }
1022       break;
1023       
1024     case aExport:
1025     case aSendKeys:
1026     case aRecvKeys:
1027 /*        sl = NULL; */
1028 /*        for ( ; argc; argc--, argv++ ) */
1029 /*          add_to_strlist (&sl, *argv); */
1030 /*        if ( cmd == aSendKeys ) */
1031 /*          ldap_export (sl); */
1032 /*        else if (cmd == aRecvKeys ) */
1033 /*          ldap_import (sl); */
1034 /*        else */
1035 /*          export_pubkeys (sl, (cmd == aExport)); */
1036 /*        free_strlist (sl); */
1037       break;
1038
1039       default:
1040         if (argc > 1)
1041           wrong_args(_("[filename]"));
1042         /* Issue some output for the unix newbie */
1043         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1044             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1045           log_info (_("Go ahead and type your message ...\n"));
1046         
1047 #if 0
1048         if ( !(a = iobuf_open(fname)) )
1049           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1050         else
1051           {
1052             if (!opt.no_armor) 
1053               iobuf_close(a);
1054         }
1055 #endif
1056         break;
1057     }
1058   
1059   /* cleanup */
1060   FREE_STRLIST(remusr);
1061   FREE_STRLIST(locusr);
1062   gpgsm_exit(0);
1063   return 8; /*NEVER REACHED*/
1064 }
1065
1066
1067 void
1068 gpgsm_exit (int rc)
1069 {
1070   #if 0
1071 #warning no update_random_seed_file
1072   update_random_seed_file();
1073   #endif
1074 #if 0
1075   /* at this time a bit annoying */
1076   if (opt.debug & DBG_MEMSTAT_VALUE)
1077     {
1078       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1079       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1080     }
1081   if (opt.debug)
1082     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1083 #endif
1084   gcry_control (GCRYCTL_TERM_SECMEM );
1085   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1086   exit (rc);
1087 }
1088
1089
1090 /* Check whether the filename has the form "-&nnnn", where n is a
1091    non-zero number.  Returns this number or -1 if it is not the case.  */
1092 static int
1093 check_special_filename (const char *fname)
1094 {
1095   if (allow_special_filenames
1096       && fname && *fname == '-' && fname[1] == '&' ) {
1097     int i;
1098     
1099     fname += 2;
1100     for (i=0; isdigit (fname[i]); i++ )
1101       ;
1102     if ( !fname[i] ) 
1103       return atoi (fname);
1104   }
1105   return -1;
1106 }
1107
1108
1109
1110 /* Open the FILENAME for read and return the fieldescriptor.  Stop
1111    with an error message in case of problems.  "-" denotes stdin and
1112    if special filenames are allowed the given fd is opend instead. */
1113 static int 
1114 open_read (const char *filename)
1115 {
1116   int fd;
1117
1118   if (filename[0] == '-' && !filename[1])
1119     return 0; /* stdin */
1120   fd = check_special_filename (filename);
1121   if (fd != -1)
1122     return fd;
1123   fd = open (filename, O_RDONLY);
1124   if (fd == -1)
1125     {
1126       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1127       gpgsm_exit (2);
1128     }
1129   return fd;
1130 }