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