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