(main): New commands --dump-keys, --dump-external-keys,
[gnupg.git] / sm / gpgsm.c
1 /* gpgsm.c - GnuPG for S/MIME 
2  * Copyright (C) 2001, 2002, 2003, 2004 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 "gpgsm.h"
31 #include <gcrypt.h>
32 #include <assuan.h> /* malloc hooks */
33
34 #include "../kbx/keybox.h" /* malloc hooks */
35 #include "i18n.h"
36 #include "keydb.h"
37 #include "sysutils.h"
38
39 enum cmd_and_opt_values {
40   aNull = 0,
41   oArmor        = 'a',
42   aDetachedSign = 'b',
43   aSym          = 'c',
44   aDecrypt      = 'd',
45   aEncr         = 'e',
46   oInteractive  = 'i',
47   aListKeys     = 'k',
48   aListSecretKeys = 'K',
49   oDryRun       = 'n',
50   oOutput       = 'o',
51   oQuiet        = 'q',
52   oRecipient    = 'r',
53   aSign         = 's',
54   oTextmodeShort= 't',
55   oUser         = 'u',
56   oVerbose      = 'v',
57   oCompress     = 'z',
58   oNotation     = 'N',
59   oBatch        = 500,
60   aClearsign,
61   aStore,
62   aKeygen,
63   aSignEncr,
64   aSignKey,
65   aLSignKey,
66   aListPackets,
67   aEditKey,
68   aDeleteKey,
69   aImport,
70   aVerify,
71   aVerifyFiles,
72   aListExternalKeys,
73   aListSigs,
74   aSendKeys,
75   aRecvKeys,
76   aExport,
77   aExportSecretKeyP12,
78   aCheckKeys, /* nyi */
79   aServer,                        
80   aLearnCard,
81   aCallDirmngr,
82   aCallProtectTool,
83   aPasswd,
84   aGPGConfList,
85   aDumpKeys,
86   aDumpSecretKeys,
87   aDumpExternalKeys,
88
89   oOptions,
90   oDebug,
91   oDebugLevel,
92   oDebugAll,
93   oDebugWait,
94   oDebugNoChainValidation,
95   oDebugIgnoreExpiration,
96   oLogFile,
97
98   oEnableSpecialFilenames,
99
100   oAgentProgram,
101   oDisplay,
102   oTTYname,
103   oTTYtype,
104   oLCctype,
105   oLCmessages,
106
107   oDirmngrProgram,
108   oProtectToolProgram,
109   oFakedSystemTime,
110
111
112   oAssumeArmor,
113   oAssumeBase64,
114   oAssumeBinary,
115
116   oBase64,
117   oNoArmor,
118
119   oDisableCRLChecks,
120   oEnableCRLChecks,
121   oForceCRLRefresh,
122
123   oDisableOCSP,
124   oEnableOCSP,
125
126   oIncludeCerts,
127   oPolicyFile,
128   oDisablePolicyChecks,
129   oEnablePolicyChecks,
130   oAutoIssuerKeyRetrieve,
131   
132
133   oTextmode,
134   oFingerprint,
135   oWithFingerprint,
136   oWithMD5Fingerprint,
137   oAnswerYes,
138   oAnswerNo,
139   oKeyring,
140   oSecretKeyring,
141   oDefaultKey,
142   oDefRecipient,
143   oDefRecipientSelf,
144   oNoDefRecipient,
145   oStatusFD,
146   oNoComment,
147   oNoVersion,
148   oEmitVersion,
149   oCompletesNeeded,
150   oMarginalsNeeded,
151   oMaxCertDepth,
152   oLoadExtension,
153   oRFC1991,
154   oOpenPGP,
155   oCipherAlgo,
156   oDigestAlgo,
157   oCompressAlgo,
158   oCommandFD,
159   oNoVerbose,
160   oTrustDBName,
161   oNoSecmemWarn,
162   oNoDefKeyring,
163   oNoGreeting,
164   oNoTTY,
165   oNoOptions,
166   oNoBatch,
167   oHomedir,
168   oWithColons,
169   oWithKeyData,
170   oWithValidation,
171   oSkipVerify,
172   oCompressKeys,
173   oCompressSigs,
174   oAlwaysTrust,
175   oRunAsShmCP,
176   oSetFilename,
177   oSetPolicyURL,
178   oUseEmbeddedFilename,
179   oComment,
180   oDefaultComment,
181   oThrowKeyid,
182   oForceV3Sigs,
183   oForceMDC,
184   oS2KMode,
185   oS2KDigest,
186   oS2KCipher,
187   oCharset,
188   oNotDashEscaped,
189   oEscapeFrom,
190   oLockOnce,
191   oLockMultiple,
192   oLockNever,
193   oKeyServer,
194   oEncryptTo,
195   oNoEncryptTo,
196   oLoggerFD,
197   oUtf8Strings,
198   oNoUtf8Strings,
199   oDisableCipherAlgo,
200   oDisablePubkeyAlgo,
201   oAllowNonSelfsignedUID,
202   oAllowFreeformUID,
203   oNoLiteral,
204   oSetFilesize,
205   oHonorHttpProxy,
206   oFastListMode,
207   oListOnly,
208   oIgnoreTimeConflict,
209   oNoRandomSeedFile,
210   oNoAutoKeyRetrieve,
211   oUseAgent,
212   oMergeOnly,
213   oTryAllSecrets,
214   oTrustedKey,
215   oEmuMDEncodeBug,
216   aDummy
217  };
218
219
220 static ARGPARSE_OPTS opts[] = {
221
222     { 300, NULL, 0, N_("@Commands:\n ") },
223
224     { aSign, "sign",      256, N_("|[FILE]|make a signature")},
225     { aClearsign, "clearsign", 256, N_("|[FILE]|make a clear text signature") },
226     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
227     { aEncr, "encrypt",   256, N_("encrypt data")},
228     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
229     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
230     { aVerify, "verify"   , 256, N_("verify a signature")},
231     { aVerifyFiles, "verify-files" , 256, "@" },
232     { aListKeys, "list-keys", 256, N_("list keys")},
233     { aListExternalKeys, "list-external-keys", 256, N_("list external keys")},
234     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
235     { aListSigs,   "list-sigs", 256, N_("list certificate chain")}, 
236     { aListSigs,   "check-sigs",256, "@"},
237     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
238     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
239     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
240     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
241     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
242     { aImport, "import",      256     , N_("import certificates")},
243     { aExport, "export",      256     , N_("export certificates")},
244     { aLearnCard, "learn-card", 256 ,N_("register a smartcard")},
245     { aServer, "server",      256, N_("run in server mode")},
246     { aCallDirmngr, "call-dirmngr", 256, N_("pass a command to the dirmngr")},
247     { aCallProtectTool, "call-protect-tool", 256,
248                                    N_("invoke gpg-protect-tool")},
249     { aPasswd, "passwd",      256, N_("change a passphrase")},
250     { aGPGConfList, "gpgconf-list", 256, "@" },
251
252     { aDumpKeys, "dump-keys", 256, "@"},
253     { aDumpExternalKeys, "dump-external-keys", 256, "@"},
254     { aDumpSecretKeys, "dump-secret-keys", 256, "@"},
255
256     { 301, NULL, 0, N_("@\nOptions:\n ") },
257
258     { oArmor, "armor",     0, N_("create ascii armored output")},
259     { oArmor, "armour",    0, "@" },
260     { oBase64, "base64",    0, N_("create base-64 encoded output")},
261     
262     { oAssumeArmor,  "assume-armor", 0, N_("assume input is in PEM format")},
263     { oAssumeBase64, "assume-base64", 0,
264                                       N_("assume input is in base-64 format")},
265     { oAssumeBinary, "assume-binary", 0,
266                                       N_("assume input is in binary format")},
267
268     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
269
270
271     { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")},
272     { oEnableCRLChecks, "enable-crl-checks", 0, "@"},
273     { oForceCRLRefresh, "force-crl-refresh", 0, "@"},
274
275     { oDisableOCSP, "disable-ocsp", 0, "@" },
276     { oEnableOCSP,  "enable-ocsp", 0, N_("check validity using OCSP")},
277
278     { oIncludeCerts, "include-certs", 1,
279                                  N_("|N|number of certificates to include") },
280
281     { oPolicyFile, "policy-file", 2,
282                     N_("|FILE|take policy information from FILE") },
283
284     { oDisablePolicyChecks, "disable-policy-checks", 0,
285                            N_("do not check certificate policies")},
286     { oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
287
288     { oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0, 
289       N_("fetch missing issuer certificates")},
290
291 #if 0
292     { oDefRecipient, "default-recipient" ,2,
293                                   N_("|NAME|use NAME as default recipient")},
294     { oDefRecipientSelf, "default-recipient-self" ,0,
295                                 N_("use the default key as default recipient")},
296     { oNoDefRecipient, "no-default-recipient", 0, "@" },
297 #endif
298     { oEncryptTo, "encrypt-to", 2, "@" },
299     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
300
301     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
302
303 #if 0
304     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
305     { oTextmodeShort, NULL,   0, "@"},
306     { oTextmode, "textmode",  0, N_("use canonical text mode")},
307 #endif
308
309     { oOutput, "output",    2, N_("use as output file")},
310     { oVerbose, "verbose",   0, N_("verbose") },
311     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
312     { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
313     { oLogFile, "log-file"   ,2, N_("use a log file for the server")},
314 #if 0
315     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
316     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
317 #endif
318     { oDryRun, "dry-run",   0, N_("do not make any changes") },
319   /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
320     /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/
321     { oBatch, "batch",     0, N_("batch mode: never ask")},
322     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
323     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
324
325     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
326     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
327     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
328     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
329     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
330     { oOptions, "options"   , 2, N_("read options from file")},
331
332     { oDebug, "debug"     ,4|16, "@"},
333     { oDebugLevel, "debug-level" ,2, "@"},
334     { oDebugAll, "debug-all" ,0, "@"},
335     { oDebugWait, "debug-wait" ,1, "@"},
336     { oDebugNoChainValidation, "debug-no-chain-validation", 0, "@"},
337     { oDebugIgnoreExpiration,  "debug-ignore-expiration", 0, "@"},
338     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
339     { aDummy, "no-comment", 0,   "@"},
340     { aDummy, "completes-needed", 1, "@"},
341     { aDummy, "marginals-needed", 1, "@"},
342     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
343     { aDummy, "trusted-key", 2, "@"},
344     { oLoadExtension, "load-extension" ,2,
345       N_("|FILE|load extension module FILE")},
346     { aDummy, "rfc1991",   0, "@"},
347     { aDummy, "openpgp",   0, "@"},
348     { aDummy, "s2k-mode",  1, "@"},
349     { aDummy, "s2k-digest-algo",2, "@"},
350     { aDummy, "s2k-cipher-algo",2, "@"},
351     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
352     { oDigestAlgo, "digest-algo", 2 ,
353       N_("|NAME|use message digest algorithm NAME")},
354 #if 0
355     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
356 #endif
357     { aDummy, "throw-keyid", 0, "@"},
358     { aDummy, "notation-data", 2, "@"},
359     { aExportSecretKeyP12, "export-secret-key-p12", 256, "@"}, 
360     
361
362     { 302, NULL, 0, N_(
363   "@\n(See the man page for a complete listing of all commands and options)\n"
364                       )},
365
366     { 303, NULL, 0, N_("@\nExamples:\n\n"
367     " -se -r Bob [file]          sign and encrypt for user Bob\n"
368     " --clearsign [file]         make a clear text signature\n"
369     " --detach-sign [file]       make a detached signature\n"
370     " --list-keys [names]        show keys\n"
371     " --fingerprint [names]      show fingerprints\n"  ) },
372
373   /* hidden options */
374     { oNoVerbose, "no-verbose", 0, "@"},
375
376     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
377
378
379     { oTrustDBName, "trustdb-name", 2, "@" },
380     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, 
381     { oNoArmor, "no-armor",   0, "@"},
382     { oNoArmor, "no-armour",   0, "@"},
383     { oNoDefKeyring, "no-default-keyring", 0, "@" },
384     { oNoGreeting, "no-greeting", 0, "@" },
385     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
386     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
387     { oAgentProgram, "agent-program", 2 , "@" },
388     { oDisplay,    "display",     2, "@" },
389     { oTTYname,    "ttyname",     2, "@" },
390     { oTTYtype,    "ttytype",     2, "@" },
391     { oLCctype,    "lc-ctype",    2, "@" },
392     { oLCmessages, "lc-messages", 2, "@" },
393     { oDirmngrProgram, "dirmngr-program", 2 , "@" },
394     { oProtectToolProgram, "protect-tool-program", 2 , "@" },
395     { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */
396
397
398     { oNoBatch, "no-batch", 0, "@" },
399     { oWithColons, "with-colons", 0, "@"},
400     { oWithKeyData,"with-key-data", 0, "@"},
401     { oWithValidation, "with-validation", 0, "@"},
402     { oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"},
403     { aListKeys, "list-key", 0, "@" }, /* alias */
404     { aListSigs, "list-sig", 0, "@" }, /* alias */
405     { aListSigs, "check-sig",0, "@" }, /* alias */
406     { oSkipVerify, "skip-verify",0, "@" },
407     { oCompressKeys, "compress-keys",0, "@"},
408     { oCompressSigs, "compress-sigs",0, "@"},
409     { oAlwaysTrust, "always-trust", 0, "@"},
410     { oNoVersion, "no-version", 0, "@"},
411     { oLockOnce, "lock-once", 0, "@" },
412     { oLockMultiple, "lock-multiple", 0, "@" },
413     { oLockNever, "lock-never", 0, "@" },
414     { oLoggerFD, "logger-fd",1, "@" },
415     { oWithFingerprint, "with-fingerprint", 0, "@" },
416     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
417     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
418     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
419     { oListOnly, "list-only", 0, "@"},
420     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
421     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
422 {0} };
423
424
425
426 int gpgsm_errors_seen = 0;
427
428 /* It is possible that we are currentlu running under setuid permissions */
429 static int maybe_setuid = 1;
430
431 /* Option --enable-special-filenames */
432 static int allow_special_filenames;
433
434
435 static char *build_list (const char *text,
436                          const char *(*mapf)(int), int (*chkf)(int));
437 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
438                      enum cmd_and_opt_values new_cmd );
439
440 static void emergency_cleanup (void);
441 static int check_special_filename (const char *fname);
442 static int open_read (const char *filename);
443 static FILE *open_fwrite (const char *filename);
444 static void run_protect_tool (int argc, char **argv);
445
446
447 static int
448 our_pk_test_algo (int algo)
449 {
450   return 1;
451 }
452
453 static int
454 our_cipher_test_algo (int algo)
455 {
456   return 1;
457 }
458
459 static int
460 our_md_test_algo (int algo)
461 {
462   return 1;
463 }
464
465 static const char *
466 my_strusage( int level )
467 {
468   static char *digests, *pubkeys, *ciphers;
469   const char *p;
470
471   switch (level)
472     {
473     case 11: p = "gpgsm (GnuPG)";
474       break;
475     case 13: p = VERSION; break;
476     case 17: p = PRINTABLE_OS_NAME; break;
477     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
478       break;
479     case 1:
480     case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
481       break;
482     case 41:
483       p = _("Syntax: gpgsm [options] [files]\n"
484             "sign, check, encrypt or decrypt using the S/MIME protocol\n"
485             "default operation depends on the input data\n");
486       break;
487
488     case 31: p = "\nHome: "; break;
489     case 32: p = opt.homedir; break;
490     case 33: p = _("\nSupported algorithms:\n"); break;
491     case 34:
492       if (!ciphers)
493         ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
494                               our_cipher_test_algo );
495       p = ciphers;
496       break;
497     case 35:
498       if (!pubkeys)
499         pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
500                               our_pk_test_algo );
501       p = pubkeys;
502       break;
503     case 36:
504       if (!digests)
505         digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
506       p = digests;
507       break;
508       
509     default: p = NULL; break;
510     }
511   return p;
512 }
513
514
515 static char *
516 build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
517 {
518   int i;
519   size_t n=strlen(text)+2;
520   char *list, *p;
521   
522   if (maybe_setuid) {
523     gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
524   }
525
526   for (i=1; i < 110; i++ )
527     if (!chkf(i))
528       n += strlen(mapf(i)) + 2;
529   list = xmalloc (21 + n);
530   *list = 0;
531   for (p=NULL, i=1; i < 110; i++)
532     {
533       if (!chkf(i))
534         {
535           if( !p )
536             p = stpcpy (list, text );
537           else
538             p = stpcpy (p, ", ");
539           p = stpcpy (p, mapf(i) );
540         }
541     }
542   if (p)
543     p = stpcpy(p, "\n" );
544   return list;
545 }
546
547
548 static void
549 i18n_init(void)
550 {
551 #ifdef USE_SIMPLE_GETTEXT
552   set_gettext_file (PACKAGE_GT);
553 #else
554 # ifdef ENABLE_NLS
555 #  ifdef HAVE_LC_MESSAGES
556   setlocale (LC_TIME, "");
557   setlocale (LC_MESSAGES, "");
558 #  else
559   setlocale (LC_ALL, "" );
560 #  endif
561   bindtextdomain (PACKAGE_GT, LOCALEDIR);
562   textdomain (PACKAGE_GT);
563 # endif
564 #endif
565 }
566
567
568 static void
569 wrong_args (const char *text)
570 {
571   fputs (_("usage: gpgsm [options] "), stderr);
572   fputs (text, stderr);
573   putc ('\n', stderr);
574   gpgsm_exit (2);
575 }
576
577
578 /* Setup the debugging.  With a LEVEL of NULL only the active debug
579    flags are propagated to the subsystems.  With LEVEL set, a specific
580    set of debug flags is set; thus overriding all flags already
581    set. */
582 static void
583 set_debug (const char *level)
584 {
585   if (!level)
586     ;
587   else if (!strcmp (level, "none"))
588     opt.debug = 0;
589   else if (!strcmp (level, "basic"))
590     opt.debug = DBG_ASSUAN_VALUE;
591   else if (!strcmp (level, "advanced"))
592     opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE;
593   else if (!strcmp (level, "expert"))
594     opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE
595                  |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE);
596   else if (!strcmp (level, "guru"))
597     opt.debug = ~0;
598   else
599     {
600       log_error (_("invalid debug-level `%s' given\n"), level);
601       gpgsm_exit(2);
602     }
603
604
605   if (opt.debug && !opt.verbose)
606     {
607       opt.verbose = 1;
608       gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
609     }
610   if (opt.debug && opt.quiet)
611     opt.quiet = 0;
612
613   if (opt.debug & DBG_MPI_VALUE)
614     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
615   if (opt.debug & DBG_CRYPTO_VALUE )
616     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
617 }
618  
619
620
621 static void
622 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
623 {
624   enum cmd_and_opt_values cmd = *ret_cmd;
625
626   if (!cmd || cmd == new_cmd)
627     cmd = new_cmd;
628   else if ( cmd == aSign && new_cmd == aEncr )
629     cmd = aSignEncr;
630   else if ( cmd == aEncr && new_cmd == aSign )
631     cmd = aSignEncr;
632   else if ( (cmd == aSign && new_cmd == aClearsign)
633             || (cmd == aClearsign && new_cmd == aSign) )
634     cmd = aClearsign;
635   else 
636     {
637       log_error(_("conflicting commands\n"));
638       gpgsm_exit(2);
639     }
640
641   *ret_cmd = cmd;
642 }
643
644
645 /* Helper to add recipients to a list. */
646 static void
647 do_add_recipient (ctrl_t ctrl, const char *name,
648                   certlist_t *recplist, int is_encrypt_to)
649 {
650   int rc = gpgsm_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to);
651   if (rc)
652     {
653       log_error (_("can't encrypt to `%s': %s\n"), name, gpg_strerror (rc));
654       gpgsm_status2 (ctrl, STATUS_INV_RECP,
655                      gpg_err_code (rc) == -1?                         "1":
656                      gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?          "1":
657                      gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME?     "2":
658                      gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE?    "3":
659                      gpg_err_code (rc) == GPG_ERR_CERT_REVOKED?       "4":
660                      gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED?       "5":
661                      gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN?       "6":
662                      gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD?        "7":
663                      gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH?    "8":
664                      "0",
665                      name, NULL);
666     }
667 }
668
669
670 int
671 main ( int argc, char **argv)
672 {
673   ARGPARSE_ARGS pargs;
674   int orig_argc;
675   char **orig_argv;
676   const char *fname;
677   /*  char *username;*/
678   int may_coredump;
679   STRLIST sl, remusr= NULL, locusr=NULL;
680   STRLIST nrings=NULL;
681   int detached_sig = 0;
682   FILE *configfp = NULL;
683   char *configname = NULL;
684   unsigned configlineno;
685   int parse_debug = 0;
686   int no_more_options = 0;
687   int default_config =1;
688   int default_keyring = 1;
689   char *logfile = NULL;
690   int greeting = 0;
691   int nogreeting = 0;
692   int debug_wait = 0;
693   const char *debug_level = NULL;
694   int use_random_seed = 1;
695   int with_fpr = 0;
696   char *def_digest_string = NULL;
697   enum cmd_and_opt_values cmd = 0;
698   struct server_control_s ctrl;
699   CERTLIST recplist = NULL;
700   CERTLIST signerlist = NULL;
701   int do_not_setup_keys = 0;
702   char *config_filename = NULL;
703
704   /* trap_unaligned ();*/
705   set_strusage (my_strusage);
706   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
707   /* We don't need any locking in libgcrypt unless we use any kind of
708      threading. */
709   gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
710
711   /* Please note that we may running SUID(ROOT), so be very CAREFUL
712      when adding any stuff between here and the call to secmem_init()
713      somewhere after the option parsing */
714   log_set_prefix ("gpgsm", 1);
715
716   /* Try to auto set the character set.  */
717   set_native_charset (NULL); 
718
719   /* Check that the libraries are suitable.  Do it here because the
720      option parse may need services of the library */
721   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
722     {
723       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
724                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
725     }
726   if (!ksba_check_version (NEED_KSBA_VERSION) )
727     {
728       log_fatal( _("libksba is too old (need %s, have %s)\n"),
729                  NEED_KSBA_VERSION, ksba_check_version (NULL) );
730     }
731
732   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
733
734   may_coredump = disable_core_dumps ();
735   
736   gnupg_init_signals (0, emergency_cleanup);
737   
738   create_dotlock (NULL); /* register locking cleanup */
739   i18n_init();
740
741   opt.def_cipher_algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
742 #ifdef __MINGW32__
743   opt.homedir = read_w32_registry_string ( NULL,
744                                            "Software\\GNU\\GnuPG", "HomeDir" );
745 #else
746   opt.homedir = getenv ("GNUPGHOME");
747 #endif
748   if (!opt.homedir || !*opt.homedir ) 
749     opt.homedir = GNUPG_DEFAULT_HOMEDIR;
750
751   /* first check whether we have a config file on the commandline */
752   orig_argc = argc;
753   orig_argv = argv;
754   pargs.argc = &argc;
755   pargs.argv = &argv;
756   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
757   while (arg_parse( &pargs, opts))
758     {
759       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
760         parse_debug++;
761       else if (pargs.r_opt == oOptions)
762         { /* yes there is one, so we do not try the default one but
763              read the config file when it is encountered at the
764              commandline */
765           default_config = 0;
766         }
767       else if (pargs.r_opt == oNoOptions)
768         default_config = 0; /* --no-options */
769       else if (pargs.r_opt == oHomedir)
770         opt.homedir = pargs.r.ret_str;
771       else if (pargs.r_opt == aCallProtectTool)
772         break; /* This break makes sure that --version and --help are
773                   passed to the protect-tool. */
774     }
775   
776   
777   /* initialize the secure memory. */
778   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
779   maybe_setuid = 0;
780
781   /* 
782      Now we are now working under our real uid 
783   */
784
785   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
786
787   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
788   assuan_set_assuan_log_stream (log_get_stream ());
789   assuan_set_assuan_log_prefix (log_get_prefix (NULL));
790
791   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
792
793   /* Setup a default control structure for command line mode */
794   memset (&ctrl, 0, sizeof ctrl);
795   gpgsm_init_default_ctrl (&ctrl);
796   ctrl.no_server = 1;
797   ctrl.status_fd = -1; /* not status output */
798   ctrl.autodetect_encoding = 1;
799
800   /* set the default option file */
801   if (default_config )
802     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
803   /* cet the default policy file */
804   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
805   
806   argc        = orig_argc;
807   argv        = orig_argv;
808   pargs.argc  = &argc;
809   pargs.argv  = &argv;
810   pargs.flags =  1;  /* do not remove the args */
811
812  next_pass:
813   if (configname) {
814     configlineno = 0;
815     configfp = fopen (configname, "r");
816     if (!configfp)
817       {
818         if (default_config)
819           {
820             if (parse_debug)
821               log_info (_("NOTE: no default option file `%s'\n"), configname);
822           }
823         else 
824           {
825             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
826             gpgsm_exit(2);
827           }
828         xfree(configname);
829         configname = NULL;
830       }
831     if (parse_debug && configname)
832       log_info (_("reading options from `%s'\n"), configname);
833     default_config = 0;
834   }
835
836   while (!no_more_options 
837          && optfile_parse (configfp, configname, &configlineno, &pargs, opts))
838     {
839       switch (pargs.r_opt)
840         {
841         case aGPGConfList: 
842           set_cmd (&cmd, pargs.r_opt);
843           do_not_setup_keys = 1;
844           nogreeting = 1;
845           break;
846
847         case aServer: 
848           opt.batch = 1;
849           set_cmd (&cmd, aServer);
850           break;
851
852         case aCallDirmngr:
853           opt.batch = 1;
854           set_cmd (&cmd, aCallDirmngr);
855           do_not_setup_keys = 1;
856           break;
857
858         case aCallProtectTool:
859           opt.batch = 1;
860           set_cmd (&cmd, aCallProtectTool);
861           no_more_options = 1; /* Stop parsing. */
862           do_not_setup_keys = 1;
863           break;
864         
865         case aDeleteKey:
866           set_cmd (&cmd, aDeleteKey);
867           /*greeting=1;*/
868           do_not_setup_keys = 1;
869           break;
870
871         case aDetachedSign:
872           detached_sig = 1;
873           set_cmd (&cmd, aSign ); 
874           break;
875
876         case aKeygen:
877           set_cmd (&cmd, aKeygen);
878           greeting=1; 
879           do_not_setup_keys = 1;
880           break;
881
882         case aCheckKeys:
883         case aImport: 
884         case aSendKeys: 
885         case aRecvKeys: 
886         case aExport: 
887         case aExportSecretKeyP12: 
888         case aDumpKeys:
889         case aDumpExternalKeys: 
890         case aDumpSecretKeys: 
891         case aListKeys:
892         case aListExternalKeys: 
893         case aListSecretKeys: 
894         case aListSigs: 
895         case aLearnCard: 
896         case aPasswd: 
897           do_not_setup_keys = 1;
898           set_cmd (&cmd, pargs.r_opt);
899           break;
900
901         case aSym:
902         case aDecrypt: 
903         case aEncr: 
904         case aSign: 
905         case aClearsign: 
906         case aVerify: 
907           set_cmd (&cmd, pargs.r_opt);
908           break;
909
910           /* output encoding selection */
911         case oArmor:
912           ctrl.create_pem = 1;
913           break;
914         case oBase64: 
915           ctrl.create_pem = 0;
916           ctrl.create_base64 = 1;
917           break;
918         case oNoArmor: 
919           ctrl.create_pem = 0;
920           ctrl.create_base64 = 0;
921           break;
922           
923           /* Input encoding selection */
924         case oAssumeArmor:
925           ctrl.autodetect_encoding = 0;
926           ctrl.is_pem = 1;
927           ctrl.is_base64 = 0;
928           break;
929         case oAssumeBase64:
930           ctrl.autodetect_encoding = 0;
931           ctrl.is_pem = 0;
932           ctrl.is_base64 = 1;
933           break;
934         case oAssumeBinary:
935           ctrl.autodetect_encoding = 0;
936           ctrl.is_pem = 0;
937           ctrl.is_base64 = 0;
938           break;
939
940         case oDisableCRLChecks:
941           opt.no_crl_check = 1;
942           break;
943         case oEnableCRLChecks:
944           opt.no_crl_check = 0;
945           break;
946         case oForceCRLRefresh:
947           opt.force_crl_refresh = 1;
948           break;
949
950         case oDisableOCSP:
951           ctrl.use_ocsp = opt.enable_ocsp = 0;
952           break;
953         case oEnableOCSP:
954           ctrl.use_ocsp = opt.enable_ocsp = 1;
955           break;
956
957         case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
958
959         case oPolicyFile:
960           xfree (opt.policy_file);
961           if (*pargs.r.ret_str)
962             opt.policy_file = xstrdup (pargs.r.ret_str);
963           else
964             opt.policy_file = NULL;
965           break;
966
967         case oDisablePolicyChecks:
968           opt.no_policy_check = 1;
969           break;
970         case oEnablePolicyChecks:
971           opt.no_policy_check = 0;
972           break;
973           
974         case oAutoIssuerKeyRetrieve:
975           opt.auto_issuer_key_retrieve = 1;
976           break;
977
978         case oOutput: opt.outfile = pargs.r.ret_str; break;
979
980         
981         case oQuiet: opt.quiet = 1; break;
982         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
983         case oDryRun: opt.dry_run = 1; break;
984
985         case oVerbose:
986           opt.verbose++;
987           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
988           break;
989         case oNoVerbose:
990           opt.verbose = 0;
991           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
992           break;
993
994         case oLogFile: logfile = pargs.r.ret_str; break;
995           
996         case oBatch: 
997           opt.batch = 1;
998           greeting = 0;
999           break;
1000         case oNoBatch: opt.batch = 0; break;
1001           
1002         case oAnswerYes: opt.answer_yes = 1; break;
1003         case oAnswerNo: opt.answer_no = 1; break;
1004
1005         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
1006
1007         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
1008         case oDebugAll: opt.debug = ~0; break;
1009         case oDebugLevel: debug_level = pargs.r.ret_str; break;
1010         case oDebugWait: debug_wait = pargs.r.ret_int; break;
1011         case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
1012         case oDebugIgnoreExpiration: opt.ignore_expiration = 1; break;
1013
1014         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
1015         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
1016         case oWithMD5Fingerprint:
1017           opt.with_md5_fingerprint=1; /*fall thru*/
1018         case oWithFingerprint:
1019           with_fpr=1; /*fall thru*/
1020         case oFingerprint:
1021           opt.fingerprint++;
1022           break;
1023
1024         case oOptions:
1025           /* config files may not be nested (silently ignore them) */
1026           if (!configfp)
1027             {
1028               xfree(configname);
1029               configname = xstrdup (pargs.r.ret_str);
1030               goto next_pass;
1031             }
1032           break;
1033         case oNoOptions: break; /* no-options */
1034         case oHomedir: opt.homedir = pargs.r.ret_str; break;
1035         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
1036         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
1037         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
1038         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
1039         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
1040         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
1041         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
1042         case oProtectToolProgram:
1043           opt.protect_tool_program = pargs.r.ret_str; 
1044           break;
1045           
1046         case oFakedSystemTime:
1047           gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
1048           break;
1049
1050         case oNoDefKeyring: default_keyring = 0; break;
1051         case oNoGreeting: nogreeting = 1; break;
1052
1053         case oDefaultKey:
1054           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
1055           break;
1056         case oDefRecipient:
1057           if (*pargs.r.ret_str)
1058             opt.def_recipient = xstrdup (pargs.r.ret_str);
1059           break;
1060         case oDefRecipientSelf:
1061           xfree (opt.def_recipient);
1062           opt.def_recipient = NULL;
1063           opt.def_recipient_self = 1;
1064           break;
1065         case oNoDefRecipient:
1066           xfree (opt.def_recipient);
1067           opt.def_recipient = NULL;
1068           opt.def_recipient_self = 0;
1069           break;
1070
1071         case oWithKeyData: opt.with_key_data=1; /* fall thru */
1072         case oWithColons: ctrl.with_colons = 1; break;
1073         case oWithValidation: ctrl.with_validation=1; break;
1074
1075         case oSkipVerify: opt.skip_verify=1; break;
1076
1077         case oNoEncryptTo: opt.no_encrypt_to = 1; break;
1078         case oEncryptTo: /* Store the recipient in the second list */
1079           sl = add_to_strlist (&remusr, pargs.r.ret_str);
1080           sl->flags = 1;
1081           break;
1082
1083         case oRecipient: /* store the recipient */
1084           add_to_strlist ( &remusr, pargs.r.ret_str);
1085           break;
1086
1087         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
1088         case oTextmode: /*fixme:opt.textmode=1;*/  break;
1089
1090         case oUser: /* store the local users, the first one is the default */
1091           if (!opt.local_user)
1092             opt.local_user = pargs.r.ret_str;
1093           add_to_strlist (&locusr, pargs.r.ret_str);
1094           break;
1095
1096         case oNoSecmemWarn:
1097           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
1098           break;
1099
1100         case oCipherAlgo:
1101           opt.def_cipher_algoid = pargs.r.ret_str;
1102           break;
1103
1104         case oDisableCipherAlgo: 
1105           {
1106             int algo = gcry_cipher_map_name (pargs.r.ret_str);
1107             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
1108           }
1109           break;
1110         case oDisablePubkeyAlgo: 
1111           {
1112             int algo = gcry_pk_map_name (pargs.r.ret_str);
1113             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
1114           }
1115           break;
1116
1117         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
1118         case oNoRandomSeedFile: use_random_seed = 0; break;
1119
1120         case oEnableSpecialFilenames: allow_special_filenames =1; break;
1121           
1122
1123         case aDummy:
1124           break;
1125         default: 
1126           pargs.err = configfp? 1:2; 
1127           break;
1128         }
1129     }
1130
1131   if (configfp)
1132     {
1133       fclose (configfp);
1134       configfp = NULL;
1135       /* Keep a copy of the config filename. */
1136       config_filename = configname;
1137       configname = NULL;
1138       goto next_pass;
1139     }
1140   
1141   xfree (configname);
1142   configname = NULL;
1143
1144   if (log_get_errorcount(0))
1145     gpgsm_exit(2);
1146   
1147   if (nogreeting)
1148     greeting = 0;
1149   
1150   if (greeting)
1151     {
1152       fprintf(stderr, "%s %s; %s\n",
1153               strusage(11), strusage(13), strusage(14) );
1154       fprintf(stderr, "%s\n", strusage(15) );
1155     }
1156 #  ifdef IS_DEVELOPMENT_VERSION
1157   if (!opt.batch)
1158     {
1159       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
1160       log_info ("It is only intended for test purposes and should NOT be\n");
1161       log_info ("used in a production environment or with production keys!\n");
1162     }
1163 #  endif
1164
1165   if (may_coredump && !opt.quiet)
1166     log_info (_("WARNING: program may create a core file!\n"));
1167
1168   if (logfile && cmd == aServer)
1169     {
1170       log_set_file (logfile);
1171       log_set_prefix (NULL, 1|2|4);
1172     }
1173
1174   if (gnupg_faked_time_p ())
1175     {
1176       gnupg_isotime_t tbuf;
1177
1178       log_info (_("WARNING: running with faked system time: "));
1179       gnupg_get_isotime (tbuf);
1180       gpgsm_dump_time (tbuf);
1181       log_printf ("\n");
1182     }
1183   
1184 /*FIXME    if (opt.batch) */
1185 /*      tty_batchmode (1); */
1186
1187   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
1188
1189   set_debug (debug_level);
1190
1191   /* FIXME: should set filenames of libgcrypt explicitly
1192    * gpg_opt_homedir = opt.homedir; */
1193
1194   /* must do this after dropping setuid, because the mapping functions
1195      may try to load an module and we may have disabled an algorithm */
1196   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
1197        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
1198     log_error (_("selected cipher algorithm is invalid\n"));
1199
1200   if (def_digest_string)
1201     {
1202       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
1203       xfree (def_digest_string);
1204       def_digest_string = NULL;
1205       if (our_md_test_algo(opt.def_digest_algo) )
1206         log_error (_("selected digest algorithm is invalid\n"));
1207     }
1208
1209   if (log_get_errorcount(0))
1210     gpgsm_exit(2);
1211   
1212   /* set the random seed file */
1213   if (use_random_seed) {
1214     char *p = make_filename (opt.homedir, "random_seed", NULL);
1215     gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
1216     xfree(p);
1217   }
1218
1219
1220   if (!cmd && opt.fingerprint && !with_fpr)
1221     set_cmd (&cmd, aListKeys);
1222   
1223   if (!nrings && default_keyring)  /* add default keybox */
1224     keydb_add_resource ("pubring.kbx", 0, 0);
1225   for (sl = nrings; sl; sl = sl->next)
1226     keydb_add_resource (sl->d, 0, 0);
1227   FREE_STRLIST(nrings);
1228
1229   if (!do_not_setup_keys)
1230     {
1231       for (sl = locusr; sl ; sl = sl->next)
1232         {
1233           int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist, 0);
1234           if (rc)
1235             {
1236               log_error (_("can't sign using `%s': %s\n"),
1237                          sl->d, gpg_strerror (rc));
1238               gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1239                          gpg_err_code (rc) == -1?                      "1":
1240                          gpg_err_code (rc) == GPG_ERR_NO_PUBKEY?       "1":
1241                          gpg_err_code (rc) == GPG_ERR_AMBIGUOUS_NAME?  "2":
1242                          gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE? "3":
1243                          gpg_err_code (rc) == GPG_ERR_CERT_REVOKED?    "4":
1244                          gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED?    "5":
1245                          gpg_err_code (rc) == GPG_ERR_NO_CRL_KNOWN?    "6":
1246                          gpg_err_code (rc) == GPG_ERR_CRL_TOO_OLD?     "7":
1247                          gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH? "8":
1248                          gpg_err_code (rc) == GPG_ERR_NO_SECKEY?       "9":
1249                          "0",
1250                          sl->d, NULL);
1251             }
1252         }
1253       
1254       /* Build the recipient list.  We first add the regular ones and then
1255          the encrypt-to ones because the underlying function will silenty
1256          ignore duplicates and we can't allow to keep a duplicate which is
1257          flagged as encrypt-to as the actually encrypt function would then
1258          complain about no (regular) recipients. */
1259       for (sl = remusr; sl; sl = sl->next)
1260         if (!(sl->flags & 1))
1261           do_add_recipient (&ctrl, sl->d, &recplist, 0);
1262       if (!opt.no_encrypt_to)
1263         {
1264           for (sl = remusr; sl; sl = sl->next)
1265             if ((sl->flags & 1))
1266               do_add_recipient (&ctrl, sl->d, &recplist, 1);
1267         }
1268     }
1269
1270   if (log_get_errorcount(0))
1271     gpgsm_exit(1); /* must stop for invalid recipients */
1272   
1273   fname = argc? *argv : NULL;
1274   
1275   switch (cmd)
1276     {
1277     case aGPGConfList: 
1278       { /* List options and default values in the GPG Conf format.  */
1279
1280         /* The following list is taken from gnupg/tools/gpgconf-comp.c.  */
1281         /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
1282            FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
1283 #define GC_OPT_FLAG_NONE        0UL
1284         /* The RUNTIME flag for an option indicates that the option can be
1285            changed at runtime.  */
1286 #define GC_OPT_FLAG_RUNTIME     (1UL << 3)
1287         /* The DEFAULT flag for an option indicates that the option has a
1288            default value.  */
1289 #define GC_OPT_FLAG_DEFAULT     (1UL << 4)
1290         /* The DEF_DESC flag for an option indicates that the option has a
1291            default, which is described by the value of the default field.  */
1292 #define GC_OPT_FLAG_DEF_DESC    (1UL << 5)
1293         /* The NO_ARG_DESC flag for an option indicates that the argument has
1294            a default, which is described by the value of the ARGDEF field.  */
1295 #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
1296
1297         printf ("gpgconf-gpgsm.conf:%lu:\"%s\n",
1298                 GC_OPT_FLAG_DEFAULT,
1299                 config_filename?config_filename:"/dev/null");
1300         
1301         printf ("verbose:%lu:\n"
1302                 "quiet:%lu:\n"
1303                 "debug-level:%lu:\"none:\n"
1304                 "log-file:%lu:\n",
1305                 GC_OPT_FLAG_NONE,
1306                 GC_OPT_FLAG_NONE,
1307                 GC_OPT_FLAG_DEFAULT,
1308                 GC_OPT_FLAG_NONE );
1309         printf ("disable-crl-checks:%lu:\n",
1310                 GC_OPT_FLAG_NONE );
1311         printf ("enable-ocsp:%lu:\n",
1312                 GC_OPT_FLAG_NONE );
1313         printf ("include-certs:%lu:1:\n",
1314                 GC_OPT_FLAG_DEFAULT );
1315         printf ("disable-policy-checks:%lu:\n",
1316                 GC_OPT_FLAG_NONE );
1317         printf ("auto-issuer-key-retrieve:%lu:\n",
1318                 GC_OPT_FLAG_NONE );
1319
1320       }
1321       break;
1322
1323     case aServer:
1324       if (debug_wait)
1325         {
1326           log_debug ("waiting for debugger - my pid is %u .....\n",
1327                      (unsigned int)getpid());
1328           sleep (debug_wait);
1329           log_debug ("... okay\n");
1330          }
1331       gpgsm_server (recplist);
1332       break;
1333
1334     case aCallDirmngr:
1335       if (!argc)
1336         wrong_args ("--call-dirmngr <command> {args}");
1337       else
1338         if (gpgsm_dirmngr_run_command (&ctrl, *argv, argc-1, argv+1))
1339           gpgsm_exit (1);
1340       break;
1341
1342     case aCallProtectTool:
1343       run_protect_tool (argc, argv);
1344       break;
1345
1346     case aEncr: /* encrypt the given file */
1347       if (!argc)
1348         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1349       else if (argc == 1)
1350         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1351       else
1352         wrong_args ("--encrypt [datafile]");
1353       break;
1354
1355     case aSign: /* sign the given file */
1356       /* FIXME: We don't handle --output yet. We should also allow
1357          to concatenate multiple files for signing because that is
1358          what gpg does.*/
1359       if (!argc)
1360         gpgsm_sign (&ctrl, signerlist,
1361                     0, detached_sig, stdout); /* create from stdin */
1362       else if (argc == 1)
1363         gpgsm_sign (&ctrl, signerlist,
1364                     open_read (*argv), detached_sig, stdout); /* from file */
1365       else
1366         wrong_args ("--sign [datafile]");
1367       break;
1368         
1369     case aSignEncr: /* sign and encrypt the given file */
1370       log_error ("this command has not yet been implemented\n");
1371       break;
1372
1373     case aClearsign: /* make a clearsig */
1374       log_error ("this command has not yet been implemented\n");
1375       break;
1376
1377     case aVerify:
1378       {
1379         FILE *fp = NULL;
1380
1381         if (argc == 2 && opt.outfile)
1382           log_info ("option --output ignored for a detached signature\n");
1383         else if (opt.outfile)
1384           fp = open_fwrite (opt.outfile);
1385
1386         if (!argc)
1387           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1388         else if (argc == 1)
1389           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1390         else if (argc == 2) /* detached signature (sig, detached) */
1391           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1392         else
1393           wrong_args ("--verify [signature [detached_data]]");
1394
1395         if (fp && fp != stdout)
1396           fclose (fp);
1397       }
1398       break;
1399
1400     case aVerifyFiles:
1401       log_error (_("this command has not yet been implemented\n"));
1402       break;
1403
1404     case aDecrypt:
1405       if (!argc)
1406         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1407       else if (argc == 1)
1408         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1409       else
1410         wrong_args ("--decrypt [filename]");
1411       break;
1412
1413     case aDeleteKey:
1414       for (sl=NULL; argc; argc--, argv++)
1415         add_to_strlist (&sl, *argv);
1416       gpgsm_delete (&ctrl, sl);
1417       free_strlist(sl);
1418       break;
1419
1420     case aListSigs:
1421       ctrl.with_chain = 1;
1422     case aListKeys:
1423       for (sl=NULL; argc; argc--, argv++)
1424         add_to_strlist (&sl, *argv);
1425       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1426       free_strlist(sl);
1427       break;
1428
1429     case aDumpKeys:
1430       for (sl=NULL; argc; argc--, argv++)
1431         add_to_strlist (&sl, *argv);
1432       gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6)));
1433       free_strlist(sl);
1434       break;
1435
1436     case aListExternalKeys:
1437       for (sl=NULL; argc; argc--, argv++)
1438         add_to_strlist (&sl, *argv);
1439       gpgsm_list_keys (&ctrl, sl, stdout,
1440                        (0 | (1<<7)));
1441       free_strlist(sl);
1442       break;
1443
1444     case aDumpExternalKeys:
1445       for (sl=NULL; argc; argc--, argv++)
1446         add_to_strlist (&sl, *argv);
1447       gpgsm_list_keys (&ctrl, sl, stdout,
1448                        (256 | (1<<7)));
1449       free_strlist(sl);
1450       break;
1451
1452     case aListSecretKeys:
1453       for (sl=NULL; argc; argc--, argv++)
1454         add_to_strlist (&sl, *argv);
1455       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1456       free_strlist(sl);
1457       break;
1458
1459     case aDumpSecretKeys:
1460       for (sl=NULL; argc; argc--, argv++)
1461         add_to_strlist (&sl, *argv);
1462       gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6)));
1463       free_strlist(sl);
1464       break;
1465
1466     case aKeygen: /* generate a key */
1467       log_error ("this function is not yet available from the commandline\n");
1468       break;
1469
1470     case aImport:
1471       gpgsm_import_files (&ctrl, argc, argv, open_read);
1472       break;
1473
1474     case aExport:
1475       for (sl=NULL; argc; argc--, argv++)
1476         add_to_strlist (&sl, *argv);
1477       gpgsm_export (&ctrl, sl, stdout);
1478       free_strlist(sl);
1479       break;
1480
1481     case aExportSecretKeyP12:
1482       if (argc == 1)
1483         gpgsm_p12_export (&ctrl, *argv, stdout);
1484       else
1485         wrong_args ("--export-secret-key-p12 KEY-ID");
1486       break;
1487       
1488     case aSendKeys:
1489     case aRecvKeys:
1490       log_error ("this command has not yet been implemented\n");
1491       break;
1492
1493
1494     case aLearnCard:
1495       if (argc)
1496         wrong_args ("--learn-card");
1497       else
1498         {
1499           int rc = gpgsm_agent_learn ();
1500           if (rc)
1501             log_error ("error learning card: %s\n", gpg_strerror (rc));
1502         }
1503       break;
1504
1505     case aPasswd:
1506       if (argc != 1)
1507         wrong_args ("--passwd <key-Id>");
1508       else
1509         {
1510           int rc;
1511           ksba_cert_t cert = NULL;
1512           char *grip = NULL;
1513
1514           rc = gpgsm_find_cert (*argv, &cert);
1515           if (rc)
1516             ;
1517           else if (!(grip = gpgsm_get_keygrip_hexstring (cert)))
1518             rc = gpg_error (GPG_ERR_BUG);
1519           else 
1520             {
1521               char *desc = gpgsm_format_keydesc (cert);
1522               rc = gpgsm_agent_passwd (grip, desc);
1523               xfree (desc);
1524             }
1525           if (rc)
1526             log_error ("error changing passphrase: %s\n", gpg_strerror (rc));
1527           xfree (grip);
1528           ksba_cert_release (cert);
1529         }
1530       break;
1531
1532     default:
1533         log_error ("invalid command (there is no implicit command)\n");
1534         break;
1535     }
1536   
1537   /* cleanup */
1538   gpgsm_release_certlist (recplist);
1539   gpgsm_release_certlist (signerlist);
1540   FREE_STRLIST(remusr);
1541   FREE_STRLIST(locusr);
1542   gpgsm_exit(0);
1543   return 8; /*NEVER REACHED*/
1544 }
1545
1546 /* Note: This function is used by signal handlers!. */
1547 static void
1548 emergency_cleanup (void)
1549 {
1550   gcry_control (GCRYCTL_TERM_SECMEM );
1551 }
1552
1553
1554 void
1555 gpgsm_exit (int rc)
1556 {
1557   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
1558   if (opt.debug & DBG_MEMSTAT_VALUE)
1559     {
1560       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1561       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1562     }
1563   if (opt.debug)
1564     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1565   emergency_cleanup ();
1566   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1567   exit (rc);
1568 }
1569
1570
1571 void
1572 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1573 {
1574   ctrl->include_certs = 1;  /* only include the signer's cert */
1575   ctrl->use_ocsp = opt.enable_ocsp;
1576 }
1577
1578
1579
1580 /* Check whether the filename has the form "-&nnnn", where n is a
1581    non-zero number.  Returns this number or -1 if it is not the case.  */
1582 static int
1583 check_special_filename (const char *fname)
1584 {
1585   if (allow_special_filenames
1586       && fname && *fname == '-' && fname[1] == '&' ) {
1587     int i;
1588     
1589     fname += 2;
1590     for (i=0; isdigit (fname[i]); i++ )
1591       ;
1592     if ( !fname[i] ) 
1593       return atoi (fname);
1594   }
1595   return -1;
1596 }
1597
1598
1599
1600 /* Open the FILENAME for read and return the filedescriptor.  Stop
1601    with an error message in case of problems.  "-" denotes stdin and
1602    if special filenames are allowed the given fd is opened instead. */
1603 static int 
1604 open_read (const char *filename)
1605 {
1606   int fd;
1607
1608   if (filename[0] == '-' && !filename[1])
1609     return 0; /* stdin */
1610   fd = check_special_filename (filename);
1611   if (fd != -1)
1612     return fd;
1613   fd = open (filename, O_RDONLY);
1614   if (fd == -1)
1615     {
1616       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1617       gpgsm_exit (2);
1618     }
1619   return fd;
1620 }
1621
1622 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1623    message in case of problems.  "-" denotes stdout and if special
1624    filenames are allowed the given fd is opened instead. Caller must
1625    close the returned stream unless it is stdout. */
1626 static FILE *
1627 open_fwrite (const char *filename)
1628 {
1629   int fd;
1630   FILE *fp;
1631
1632   if (filename[0] == '-' && !filename[1])
1633     return stdout;
1634
1635   fd = check_special_filename (filename);
1636   if (fd != -1)
1637     {
1638       fp = fdopen (dup (fd), "wb");
1639       if (!fp)
1640         {
1641           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1642           gpgsm_exit (2);
1643         }
1644       return fp;
1645     }
1646   fp = fopen (filename, "wb");
1647   if (!fp)
1648     {
1649       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1650       gpgsm_exit (2);
1651     }
1652   return fp;
1653 }
1654
1655
1656 static void
1657 run_protect_tool (int argc, char **argv)
1658 {
1659   const char *pgm;
1660   char **av;
1661   int i;
1662
1663   if (!opt.protect_tool_program || !*opt.protect_tool_program)
1664     pgm = GNUPG_DEFAULT_PROTECT_TOOL;
1665   else
1666     pgm = opt.protect_tool_program;
1667
1668   av = xcalloc (argc+2, sizeof *av);
1669   av[0] = strrchr (pgm, '/');
1670   if (!av[0])
1671     av[0] = xstrdup (pgm);
1672   for (i=1; argc; i++, argc--, argv++)
1673     av[i] = *argv;
1674   av[i] = NULL;
1675   execv (pgm, av); 
1676   log_error ("error executing `%s': %s\n", pgm, strerror (errno));
1677   gpgsm_exit (2);
1678 }