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