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