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