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