Revert that last stupid setuid detection fix.
[gnupg.git] / g10 / gpg.c
1 /* gpg.c - The GnuPG utility (main for gpg)
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3  *               2006, 2007 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
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 <assert.h>
29 #ifdef HAVE_STAT
30 #include <sys/stat.h> /* for stat() */
31 #endif
32 #include <fcntl.h>
33 #include <assuan.h>
34 #ifdef HAVE_W32_SYSTEM
35 #include <windows.h>
36 #endif
37
38 #define INCLUDED_BY_MAIN_MODULE 1
39 #include "gpg.h"
40 #include "packet.h"
41 #include "../common/iobuf.h"
42 #include "util.h"
43 #include "main.h"
44 #include "options.h"
45 #include "keydb.h"
46 #include "trustdb.h"
47 #include "cipher.h"
48 #include "filter.h"
49 #include "ttyio.h"
50 #include "i18n.h"
51 #include "sysutils.h"
52 #include "status.h"
53 #include "keyserver-internal.h"
54 #include "exec.h"
55 #include "gc-opt-flags.h"
56
57 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
58 #define MY_O_BINARY  O_BINARY
59 #ifndef S_IRGRP
60 # define S_IRGRP 0
61 # define S_IWGRP 0
62 #endif
63 #else
64 #define MY_O_BINARY  0
65 #endif
66
67
68 enum cmd_and_opt_values
69   {
70     aNull = 0,
71     oArmor        = 'a',
72     aDetachedSign = 'b',
73     aSym          = 'c',
74     aDecrypt      = 'd',
75     aEncr         = 'e',
76     oInteractive  = 'i',
77     aListKeys     = 'k',
78     oDryRun       = 'n',
79     oOutput       = 'o',
80     oQuiet        = 'q',
81     oRecipient    = 'r',
82     oHiddenRecipient = 'R',
83     aSign         = 's',
84     oTextmodeShort= 't',
85     oLocalUser    = 'u',
86     oVerbose      = 'v',
87     oCompress     = 'z',
88     oSetNotation  = 'N',
89     aListSecretKeys = 'K',
90     oBatch        = 500,
91     oMaxOutput,
92     oSigNotation,
93     oCertNotation,
94     oShowNotation,
95     oNoShowNotation,
96     aEncrFiles,
97     aEncrSym,
98     aDecryptFiles,
99     aClearsign,
100     aStore,
101     aKeygen,
102     aSignEncr,
103     aSignEncrSym,
104     aSignSym,
105     aSignKey,
106     aLSignKey,
107     aListConfig,
108     aGPGConfList,
109     aGPGConfTest,
110     aListPackets,
111     aEditKey,
112     aDeleteKeys,
113     aDeleteSecretKeys,
114     aDeleteSecretAndPublicKeys,
115     aImport,
116     aFastImport,
117     aVerify,
118     aVerifyFiles,
119     aListSigs,
120     aSendKeys,
121     aRecvKeys,
122     aLocateKeys,
123     aSearchKeys,
124     aRefreshKeys,
125     aFetchKeys,
126     aExport,
127     aExportSecret,
128     aExportSecretSub,
129     aCheckKeys,
130     aGenRevoke,
131     aDesigRevoke,
132     aPrimegen,
133     aPrintMD,
134     aPrintMDs,
135     aCheckTrustDB,
136     aUpdateTrustDB,
137     aFixTrustDB,
138     aListTrustDB,
139     aListTrustPath,
140     aExportOwnerTrust,
141     aImportOwnerTrust,
142     aDeArmor,
143     aEnArmor,
144     aGenRandom,
145     aRebuildKeydbCaches,
146     aCardStatus,
147     aCardEdit,
148     aChangePIN,
149     aServer,
150
151     oTextmode,
152     oNoTextmode,
153     oExpert,
154     oNoExpert,
155     oDefSigExpire,
156     oAskSigExpire,
157     oNoAskSigExpire,
158     oDefCertExpire,
159     oAskCertExpire,
160     oNoAskCertExpire,
161     oDefCertLevel,
162     oMinCertLevel,
163     oAskCertLevel,
164     oNoAskCertLevel,
165     oFingerprint,
166     oWithFingerprint,
167     oAnswerYes,
168     oAnswerNo,
169     oKeyring,
170     oPrimaryKeyring,
171     oSecretKeyring,
172     oShowKeyring,
173     oDefaultKey,
174     oDefRecipient,
175     oDefRecipientSelf,
176     oNoDefRecipient,
177     oOptions,
178     oDebug,
179     oDebugLevel,
180     oDebugAll,
181     oDebugCCIDDriver,
182     oStatusFD,
183     oStatusFile,
184     oAttributeFD,
185     oAttributeFile,
186     oEmitVersion,
187     oNoEmitVersion,
188     oCompletesNeeded,
189     oMarginalsNeeded,
190     oMaxCertDepth,
191     oLoadExtension,
192     oGnuPG,
193     oRFC1991,
194     oRFC2440,
195     oRFC4880,
196     oOpenPGP,
197     oPGP2,
198     oPGP6,
199     oPGP7,
200     oPGP8,
201     oRFC2440Text,
202     oNoRFC2440Text,
203     oCipherAlgo,
204     oDigestAlgo,
205     oCertDigestAlgo,
206     oCompressAlgo,
207     oCompressLevel,
208     oBZ2CompressLevel,
209     oBZ2DecompressLowmem,
210     oPasswd,
211     oPasswdFD,
212     oPasswdFile,
213     oPasswdRepeat,
214     oCommandFD,
215     oCommandFile,
216     oQuickRandom,
217     oNoVerbose,
218     oTrustDBName,
219     oNoSecmemWarn,
220     oRequireSecmem,
221     oNoRequireSecmem,
222     oNoPermissionWarn,
223     oNoMDCWarn,
224     oNoArmor,
225     oNoDefKeyring,
226     oNoGreeting,
227     oNoTTY,
228     oNoOptions,
229     oNoBatch,
230     oHomedir,
231     oWithColons,
232     oWithKeyData,
233     oWithSigList,
234     oWithSigCheck,
235     oSkipVerify,
236     oCompressKeys,
237     oCompressSigs,
238     oAlwaysTrust,
239     oTrustModel,
240     oForceOwnertrust,
241     oSetFilename,
242     oForYourEyesOnly,
243     oNoForYourEyesOnly,
244     oSetPolicyURL,
245     oSigPolicyURL,
246     oCertPolicyURL,
247     oShowPolicyURL,
248     oNoShowPolicyURL,
249     oSigKeyserverURL,
250     oUseEmbeddedFilename,
251     oNoUseEmbeddedFilename,
252     oComment,
253     oDefaultComment,
254     oNoComments,
255     oThrowKeyids,
256     oNoThrowKeyids,
257     oShowPhotos,
258     oNoShowPhotos,
259     oPhotoViewer,
260     oForceV3Sigs,
261     oNoForceV3Sigs,
262     oForceV4Certs,
263     oNoForceV4Certs,
264     oForceMDC,
265     oNoForceMDC,
266     oDisableMDC,
267     oNoDisableMDC,
268     oS2KMode,
269     oS2KDigest,
270     oS2KCipher,
271     oS2KCount,
272     oSimpleSKChecksum,                          
273     oDisplayCharset,
274     oNotDashEscaped,
275     oEscapeFrom,
276     oNoEscapeFrom,
277     oLockOnce,
278     oLockMultiple,
279     oLockNever,
280     oKeyServer,
281     oKeyServerOptions,
282     oImportOptions,
283     oExportOptions,
284     oListOptions,
285     oVerifyOptions,
286     oTempDir,
287     oExecPath,
288     oEncryptTo,
289     oHiddenEncryptTo,
290     oNoEncryptTo,
291     oLoggerFD,
292     oLoggerFile,
293     oUtf8Strings,
294     oNoUtf8Strings,
295     oDisableCipherAlgo,
296     oDisablePubkeyAlgo,
297     oAllowNonSelfsignedUID,
298     oNoAllowNonSelfsignedUID,
299     oAllowFreeformUID,
300     oNoAllowFreeformUID,
301     oAllowSecretKeyImport,                      
302     oEnableSpecialFilenames,
303     oNoLiteral,
304     oSetFilesize,
305     oHonorHttpProxy,
306     oFastListMode,
307     oListOnly,
308     oIgnoreTimeConflict,
309     oIgnoreValidFrom,
310     oIgnoreCrcError,
311     oIgnoreMDCError,
312     oShowSessionKey,
313     oOverrideSessionKey,
314     oNoRandomSeedFile,
315     oAutoKeyRetrieve,
316     oNoAutoKeyRetrieve,
317     oUseAgent,
318     oNoUseAgent,
319     oGpgAgentInfo,
320     oMergeOnly,
321     oTryAllSecrets,
322     oTrustedKey,
323     oNoExpensiveTrustChecks,
324     oFixedListMode,
325     oNoSigCache,
326     oNoSigCreateCheck,
327     oAutoCheckTrustDB,
328     oNoAutoCheckTrustDB,
329     oPreservePermissions,
330     oDefaultPreferenceList,
331     oDefaultKeyserverURL,
332     oPersonalCipherPreferences,
333     oPersonalDigestPreferences,
334     oPersonalCompressPreferences,
335     oAgentProgram,
336     oDisplay,
337     oTTYname,
338     oTTYtype,
339     oLCctype,
340     oLCmessages,
341     oXauthority,
342     oGroup,
343     oUnGroup,
344     oNoGroups,
345     oStrict,
346     oNoStrict,
347     oMangleDosFilenames,
348     oNoMangleDosFilenames,
349     oEnableProgressFilter,
350     oMultifile,
351     oKeyidFormat,
352     oExitOnStatusWriteError,
353     oLimitCardInsertTries,
354     oRequireCrossCert,
355     oNoRequireCrossCert,
356     oAutoKeyLocate,
357     oNoAutoKeyLocate,
358     oAllowMultisigVerification,
359     oEnableDSA2,
360     oDisableDSA2,
361     oAllowMultipleMessages,
362     oNoAllowMultipleMessages,
363
364     oNoop
365   };
366
367
368 static ARGPARSE_OPTS opts[] = {
369
370     { 300, NULL, 0, N_("@Commands:\n ") },
371
372     { aSign, "sign",      256, N_("|[file]|make a signature")},
373     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature")},
374     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
375     { aEncr, "encrypt",   256, N_("encrypt data")},
376     { aEncrFiles, "encrypt-files", 256, "@"},
377     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
378     { aStore, "store",     256, "@"},
379     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
380     { aDecryptFiles, "decrypt-files", 256, "@"},
381     { aVerify, "verify"   , 256, N_("verify a signature")},
382     { aVerifyFiles, "verify-files" , 256, "@" },
383     { aListKeys, "list-keys", 256, N_("list keys")},
384     { aListKeys, "list-public-keys", 256, "@" },
385     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
386     { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
387     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
388     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
389     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
390     { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")},
391     { aDeleteSecretKeys, "delete-secret-keys",256,
392                                     N_("remove keys from the secret keyring")},
393     { aSignKey,  "sign-key"   ,256, N_("sign a key")},
394     { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
395     { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
396     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
397     { aDesigRevoke, "desig-revoke",256, "@" },
398     { aExport, "export"           , 256, N_("export keys") },
399     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
400     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
401     { aSearchKeys, "search-keys" , 256,
402                                     N_("search for keys on a key server") },
403     { aRefreshKeys, "refresh-keys", 256,
404                                     N_("update all keys from a keyserver")},
405     { aLocateKeys, "locate-keys", 256, "@"},
406     { aFetchKeys, "fetch-keys" , 256, "@" },
407     { aExportSecret, "export-secret-keys" , 256, "@" },
408     { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
409     { aImport, "import",      256     , N_("import/merge keys")},
410     { aFastImport, "fast-import",  256 , "@"},
411 #ifdef ENABLE_CARD_SUPPORT
412     { aCardStatus,  "card-status", 256, N_("print the card status")},
413     { aCardEdit,   "card-edit",  256, N_("change data on a card")},
414     { aChangePIN,  "change-pin", 256, N_("change a card's PIN")},
415 #endif
416     { aListConfig, "list-config", 256, "@"},
417     { aGPGConfList, "gpgconf-list", 256, "@" },
418     { aGPGConfTest, "gpgconf-test", 256, "@" },
419     { aListPackets, "list-packets",256, "@"},
420     { aExportOwnerTrust, "export-ownertrust", 256, "@"},
421     { aImportOwnerTrust, "import-ownertrust", 256, "@"},
422     { aUpdateTrustDB,
423               "update-trustdb",0 , N_("update the trust database")},
424     { aCheckTrustDB, "check-trustdb", 0, "@"},
425     { aFixTrustDB, "fix-trustdb", 0, "@"},
426     { aDeArmor, "dearmor", 256, "@"},
427     { aDeArmor, "dearmour", 256, "@"},
428     { aEnArmor, "enarmor", 256, "@"},
429     { aEnArmor, "enarmour", 256, "@"},
430     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
431     { aPrimegen, "gen-prime" , 256, "@" },
432     { aGenRandom, "gen-random", 256, "@" },
433     { aServer,   "server",      256, N_("run in server mode")},
434
435     { 301, NULL, 0, N_("@\nOptions:\n ") },
436
437     { oArmor, "armor",     0, N_("create ascii armored output")},
438     { oArmor, "armour",     0, "@" },
439     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
440     { oHiddenRecipient, "hidden-recipient", 2, "@" },
441     { oRecipient, "remote-user", 2, "@"},  /* old option name */
442     { oDefRecipient, "default-recipient", 2, "@"},
443     { oDefRecipientSelf, "default-recipient-self", 0, "@"},
444     { oNoDefRecipient, "no-default-recipient", 0, "@" },
445     { oTempDir, "temp-directory", 2, "@" },
446     { oExecPath, "exec-path", 2, "@" },
447     { oEncryptTo, "encrypt-to", 2, "@" },
448     { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
449     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
450     { oLocalUser, "local-user",2, N_("use this user-id to sign or decrypt")},
451     { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
452     { oCompressLevel, "compress-level", 1, "@" },
453     { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
454     { oBZ2DecompressLowmem, "bzip2-decompress-lowmem", 0, "@" },
455     { oTextmodeShort, NULL,   0, "@"},
456     { oTextmode, "textmode",  0, N_("use canonical text mode")},
457     { oNoTextmode, "no-textmode",  0, "@"},
458     { oExpert, "expert",   0, "@"},
459     { oNoExpert, "no-expert",   0, "@"},
460     { oDefSigExpire, "default-sig-expire", 2, "@"},
461     { oAskSigExpire, "ask-sig-expire",   0, "@"},
462     { oNoAskSigExpire, "no-ask-sig-expire",   0, "@"},
463     { oDefCertExpire, "default-cert-expire", 2, "@"},
464     { oAskCertExpire, "ask-cert-expire",   0, "@"},
465     { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
466     { oDefCertLevel, "default-cert-level", 1, "@"},
467     { oMinCertLevel, "min-cert-level", 1, "@"},
468     { oAskCertLevel, "ask-cert-level",   0, "@"},
469     { oNoAskCertLevel, "no-ask-cert-level",   0, "@"},
470     { oOutput, "output",    2, N_("|FILE|write output to FILE")},
471     { oMaxOutput, "max-output", 16|4, "@" },
472     { oVerbose, "verbose",   0, N_("verbose") },
473     { oQuiet,   "quiet",   0, "@"},
474     { oNoTTY, "no-tty", 0, "@"},
475     { oForceV3Sigs, "force-v3-sigs", 0, "@"},
476     { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@"},
477     { oForceV4Certs, "force-v4-certs", 0, "@"},
478     { oNoForceV4Certs, "no-force-v4-certs", 0, "@"},
479     { oForceMDC, "force-mdc", 0, "@"},
480     { oNoForceMDC, "no-force-mdc", 0, "@" },
481     { oDisableMDC, "disable-mdc", 0, "@"},
482     { oNoDisableMDC, "no-disable-mdc", 0, "@" },
483     { oDryRun, "dry-run",   0, N_("do not make any changes") },
484     { oInteractive, "interactive", 0, N_("prompt before overwriting") },
485     { oUseAgent, "use-agent",0, "@"},
486     { oNoUseAgent, "no-use-agent",0, "@"},
487     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
488     { oBatch, "batch", 0, "@"},
489     { oAnswerYes, "yes", 0, "@"},
490     { oAnswerNo, "no", 0, "@"},
491     { oKeyring, "keyring", 2, "@"},
492     { oPrimaryKeyring, "primary-keyring",2, "@" },
493     { oSecretKeyring, "secret-keyring", 2, "@"},
494     { oShowKeyring, "show-keyring", 0, "@"},
495     { oDefaultKey, "default-key", 2, "@"},
496     { oKeyServer, "keyserver", 2, "@"},
497     { oKeyServerOptions, "keyserver-options",2,"@"},
498     { oImportOptions, "import-options",2,"@"},
499     { oExportOptions, "export-options",2,"@"},
500     { oListOptions, "list-options",2,"@"},
501     { oVerifyOptions, "verify-options",2,"@"},
502     { oDisplayCharset, "display-charset", 2, "@"},
503     { oDisplayCharset, "charset", 2, "@"},
504     { oOptions, "options", 2, "@"},
505     { oDebug, "debug"     ,4|16, "@"},
506     { oDebugLevel, "debug-level" ,2, "@"},
507     { oDebugAll, "debug-all" ,0, "@"},
508     { oStatusFD, "status-fd" ,1, "@"},
509     { oStatusFile, "status-file" ,2, "@"},
510     { oAttributeFD, "attribute-fd" ,1, "@" },
511     { oAttributeFile, "attribute-file" ,2, "@" },
512     { oNoop, "sk-comments", 0,   "@"},
513     { oNoop, "no-sk-comments", 0,   "@"},
514     { oCompletesNeeded, "completes-needed", 1, "@"},
515     { oMarginalsNeeded, "marginals-needed", 1, "@"},
516     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
517     { oTrustedKey, "trusted-key", 2, "@"},
518     { oLoadExtension, "load-extension", 2, "@"},
519     { oGnuPG, "gnupg",   0, "@"},
520     { oGnuPG, "no-pgp2", 0, "@"},
521     { oGnuPG, "no-pgp6", 0, "@"},
522     { oGnuPG, "no-pgp7", 0, "@"},
523     { oGnuPG, "no-pgp8", 0, "@"},
524     { oRFC1991, "rfc1991",   0, "@"},
525     { oRFC2440, "rfc2440", 0, "@" },
526     { oRFC4880, "rfc4880", 0, "@" },
527     { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
528     { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
529     { oPGP6, "pgp6", 0, "@"},
530     { oPGP7, "pgp7", 0, "@"},
531     { oPGP8, "pgp8", 0, "@"},
532     { oRFC2440Text, "rfc2440-text", 0, "@"},
533     { oNoRFC2440Text, "no-rfc2440-text", 0, "@"},
534     { oS2KMode, "s2k-mode", 1, "@"},
535     { oS2KDigest, "s2k-digest-algo", 2, "@"},
536     { oS2KCipher, "s2k-cipher-algo", 2, "@"},
537     { oS2KCount, "s2k-count", 1, "@"},
538     { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
539     { oCipherAlgo, "cipher-algo", 2, "@"},
540     { oDigestAlgo, "digest-algo", 2, "@"},
541     { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
542     { oCompressAlgo,"compress-algo", 2, "@"},
543     { oCompressAlgo, "compression-algo", 2, "@"}, /* Alias */
544     { oThrowKeyids, "throw-keyid", 0, "@"},
545     { oThrowKeyids, "throw-keyids", 0, "@"},
546     { oNoThrowKeyids, "no-throw-keyid", 0, "@" },
547     { oNoThrowKeyids, "no-throw-keyids", 0, "@" },
548     { oShowPhotos,   "show-photos", 0, "@" },
549     { oNoShowPhotos, "no-show-photos", 0, "@" },
550     { oPhotoViewer,  "photo-viewer", 2, "@" },
551     { oSetNotation,  "set-notation", 2, "@" },
552     { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
553     { oSigNotation,  "sig-notation", 2, "@" },
554     { oCertNotation, "cert-notation", 2, "@" },
555
556     { 302, NULL, 0, N_(
557   "@\n(See the man page for a complete listing of all commands and options)\n"
558                       )},
559
560     { 303, NULL, 0, N_("@\nExamples:\n\n"
561     " -se -r Bob [file]          sign and encrypt for user Bob\n"
562     " --clearsign [file]         make a clear text signature\n"
563     " --detach-sign [file]       make a detached signature\n"
564     " --list-keys [names]        show keys\n"
565     " --fingerprint [names]      show fingerprints\n"  ) },
566
567   /* hidden options */
568     { aPrintMDs, "print-mds" , 256, "@"}, /* old */
569     { aListTrustDB, "list-trustdb",0 , "@"},
570     /* Not yet used */
571     /* { aListTrustPath, "list-trust-path",0, "@"}, */
572     { oPasswd, "passphrase",2, "@" },
573     { oPasswdFD, "passphrase-fd",1, "@" },
574     { oPasswdFile, "passphrase-file",2, "@" },
575     { oPasswdRepeat, "passphrase-repeat", 1, "@"},
576     { oCommandFD, "command-fd",1, "@" },
577     { oCommandFile, "command-file",2, "@" },
578     { oQuickRandom, "debug-quick-random", 0, "@"},
579     { oNoVerbose, "no-verbose", 0, "@"},
580     { oTrustDBName, "trustdb-name", 2, "@" },
581     { oNoSecmemWarn, "no-secmem-warning", 0, "@" },
582     { oRequireSecmem,"require-secmem", 0, "@" },
583     { oNoRequireSecmem,"no-require-secmem", 0, "@" },
584     { oNoPermissionWarn, "no-permission-warning", 0, "@" },
585     { oNoMDCWarn, "no-mdc-warning", 0, "@" },
586     { oNoArmor, "no-armor",   0, "@"},
587     { oNoArmor, "no-armour",   0, "@"},
588     { oNoDefKeyring, "no-default-keyring", 0, "@" },
589     { oNoGreeting, "no-greeting", 0, "@" },
590     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
591     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
592     { oNoBatch, "no-batch", 0, "@" },
593     { oWithColons, "with-colons", 0, "@"},
594     { oWithKeyData,"with-key-data", 0, "@"},
595     { oWithSigList,"with-sig-list", 0, "@"},
596     { oWithSigCheck,"with-sig-check", 0, "@"},
597     { aListKeys, "list-key", 0, "@" }, /* alias */
598     { aListSigs, "list-sig", 0, "@" }, /* alias */
599     { aCheckKeys, "check-sig",0, "@" }, /* alias */
600     { oSkipVerify, "skip-verify",0, "@" },
601     { oCompressKeys, "compress-keys",0, "@"},
602     { oCompressSigs, "compress-sigs",0, "@"},
603     { oDefCertLevel, "default-cert-check-level", 1, "@"}, /* Old option */
604     { oAlwaysTrust, "always-trust", 0, "@"},
605     { oTrustModel, "trust-model", 2, "@"},
606     { oForceOwnertrust, "force-ownertrust", 2, "@"},
607     { oSetFilename, "set-filename", 2, "@" },
608     { oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
609     { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
610     { oSetPolicyURL, "set-policy-url", 2, "@" },
611     { oSigPolicyURL, "sig-policy-url", 2, "@" },
612     { oCertPolicyURL, "cert-policy-url", 2, "@" },
613     { oShowPolicyURL, "show-policy-url", 0, "@" },
614     { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
615     { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
616     { oShowNotation, "show-notation", 0, "@" },
617     { oNoShowNotation, "no-show-notation", 0, "@" },
618     { oComment, "comment", 2, "@" },
619     { oDefaultComment, "default-comment", 0, "@" },
620     { oNoComments, "no-comments", 0, "@" },
621     { oEmitVersion, "emit-version", 0, "@"},
622     { oNoEmitVersion, "no-emit-version", 0, "@"},
623     { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
624     { oNotDashEscaped, "not-dash-escaped", 0, "@" },
625     { oEscapeFrom, "escape-from-lines", 0, "@" },
626     { oNoEscapeFrom, "no-escape-from-lines", 0, "@" },
627     { oLockOnce, "lock-once", 0, "@" },
628     { oLockMultiple, "lock-multiple", 0, "@" },
629     { oLockNever, "lock-never", 0, "@" },
630     { oLoggerFD, "logger-fd",1, "@" },
631     { oLoggerFile, "log-file",2, "@" },
632     { oLoggerFile, "logger-file",2, "@" },  /* For 1.4 compatibility.  */
633     { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
634     { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" },
635     { oUtf8Strings, "utf8-strings", 0, "@" },
636     { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
637     { oWithFingerprint, "with-fingerprint", 0, "@" },
638     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
639     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
640     { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
641     { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" },
642     { oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
643     { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" },
644     { oNoLiteral, "no-literal", 0, "@" },
645     { oSetFilesize, "set-filesize", 20, "@" },
646     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
647     { oFastListMode,"fast-list-mode", 0, "@" },
648     { oFixedListMode,"fixed-list-mode", 0, "@" },
649     { oListOnly, "list-only", 0, "@"},
650     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
651     { oIgnoreValidFrom,    "ignore-valid-from",    0, "@" },
652     { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
653     { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
654     { oShowSessionKey, "show-session-key", 0, "@" },
655     { oOverrideSessionKey, "override-session-key", 2, "@" },
656     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
657     { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" },
658     { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
659     { oNoSigCache,         "no-sig-cache", 0, "@" },
660     { oNoSigCreateCheck,   "no-sig-create-check", 0, "@" },
661     { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"},
662     { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
663     { oMergeOnly,         "merge-only", 0, "@" },
664     { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
665     { oTryAllSecrets,  "try-all-secrets", 0, "@" },
666     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
667     { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" },
668     { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" },
669     { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
670     { oPreservePermissions, "preserve-permissions", 0, "@"},
671     { oDefaultPreferenceList,  "default-preference-list", 2, "@"},
672     { oDefaultKeyserverURL,  "default-keyserver-url", 2, "@"},
673     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
674     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
675     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
676     /* Aliases.  I constantly mistype these, and assume other people
677        do as well. */
678     { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
679     { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
680     { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
681     { oAgentProgram, "agent-program", 2 , "@" },
682     { oDisplay,    "display",     2, "@" },
683     { oTTYname,    "ttyname",     2, "@" },
684     { oTTYtype,    "ttytype",     2, "@" },
685     { oLCctype,    "lc-ctype",    2, "@" },
686     { oLCmessages, "lc-messages", 2, "@" },
687     { oXauthority, "xauthority",  2, "@" },
688     { oGroup,      "group",       2, "@" },
689     { oUnGroup,    "ungroup",     2, "@" },
690     { oNoGroups,   "no-groups",    0, "@" },
691     { oStrict,     "strict",      0, "@" },
692     { oNoStrict,   "no-strict",   0, "@" },
693     { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
694     { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
695     { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
696     { oMultifile, "multifile", 0, "@" },
697     { oKeyidFormat, "keyid-format", 2, "@" },
698     { oExitOnStatusWriteError, "exit-on-status-write-error", 0, "@" },
699     { oLimitCardInsertTries, "limit-card-insert-tries", 1, "@"},
700
701     { oAllowMultisigVerification, "allow-multisig-verification", 0, "@"},
702     { oEnableDSA2, "enable-dsa2", 0, "@"},
703     { oDisableDSA2, "disable-dsa2", 0, "@"},
704     { oAllowMultipleMessages, "allow-multiple-messages", 0, "@"},
705     { oNoAllowMultipleMessages, "no-allow-multiple-messages", 0, "@"},
706
707     /* These two are aliases to help users of the PGP command line
708        product use gpg with minimal pain.  Many commands are common
709        already as they seem to have borrowed commands from us.  Now
710        I'm returning the favor. */
711     { oLocalUser, "sign-with", 2, "@" },
712     { oRecipient, "user", 2, "@" },
713
714     { oRequireCrossCert, "require-backsigs", 0, "@"},
715     { oRequireCrossCert, "require-cross-certification", 0, "@"},
716     { oNoRequireCrossCert, "no-require-backsigs", 0, "@"},
717     { oNoRequireCrossCert, "no-require-cross-certification", 0, "@"},
718     { oAutoKeyLocate, "auto-key-locate", 2, "@"},
719     { oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"},
720
721     {0,NULL,0,NULL}
722 };
723
724
725 #ifdef ENABLE_SELINUX_HACKS
726 #define ALWAYS_ADD_KEYRINGS 1
727 #else
728 #define ALWAYS_ADD_KEYRINGS 0
729 #endif
730
731
732 int g10_errors_seen = 0;
733
734 static int utf8_strings = 0;
735 static int maybe_setuid = 1;
736
737 static char *build_list( const char *text, char letter,
738                          const char *(*mapf)(int), int (*chkf)(int) );
739 static char *build_lib_list (const char *text);
740 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
741                         enum cmd_and_opt_values new_cmd );
742 static void print_mds( const char *fname, int algo );
743 static void add_notation_data( const char *string, int which );
744 static void add_policy_url( const char *string, int which );
745 static void add_keyserver_url( const char *string, int which );
746 static void emergency_cleanup (void);
747
748
749 static const char *
750 my_strusage( int level )
751 {
752   static char *digests, *pubkeys, *ciphers, *zips, *libs;
753     const char *p;
754     switch( level ) {
755       case 11: p = "gpg (GnuPG)";
756         break;
757       case 13: p = VERSION; break;
758       case 17: p = PRINTABLE_OS_NAME; break;
759       case 19: p =
760             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
761         break;
762
763 #ifdef IS_DEVELOPMENT_VERSION
764       case 20:
765         p="NOTE: THIS IS A DEVELOPMENT VERSION!";
766         break;
767       case 21:
768         p="It is only intended for test purposes and should NOT be";
769         break;
770       case 22:
771         p="used in a production environment or with production keys!";
772         break;
773 #endif
774
775       case 1:
776       case 40:  p =
777             _("Usage: gpg [options] [files] (-h for help)");
778         break;
779       case 41:  p =
780             _("Syntax: gpg [options] [files]\n"
781               "sign, check, encrypt or decrypt\n"
782               "default operation depends on the input data\n");
783         break;
784
785       case 31: p = "\nHome: "; break;
786 #ifndef __riscos__
787       case 32: p = opt.homedir; break;
788 #else /* __riscos__ */
789       case 32: p = make_filename(opt.homedir, NULL); break;
790 #endif /* __riscos__ */
791       case 33: p = _("\nSupported algorithms:\n"); break;
792       case 34:
793         if (!pubkeys)
794             pubkeys = build_list (_("Pubkey: "), 0,
795                                   gcry_pk_algo_name,
796                                   openpgp_pk_test_algo );
797         p = pubkeys;
798         break;
799       case 35:
800         if( !ciphers )
801             ciphers = build_list(_("Cipher: "), 'S', 
802                                  openpgp_cipher_algo_name,
803                                  openpgp_cipher_test_algo );
804         p = ciphers;
805         break;
806       case 36:
807         if( !digests )
808             digests = build_list(_("Hash: "), 'H', 
809                                  gcry_md_algo_name,
810                                  openpgp_md_test_algo );
811         p = digests;
812         break;
813       case 37:
814         if( !zips )
815             zips = build_list(_("Compression: "),'Z',
816                               compress_algo_to_string,
817                               check_compress_algo);
818         p = zips;
819         break;
820       case 38:
821         if (!libs)
822           libs = build_lib_list(_("Used libraries:"));
823         p = libs;
824         break;
825
826       default:  p = NULL;
827     }
828     return p;
829 }
830
831
832 static char *
833 build_list( const char *text, char letter,
834             const char * (*mapf)(int), int (*chkf)(int) )
835 {
836     int i;
837     const char *s;
838     size_t n=strlen(text)+2;
839     char *list, *p, *line=NULL;
840
841     if (maybe_setuid)
842       gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
843
844     for(i=0; i <= 110; i++ )
845         if( !chkf(i) && (s=mapf(i)) )
846             n += strlen(s) + 7 + 2;
847     list = xmalloc( 21 + n ); *list = 0;
848     for(p=NULL, i=0; i <= 110; i++ ) {
849         if( !chkf(i) && (s=mapf(i)) ) {
850             if( !p ) {
851                 p = stpcpy( list, text );
852                 line=p;
853             }
854             else
855                 p = stpcpy( p, ", ");
856
857             if(strlen(line)>60) {
858               int spaces=strlen(text);
859
860               list=xrealloc(list,n+spaces+1);
861               /* realloc could move the block, so find the end again */
862               p=list;
863               while(*p)
864                 p++;
865
866               p=stpcpy(p, "\n");
867               line=p;
868               for(;spaces;spaces--)
869                 p=stpcpy(p, " ");
870             }
871
872             p = stpcpy(p, s );
873             if(opt.verbose && letter)
874               {
875                 char num[8];
876                 sprintf(num," (%c%d)",letter,i);
877                 p = stpcpy(p,num);
878               }
879         }
880     }
881     if( p )
882         p = stpcpy(p, "\n" );
883     return list;
884 }
885
886
887 static char *
888 build_lib_list (const char *text)
889 {
890   struct { const char *name; const char *version; } array[3];
891   int idx;
892   size_t n;
893   char *list, *p;
894
895   if (maybe_setuid)
896     gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
897
898   idx = 0;
899   array[idx].name = "gcrypt";
900   array[idx++].version = gcry_check_version (NULL);
901   array[idx].name = NULL;
902   array[idx++].version = NULL;
903
904   n = strlen (text) + 1;
905   for (idx=0; array[idx].name; idx++)
906     {
907       n += 2 + strlen (array[idx].name);
908       if (array[idx].version)
909         n += 1 + strlen (array[idx].version) + 1;
910     }
911   n++;
912   list = xmalloc (n+1);
913   p = stpcpy (stpcpy (list, text), " ");
914   for (idx=0; array[idx].name; idx++)
915     {
916       if (idx)
917         p = stpcpy (p, ", ");
918       p = stpcpy (p, array[idx].name);
919       if (array[idx].version)
920         p = stpcpy (stpcpy (stpcpy (p, "("), array[idx].version), ")");
921     }
922   strcpy (p, "\n");
923   return list;
924 }
925
926
927 static void
928 wrong_args( const char *text)
929 {
930     fputs(_("usage: gpg [options] "),stderr);
931     fputs(text,stderr);
932     putc('\n',stderr);
933     g10_exit(2);
934 }
935
936
937 static char *
938 make_username( const char *string )
939 {
940     char *p;
941     if( utf8_strings )
942         p = xstrdup(string);
943     else
944         p = native_to_utf8( string );
945     return p;
946 }
947
948
949 /* Setup the debugging.  With a LEVEL of NULL only the active debug
950    flags are propagated to the subsystems.  With LEVEL set, a specific
951    set of debug flags is set; thus overriding all flags already
952    set. */
953 static void
954 set_debug (const char *level)
955 {
956   if (!level)
957     ;
958   else if (!strcmp (level, "none"))
959     opt.debug = 0;
960   else if (!strcmp (level, "basic"))
961     opt.debug = DBG_MEMSTAT_VALUE;
962   else if (!strcmp (level, "advanced"))
963     opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE;
964   else if (!strcmp (level, "expert"))
965     opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE
966                  |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
967   else if (!strcmp (level, "guru"))
968     opt.debug = ~0;
969   else
970     {
971       log_error (_("invalid debug-level `%s' given\n"), level);
972       g10_exit (2);
973     }
974
975   if (opt.debug & DBG_MEMORY_VALUE )
976     memory_debug_mode = 1;
977   if (opt.debug & DBG_MEMSTAT_VALUE )
978     memory_stat_debug_mode = 1;
979   if (opt.debug & DBG_MPI_VALUE)
980     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
981   if (opt.debug & DBG_CIPHER_VALUE )
982     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
983   if (opt.debug & DBG_IOBUF_VALUE )
984     iobuf_debug_mode = 1;
985   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
986 }
987
988
989
990 /* We need the home directory also in some other directories, so make
991    sure that both variables are always in sync. */
992 static void
993 set_homedir (const char *dir)
994 {
995   if (!dir)
996     dir = "";
997   opt.homedir = dir;
998 }
999
1000
1001 /* We set the screen dimensions for UI purposes.  Do not allow screens
1002    smaller than 80x24 for the sake of simplicity. */
1003 static void
1004 set_screen_dimensions(void)
1005 {
1006 #ifndef HAVE_W32_SYSTEM
1007   char *str;
1008
1009   str=getenv("COLUMNS");
1010   if(str)
1011     opt.screen_columns=atoi(str);
1012
1013   str=getenv("LINES");
1014   if(str)
1015     opt.screen_lines=atoi(str);
1016 #endif
1017
1018   if(opt.screen_columns<80 || opt.screen_columns>255)
1019     opt.screen_columns=80;
1020
1021   if(opt.screen_lines<24 || opt.screen_lines>255)
1022     opt.screen_lines=24;
1023 }
1024
1025
1026 /* Helper to open a file FNAME either for reading or writing to be
1027    used with --status-file etc functions.  Not generally useful but it
1028    avoids the riscos specific functions and well some Windows people
1029    might like it too.  Prints an error message and returns -1 on
1030    error. On success the file descriptor is returned.  */
1031 static int
1032 open_info_file (const char *fname, int for_write)
1033 {
1034 #ifdef __riscos__
1035   return riscos_fdopenfile (fname, for_write);
1036 #elif defined (ENABLE_SELINUX_HACKS)
1037   /* We can't allow these even when testing for a secured filename
1038      because files to be secured might not yet been secured.  This is
1039      similar to the option file but in that case it is unlikely that
1040      sensitive information may be retrieved by means of error
1041      messages.  */
1042   return -1;
1043 #else 
1044   int fd;
1045
1046 /*   if (is_secured_filename (fname)) */
1047 /*     { */
1048 /*       fd = -1; */
1049 /*       errno = EPERM; */
1050 /*     } */
1051 /*   else */
1052 /*     { */
1053       do
1054         {
1055           if (for_write)
1056             fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY,
1057                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
1058           else
1059             fd = open (fname, O_RDONLY | MY_O_BINARY);
1060         }
1061       while (fd == -1 && errno == EINTR);
1062 /*     } */
1063   if ( fd == -1)
1064     log_error ( for_write? _("can't create `%s': %s\n")
1065                          : _("can't open `%s': %s\n"), fname, strerror(errno));
1066   
1067   return fd;
1068 #endif
1069 }
1070
1071 static void
1072 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
1073 {
1074     enum cmd_and_opt_values cmd = *ret_cmd;
1075
1076     if( !cmd || cmd == new_cmd )
1077         cmd = new_cmd;
1078     else if( cmd == aSign && new_cmd == aEncr )
1079         cmd = aSignEncr;
1080     else if( cmd == aEncr && new_cmd == aSign )
1081         cmd = aSignEncr;
1082     else if( cmd == aSign && new_cmd == aSym )
1083         cmd = aSignSym;
1084     else if( cmd == aSym && new_cmd == aSign )
1085         cmd = aSignSym;
1086     else if( cmd == aSym && new_cmd == aEncr )
1087         cmd = aEncrSym;
1088     else if( cmd == aEncr && new_cmd == aSym )
1089         cmd = aEncrSym;
1090     else if (cmd == aSignEncr && new_cmd == aSym)
1091         cmd = aSignEncrSym;
1092     else if (cmd == aSignSym && new_cmd == aEncr)
1093         cmd = aSignEncrSym;
1094     else if (cmd == aEncrSym && new_cmd == aSign)
1095         cmd = aSignEncrSym;
1096     else if(    ( cmd == aSign     && new_cmd == aClearsign )
1097              || ( cmd == aClearsign && new_cmd == aSign )  )
1098         cmd = aClearsign;
1099     else {
1100         log_error(_("conflicting commands\n"));
1101         g10_exit(2);
1102     }
1103
1104     *ret_cmd = cmd;
1105 }
1106
1107
1108 static void
1109 add_group(char *string)
1110 {
1111   char *name,*value;
1112   struct groupitem *item;
1113
1114   /* Break off the group name */
1115   name=strsep(&string,"=");
1116   if(string==NULL)
1117     {
1118       log_error(_("no = sign found in group definition `%s'\n"),name);
1119       return;
1120     }
1121
1122   trim_trailing_ws(name,strlen(name));
1123
1124   /* Does this group already exist? */
1125   for(item=opt.grouplist;item;item=item->next)
1126     if(strcasecmp(item->name,name)==0)
1127       break;
1128
1129   if(!item)
1130     {
1131       item=xmalloc(sizeof(struct groupitem));
1132       item->name=name;
1133       item->next=opt.grouplist;
1134       item->values=NULL;
1135       opt.grouplist=item;
1136     }
1137
1138   /* Break apart the values */
1139   while ((value= strsep(&string," \t")))
1140     {
1141       if (*value)
1142         add_to_strlist2(&item->values,value,utf8_strings);
1143     }
1144 }
1145
1146
1147 static void
1148 rm_group(char *name)
1149 {
1150   struct groupitem *item,*last=NULL;
1151
1152   trim_trailing_ws(name,strlen(name));
1153
1154   for(item=opt.grouplist;item;last=item,item=item->next)
1155     {
1156       if(strcasecmp(item->name,name)==0)
1157         {
1158           if(last)
1159             last->next=item->next;
1160           else
1161             opt.grouplist=item->next;
1162
1163           free_strlist(item->values);
1164           xfree(item);
1165           break;
1166         }
1167     }
1168 }
1169
1170
1171 /* We need to check three things.
1172
1173    0) The homedir.  It must be x00, a directory, and owned by the
1174    user.
1175
1176    1) The options/gpg.conf file.  Okay unless it or its containing
1177    directory is group or other writable or not owned by us.  Disable
1178    exec in this case.
1179
1180    2) Extensions.  Same as #1.
1181
1182    Returns true if the item is unsafe. */
1183 static int
1184 check_permissions(const char *path,int item)
1185 {
1186 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
1187   static int homedir_cache=-1;
1188   char *tmppath,*dir;
1189   struct stat statbuf,dirbuf;
1190   int homedir=0,ret=0,checkonly=0;
1191   int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
1192
1193   if(opt.no_perm_warn)
1194     return 0;
1195
1196   assert(item==0 || item==1 || item==2);
1197
1198   /* extensions may attach a path */
1199   if(item==2 && path[0]!=DIRSEP_C)
1200     {
1201       if(strchr(path,DIRSEP_C))
1202         tmppath=make_filename(path,NULL);
1203       else
1204         tmppath=make_filename(gnupg_libdir (),path,NULL);
1205     }
1206   else
1207     tmppath=xstrdup(path);
1208
1209   /* If the item is located in the homedir, but isn't the homedir,
1210      don't continue if we already checked the homedir itself.  This is
1211      to avoid user confusion with an extra options file warning which
1212      could be rectified if the homedir itself had proper
1213      permissions. */
1214   if(item!=0 && homedir_cache>-1
1215      && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
1216     {
1217       ret=homedir_cache;
1218       goto end;
1219     }
1220
1221   /* It's okay if the file or directory doesn't exist */
1222   if(stat(tmppath,&statbuf)!=0)
1223     {
1224       ret=0;
1225       goto end;
1226     }
1227
1228   /* Now check the enclosing directory.  Theoretically, we could walk
1229      this test up to the root directory /, but for the sake of sanity,
1230      I'm stopping at one level down. */
1231   dir=make_dirname(tmppath);
1232
1233   if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode))
1234     {
1235       /* Weird error */
1236       ret=1;
1237       goto end;
1238     }
1239
1240   xfree(dir);
1241
1242   /* Assume failure */
1243   ret=1;
1244
1245   if(item==0)
1246     {
1247       /* The homedir must be x00, a directory, and owned by the user. */
1248
1249       if(S_ISDIR(statbuf.st_mode))
1250         {
1251           if(statbuf.st_uid==getuid())
1252             {
1253               if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1254                 ret=0;
1255               else
1256                 perm=1;
1257             }
1258           else
1259             own=1;
1260
1261           homedir_cache=ret;
1262         }
1263     }
1264   else if(item==1 || item==2)
1265     {
1266       /* The options or extension file.  Okay unless it or its
1267          containing directory is group or other writable or not owned
1268          by us or root. */
1269
1270       if(S_ISREG(statbuf.st_mode))
1271         {
1272           if(statbuf.st_uid==getuid() || statbuf.st_uid==0)
1273             {
1274               if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1275                 {
1276                   /* it's not writable, so make sure the enclosing
1277                      directory is also not writable */
1278                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1279                     {
1280                       if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1281                         ret=0;
1282                       else
1283                         enc_dir_perm=1;
1284                     }
1285                   else
1286                     enc_dir_own=1;
1287                 }
1288               else
1289                 {
1290                   /* it's writable, so the enclosing directory had
1291                      better not let people get to it. */
1292                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1293                     {
1294                       if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1295                         ret=0;
1296                       else
1297                         perm=enc_dir_perm=1; /* unclear which one to fix! */
1298                     }
1299                   else
1300                     enc_dir_own=1;
1301                 }
1302             }
1303           else
1304             own=1;
1305         }
1306     }
1307   else
1308     BUG();
1309
1310   if(!checkonly)
1311     {
1312       if(own)
1313         {
1314           if(item==0)
1315             log_info(_("WARNING: unsafe ownership on"
1316                        " homedir `%s'\n"),tmppath);
1317           else if(item==1)
1318             log_info(_("WARNING: unsafe ownership on"
1319                        " configuration file `%s'\n"),tmppath);
1320           else
1321             log_info(_("WARNING: unsafe ownership on"
1322                        " extension `%s'\n"),tmppath);
1323         }
1324       if(perm)
1325         {
1326           if(item==0)
1327             log_info(_("WARNING: unsafe permissions on"
1328                        " homedir `%s'\n"),tmppath);
1329           else if(item==1)
1330             log_info(_("WARNING: unsafe permissions on"
1331                        " configuration file `%s'\n"),tmppath);
1332           else
1333             log_info(_("WARNING: unsafe permissions on"
1334                        " extension `%s'\n"),tmppath);
1335         }
1336       if(enc_dir_own)
1337         {
1338           if(item==0)
1339             log_info(_("WARNING: unsafe enclosing directory ownership on"
1340                        " homedir `%s'\n"),tmppath);
1341           else if(item==1)
1342             log_info(_("WARNING: unsafe enclosing directory ownership on"
1343                        " configuration file `%s'\n"),tmppath);
1344           else
1345             log_info(_("WARNING: unsafe enclosing directory ownership on"
1346                        " extension `%s'\n"),tmppath);
1347         }
1348       if(enc_dir_perm)
1349         {
1350           if(item==0)
1351             log_info(_("WARNING: unsafe enclosing directory permissions on"
1352                        " homedir `%s'\n"),tmppath);
1353           else if(item==1)
1354             log_info(_("WARNING: unsafe enclosing directory permissions on"
1355                        " configuration file `%s'\n"),tmppath);
1356           else
1357             log_info(_("WARNING: unsafe enclosing directory permissions on"
1358                        " extension `%s'\n"),tmppath);
1359         }
1360     }
1361
1362  end:
1363   xfree(tmppath);
1364
1365   if(homedir)
1366     homedir_cache=ret;
1367
1368   return ret;
1369
1370 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
1371
1372   return 0;
1373 }
1374
1375
1376 static void
1377 print_algo_numbers(int (*checker)(int))
1378 {
1379   int i,first=1;
1380
1381   for(i=0;i<=110;i++)
1382     {
1383       if(!checker(i))
1384         {
1385           if(first)
1386             first=0;
1387           else
1388             printf(";");
1389           printf("%d",i);
1390         }
1391     }
1392 }
1393
1394
1395 static void
1396 print_algo_names(int (*checker)(int),const char *(*mapper)(int))
1397 {
1398   int i,first=1;
1399
1400   for(i=0;i<=110;i++)
1401     {
1402       if(!checker(i))
1403         {
1404           if(first)
1405             first=0;
1406           else
1407             printf(";");
1408           printf("%s",mapper(i));
1409         }
1410     }
1411 }
1412
1413 /* In the future, we can do all sorts of interesting configuration
1414    output here.  For now, just give "group" as the Enigmail folks need
1415    it, and pubkey, cipher, hash, and compress as they may be useful
1416    for frontends. */
1417 static void
1418 list_config(char *items)
1419 {
1420   int show_all=(items==NULL);
1421   char *name=NULL;
1422
1423   if(!opt.with_colons)
1424     return;
1425
1426   while(show_all || (name=strsep(&items," ")))
1427     {
1428       int any=0;
1429
1430       if(show_all || ascii_strcasecmp(name,"group")==0)
1431         {
1432           struct groupitem *iter;
1433
1434           for(iter=opt.grouplist;iter;iter=iter->next)
1435             {
1436               strlist_t sl;
1437
1438               printf("cfg:group:");
1439               print_string(stdout,iter->name,strlen(iter->name),':');
1440               printf(":");
1441
1442               for(sl=iter->values;sl;sl=sl->next)
1443                 {
1444                   print_sanitized_string2 (stdout, sl->d, ':',';');
1445                   if(sl->next)
1446                     printf(";");
1447                 }
1448
1449               printf("\n");
1450             }
1451
1452           any=1;
1453         }
1454
1455       if(show_all || ascii_strcasecmp(name,"version")==0)
1456         {
1457           printf("cfg:version:");
1458           print_string(stdout,VERSION,strlen(VERSION),':');
1459           printf("\n");
1460           any=1;
1461         }
1462
1463       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
1464         {
1465           printf("cfg:pubkey:");
1466           print_algo_numbers (openpgp_pk_test_algo);
1467           printf("\n");
1468           any=1;
1469         }
1470
1471       if(show_all || ascii_strcasecmp(name,"cipher")==0)
1472         {
1473           printf("cfg:cipher:");
1474           print_algo_numbers(openpgp_cipher_test_algo);
1475           printf("\n");
1476           any=1;
1477         }
1478
1479       if (show_all || !ascii_strcasecmp (name,"ciphername"))
1480         {
1481           printf ("cfg:ciphername:");
1482           print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
1483           printf ("\n");
1484           any = 1;
1485         }
1486
1487       if(show_all
1488          || ascii_strcasecmp(name,"digest")==0
1489          || ascii_strcasecmp(name,"hash")==0)
1490         {
1491           printf("cfg:digest:");
1492           print_algo_numbers(openpgp_md_test_algo);
1493           printf("\n");
1494           any=1;
1495         }
1496
1497       if (show_all
1498           || !ascii_strcasecmp(name,"digestname")
1499           || !ascii_strcasecmp(name,"hashname"))
1500         {
1501           printf ("cfg:digestname:");
1502           print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
1503           printf("\n");
1504           any=1;
1505         }
1506       
1507       if(show_all || ascii_strcasecmp(name,"compress")==0)
1508         {
1509           printf("cfg:compress:");
1510           print_algo_numbers(check_compress_algo);
1511           printf("\n");
1512           any=1;
1513         }
1514
1515       if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
1516         {
1517 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB) \
1518     && GNUPG_MAJOR_VERSION == 1
1519
1520           char *p, *p2, *list = ccid_get_reader_list ();
1521
1522           for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
1523             {
1524               *p2 = 0;
1525               printf("cfg:ccid-reader-id:%s\n", p);
1526             }
1527           free (list);
1528 #endif
1529           any=1;
1530         }
1531
1532       if(show_all)
1533         break;
1534
1535       if(!any)
1536         log_error(_("unknown configuration item `%s'\n"),name);
1537     }
1538 }
1539
1540
1541 /* List options and default values in the GPG Conf format.  This is a
1542    new tool distributed with gnupg 1.9.x but we also want some limited
1543    support in older gpg versions.  The output is the name of the
1544    configuration file and a list of options available for editing by
1545    gpgconf.  */
1546 static void
1547 gpgconf_list (const char *configfile)
1548 {
1549   char *configfile_esc = percent_escape (configfile, NULL);
1550
1551   printf ("gpgconf-gpg.conf:%lu:\"%s\n",
1552           GC_OPT_FLAG_DEFAULT, configfile_esc ? configfile_esc : "/dev/null");
1553   printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
1554   printf ("quiet:%lu:\n",   GC_OPT_FLAG_NONE);
1555   printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
1556   printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
1557   printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
1558   printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
1559   printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
1560   printf ("allow-pka-lookup:%lu:\n", GC_OPT_FLAG_NONE);
1561   printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
1562   printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
1563   printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
1564
1565   xfree (configfile_esc);
1566 }
1567
1568
1569 static int
1570 parse_subpacket_list(char *list)
1571 {
1572   char *tok;
1573   byte subpackets[128],i;
1574   int count=0;
1575
1576   if(!list)
1577     {
1578       /* No arguments means all subpackets */
1579       memset(subpackets+1,1,sizeof(subpackets)-1);
1580       count=127;
1581     }
1582   else
1583     {
1584       memset(subpackets,0,sizeof(subpackets));
1585
1586       /* Merge with earlier copy */
1587       if(opt.show_subpackets)
1588         {
1589           byte *in;
1590
1591           for(in=opt.show_subpackets;*in;in++)
1592             {
1593               if(*in>127 || *in<1)
1594                 BUG();
1595
1596               if(!subpackets[*in])
1597                 count++;
1598               subpackets[*in]=1;
1599             }
1600         }
1601
1602       while((tok=strsep(&list," ,")))
1603         {
1604           if(!*tok)
1605             continue;
1606
1607           i=atoi(tok);
1608           if(i>127 || i<1)
1609             return 0;
1610
1611           if(!subpackets[i])
1612             count++;
1613           subpackets[i]=1;
1614         }
1615     }
1616
1617   xfree(opt.show_subpackets);
1618   opt.show_subpackets=xmalloc(count+1);
1619   opt.show_subpackets[count--]=0;
1620
1621   for(i=1;i<128 && count>=0;i++)
1622     if(subpackets[i])
1623       opt.show_subpackets[count--]=i;
1624
1625   return 1;
1626 }
1627
1628
1629 static int
1630 parse_list_options(char *str)
1631 {
1632   char *subpackets=""; /* something that isn't NULL */
1633   struct parse_options lopts[]=
1634     {
1635       {"show-photos",LIST_SHOW_PHOTOS,NULL,
1636        N_("display photo IDs during key listings")},
1637       {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL,
1638        N_("show policy URLs during signature listings")},
1639       {"show-notations",LIST_SHOW_NOTATIONS,NULL,
1640        N_("show all notations during signature listings")},
1641       {"show-std-notations",LIST_SHOW_STD_NOTATIONS,NULL,
1642        N_("show IETF standard notations during signature listings")},
1643       {"show-standard-notations",LIST_SHOW_STD_NOTATIONS,NULL,
1644        NULL},
1645       {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL,
1646        N_("show user-supplied notations during signature listings")},
1647       {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL,
1648        N_("show preferred keyserver URLs during signature listings")},
1649       {"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL,
1650        N_("show user ID validity during key listings")},
1651       {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS,NULL,
1652        N_("show revoked and expired user IDs in key listings")},
1653       {"show-unusable-subkeys",LIST_SHOW_UNUSABLE_SUBKEYS,NULL,
1654        N_("show revoked and expired subkeys in key listings")},
1655       {"show-keyring",LIST_SHOW_KEYRING,NULL,
1656        N_("show the keyring name in key listings")},
1657       {"show-sig-expire",LIST_SHOW_SIG_EXPIRE,NULL,
1658        N_("show expiration dates during signature listings")},
1659       {"show-sig-subpackets",LIST_SHOW_SIG_SUBPACKETS,NULL,
1660        NULL},
1661       {NULL,0,NULL,NULL}
1662     };
1663
1664   /* C99 allows for non-constant initializers, but we'd like to
1665      compile everywhere, so fill in the show-sig-subpackets argument
1666      here.  Note that if the parse_options array changes, we'll have
1667      to change the subscript here. */
1668   lopts[12].value=&subpackets;
1669
1670   if(parse_options(str,&opt.list_options,lopts,1))
1671     {
1672       if(opt.list_options&LIST_SHOW_SIG_SUBPACKETS)
1673         {
1674           /* Unset so users can pass multiple lists in. */
1675           opt.list_options&=~LIST_SHOW_SIG_SUBPACKETS;
1676           if(!parse_subpacket_list(subpackets))
1677             return 0;
1678         }
1679       else if(subpackets==NULL && opt.show_subpackets)
1680         {
1681           /* User did 'no-show-subpackets' */
1682           xfree(opt.show_subpackets);
1683           opt.show_subpackets=NULL;
1684         }
1685
1686       return 1;
1687     }
1688   else
1689     return 0;
1690 }
1691
1692
1693 /* Collapses argc/argv into a single string that must be freed */
1694 static char *
1695 collapse_args(int argc,char *argv[])
1696 {
1697   char *str=NULL;
1698   int i,first=1,len=0;
1699
1700   for(i=0;i<argc;i++)
1701     {
1702       len+=strlen(argv[i])+2;
1703       str=xrealloc(str,len);
1704       if(first)
1705         {
1706           str[0]='\0';
1707           first=0;
1708         }
1709       else
1710         strcat(str," ");
1711
1712       strcat(str,argv[i]);
1713     }
1714
1715   return str;
1716 }
1717
1718 static void
1719 parse_trust_model(const char *model)
1720 {
1721   if(ascii_strcasecmp(model,"pgp")==0)
1722     opt.trust_model=TM_PGP;
1723   else if(ascii_strcasecmp(model,"classic")==0)
1724     opt.trust_model=TM_CLASSIC;
1725   else if(ascii_strcasecmp(model,"always")==0)
1726     opt.trust_model=TM_ALWAYS;
1727   else if(ascii_strcasecmp(model,"direct")==0)
1728     opt.trust_model=TM_DIRECT;
1729   else if(ascii_strcasecmp(model,"auto")==0)
1730     opt.trust_model=TM_AUTO;
1731   else
1732     log_error("unknown trust model `%s'\n",model);
1733 }
1734
1735
1736 /* Pack an s2k iteration count into the form specified in 2440.  If
1737    we're in between valid values, round up. */
1738 static unsigned char
1739 encode_s2k_iterations(int iterations)
1740 {
1741   unsigned char c=0,result;
1742   unsigned int count;
1743
1744   if(iterations<=1024)
1745     return 0;
1746
1747   if(iterations>=65011712)
1748     return 255;
1749
1750   /* Need count to be in the range 16-31 */
1751   for(count=iterations>>6;count>=32;count>>=1)
1752     c++;
1753
1754   result=(c<<4)|(count-16);
1755
1756   if(S2K_DECODE_COUNT(result)<iterations)
1757     result++;
1758
1759   return result;
1760 }
1761
1762
1763 /* This fucntion called to initialized a new control object.  It is
1764    assumed that this object has been zeroed out before calling this
1765    function. */
1766 static void
1767 gpg_init_default_ctrl (ctrl_t ctrl)
1768 {
1769 }
1770
1771
1772 /* This function is called to deinitialize a control object.  It is
1773    not deallocated. */
1774 static void
1775 gpg_deinit_default_ctrl (ctrl_t ctrl)
1776 {
1777 }
1778
1779
1780 char *
1781 get_default_configname (void)
1782 {
1783   char *configname = NULL;
1784   char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
1785   char *ver = &name[strlen ("gpg" EXTSEP_S "conf-")];
1786
1787   do
1788     {
1789       if (configname)
1790         {
1791           char *tok;
1792           
1793           xfree (configname);
1794           configname = NULL;
1795
1796           if ((tok = strrchr (ver, SAFE_VERSION_DASH)))
1797             *tok='\0';
1798           else if ((tok = strrchr (ver, SAFE_VERSION_DOT)))
1799             *tok='\0';
1800           else
1801             break;
1802         }
1803       
1804       configname = make_filename (opt.homedir, name, NULL);
1805     }
1806   while (access (configname, R_OK));
1807
1808   xfree(name);
1809   
1810   if (! configname)
1811     configname = make_filename (opt.homedir, "gpg" EXTSEP_S "conf", NULL);
1812   if (! access (configname, R_OK))
1813     {
1814       /* Print a warning when both config files are present.  */
1815       char *p = make_filename (opt.homedir, "options", NULL);
1816       if (! access (p, R_OK))
1817         log_info (_("NOTE: old default options file `%s' ignored\n"), p);
1818       xfree (p);
1819     }
1820   else
1821     {
1822       /* Use the old default only if it exists.  */
1823       char *p = make_filename (opt.homedir, "options", NULL);
1824       if (!access (p, R_OK))
1825         {
1826           xfree (configname);
1827           configname = p;
1828         }
1829       else
1830         xfree (p);
1831     }
1832
1833   return configname;
1834 }
1835
1836
1837 int
1838 main (int argc, char **argv)
1839 {
1840     ARGPARSE_ARGS pargs;
1841     IOBUF a;
1842     int rc=0;
1843     int orig_argc;
1844     char **orig_argv;
1845     const char *fname;
1846     char *username;
1847     int may_coredump;
1848     strlist_t sl, remusr= NULL, locusr=NULL;
1849     strlist_t nrings=NULL, sec_nrings=NULL;
1850     armor_filter_context_t *afx = NULL;
1851     int detached_sig = 0;
1852     FILE *configfp = NULL;
1853     char *configname = NULL;
1854     char *save_configname = NULL;
1855     char *default_configname = NULL;
1856     unsigned configlineno;
1857     int parse_debug = 0;
1858     int default_config = 1;
1859     int default_keyring = 1;
1860     int greeting = 0;
1861     int nogreeting = 0;
1862     char *logfile = NULL;
1863     int use_random_seed = 1;
1864     enum cmd_and_opt_values cmd = 0;
1865     const char *debug_level = NULL;
1866     const char *trustdb_name = NULL;
1867     char *def_cipher_string = NULL;
1868     char *def_digest_string = NULL;
1869     char *compress_algo_string = NULL;
1870     char *cert_digest_string = NULL;
1871     char *s2k_cipher_string = NULL;
1872     char *s2k_digest_string = NULL;
1873     char *pers_cipher_list = NULL;
1874     char *pers_digest_list = NULL;
1875     char *pers_compress_list = NULL;
1876     int eyes_only=0;
1877     int multifile=0;
1878     int pwfd = -1;
1879     int with_fpr = 0; /* make an option out of --fingerprint */
1880     int any_explicit_recipient = 0;
1881     int require_secmem=0,got_secmem=0;
1882
1883 #ifdef __riscos__
1884     opt.lock_once = 1;
1885 #endif /* __riscos__ */
1886
1887
1888     /* Please note that we may running SUID(ROOT), so be very CAREFUL
1889        when adding any stuff between here and the call to
1890        secmem_init() somewhere after the option parsing. */
1891     gnupg_reopen_std ("gpg");
1892     trap_unaligned ();
1893     gnupg_rl_initialize ();
1894     set_strusage (my_strusage);
1895     gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
1896     /* We don't need any locking in libgcrypt unless we use any kind of
1897        threading. */
1898     gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
1899     log_set_prefix ("gpg", 1);
1900
1901     /* Make sure that our subsystems are ready.  */
1902     init_common_subsystems ();
1903
1904     /* Check that the libraries are suitable.  Do it right here because the
1905        option parsing may need services of the library.  */
1906     if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
1907       {
1908         log_fatal ( _("libgcrypt is too old (need %s, have %s)\n"),
1909                     NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
1910       }
1911
1912     /* Put random number into secure memory */
1913     gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
1914
1915     may_coredump = disable_core_dumps();
1916
1917     gnupg_init_signals (0, emergency_cleanup);
1918
1919     create_dotlock(NULL); /* Register locking cleanup. */
1920
1921     i18n_init();
1922
1923     opt.command_fd = -1; /* no command fd */
1924     opt.compress_level = -1; /* defaults to standard compress level */
1925     opt.bz2_compress_level = -1; /* defaults to standard compress level */
1926     /* note: if you change these lines, look at oOpenPGP */
1927     opt.def_cipher_algo = 0;
1928     opt.def_digest_algo = 0;
1929     opt.cert_digest_algo = 0;
1930     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
1931     opt.s2k_mode = 3; /* iterated+salted */
1932     opt.s2k_count = 96; /* 65536 iterations */
1933 #ifdef USE_CAST5
1934     opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
1935 #else
1936     opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
1937 #endif
1938     opt.completes_needed = 1;
1939     opt.marginals_needed = 3;
1940     opt.max_cert_depth = 5;
1941     opt.pgp2_workarounds = 1;
1942     opt.escape_from = 1;
1943     opt.flags.require_cross_cert = 1;
1944     opt.import_options=IMPORT_SK2PK;
1945     opt.export_options=EXPORT_ATTRIBUTES;
1946     opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
1947     opt.keyserver_options.export_options=EXPORT_ATTRIBUTES;
1948     opt.keyserver_options.options=
1949       KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD;
1950     opt.verify_options=
1951       VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
1952     opt.trust_model=TM_AUTO;
1953     opt.mangle_dos_filenames=0;
1954     opt.min_cert_level=2;
1955     set_screen_dimensions();
1956     opt.keyid_format=KF_SHORT;
1957     opt.def_sig_expire="0";
1958     opt.def_cert_expire="0";
1959     set_homedir ( default_homedir () );
1960     opt.passwd_repeat=1;
1961
1962     /* Check whether we have a config file on the command line.  */
1963     orig_argc = argc;
1964     orig_argv = argv;
1965     pargs.argc = &argc;
1966     pargs.argv = &argv;
1967     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
1968     while( arg_parse( &pargs, opts) ) {
1969         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
1970             parse_debug++;
1971         else if( pargs.r_opt == oOptions ) {
1972             /* yes there is one, so we do not try the default one, but
1973              * read the option file when it is encountered at the commandline
1974              */
1975             default_config = 0;
1976         }
1977         else if( pargs.r_opt == oNoOptions )
1978           {
1979             default_config = 0; /* --no-options */
1980             opt.no_homedir_creation = 1;
1981           }
1982         else if( pargs.r_opt == oHomedir )
1983             set_homedir ( pargs.r.ret_str );
1984         else if( pargs.r_opt == oNoPermissionWarn )
1985             opt.no_perm_warn=1;
1986         else if (pargs.r_opt == oStrict )
1987           {
1988             /* Not used */
1989           }
1990         else if (pargs.r_opt == oNoStrict )
1991           {
1992             /* Not used */
1993           }
1994     }
1995
1996 #ifdef HAVE_DOSISH_SYSTEM
1997     if ( strchr (opt.homedir,'\\') ) {
1998         char *d, *buf = xmalloc (strlen (opt.homedir)+1);
1999         const char *s = opt.homedir;
2000         for (d=buf,s=opt.homedir; *s; s++)
2001           {
2002             *d++ = *s == '\\'? '/': *s;
2003 #ifdef HAVE_W32_SYSTEM
2004             if (s[1] && IsDBCSLeadByte (*s))
2005               *d++ = *++s;
2006 #endif
2007           }
2008         *d = 0;
2009         set_homedir (buf);
2010     }
2011 #endif
2012
2013     /* Initialize the secure memory. */
2014     if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0))
2015       got_secmem = 1; 
2016 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
2017     /* There should be no way to get to this spot while still carrying
2018        setuid privs.  Just in case, bomb out if we are. */
2019     if ( getuid () != geteuid () )
2020       BUG ();
2021 #endif
2022     maybe_setuid = 0;
2023
2024     /* Okay, we are now working under our real uid */
2025
2026     /* malloc hooks go here ... */
2027     assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
2028     assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT);
2029  
2030
2031     /* Try for a version specific config file first */
2032     default_configname = get_default_configname ();
2033     if (default_config)
2034       configname = xstrdup (default_configname);
2035
2036     argc = orig_argc;
2037     argv = orig_argv;
2038     pargs.argc = &argc;
2039     pargs.argv = &argv;
2040     pargs.flags=  1;  /* do not remove the args */
2041
2042     /* By this point we have a homedir, and cannot change it. */
2043     check_permissions(opt.homedir,0);
2044
2045   next_pass:
2046     if( configname ) {
2047       if(check_permissions(configname,1))
2048         {
2049           /* If any options file is unsafe, then disable any external
2050              programs for keyserver calls or photo IDs.  Since the
2051              external program to call is set in the options file, a
2052              unsafe options file can lead to an arbitrary program
2053              being run. */
2054
2055           opt.exec_disable=1;
2056         }
2057
2058         configlineno = 0;
2059         configfp = fopen( configname, "r" );
2060         if (configfp && is_secured_file (fileno (configfp)))
2061           {
2062             fclose (configfp);
2063             configfp = NULL;
2064             errno = EPERM;
2065           }
2066         if( !configfp ) {
2067             if( default_config ) {
2068                 if( parse_debug )
2069                     log_info(_("NOTE: no default option file `%s'\n"),
2070                                                             configname );
2071             }
2072             else {
2073                 log_error(_("option file `%s': %s\n"),
2074                                     configname, strerror(errno) );
2075                 g10_exit(2);
2076             }
2077             xfree(configname); configname = NULL;
2078         }
2079         if( parse_debug && configname )
2080             log_info(_("reading options from `%s'\n"), configname );
2081         default_config = 0;
2082     }
2083
2084     while( optfile_parse( configfp, configname, &configlineno,
2085                                                 &pargs, opts) )
2086       {
2087         switch( pargs.r_opt )
2088           {
2089           case aCheckKeys: 
2090           case aListConfig:
2091           case aGPGConfList:
2092           case aGPGConfTest:
2093           case aListPackets:
2094           case aImport: 
2095           case aFastImport: 
2096           case aSendKeys: 
2097           case aRecvKeys: 
2098           case aSearchKeys:
2099           case aRefreshKeys:
2100           case aFetchKeys:
2101           case aExport: 
2102 #ifdef ENABLE_CARD_SUPPORT
2103           case aCardStatus:
2104           case aCardEdit: 
2105           case aChangePIN:
2106 #endif /* ENABLE_CARD_SUPPORT*/
2107           case aListKeys: 
2108           case aLocateKeys:
2109           case aListSigs: 
2110           case aExportSecret: 
2111           case aExportSecretSub: 
2112           case aSym:
2113           case aClearsign: 
2114           case aGenRevoke: 
2115           case aDesigRevoke: 
2116           case aPrimegen: 
2117           case aGenRandom:
2118           case aPrintMD:
2119           case aPrintMDs: 
2120           case aListTrustDB: 
2121           case aCheckTrustDB:
2122           case aUpdateTrustDB: 
2123           case aFixTrustDB: 
2124           case aListTrustPath: 
2125           case aDeArmor: 
2126           case aEnArmor: 
2127           case aSign: 
2128           case aSignKey: 
2129           case aLSignKey:
2130           case aStore: 
2131           case aExportOwnerTrust: 
2132           case aImportOwnerTrust: 
2133           case aRebuildKeydbCaches:
2134             set_cmd (&cmd, pargs.r_opt);
2135             break;
2136
2137           case aKeygen: 
2138           case aEditKey:
2139           case aDeleteSecretKeys:
2140           case aDeleteSecretAndPublicKeys:
2141           case aDeleteKeys:
2142             set_cmd (&cmd, pargs.r_opt);
2143             greeting=1;
2144             break;
2145
2146           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
2147
2148           case aDecryptFiles: multifile=1; /* fall through */
2149           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
2150
2151           case aEncrFiles: multifile=1; /* fall through */
2152           case aEncr: set_cmd( &cmd, aEncr); break;
2153
2154           case aVerifyFiles: multifile=1; /* fall through */
2155           case aVerify: set_cmd( &cmd, aVerify); break;
2156
2157           case aServer:
2158             set_cmd (&cmd, pargs.r_opt);
2159             opt.batch = 1;
2160             break;
2161
2162           case oArmor: opt.armor = 1; opt.no_armor=0; break;
2163           case oOutput: opt.outfile = pargs.r.ret_str; break;
2164           case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
2165           case oQuiet: opt.quiet = 1; break;
2166           case oNoTTY: tty_no_terminal(1); break;
2167           case oDryRun: opt.dry_run = 1; break;
2168           case oInteractive: opt.interactive = 1; break;
2169           case oVerbose:
2170             opt.verbose++;
2171             gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
2172             opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
2173             opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
2174             break;
2175
2176           case oBatch:
2177             opt.batch = 1;
2178             nogreeting = 1;
2179             break;
2180
2181           case oUseAgent: /* Dummy. */
2182             break;
2183           case oNoUseAgent:
2184             obsolete_option (configname, configlineno, "--no-use-agent");
2185             break;
2186           case oGpgAgentInfo: 
2187             obsolete_option (configname, configlineno, "--gpg-agent-info");
2188             break;
2189
2190           case oAnswerYes: opt.answer_yes = 1; break;
2191           case oAnswerNo: opt.answer_no = 1; break;
2192           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
2193           case oPrimaryKeyring:
2194             sl=append_to_strlist( &nrings, pargs.r.ret_str);
2195             sl->flags=2;
2196             break;
2197           case oShowKeyring:
2198             deprecated_warning(configname,configlineno,"--show-keyring",
2199                                "--list-options ","show-keyring");
2200             opt.list_options|=LIST_SHOW_KEYRING;
2201             break;
2202
2203           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
2204           case oDebugAll: opt.debug = ~0; break;
2205           case oDebugLevel: debug_level = pargs.r.ret_str; break;
2206
2207           case oStatusFD:
2208             set_status_fd( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
2209             break;
2210           case oStatusFile:
2211             set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
2212             break;
2213           case oAttributeFD:
2214             set_attrib_fd(translate_sys2libc_fd_int (pargs.r.ret_int, 1));
2215             break;
2216           case oAttributeFile:
2217             set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
2218             break;
2219           case oLoggerFD:
2220             log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
2221             break;
2222           case oLoggerFile:
2223             logfile = pargs.r.ret_str;
2224             break;
2225
2226           case oWithFingerprint:
2227             opt.with_fingerprint = 1;
2228             with_fpr=1; /*fall thru*/
2229           case oFingerprint: opt.fingerprint++; break;
2230           case oSecretKeyring:
2231             append_to_strlist( &sec_nrings, pargs.r.ret_str);
2232             break;
2233           case oOptions:
2234             /* config files may not be nested (silently ignore them) */
2235             if( !configfp ) {
2236                 xfree(configname);
2237                 configname = xstrdup(pargs.r.ret_str);
2238                 goto next_pass;
2239             }
2240             break;
2241           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
2242           case oNoDefKeyring: default_keyring = 0; break;
2243           case oNoGreeting: nogreeting = 1; break;
2244           case oNoVerbose: 
2245             opt.verbose = 0;
2246             gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
2247             opt.list_sigs=0;
2248             break;
2249           case oQuickRandom: 
2250             gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
2251             break;
2252           case oEmitVersion: opt.no_version=0; break;
2253           case oNoEmitVersion: opt.no_version=1; break;
2254           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
2255           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
2256           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
2257           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
2258           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
2259           case oDefRecipient:
2260             if( *pargs.r.ret_str )
2261               opt.def_recipient = make_username(pargs.r.ret_str);
2262             break;
2263           case oDefRecipientSelf:
2264             xfree(opt.def_recipient); opt.def_recipient = NULL;
2265             opt.def_recipient_self = 1;
2266             break;
2267           case oNoDefRecipient:
2268             xfree(opt.def_recipient); opt.def_recipient = NULL;
2269             opt.def_recipient_self = 0;
2270             break;
2271           case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
2272           case oHomedir: break;
2273           case oNoBatch: opt.batch = 0; break;
2274
2275           case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
2276           case oWithColons: opt.with_colons=':'; break;
2277
2278           case oWithSigCheck: opt.check_sigs = 1; /*FALLTHRU*/
2279           case oWithSigList: opt.list_sigs = 1; break;  
2280
2281           case oSkipVerify: opt.skip_verify=1; break;
2282           case oCompressKeys: opt.compress_keys = 1; break;
2283           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
2284             /* There are many programs (like mutt) that call gpg with
2285                --always-trust so keep this option around for a long
2286                time. */
2287           case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
2288           case oTrustModel:
2289             parse_trust_model(pargs.r.ret_str);
2290             break;
2291           case oForceOwnertrust:
2292             log_info(_("NOTE: %s is not for normal use!\n"),
2293                      "--force-ownertrust");
2294             opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
2295             if(opt.force_ownertrust==-1)
2296               {
2297                 log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
2298                 opt.force_ownertrust=0;
2299               }
2300             break;
2301           case oLoadExtension:
2302             /* Dummy so that gpg 1.4 conf files can work. Should
2303                eventually be removed.  */
2304             break;
2305           case oRFC1991:
2306             opt.compliance = CO_RFC1991;
2307             opt.force_v4_certs = 0;
2308             opt.escape_from = 1;
2309             break;
2310           case oOpenPGP:
2311           case oRFC4880:
2312             /* This is effectively the same as RFC2440, but with
2313                "--enable-dsa2 --no-rfc2440-text --escape-from-lines
2314                --require-cross-certification". */
2315             opt.compliance = CO_RFC4880;
2316             opt.flags.dsa2 = 1;
2317             opt.flags.require_cross_cert = 1;
2318             opt.rfc2440_text = 0;
2319             opt.allow_non_selfsigned_uid = 1;
2320             opt.allow_freeform_uid = 1;
2321             opt.pgp2_workarounds = 0;
2322             opt.escape_from = 1;
2323             opt.force_v3_sigs = 0;
2324             opt.compress_keys = 0;          /* not mandated, but we do it */
2325             opt.compress_sigs = 0;          /* ditto. */
2326             opt.not_dash_escaped = 0;
2327             opt.def_cipher_algo = 0;
2328             opt.def_digest_algo = 0;
2329             opt.cert_digest_algo = 0;
2330             opt.compress_algo = -1;
2331             opt.s2k_mode = 3; /* iterated+salted */
2332             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
2333             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
2334             break;
2335           case oRFC2440:
2336             opt.compliance = CO_RFC2440;
2337             opt.flags.dsa2 = 0;
2338             opt.rfc2440_text = 1;
2339             opt.allow_non_selfsigned_uid = 1;
2340             opt.allow_freeform_uid = 1;
2341             opt.pgp2_workarounds = 0;
2342             opt.escape_from = 0;
2343             opt.force_v3_sigs = 0;
2344             opt.compress_keys = 0;          /* not mandated, but we do it */
2345             opt.compress_sigs = 0;          /* ditto. */
2346             opt.not_dash_escaped = 0;
2347             opt.def_cipher_algo = 0;
2348             opt.def_digest_algo = 0;
2349             opt.cert_digest_algo = 0;
2350             opt.compress_algo = -1;
2351             opt.s2k_mode = 3; /* iterated+salted */
2352             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
2353             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
2354             break;
2355           case oPGP2:  opt.compliance = CO_PGP2;  break;
2356           case oPGP6:  opt.compliance = CO_PGP6;  break;
2357           case oPGP7:  opt.compliance = CO_PGP7;  break;
2358           case oPGP8:  opt.compliance = CO_PGP8;  break;
2359           case oGnuPG: opt.compliance = CO_GNUPG; break;
2360           case oCompressSigs: opt.compress_sigs = 1; break;
2361           case oRFC2440Text: opt.rfc2440_text=1; break;
2362           case oNoRFC2440Text: opt.rfc2440_text=0; break;
2363           case oSetFilename:
2364             if(utf8_strings)
2365               opt.set_filename = pargs.r.ret_str;
2366             else
2367               opt.set_filename = native_to_utf8(pargs.r.ret_str);
2368             break;
2369           case oForYourEyesOnly: eyes_only = 1; break;
2370           case oNoForYourEyesOnly: eyes_only = 0; break;
2371           case oSetPolicyURL:
2372             add_policy_url(pargs.r.ret_str,0);
2373             add_policy_url(pargs.r.ret_str,1);
2374             break;
2375           case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
2376           case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
2377           case oShowPolicyURL:
2378             deprecated_warning(configname,configlineno,"--show-policy-url",
2379                                "--list-options ","show-policy-urls");
2380             deprecated_warning(configname,configlineno,"--show-policy-url",
2381                                "--verify-options ","show-policy-urls");
2382             opt.list_options|=LIST_SHOW_POLICY_URLS;
2383             opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
2384             break;
2385           case oNoShowPolicyURL:
2386             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2387                                "--list-options ","no-show-policy-urls");
2388             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2389                                "--verify-options ","no-show-policy-urls");
2390             opt.list_options&=~LIST_SHOW_POLICY_URLS;
2391             opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
2392             break;
2393           case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
2394           case oUseEmbeddedFilename:
2395             opt.flags.use_embedded_filename=1;
2396             break;
2397           case oNoUseEmbeddedFilename:
2398             opt.flags.use_embedded_filename=0;
2399             break;
2400           case oComment:
2401             if(pargs.r.ret_str[0])
2402               append_to_strlist(&opt.comments,pargs.r.ret_str);
2403             break;
2404           case oDefaultComment:
2405             deprecated_warning(configname,configlineno,
2406                                "--default-comment","--no-comments","");
2407             /* fall through */
2408           case oNoComments:
2409             free_strlist(opt.comments);
2410             opt.comments=NULL;
2411             break;
2412           case oThrowKeyids: opt.throw_keyid = 1; break;
2413           case oNoThrowKeyids: opt.throw_keyid = 0; break;
2414           case oShowPhotos:
2415             deprecated_warning(configname,configlineno,"--show-photos",
2416                                "--list-options ","show-photos");
2417             deprecated_warning(configname,configlineno,"--show-photos",
2418                                "--verify-options ","show-photos");
2419             opt.list_options|=LIST_SHOW_PHOTOS;
2420             opt.verify_options|=VERIFY_SHOW_PHOTOS;
2421             break;
2422           case oNoShowPhotos:
2423             deprecated_warning(configname,configlineno,"--no-show-photos",
2424                                "--list-options ","no-show-photos");
2425             deprecated_warning(configname,configlineno,"--no-show-photos",
2426                                "--verify-options ","no-show-photos");
2427             opt.list_options&=~LIST_SHOW_PHOTOS;
2428             opt.verify_options&=~VERIFY_SHOW_PHOTOS;
2429             break;
2430           case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
2431           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
2432           case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
2433           case oForceV4Certs: opt.force_v4_certs = 1; break;
2434           case oNoForceV4Certs: opt.force_v4_certs = 0; break;
2435           case oForceMDC: opt.force_mdc = 1; break;
2436           case oNoForceMDC: opt.force_mdc = 0; break;
2437           case oDisableMDC: opt.disable_mdc = 1; break;
2438           case oNoDisableMDC: opt.disable_mdc = 0; break;
2439           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
2440           case oS2KDigest: s2k_digest_string = xstrdup(pargs.r.ret_str); break;
2441           case oS2KCipher: s2k_cipher_string = xstrdup(pargs.r.ret_str); break;
2442           case oS2KCount:
2443             opt.s2k_count=encode_s2k_iterations(pargs.r.ret_int);
2444             break;
2445           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
2446           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
2447           case oEncryptTo: /* store the recipient in the second list */
2448             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2449             sl->flags = 1;
2450             break;
2451           case oHiddenEncryptTo: /* store the recipient in the second list */
2452             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2453             sl->flags = 1|2;
2454             break;
2455           case oRecipient: /* store the recipient */
2456             add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2457             any_explicit_recipient = 1;
2458             break;
2459           case oHiddenRecipient: /* store the recipient with a flag */
2460             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2461             sl->flags = 2;
2462             any_explicit_recipient = 1;
2463             break;
2464           case oTextmodeShort: opt.textmode = 2; break;
2465           case oTextmode: opt.textmode=1;  break;
2466           case oNoTextmode: opt.textmode=0;  break;
2467           case oExpert: opt.expert = 1; break;
2468           case oNoExpert: opt.expert = 0; break;
2469           case oDefSigExpire:
2470             if(*pargs.r.ret_str!='\0')
2471               {
2472                 if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
2473                   log_error(_("`%s' is not a valid signature expiration\n"),
2474                             pargs.r.ret_str);
2475                 else
2476                   opt.def_sig_expire=pargs.r.ret_str;
2477               }
2478             break;
2479           case oAskSigExpire: opt.ask_sig_expire = 1; break;
2480           case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
2481           case oDefCertExpire:
2482             if(*pargs.r.ret_str!='\0')
2483               {
2484                 if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
2485                   log_error(_("`%s' is not a valid signature expiration\n"),
2486                             pargs.r.ret_str);
2487                 else
2488                   opt.def_cert_expire=pargs.r.ret_str;
2489               }
2490             break;
2491           case oAskCertExpire: opt.ask_cert_expire = 1; break;
2492           case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
2493           case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
2494           case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
2495           case oAskCertLevel: opt.ask_cert_level = 1; break;
2496           case oNoAskCertLevel: opt.ask_cert_level = 0; break;
2497           case oLocalUser: /* store the local users */
2498             add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
2499             break;
2500           case oCompress:
2501             /* this is the -z command line option */
2502             opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
2503             break;
2504           case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
2505           case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
2506           case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
2507           case oPasswd:
2508             set_passphrase_from_string(pargs.r.ret_str);
2509             break;
2510           case oPasswdFD:
2511             pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
2512             break;
2513           case oPasswdFile:
2514             pwfd = open_info_file (pargs.r.ret_str, 0);
2515             break;
2516           case oPasswdRepeat: opt.passwd_repeat=pargs.r.ret_int; break;
2517           case oCommandFD:
2518             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
2519             break;
2520           case oCommandFile:
2521             opt.command_fd = open_info_file (pargs.r.ret_str, 0);
2522             break;
2523           case oCipherAlgo: 
2524             def_cipher_string = xstrdup(pargs.r.ret_str);
2525             break;
2526           case oDigestAlgo:
2527             def_digest_string = xstrdup(pargs.r.ret_str);
2528             break;
2529           case oCompressAlgo:
2530             /* If it is all digits, stick a Z in front of it for
2531                later.  This is for backwards compatibility with
2532                versions that took the compress algorithm number. */
2533             {
2534               char *pt=pargs.r.ret_str;
2535               while(*pt)
2536                 {
2537                   if (!isascii (*pt) || !isdigit (*pt))
2538                     break;
2539
2540                   pt++;
2541                 }
2542
2543               if(*pt=='\0')
2544                 {
2545                   compress_algo_string=xmalloc(strlen(pargs.r.ret_str)+2);
2546                   strcpy(compress_algo_string,"Z");
2547                   strcat(compress_algo_string,pargs.r.ret_str);
2548                 }
2549               else
2550                 compress_algo_string = xstrdup(pargs.r.ret_str);
2551             }
2552             break;
2553           case oCertDigestAlgo: 
2554             cert_digest_string = xstrdup(pargs.r.ret_str);
2555             break;
2556
2557           case oNoSecmemWarn: 
2558             gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
2559             break;
2560
2561           case oRequireSecmem: require_secmem=1; break;
2562           case oNoRequireSecmem: require_secmem=0; break;
2563           case oNoPermissionWarn: opt.no_perm_warn=1; break;
2564           case oNoMDCWarn: opt.no_mdc_warn=1; break;
2565           case oDisplayCharset:
2566             if( set_native_charset( pargs.r.ret_str ) )
2567                 log_error(_("`%s' is not a valid character set\n"),
2568                           pargs.r.ret_str);
2569             break;
2570           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
2571           case oEscapeFrom: opt.escape_from = 1; break;
2572           case oNoEscapeFrom: opt.escape_from = 0; break;
2573           case oLockOnce: opt.lock_once = 1; break;
2574           case oLockNever:
2575             disable_dotlock ();
2576             break;
2577           case oLockMultiple:
2578 #ifndef __riscos__
2579             opt.lock_once = 0;
2580 #else /* __riscos__ */
2581             riscos_not_implemented("lock-multiple");
2582 #endif /* __riscos__ */
2583             break;
2584           case oKeyServer:
2585             {
2586               struct keyserver_spec *keyserver;
2587               keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
2588                                             configname,configlineno);
2589               if(!keyserver)
2590                 log_error(_("could not parse keyserver URL\n"));
2591               else
2592                 {
2593                   keyserver->next=opt.keyserver;
2594                   opt.keyserver=keyserver;
2595                 }
2596             }
2597             break;
2598           case oKeyServerOptions:
2599             if(!parse_keyserver_options(pargs.r.ret_str))
2600               {
2601                 if(configname)
2602                   log_error(_("%s:%d: invalid keyserver options\n"),
2603                             configname,configlineno);
2604                 else
2605                   log_error(_("invalid keyserver options\n"));
2606               }
2607             break;
2608           case oImportOptions:
2609             if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
2610               {
2611                 if(configname)
2612                   log_error(_("%s:%d: invalid import options\n"),
2613                             configname,configlineno);
2614                 else
2615                   log_error(_("invalid import options\n"));
2616               }
2617             break;
2618           case oExportOptions:
2619             if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
2620               {
2621                 if(configname)
2622                   log_error(_("%s:%d: invalid export options\n"),
2623                             configname,configlineno);
2624                 else
2625                   log_error(_("invalid export options\n"));
2626               }
2627             break;
2628           case oListOptions:
2629             if(!parse_list_options(pargs.r.ret_str))
2630               {
2631                 if(configname)
2632                   log_error(_("%s:%d: invalid list options\n"),
2633                             configname,configlineno);
2634                 else
2635                   log_error(_("invalid list options\n"));
2636               }
2637             break;
2638           case oVerifyOptions:
2639             {
2640               struct parse_options vopts[]=
2641                 {
2642                   {"show-photos",VERIFY_SHOW_PHOTOS,NULL,
2643                    N_("display photo IDs during signature verification")},
2644                   {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL,
2645                    N_("show policy URLs during signature verification")},
2646                   {"show-notations",VERIFY_SHOW_NOTATIONS,NULL,
2647                    N_("show all notations during signature verification")},
2648                   {"show-std-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
2649                    N_("show IETF standard notations during signature verification")},
2650                   {"show-standard-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
2651                    NULL},
2652                   {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL,
2653                    N_("show user-supplied notations during signature verification")},
2654                   {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL,
2655                    N_("show preferred keyserver URLs during signature verification")},
2656                   {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL,
2657                    N_("show user ID validity during signature verification")},
2658                   {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL,
2659                    N_("show revoked and expired user IDs in signature verification")},
2660                   {"show-primary-uid-only",VERIFY_SHOW_PRIMARY_UID_ONLY,NULL,
2661                    N_("show only the primary user ID in signature verification")},
2662                   {"pka-lookups",VERIFY_PKA_LOOKUPS,NULL,
2663                    N_("validate signatures with PKA data")},
2664                   {"pka-trust-increase",VERIFY_PKA_TRUST_INCREASE,NULL,
2665                    N_("elevate the trust of signatures with valid PKA data")},
2666                   {NULL,0,NULL,NULL}
2667                 };
2668
2669               if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
2670                 {
2671                   if(configname)
2672                     log_error(_("%s:%d: invalid verify options\n"),
2673                               configname,configlineno);
2674                   else
2675                     log_error(_("invalid verify options\n"));
2676                 }
2677             }
2678             break;
2679           case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
2680           case oExecPath:
2681             if(set_exec_path(pargs.r.ret_str))
2682               log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
2683             else
2684               opt.exec_path_set=1;
2685             break;
2686           case oSetNotation:
2687             add_notation_data( pargs.r.ret_str, 0 );
2688             add_notation_data( pargs.r.ret_str, 1 );
2689             break;
2690           case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
2691           case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
2692           case oShowNotation:
2693             deprecated_warning(configname,configlineno,"--show-notation",
2694                                "--list-options ","show-notations");
2695             deprecated_warning(configname,configlineno,"--show-notation",
2696                                "--verify-options ","show-notations");
2697             opt.list_options|=LIST_SHOW_NOTATIONS;
2698             opt.verify_options|=VERIFY_SHOW_NOTATIONS;
2699             break;
2700           case oNoShowNotation:
2701             deprecated_warning(configname,configlineno,"--no-show-notation",
2702                                "--list-options ","no-show-notations");
2703             deprecated_warning(configname,configlineno,"--no-show-notation",
2704                                "--verify-options ","no-show-notations");
2705             opt.list_options&=~LIST_SHOW_NOTATIONS;
2706             opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
2707             break;
2708           case oUtf8Strings: utf8_strings = 1; break;
2709           case oNoUtf8Strings: utf8_strings = 0; break;
2710           case oDisableCipherAlgo:
2711             {
2712               int algo = string_to_cipher_algo (pargs.r.ret_str);
2713               gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
2714             }
2715             break;
2716           case oDisablePubkeyAlgo:
2717             {
2718               int algo = gcry_pk_map_name (pargs.r.ret_str);
2719               gcry_pk_ctl (GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
2720             }
2721             break;
2722           case oNoSigCache: opt.no_sig_cache = 1; break;
2723           case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
2724           case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
2725           case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
2726           case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
2727           case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
2728           case oNoLiteral: opt.no_literal = 1; break;
2729           case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
2730           case oHonorHttpProxy:
2731                 add_to_strlist(&opt.keyserver_options.other,"http-proxy");
2732                 deprecated_warning(configname,configlineno,
2733                                    "--honor-http-proxy",
2734                                    "--keyserver-options ","http-proxy");
2735                 break;
2736           case oFastListMode: opt.fast_list_mode = 1; break;
2737           case oFixedListMode: /* Dummy */ break;
2738           case oListOnly: opt.list_only=1; break;
2739           case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
2740           case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
2741           case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
2742           case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
2743           case oNoRandomSeedFile: use_random_seed = 0; break;
2744           case oAutoKeyRetrieve:
2745           case oNoAutoKeyRetrieve:
2746                 if(pargs.r_opt==oAutoKeyRetrieve)
2747                   opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
2748                 else
2749                   opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
2750
2751                 deprecated_warning(configname,configlineno,
2752                            pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
2753                                "--no-auto-key-retrieve","--keyserver-options ",
2754                            pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
2755                                "no-auto-key-retrieve");
2756                 break;
2757           case oShowSessionKey: opt.show_session_key = 1; break;
2758           case oOverrideSessionKey:
2759                 opt.override_session_key = pargs.r.ret_str;
2760                 break;
2761           case oMergeOnly:
2762                 deprecated_warning(configname,configlineno,"--merge-only",
2763                                    "--import-options ","merge-only");
2764                 opt.import_options|=IMPORT_MERGE_ONLY;
2765             break;
2766           case oAllowSecretKeyImport: /* obsolete */ break;
2767           case oTryAllSecrets: opt.try_all_secrets = 1; break;
2768           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
2769           case oEnableSpecialFilenames:
2770             iobuf_enable_special_filenames (1);
2771             break;
2772           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
2773           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
2774           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
2775           case oPreservePermissions: opt.preserve_permissions=1; break;
2776           case oDefaultPreferenceList:
2777             opt.def_preference_list = pargs.r.ret_str;
2778             break;
2779           case oDefaultKeyserverURL:
2780             {
2781               struct keyserver_spec *keyserver;
2782               keyserver=parse_keyserver_uri(pargs.r.ret_str,1,
2783                                             configname,configlineno);
2784               if(!keyserver)
2785                 log_error(_("could not parse keyserver URL\n"));
2786               else
2787                 free_keyserver_spec(keyserver);
2788
2789               opt.def_keyserver_url = pargs.r.ret_str;
2790             }
2791             break;
2792           case oPersonalCipherPreferences:
2793             pers_cipher_list=pargs.r.ret_str;
2794             break;
2795           case oPersonalDigestPreferences:
2796             pers_digest_list=pargs.r.ret_str;
2797             break;
2798           case oPersonalCompressPreferences:
2799             pers_compress_list=pargs.r.ret_str;
2800             break;
2801           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
2802           case oDisplay: opt.display = pargs.r.ret_str; break;
2803           case oTTYname: opt.ttyname = pargs.r.ret_str; break;
2804           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
2805           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
2806           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
2807           case oXauthority: opt.xauthority = pargs.r.ret_str; break;
2808           case oGroup: add_group(pargs.r.ret_str); break;
2809           case oUnGroup: rm_group(pargs.r.ret_str); break;
2810           case oNoGroups:
2811             while(opt.grouplist)
2812               {
2813                 struct groupitem *iter=opt.grouplist;
2814                 free_strlist(iter->values);
2815                 opt.grouplist=opt.grouplist->next;
2816                 xfree(iter);
2817               }
2818             break;
2819
2820           case oStrict: 
2821           case oNoStrict: 
2822             /* Not used */
2823             break;
2824
2825           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
2826           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
2827           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
2828           case oMultifile: multifile=1; break;
2829           case oKeyidFormat:
2830             if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
2831               opt.keyid_format=KF_SHORT;
2832             else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
2833               opt.keyid_format=KF_LONG;
2834             else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
2835               opt.keyid_format=KF_0xSHORT;
2836             else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
2837               opt.keyid_format=KF_0xLONG;
2838             else
2839               log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
2840             break;
2841
2842           case oExitOnStatusWriteError:
2843             opt.exit_on_status_write_error = 1;
2844             break;
2845
2846           case oLimitCardInsertTries: 
2847             opt.limit_card_insert_tries = pargs.r.ret_int; 
2848             break;
2849
2850           case oRequireCrossCert: opt.flags.require_cross_cert=1; break;
2851           case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
2852
2853           case oAutoKeyLocate:
2854             if(!parse_auto_key_locate(pargs.r.ret_str))
2855               {
2856                 if(configname)
2857                   log_error(_("%s:%d: invalid auto-key-locate list\n"),
2858                             configname,configlineno);
2859                 else
2860                   log_error(_("invalid auto-key-locate list\n"));
2861               }
2862             break;
2863           case oNoAutoKeyLocate:
2864             release_akl();
2865             break;
2866
2867           case oEnableDSA2: opt.flags.dsa2=1; break;
2868           case oDisableDSA2: opt.flags.dsa2=0; break;
2869
2870           case oAllowMultisigVerification:
2871           case oAllowMultipleMessages:
2872             opt.flags.allow_multiple_messages=1;
2873             break;
2874
2875           case oNoAllowMultipleMessages:
2876             opt.flags.allow_multiple_messages=0;
2877             break;
2878
2879           case oNoop: break;
2880
2881           default : pargs.err = configfp? 1:2; break;
2882           }
2883       }
2884
2885
2886     if( configfp ) {
2887         fclose( configfp );
2888         configfp = NULL;
2889         /* Remember the first config file name. */
2890         if (!save_configname)
2891           save_configname = configname;
2892         else
2893           xfree(configname);
2894         configname = NULL;
2895         goto next_pass;
2896     }
2897     xfree( configname ); configname = NULL;
2898     if( log_get_errorcount(0) )
2899         g10_exit(2);
2900
2901     /* The command --gpgconf-list is pretty simple and may be called
2902        directly after the option parsing. */
2903     if (cmd == aGPGConfList)
2904       {
2905         gpgconf_list (save_configname ? save_configname : default_configname);
2906         g10_exit (0);
2907       }
2908     xfree (save_configname);
2909     xfree (default_configname);
2910
2911     if( nogreeting )
2912         greeting = 0;
2913
2914     if( greeting ) {
2915         fprintf(stderr, "%s %s; %s\n",
2916                         strusage(11), strusage(13), strusage(14) );
2917         fprintf(stderr, "%s\n", strusage(15) );
2918     }
2919 #ifdef IS_DEVELOPMENT_VERSION
2920     if( !opt.batch )
2921       {
2922         const char *s;
2923
2924         if((s=strusage(20)))
2925           log_info("%s\n",s);
2926         if((s=strusage(21)))
2927           log_info("%s\n",s);
2928         if((s=strusage(22)))
2929           log_info("%s\n",s);
2930       }
2931 #endif
2932
2933     /* FIXME: We should use logging to a file only in server mode;
2934        however we have not yet implemetyed that.  Thus we try to get
2935        away with --batch as indication for logging to file
2936        required. */
2937     if (logfile && opt.batch)
2938       {
2939         log_set_file (logfile);
2940         log_set_prefix (NULL, 1|2|4);
2941       }
2942
2943 #ifdef USE_CAMELLIA    
2944     /* We better also print a runtime warning if people build it with
2945        support for Camellia (which is not yet defined by OpenPGP). */
2946     log_info ("WARNING: This version has been built with support for the "
2947               "Camellia cipher.\n");
2948     log_info ("         It is for testing only and is NOT for production "
2949               "use!\n");
2950 #endif
2951
2952     /* Older Libgcrypts fail with an assertion during DSA key
2953        generation.  Better disable DSA2 entirely. */
2954     if (opt.flags.dsa2 && !gcry_check_version ("1.4.0") )
2955       {
2956         log_info ("WARNING: "
2957                   "DSA2 is only available with Libgcrypt 1.4 and later\n");
2958         opt.flags.dsa2 = 0;
2959       }
2960
2961     if (opt.verbose > 2)
2962         log_info ("using character set `%s'\n", get_native_charset ());
2963
2964     if( may_coredump && !opt.quiet )
2965         log_info(_("WARNING: program may create a core file!\n"));
2966
2967     if (eyes_only) {
2968       if (opt.set_filename)
2969           log_info(_("WARNING: %s overrides %s\n"),
2970                    "--for-your-eyes-only","--set-filename");
2971
2972       opt.set_filename="_CONSOLE";
2973     }
2974
2975     if (opt.no_literal) {
2976         log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
2977         if (opt.textmode)
2978             log_error(_("%s not allowed with %s!\n"),
2979                        "--textmode", "--no-literal" );
2980         if (opt.set_filename)
2981             log_error(_("%s makes no sense with %s!\n"),
2982                         eyes_only?"--for-your-eyes-only":"--set-filename",
2983                         "--no-literal" );
2984     }
2985
2986
2987     if (opt.set_filesize)
2988         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2989     if( opt.batch )
2990         tty_batchmode( 1 );
2991
2992     gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
2993
2994     if(require_secmem && !got_secmem)
2995       {
2996         log_info(_("will not run with insecure memory due to %s\n"),
2997                  "--require-secmem");
2998         g10_exit(2);
2999       }
3000
3001     set_debug (debug_level);
3002
3003     /* Do these after the switch(), so they can override settings. */
3004     if(PGP2)
3005       {
3006         int unusable=0;
3007
3008         if(cmd==aSign && !detached_sig)
3009           {
3010             log_info(_("you can only make detached or clear signatures "
3011                        "while in --pgp2 mode\n"));
3012             unusable=1;
3013           }
3014         else if(cmd==aSignEncr || cmd==aSignSym)
3015           {
3016             log_info(_("you can't sign and encrypt at the "
3017                        "same time while in --pgp2 mode\n"));
3018             unusable=1;
3019           }
3020         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
3021           {
3022             log_info(_("you must use files (and not a pipe) when "
3023                        "working with --pgp2 enabled.\n"));
3024             unusable=1;
3025           }
3026         else if(cmd==aEncr || cmd==aSym)
3027           {
3028             /* Everything else should work without IDEA (except using
3029                a secret key encrypted with IDEA and setting an IDEA
3030                preference, but those have their own error
3031                messages). */
3032
3033             if (openpgp_cipher_test_algo(CIPHER_ALGO_IDEA))
3034               {
3035                 log_info(_("encrypting a message in --pgp2 mode requires "
3036                            "the IDEA cipher\n"));
3037                 idea_cipher_warn(1);
3038                 unusable=1;
3039               }
3040             else if(cmd==aSym)
3041               {
3042                 /* This only sets IDEA for symmetric encryption
3043                    since it is set via select_algo_from_prefs for
3044                    pk encryption. */
3045                 xfree(def_cipher_string);
3046                 def_cipher_string = xstrdup("idea");
3047               }
3048
3049             /* PGP2 can't handle the output from the textmode
3050                filter, so we disable it for anything that could
3051                create a literal packet (only encryption and
3052                symmetric encryption, since we disable signing
3053                above). */
3054             if(!unusable)
3055               opt.textmode=0;
3056           }
3057
3058         if(unusable)
3059           compliance_failure();
3060         else
3061           {
3062             opt.force_v4_certs = 0;
3063             opt.escape_from = 1;
3064             opt.force_v3_sigs = 1;
3065             opt.pgp2_workarounds = 1;
3066             opt.ask_sig_expire = 0;
3067             opt.ask_cert_expire = 0;
3068             xfree(def_digest_string);
3069             def_digest_string = xstrdup("md5");
3070             xfree(s2k_digest_string);
3071             s2k_digest_string = xstrdup("md5");
3072             opt.compress_algo = COMPRESS_ALGO_ZIP;
3073           }
3074       }
3075     else if(PGP6)
3076       {
3077         opt.escape_from=1;
3078         opt.force_v3_sigs=1;
3079         opt.ask_sig_expire=0;
3080       }
3081     else if(PGP7)
3082       {
3083         opt.escape_from=1;
3084         opt.force_v3_sigs=1;
3085         opt.ask_sig_expire=0;
3086       }
3087     else if(PGP8)
3088       {
3089         opt.escape_from=1;
3090       }
3091
3092
3093     if( def_cipher_string ) {
3094         opt.def_cipher_algo = string_to_cipher_algo (def_cipher_string);
3095         if(opt.def_cipher_algo==0 &&
3096            (ascii_strcasecmp(def_cipher_string,"idea")==0
3097             || ascii_strcasecmp(def_cipher_string,"s1")==0))
3098           idea_cipher_warn(1);
3099         xfree(def_cipher_string); def_cipher_string = NULL;
3100         if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
3101             log_error(_("selected cipher algorithm is invalid\n"));
3102     }
3103     if( def_digest_string ) {
3104         opt.def_digest_algo = string_to_digest_algo (def_digest_string);
3105         xfree(def_digest_string); def_digest_string = NULL;
3106         if ( openpgp_md_test_algo (opt.def_digest_algo) )
3107             log_error(_("selected digest algorithm is invalid\n"));
3108     }
3109     if( compress_algo_string ) {
3110         opt.compress_algo = string_to_compress_algo(compress_algo_string);
3111         xfree(compress_algo_string); compress_algo_string = NULL;
3112         if( check_compress_algo(opt.compress_algo) )
3113           log_error(_("selected compression algorithm is invalid\n"));
3114     }
3115     if( cert_digest_string ) {
3116         opt.cert_digest_algo = string_to_digest_algo (cert_digest_string);
3117         xfree(cert_digest_string); cert_digest_string = NULL;
3118         if (openpgp_md_test_algo(opt.cert_digest_algo))
3119           log_error(_("selected certification digest algorithm is invalid\n"));
3120     }
3121     if( s2k_cipher_string ) {
3122         opt.s2k_cipher_algo = string_to_cipher_algo (s2k_cipher_string);
3123         xfree(s2k_cipher_string); s2k_cipher_string = NULL;
3124         if (openpgp_cipher_test_algo (opt.s2k_cipher_algo))
3125           log_error(_("selected cipher algorithm is invalid\n"));
3126     }
3127     if( s2k_digest_string ) {
3128         opt.s2k_digest_algo = string_to_digest_algo (s2k_digest_string);
3129         xfree(s2k_digest_string); s2k_digest_string = NULL;
3130         if (openpgp_md_test_algo(opt.s2k_digest_algo))
3131           log_error(_("selected digest algorithm is invalid\n"));
3132     }
3133     if( opt.completes_needed < 1 )
3134       log_error(_("completes-needed must be greater than 0\n"));
3135     if( opt.marginals_needed < 2 )
3136       log_error(_("marginals-needed must be greater than 1\n"));
3137     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
3138       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
3139     if(opt.def_cert_level<0 || opt.def_cert_level>3)
3140       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
3141     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
3142       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
3143     switch( opt.s2k_mode ) {
3144       case 0:
3145         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
3146         break;
3147       case 1: case 3: break;
3148       default:
3149         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
3150     }
3151
3152     /* This isn't actually needed, but does serve to error out if the
3153        string is invalid. */
3154     if(opt.def_preference_list &&
3155         keygen_set_std_prefs(opt.def_preference_list,0))
3156       log_error(_("invalid default preferences\n"));
3157
3158     /* We provide defaults for the personal digest list.  This is
3159        SHA-1. */
3160     if(!pers_digest_list)
3161       pers_digest_list="h2";
3162
3163     if(pers_cipher_list &&
3164        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
3165       log_error(_("invalid personal cipher preferences\n"));
3166
3167     if(pers_digest_list &&
3168        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
3169       log_error(_("invalid personal digest preferences\n"));
3170
3171     if(pers_compress_list &&
3172        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
3173       log_error(_("invalid personal compress preferences\n"));
3174
3175     /* We don't support all possible commands with multifile yet */
3176     if(multifile)
3177       {
3178         char *cmdname;
3179
3180         switch(cmd)
3181           {
3182           case aSign:
3183             cmdname="--sign";
3184             break;
3185           case aClearsign:
3186             cmdname="--clearsign";
3187             break;
3188           case aDetachedSign:
3189             cmdname="--detach-sign";
3190             break;
3191           case aSym:
3192             cmdname="--symmetric";
3193             break;
3194           case aEncrSym:
3195             cmdname="--symmetric --encrypt";
3196             break;
3197           case aStore:
3198             cmdname="--store";
3199             break;
3200           default:
3201             cmdname=NULL;
3202             break;
3203           }
3204
3205         if(cmdname)
3206           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
3207       }
3208
3209     if( log_get_errorcount(0) )
3210         g10_exit(2);
3211
3212     if(opt.compress_level==0)
3213       opt.compress_algo=COMPRESS_ALGO_NONE;
3214
3215     /* Check our chosen algorithms against the list of legal
3216        algorithms. */
3217
3218     if(!GNUPG)
3219       {
3220         const char *badalg=NULL;
3221         preftype_t badtype=PREFTYPE_NONE;
3222
3223         if(opt.def_cipher_algo
3224            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
3225           {
3226             badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
3227             badtype = PREFTYPE_SYM;
3228           }
3229         else if(opt.def_digest_algo
3230                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
3231           {
3232             badalg = gcry_md_algo_name (opt.def_digest_algo);
3233             badtype = PREFTYPE_HASH;
3234           }
3235         else if(opt.cert_digest_algo
3236                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
3237           {
3238             badalg = gcry_md_algo_name (opt.cert_digest_algo);
3239             badtype = PREFTYPE_HASH;
3240           }
3241         else if(opt.compress_algo!=-1
3242                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
3243           {
3244             badalg = compress_algo_to_string(opt.compress_algo);
3245             badtype = PREFTYPE_ZIP;
3246           }
3247
3248         if(badalg)
3249           {
3250             switch(badtype)
3251               {
3252               case PREFTYPE_SYM:
3253                 log_info(_("you may not use cipher algorithm `%s'"
3254                            " while in %s mode\n"),
3255                          badalg,compliance_option_string());
3256                 break;
3257               case PREFTYPE_HASH:
3258                 log_info(_("you may not use digest algorithm `%s'"
3259                            " while in %s mode\n"),
3260                          badalg,compliance_option_string());
3261                 break;
3262               case PREFTYPE_ZIP:
3263                 log_info(_("you may not use compression algorithm `%s'"
3264                            " while in %s mode\n"),
3265                          badalg,compliance_option_string());
3266                 break;
3267               default:
3268                 BUG();
3269               }
3270
3271             compliance_failure();
3272           }
3273       }
3274
3275     /* Set the random seed file. */
3276     if( use_random_seed ) {
3277         char *p = make_filename(opt.homedir, "random_seed", NULL );
3278         gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
3279         if (!access (p, F_OK))
3280           register_secured_file (p);
3281         xfree(p);
3282     }
3283
3284     if( !cmd && opt.fingerprint && !with_fpr ) {
3285         set_cmd( &cmd, aListKeys);
3286     }
3287
3288     /* kludge to let -sat generate a clear text signature */
3289     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
3290       {
3291         log_info ("compatibility note:\n");
3292         log_info ("\"-sat\" won't generate clear signed messages in "
3293                   "future versions\n");
3294         log_info ("Use \"--clearsign\" instead of \"-sat\"\n");
3295         cmd = aClearsign;
3296       }
3297
3298     if( opt.verbose > 1 )
3299         set_packet_list_mode(1);
3300
3301     /* Add the keyrings, but not for some special commands.  Also
3302        avoid adding the secret keyring for a couple of commands to
3303        avoid unneeded access in case the secrings are stored on a
3304        floppy.
3305        
3306        We always need to add the keyrings if we are running under
3307        SELinux, this is so that the rings are added to the list of
3308        secured files. */
3309     if( ALWAYS_ADD_KEYRINGS 
3310         || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) ) 
3311       {
3312         if (ALWAYS_ADD_KEYRINGS
3313             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
3314                 && cmd != aVerify && cmd != aSym && cmd != aLocateKeys))
3315           {
3316             if (!sec_nrings || default_keyring) /* add default secret rings */
3317               keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
3318             for (sl = sec_nrings; sl; sl = sl->next)
3319               keydb_add_resource ( sl->d, 0, 1 );
3320           }
3321         if( !nrings || default_keyring )  /* add default ring */
3322             keydb_add_resource ("pubring" EXTSEP_S "gpg", 4, 0);
3323         for(sl = nrings; sl; sl = sl->next )
3324             keydb_add_resource ( sl->d, sl->flags, 0 );
3325       }
3326     FREE_STRLIST(nrings);
3327     FREE_STRLIST(sec_nrings);
3328
3329     if (cmd == aGPGConfTest)
3330       g10_exit(0);
3331
3332
3333     if( pwfd != -1 )  /* Read the passphrase now. */
3334         read_passphrase_from_fd( pwfd );
3335
3336     fname = argc? *argv : NULL;
3337
3338     if(fname && utf8_strings)
3339       opt.flags.utf8_filename=1;
3340
3341     switch( cmd ) {
3342       case aPrimegen:
3343       case aPrintMD:
3344       case aPrintMDs:
3345       case aGenRandom:
3346       case aDeArmor:
3347       case aEnArmor:
3348       case aFixTrustDB:
3349         break;
3350       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
3351       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
3352       default: rc = setup_trustdb(1, trustdb_name ); break;
3353     }
3354     if( rc )
3355         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
3356
3357
3358     switch (cmd)
3359       {
3360       case aStore: 
3361       case aSym:  
3362       case aSign: 
3363       case aSignSym: 
3364       case aClearsign: 
3365         if (!opt.quiet && any_explicit_recipient)
3366           log_info (_("WARNING: recipients (-r) given "
3367                       "without using public key encryption\n"));
3368         break;
3369       default:
3370         break;
3371       }
3372
3373     switch( cmd )
3374       {
3375       case aServer:
3376         {
3377           ctrl_t ctrl = xtrycalloc (1, sizeof *ctrl);
3378           gpg_init_default_ctrl (ctrl);
3379           gpg_server (ctrl);
3380           gpg_deinit_default_ctrl (ctrl);
3381           xfree (ctrl);
3382         }
3383         break;
3384
3385       case aStore: /* only store the file */
3386         if( argc > 1 )
3387             wrong_args(_("--store [filename]"));
3388         if( (rc = encode_store(fname)) )
3389             log_error ("storing `%s' failed: %s\n",
3390                        print_fname_stdin(fname),g10_errstr(rc) );
3391         break;
3392       case aSym: /* encrypt the given file only with the symmetric cipher */
3393         if( argc > 1 )
3394             wrong_args(_("--symmetric [filename]"));
3395         if( (rc = encode_symmetric(fname)) )
3396             log_error (_("symmetric encryption of `%s' failed: %s\n"),
3397                         print_fname_stdin(fname),g10_errstr(rc) );
3398         break;
3399
3400       case aEncr: /* encrypt the given file */
3401         if(multifile)
3402           encode_crypt_files(argc, argv, remusr);
3403         else
3404           {
3405             if( argc > 1 )
3406               wrong_args(_("--encrypt [filename]"));
3407             if( (rc = encode_crypt(fname,remusr,0)) )
3408               log_error("%s: encryption failed: %s\n",
3409                         print_fname_stdin(fname), g10_errstr(rc) );
3410           }
3411         break;
3412
3413       case aEncrSym:
3414         /* This works with PGP 8 in the sense that it acts just like a
3415            symmetric message.  It doesn't work at all with 2 or 6.  It
3416            might work with 7, but alas, I don't have a copy to test
3417            with right now. */
3418         if( argc > 1 )
3419           wrong_args(_("--symmetric --encrypt [filename]"));
3420         else if(opt.s2k_mode==0)
3421           log_error(_("you cannot use --symmetric --encrypt"
3422                       " with --s2k-mode 0\n"));
3423         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3424           log_error(_("you cannot use --symmetric --encrypt"
3425                       " while in %s mode\n"),compliance_option_string());
3426         else
3427           {
3428             if( (rc = encode_crypt(fname,remusr,1)) )
3429               log_error("%s: encryption failed: %s\n",
3430                         print_fname_stdin(fname), g10_errstr(rc) );
3431           }
3432         break;
3433
3434       case aSign: /* sign the given file */
3435         sl = NULL;
3436         if( detached_sig ) { /* sign all files */
3437             for( ; argc; argc--, argv++ )
3438                 add_to_strlist( &sl, *argv );
3439         }
3440         else {
3441             if( argc > 1 )
3442                 wrong_args(_("--sign [filename]"));
3443             if( argc ) {
3444                 sl = xmalloc_clear( sizeof *sl + strlen(fname));
3445                 strcpy(sl->d, fname);
3446             }
3447         }
3448         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
3449             log_error("signing failed: %s\n", g10_errstr(rc) );
3450         free_strlist(sl);
3451         break;
3452
3453       case aSignEncr: /* sign and encrypt the given file */
3454         if( argc > 1 )
3455             wrong_args(_("--sign --encrypt [filename]"));
3456         if( argc ) {
3457             sl = xmalloc_clear( sizeof *sl + strlen(fname));
3458             strcpy(sl->d, fname);
3459         }
3460         else
3461             sl = NULL;
3462         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
3463             log_error("%s: sign+encrypt failed: %s\n",
3464                       print_fname_stdin(fname), g10_errstr(rc) );
3465         free_strlist(sl);
3466         break;
3467
3468       case aSignEncrSym: /* sign and encrypt the given file */
3469         if( argc > 1 )
3470             wrong_args(_("--symmetric --sign --encrypt [filename]"));
3471         else if(opt.s2k_mode==0)
3472           log_error(_("you cannot use --symmetric --sign --encrypt"
3473                       " with --s2k-mode 0\n"));
3474         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3475           log_error(_("you cannot use --symmetric --sign --encrypt"
3476                       " while in %s mode\n"),compliance_option_string());
3477         else
3478           {
3479             if( argc )
3480               {
3481                 sl = xmalloc_clear( sizeof *sl + strlen(fname));
3482                 strcpy(sl->d, fname);
3483               }
3484             else
3485               sl = NULL;
3486             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
3487               log_error("%s: symmetric+sign+encrypt failed: %s\n",
3488                         print_fname_stdin(fname), g10_errstr(rc) );
3489             free_strlist(sl);
3490           }
3491         break;
3492
3493       case aSignSym: /* sign and conventionally encrypt the given file */
3494         if (argc > 1)
3495             wrong_args(_("--sign --symmetric [filename]"));
3496         rc = sign_symencrypt_file (fname, locusr);
3497         if (rc)
3498             log_error("%s: sign+symmetric failed: %s\n",
3499                       print_fname_stdin(fname), g10_errstr(rc) );
3500         break;
3501
3502       case aClearsign: /* make a clearsig */
3503         if( argc > 1 )
3504             wrong_args(_("--clearsign [filename]"));
3505         if( (rc = clearsign_file(fname, locusr, NULL)) )
3506             log_error("%s: clearsign failed: %s\n",
3507                       print_fname_stdin(fname), g10_errstr(rc) );
3508         break;
3509
3510       case aVerify:
3511         if(multifile)
3512           {
3513             if( (rc = verify_files( argc, argv ) ))
3514               log_error("verify files failed: %s\n", g10_errstr(rc) );
3515           }
3516         else
3517           {
3518             if( (rc = verify_signatures( argc, argv ) ))
3519               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
3520           }
3521         break;
3522
3523       case aDecrypt:
3524         if(multifile)
3525           decrypt_messages(argc, argv);
3526         else
3527           {
3528             if( argc > 1 )
3529               wrong_args(_("--decrypt [filename]"));
3530             if( (rc = decrypt_message( fname ) ))
3531               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
3532           }
3533         break;
3534             
3535       case aSignKey:
3536         if( argc != 1 )
3537           wrong_args(_("--sign-key user-id"));
3538         /* fall through */
3539       case aLSignKey:
3540         if( argc != 1 )
3541           wrong_args(_("--lsign-key user-id"));
3542         /* fall through */
3543
3544         sl=NULL;
3545
3546         if(cmd==aSignKey)
3547           append_to_strlist(&sl,"sign");
3548         else if(cmd==aLSignKey)
3549           append_to_strlist(&sl,"lsign");
3550         else
3551           BUG();
3552
3553         append_to_strlist( &sl, "save" );
3554         username = make_username( fname );
3555         keyedit_menu(fname, locusr, sl, 0, 0 );
3556         xfree(username);
3557         free_strlist(sl);
3558         break;
3559
3560       case aEditKey: /* Edit a key signature */
3561         if( !argc )
3562             wrong_args(_("--edit-key user-id [commands]"));
3563         username = make_username( fname );
3564         if( argc > 1 ) {
3565             sl = NULL;
3566             for( argc--, argv++ ; argc; argc--, argv++ )
3567                 append_to_strlist( &sl, *argv );
3568             keyedit_menu( username, locusr, sl, 0, 1 );
3569             free_strlist(sl);
3570         }
3571         else
3572             keyedit_menu(username, locusr, NULL, 0, 1 );
3573         xfree(username);
3574         break;
3575
3576       case aDeleteKeys:
3577       case aDeleteSecretKeys:
3578       case aDeleteSecretAndPublicKeys:
3579         sl = NULL;
3580         /* I'm adding these in reverse order as add_to_strlist2
3581            reverses them again, and it's easier to understand in the
3582            proper order :) */
3583         for( ; argc; argc-- )
3584           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
3585         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
3586         free_strlist(sl);
3587         break;
3588
3589       case aCheckKeys:
3590         opt.check_sigs = 1;
3591       case aListSigs:
3592         opt.list_sigs = 1;
3593       case aListKeys:
3594         sl = NULL;
3595         for( ; argc; argc--, argv++ )
3596             add_to_strlist2( &sl, *argv, utf8_strings );
3597         public_key_list( sl, 0 );
3598         free_strlist(sl);
3599         break;
3600       case aListSecretKeys:
3601         sl = NULL;
3602         for( ; argc; argc--, argv++ )
3603             add_to_strlist2( &sl, *argv, utf8_strings );
3604         secret_key_list( sl );
3605         free_strlist(sl);
3606         break;
3607       case aLocateKeys:
3608         sl = NULL;
3609         for (; argc; argc--, argv++)
3610           add_to_strlist2( &sl, *argv, utf8_strings );
3611         public_key_list (sl, 1);
3612         free_strlist (sl);
3613         break;
3614
3615       case aKeygen: /* generate a key */
3616         if( opt.batch ) {
3617             if( argc > 1 )
3618                 wrong_args("--gen-key [parameterfile]");
3619             generate_keypair( argc? *argv : NULL, NULL, NULL );
3620         }
3621         else {
3622             if( argc )
3623                 wrong_args("--gen-key");
3624             generate_keypair(NULL, NULL, NULL);
3625         }
3626         break;
3627
3628       case aFastImport:
3629         opt.import_options |= IMPORT_FAST;
3630       case aImport:
3631         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3632         break;
3633
3634         /* TODO: There are a number of command that use this same
3635            "make strlist, call function, report error, free strlist"
3636            pattern.  Join them together here and avoid all that
3637            duplicated code. */
3638
3639       case aExport:
3640       case aSendKeys:
3641       case aRecvKeys:
3642         sl = NULL;
3643         for( ; argc; argc--, argv++ )
3644             append_to_strlist2( &sl, *argv, utf8_strings );
3645         if( cmd == aSendKeys )
3646             rc=keyserver_export( sl );
3647         else if( cmd == aRecvKeys )
3648             rc=keyserver_import( sl );
3649         else
3650             rc=export_pubkeys( sl, opt.export_options );
3651         if(rc)
3652           {
3653             if(cmd==aSendKeys)
3654               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3655             else if(cmd==aRecvKeys)
3656               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3657             else
3658               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3659           }
3660         free_strlist(sl);
3661         break;
3662
3663      case aSearchKeys:
3664         sl = NULL;
3665         for( ; argc; argc--, argv++ )
3666           append_to_strlist2( &sl, *argv, utf8_strings );
3667         rc=keyserver_search( sl );
3668         if(rc)
3669           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3670         free_strlist(sl);
3671         break;
3672
3673       case aRefreshKeys:
3674         sl = NULL;
3675         for( ; argc; argc--, argv++ )
3676             append_to_strlist2( &sl, *argv, utf8_strings );
3677         rc=keyserver_refresh(sl);
3678         if(rc)
3679           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3680         free_strlist(sl);
3681         break;
3682
3683       case aFetchKeys:
3684         sl = NULL;
3685         for( ; argc; argc--, argv++ )
3686             append_to_strlist2( &sl, *argv, utf8_strings );
3687         rc=keyserver_fetch(sl);
3688         if(rc)
3689           log_error("key fetch failed: %s\n",g10_errstr(rc));
3690         free_strlist(sl);
3691         break;
3692
3693       case aExportSecret:
3694         sl = NULL;
3695         for( ; argc; argc--, argv++ )
3696             add_to_strlist2( &sl, *argv, utf8_strings );
3697         export_seckeys( sl );
3698         free_strlist(sl);
3699         break;
3700
3701       case aExportSecretSub:
3702         sl = NULL;
3703         for( ; argc; argc--, argv++ )
3704             add_to_strlist2( &sl, *argv, utf8_strings );
3705         export_secsubkeys( sl );
3706         free_strlist(sl);
3707         break;
3708
3709       case aGenRevoke:
3710         if( argc != 1 )
3711             wrong_args("--gen-revoke user-id");
3712         username =  make_username(*argv);
3713         gen_revoke( username );
3714         xfree( username );
3715         break;
3716
3717       case aDesigRevoke:
3718         if( argc != 1 )
3719             wrong_args("--desig-revoke user-id");
3720         username =  make_username(*argv);
3721         gen_desig_revoke( username, locusr );
3722         xfree( username );
3723         break;
3724
3725       case aDeArmor:
3726         if( argc > 1 )
3727             wrong_args("--dearmor [file]");
3728         rc = dearmor_file( argc? *argv: NULL );
3729         if( rc )
3730             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3731         break;
3732
3733       case aEnArmor:
3734         if( argc > 1 )
3735             wrong_args("--enarmor [file]");
3736         rc = enarmor_file( argc? *argv: NULL );
3737         if( rc )
3738             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3739         break;
3740
3741
3742       case aPrimegen:
3743 #if 0 /*FIXME*/
3744         {   int mode = argc < 2 ? 0 : atoi(*argv);
3745
3746             if( mode == 1 && argc == 2 ) {
3747                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3748             }
3749             else if( mode == 2 && argc == 3 ) {
3750                 mpi_print( stdout, generate_elg_prime(
3751                                              0, atoi(argv[1]),
3752                                              atoi(argv[2]), NULL,NULL ), 1);
3753             }
3754             else if( mode == 3 && argc == 3 ) {
3755                 MPI *factors;
3756                 mpi_print( stdout, generate_elg_prime(
3757                                              1, atoi(argv[1]),
3758                                              atoi(argv[2]), NULL,&factors ), 1);
3759                 putchar('\n');
3760                 mpi_print( stdout, factors[0], 1 ); /* print q */
3761             }
3762             else if( mode == 4 && argc == 3 ) {
3763                 MPI g = mpi_alloc(1);
3764                 mpi_print( stdout, generate_elg_prime(
3765                                                  0, atoi(argv[1]),
3766                                                  atoi(argv[2]), g, NULL ), 1);
3767                 putchar('\n');
3768                 mpi_print( stdout, g, 1 );
3769                 mpi_free(g);
3770             }
3771             else
3772                 wrong_args("--gen-prime mode bits [qbits] ");
3773             putchar('\n');
3774         }
3775 #endif
3776         wrong_args("--gen-prime not yet supported ");
3777         break;
3778
3779       case aGenRandom:
3780         {
3781             int level = argc ? atoi(*argv):0;
3782             int count = argc > 1 ? atoi(argv[1]): 0;
3783             int endless = !count;
3784
3785             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3786                 wrong_args("--gen-random 0|1|2 [count]");
3787
3788             while( endless || count ) {
3789                 byte *p;
3790                 /* Wee need a multiple of 3, so that in case of
3791                    armored output we get a correct string.  No
3792                    linefolding is done, as it is best to levae this to
3793                    other tools */
3794                 size_t n = !endless && count < 99? count : 99;
3795
3796                 p = gcry_random_bytes (n, level);
3797 #ifdef HAVE_DOSISH_SYSTEM
3798                 setmode ( fileno(stdout), O_BINARY );
3799 #endif
3800                 if (opt.armor) {
3801                     char *tmp = make_radix64_string (p, n);
3802                     fputs (tmp, stdout);
3803                     xfree (tmp);
3804                     if (n%3 == 1)
3805                       putchar ('=');
3806                     if (n%3)
3807                       putchar ('=');
3808                 } else {
3809                     fwrite( p, n, 1, stdout );
3810                 }
3811                 xfree(p);
3812                 if( !endless )
3813                     count -= n;
3814             }
3815             if (opt.armor)
3816                 putchar ('\n');
3817         }
3818         break;
3819
3820       case aPrintMD:
3821         if( argc < 1)
3822             wrong_args("--print-md algo [files]");
3823         {
3824             int all_algos = (**argv=='*' && !(*argv)[1]);
3825             int algo = all_algos? 0 : gcry_md_map_name (*argv);
3826
3827             if( !algo && !all_algos )
3828                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3829             else {
3830                 argc--; argv++;
3831                 if( !argc )
3832                     print_mds(NULL, algo);
3833                 else {
3834                     for(; argc; argc--, argv++ )
3835                         print_mds(*argv, algo);
3836                 }
3837             }
3838         }
3839         break;
3840
3841       case aPrintMDs: /* old option */
3842         if( !argc )
3843             print_mds(NULL,0);
3844         else {
3845             for(; argc; argc--, argv++ )
3846                 print_mds(*argv,0);
3847         }
3848         break;
3849
3850       case aListTrustDB:
3851         if( !argc )
3852             list_trustdb(NULL);
3853         else {
3854             for( ; argc; argc--, argv++ )
3855                 list_trustdb( *argv );
3856         }
3857         break;
3858
3859       case aUpdateTrustDB:
3860         if( argc )
3861             wrong_args("--update-trustdb");
3862         update_trustdb();
3863         break;
3864
3865       case aCheckTrustDB:
3866         /* Old versions allowed for arguments - ignore them */
3867         check_trustdb();
3868         break;
3869
3870       case aFixTrustDB:
3871         log_error("this command is not yet implemented.\n");
3872         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3873         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3874         break;
3875
3876       case aListTrustPath:
3877         if( !argc )
3878             wrong_args("--list-trust-path <user-ids>");
3879         for( ; argc; argc--, argv++ ) {
3880             username = make_username( *argv );
3881             list_trust_path( username );
3882             xfree(username);
3883         }
3884         break;
3885
3886       case aExportOwnerTrust:
3887         if( argc )
3888             wrong_args("--export-ownertrust");
3889         export_ownertrust();
3890         break;
3891
3892       case aImportOwnerTrust:
3893         if( argc > 1 )
3894             wrong_args("--import-ownertrust [file]");
3895         import_ownertrust( argc? *argv:NULL );
3896         break;
3897       
3898       case aRebuildKeydbCaches:
3899         if (argc)
3900             wrong_args ("--rebuild-keydb-caches");
3901         keydb_rebuild_caches (1);
3902         break;
3903
3904 #ifdef ENABLE_CARD_SUPPORT
3905       case aCardStatus:
3906         if (argc)
3907             wrong_args ("--card-status");
3908         card_status (stdout, NULL, 0);
3909         break;
3910
3911       case aCardEdit:
3912         if (argc) {
3913             sl = NULL;
3914             for (argc--, argv++ ; argc; argc--, argv++)
3915                 append_to_strlist (&sl, *argv);
3916             card_edit (sl);
3917             free_strlist (sl);
3918         }
3919         else
3920             card_edit (NULL);
3921         break;
3922
3923       case aChangePIN:
3924         if (!argc)
3925             change_pin (0,1);
3926         else if (argc == 1)
3927             change_pin (atoi (*argv),1);
3928         else
3929         wrong_args ("--change-pin [no]");
3930         break;
3931 #endif /* ENABLE_CARD_SUPPORT*/
3932
3933       case aListConfig:
3934         {
3935           char *str=collapse_args(argc,argv);
3936           list_config(str);
3937           xfree(str);
3938         }
3939         break;
3940
3941       case aListPackets:
3942         opt.list_packets=2;
3943       default:
3944         if( argc > 1 )
3945             wrong_args(_("[filename]"));
3946         /* Issue some output for the unix newbie */
3947         if( !fname && !opt.outfile && isatty( fileno(stdin) )
3948                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
3949             log_info(_("Go ahead and type your message ...\n"));
3950
3951         a = iobuf_open(fname);
3952         if (a && is_secured_file (iobuf_get_fd (a)))
3953           {
3954             iobuf_close (a);
3955             a = NULL;
3956             errno = EPERM;
3957           }
3958         if( !a )
3959             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
3960         else {
3961
3962             if( !opt.no_armor ) {
3963                 if( use_armor_filter( a ) ) {
3964                     afx = new_armor_context ();
3965                     push_armor_filter (afx, a);
3966                 }
3967             }
3968             if( cmd == aListPackets ) {
3969                 set_packet_list_mode(1);
3970                 opt.list_packets=1;
3971             }
3972             rc = proc_packets(NULL, a );
3973             if( rc )
3974                 log_error("processing message failed: %s\n", g10_errstr(rc) );
3975             iobuf_close(a);
3976         }
3977         break;
3978       }
3979
3980     /* cleanup */
3981     release_armor_context (afx);
3982     FREE_STRLIST(remusr);
3983     FREE_STRLIST(locusr);
3984     g10_exit(0);
3985     return 8; /*NEVER REACHED*/
3986 }
3987
3988
3989 /* Note: This function is used by signal handlers!. */
3990 static void
3991 emergency_cleanup (void)
3992 {
3993   gcry_control (GCRYCTL_TERM_SECMEM );
3994 }
3995
3996
3997 void
3998 g10_exit( int rc )
3999 {
4000   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
4001   if ( (opt.debug & DBG_MEMSTAT_VALUE) )
4002     {
4003       gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
4004       gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
4005     }
4006   if (opt.debug)
4007     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
4008
4009   emergency_cleanup ();
4010   
4011   rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
4012   exit (rc);
4013 }
4014
4015
4016 /* Pretty-print hex hashes.  This assumes at least an 80-character
4017    display, but there are a few other similar assumptions in the
4018    display code. */
4019 static void
4020 print_hex( gcry_md_hd_t md, int algo, const char *fname )
4021 {
4022   int i,n,count,indent=0;
4023   const byte *p;
4024
4025   if(fname)
4026     indent=printf("%s: ",fname);
4027
4028   if(indent>40)
4029     {
4030       printf("\n");
4031       indent=0;
4032     }
4033
4034   if(algo==DIGEST_ALGO_RMD160)
4035     indent+=printf("RMD160 = ");
4036   else if(algo>0)
4037     indent+=printf("%6s = ", gcry_md_algo_name (algo));
4038   else
4039     algo=abs(algo);
4040
4041   count=indent;
4042
4043   p = gcry_md_read (md, algo);
4044   n = gcry_md_get_algo_dlen (algo);
4045
4046   count += printf ("%02X",*p++);
4047
4048   for(i=1;i<n;i++,p++)
4049     {
4050       if(n==16)
4051         {
4052           if(count+2>79)
4053             {
4054               printf("\n%*s",indent," ");
4055               count=indent;
4056             }
4057           else
4058             count+=printf(" ");
4059
4060           if(!(i%8))
4061             count+=printf(" ");
4062         }
4063       else if (n==20)
4064         {
4065           if(!(i%2))
4066             {
4067               if(count+4>79)
4068                 {
4069                   printf("\n%*s",indent," ");
4070                   count=indent;
4071                 }
4072               else
4073                 count+=printf(" ");
4074             }
4075
4076           if(!(i%10))
4077             count+=printf(" ");
4078         }
4079       else
4080         {
4081           if(!(i%4))
4082             {
4083               if(count+8>79)
4084                 {
4085                   printf("\n%*s",indent," ");
4086                   count=indent;
4087                 }
4088               else
4089                 count+=printf(" ");
4090             }
4091         }
4092
4093       count+=printf("%02X",*p);
4094     }
4095
4096   printf("\n");
4097 }
4098
4099 static void
4100 print_hashline( gcry_md_hd_t md, int algo, const char *fname )
4101 {
4102     int i, n;
4103     const byte *p;
4104     
4105     if ( fname ) {
4106         for (p = fname; *p; p++ ) {
4107             if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
4108                 printf("%%%02X", *p );
4109             else 
4110                 putchar( *p );
4111         }
4112     }
4113     putchar(':');
4114     printf("%d:", algo );
4115     p = gcry_md_read (md, algo);
4116     n = gcry_md_get_algo_dlen (algo);
4117     for(i=0; i < n ; i++, p++ ) 
4118         printf("%02X", *p );
4119     putchar(':');
4120     putchar('\n');
4121 }
4122
4123 static void
4124 print_mds( const char *fname, int algo )
4125 {
4126     FILE *fp;
4127     char buf[1024];
4128     size_t n;
4129     gcry_md_hd_t md;
4130
4131     if( !fname ) {
4132         fp = stdin;
4133 #ifdef HAVE_DOSISH_SYSTEM
4134         setmode ( fileno(fp) , O_BINARY );
4135 #endif
4136     }
4137     else {
4138         fp = fopen( fname, "rb" );
4139         if (fp && is_secured_file (fileno (fp)))
4140           {
4141             fclose (fp);
4142             fp = NULL;
4143             errno = EPERM;