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