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