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