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