* getkey.c (parse_auto_key_locate): Fix dupe-removal code.
[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         /* TODO: There are a number of command that use this same
3403            "make strlist, call function, report error, free strlist"
3404            pattern.  Join them together here and avoid all that
3405            duplicated code. */
3406
3407       case aExport:
3408       case aSendKeys:
3409       case aRecvKeys:
3410         sl = NULL;
3411         for( ; argc; argc--, argv++ )
3412             append_to_strlist2( &sl, *argv, utf8_strings );
3413         if( cmd == aSendKeys )
3414             rc=keyserver_export( sl );
3415         else if( cmd == aRecvKeys )
3416             rc=keyserver_import( sl );
3417         else
3418             rc=export_pubkeys( sl, opt.export_options );
3419         if(rc)
3420           {
3421             if(cmd==aSendKeys)
3422               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3423             else if(cmd==aRecvKeys)
3424               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3425             else
3426               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3427           }
3428         free_strlist(sl);
3429         break;
3430
3431      case aSearchKeys:
3432         sl = NULL;
3433         for( ; argc; argc--, argv++ )
3434           append_to_strlist2( &sl, *argv, utf8_strings );
3435         rc=keyserver_search( sl );
3436         if(rc)
3437           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3438         free_strlist(sl);
3439         break;
3440
3441       case aRefreshKeys:
3442         sl = NULL;
3443         for( ; argc; argc--, argv++ )
3444             append_to_strlist2( &sl, *argv, utf8_strings );
3445         rc=keyserver_refresh(sl);
3446         if(rc)
3447           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3448         free_strlist(sl);
3449         break;
3450
3451       case aFetchKeys:
3452         sl = NULL;
3453         for( ; argc; argc--, argv++ )
3454             append_to_strlist2( &sl, *argv, utf8_strings );
3455         rc=keyserver_fetch(sl);
3456         if(rc)
3457           log_error("key fetch failed: %s\n",g10_errstr(rc));
3458         free_strlist(sl);
3459         break;
3460
3461       case aExportSecret:
3462         sl = NULL;
3463         for( ; argc; argc--, argv++ )
3464             add_to_strlist2( &sl, *argv, utf8_strings );
3465         export_seckeys( sl );
3466         free_strlist(sl);
3467         break;
3468
3469       case aExportSecretSub:
3470         sl = NULL;
3471         for( ; argc; argc--, argv++ )
3472             add_to_strlist2( &sl, *argv, utf8_strings );
3473         export_secsubkeys( sl );
3474         free_strlist(sl);
3475         break;
3476
3477       case aGenRevoke:
3478         if( argc != 1 )
3479             wrong_args("--gen-revoke user-id");
3480         username =  make_username(*argv);
3481         gen_revoke( username );
3482         xfree( username );
3483         break;
3484
3485       case aDesigRevoke:
3486         if( argc != 1 )
3487             wrong_args("--desig-revoke user-id");
3488         username =  make_username(*argv);
3489         gen_desig_revoke( username, locusr );
3490         xfree( username );
3491         break;
3492
3493       case aDeArmor:
3494         if( argc > 1 )
3495             wrong_args("--dearmor [file]");
3496         rc = dearmor_file( argc? *argv: NULL );
3497         if( rc )
3498             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3499         break;
3500
3501       case aEnArmor:
3502         if( argc > 1 )
3503             wrong_args("--enarmor [file]");
3504         rc = enarmor_file( argc? *argv: NULL );
3505         if( rc )
3506             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3507         break;
3508
3509
3510       case aPrimegen:
3511         {   int mode = argc < 2 ? 0 : atoi(*argv);
3512
3513             if( mode == 1 && argc == 2 ) {
3514                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3515             }
3516             else if( mode == 2 && argc == 3 ) {
3517                 mpi_print( stdout, generate_elg_prime(
3518                                              0, atoi(argv[1]),
3519                                              atoi(argv[2]), NULL,NULL ), 1);
3520             }
3521             else if( mode == 3 && argc == 3 ) {
3522                 MPI *factors;
3523                 mpi_print( stdout, generate_elg_prime(
3524                                              1, atoi(argv[1]),
3525                                              atoi(argv[2]), NULL,&factors ), 1);
3526                 putchar('\n');
3527                 mpi_print( stdout, factors[0], 1 ); /* print q */
3528             }
3529             else if( mode == 4 && argc == 3 ) {
3530                 MPI g = mpi_alloc(1);
3531                 mpi_print( stdout, generate_elg_prime(
3532                                                  0, atoi(argv[1]),
3533                                                  atoi(argv[2]), g, NULL ), 1);
3534                 putchar('\n');
3535                 mpi_print( stdout, g, 1 );
3536                 mpi_free(g);
3537             }
3538             else
3539                 wrong_args("--gen-prime mode bits [qbits] ");
3540             putchar('\n');
3541         }
3542         break;
3543
3544       case aGenRandom:
3545         {
3546             int level = argc ? atoi(*argv):0;
3547             int count = argc > 1 ? atoi(argv[1]): 0;
3548             int endless = !count;
3549
3550             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3551                 wrong_args("--gen-random 0|1|2 [count]");
3552
3553             while( endless || count ) {
3554                 byte *p;
3555                 /* Wee need a multiple of 3, so that in case of
3556                    armored output we get a correct string.  No
3557                    linefolding is done, as it is best to levae this to
3558                    other tools */
3559                 size_t n = !endless && count < 99? count : 99;
3560
3561                 p = get_random_bits( n*8, level, 0);
3562 #ifdef HAVE_DOSISH_SYSTEM
3563                 setmode ( fileno(stdout), O_BINARY );
3564 #endif
3565                 if (opt.armor) {
3566                     char *tmp = make_radix64_string (p, n);
3567                     fputs (tmp, stdout);
3568                     xfree (tmp);
3569                     if (n%3 == 1)
3570                       putchar ('=');
3571                     if (n%3)
3572                       putchar ('=');
3573                 } else {
3574                     fwrite( p, n, 1, stdout );
3575                 }
3576                 xfree(p);
3577                 if( !endless )
3578                     count -= n;
3579             }
3580             if (opt.armor)
3581                 putchar ('\n');
3582         }
3583         break;
3584
3585       case aPrintMD:
3586         if( argc < 1)
3587             wrong_args("--print-md algo [files]");
3588         {
3589             int all_algos = (**argv=='*' && !(*argv)[1]);
3590             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3591
3592             if( !algo && !all_algos )
3593                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3594             else {
3595                 argc--; argv++;
3596                 if( !argc )
3597                     print_mds(NULL, algo);
3598                 else {
3599                     for(; argc; argc--, argv++ )
3600                         print_mds(*argv, algo);
3601                 }
3602             }
3603         }
3604         break;
3605
3606       case aPrintMDs: /* old option */
3607         if( !argc )
3608             print_mds(NULL,0);
3609         else {
3610             for(; argc; argc--, argv++ )
3611                 print_mds(*argv,0);
3612         }
3613         break;
3614
3615       case aListTrustDB:
3616         if( !argc )
3617             list_trustdb(NULL);
3618         else {
3619             for( ; argc; argc--, argv++ )
3620                 list_trustdb( *argv );
3621         }
3622         break;
3623
3624       case aUpdateTrustDB:
3625         if( argc )
3626             wrong_args("--update-trustdb");
3627         update_trustdb();
3628         break;
3629
3630       case aCheckTrustDB:
3631         /* Old versions allowed for arguments - ignore them */
3632         check_trustdb();
3633         break;
3634
3635       case aFixTrustDB:
3636         log_error("this command is not yet implemented.\n");
3637         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3638         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3639         break;
3640
3641       case aListTrustPath:
3642         if( !argc )
3643             wrong_args("--list-trust-path <user-ids>");
3644         for( ; argc; argc--, argv++ ) {
3645             username = make_username( *argv );
3646             list_trust_path( username );
3647             xfree(username);
3648         }
3649         break;
3650
3651       case aExportOwnerTrust:
3652         if( argc )
3653             wrong_args("--export-ownertrust");
3654         export_ownertrust();
3655         break;
3656
3657       case aImportOwnerTrust:
3658         if( argc > 1 )
3659             wrong_args("--import-ownertrust [file]");
3660         import_ownertrust( argc? *argv:NULL );
3661         break;
3662       
3663       case aPipeMode:
3664         if ( argc )
3665             wrong_args ("--pipemode");
3666         run_in_pipemode ();
3667         break;
3668
3669       case aRebuildKeydbCaches:
3670         if (argc)
3671             wrong_args ("--rebuild-keydb-caches");
3672         keydb_rebuild_caches (1);
3673         break;
3674
3675 #ifdef ENABLE_CARD_SUPPORT
3676       case aCardStatus:
3677         if (argc)
3678             wrong_args ("--card-status");
3679         card_status (stdout, NULL, 0);
3680         break;
3681
3682       case aCardEdit:
3683         if (argc) {
3684             sl = NULL;
3685             for (argc--, argv++ ; argc; argc--, argv++)
3686                 append_to_strlist (&sl, *argv);
3687             card_edit (sl);
3688             free_strlist (sl);
3689         }
3690         else
3691             card_edit (NULL);
3692         break;
3693
3694       case aChangePIN:
3695         if (!argc)
3696             change_pin (0,1);
3697         else if (argc == 1)
3698             change_pin (atoi (*argv),1);
3699         else
3700         wrong_args ("--change-pin [no]");
3701         break;
3702 #endif /* ENABLE_CARD_SUPPORT*/
3703
3704       case aListConfig:
3705         {
3706           char *str=collapse_args(argc,argv);
3707           list_config(str);
3708           xfree(str);
3709         }
3710         break;
3711
3712       case aListPackets:
3713         opt.list_packets=2;
3714       default:
3715         if( argc > 1 )
3716             wrong_args(_("[filename]"));
3717         /* Issue some output for the unix newbie */
3718         if( !fname && !opt.outfile && isatty( fileno(stdin) )
3719                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
3720             log_info(_("Go ahead and type your message ...\n"));
3721
3722         a = iobuf_open(fname);
3723         if (a && is_secured_file (iobuf_get_fd (a)))
3724           {
3725             iobuf_close (a);
3726             a = NULL;
3727             errno = EPERM;
3728           }
3729         if( !a )
3730             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
3731         else {
3732
3733             if( !opt.no_armor ) {
3734                 if( use_armor_filter( a ) ) {
3735                     memset( &afx, 0, sizeof afx);
3736                     iobuf_push_filter( a, armor_filter, &afx );
3737                 }
3738             }
3739             if( cmd == aListPackets ) {
3740                 set_packet_list_mode(1);
3741                 opt.list_packets=1;
3742             }
3743             rc = proc_packets(NULL, a );
3744             if( rc )
3745                 log_error("processing message failed: %s\n", g10_errstr(rc) );
3746             iobuf_close(a);
3747         }
3748         break;
3749       }
3750
3751     /* cleanup */
3752     FREE_STRLIST(remusr);
3753     FREE_STRLIST(locusr);
3754     g10_exit(0);
3755     return 8; /*NEVER REACHED*/
3756 }
3757
3758
3759 void
3760 g10_exit( int rc )
3761 {
3762 #ifdef ENABLE_CARD_SUPPORT
3763     card_close ();
3764 #endif
3765     update_random_seed_file();
3766     if( opt.debug & DBG_MEMSTAT_VALUE ) {
3767         m_print_stats("on exit");
3768         random_dump_stats();
3769     }
3770     if( opt.debug )
3771         secmem_dump_stats();
3772     secmem_term();
3773     rc = rc? rc : log_get_errorcount(0)? 2 :
3774                         g10_errors_seen? 1 : 0;
3775     exit(rc );
3776 }
3777
3778
3779 /* Pretty-print hex hashes.  This assumes at least an 80-character
3780    display, but there are a few other similar assumptions in the
3781    display code. */
3782 static void
3783 print_hex( MD_HANDLE md, int algo, const char *fname )
3784 {
3785   int i,n,count,indent=0;
3786   const byte *p;
3787
3788   if(fname)
3789     indent=printf("%s: ",fname);
3790
3791   if(indent>40)
3792     {
3793       printf("\n");
3794       indent=0;
3795     }
3796
3797   if(algo==DIGEST_ALGO_RMD160)
3798     indent+=printf("RMD160 = ");
3799   else if(algo>0)
3800     indent+=printf("%6s = ",digest_algo_to_string(algo));
3801   else
3802     algo=abs(algo);
3803
3804   count=indent;
3805
3806   p = md_read( md, algo );
3807   n = md_digest_length(algo);
3808
3809   count+=printf("%02X",*p++);
3810
3811   for(i=1;i<n;i++,p++)
3812     {
3813       if(n==16)
3814         {
3815           if(count+2>79)
3816             {
3817               printf("\n%*s",indent," ");
3818               count=indent;
3819             }
3820           else
3821             count+=printf(" ");
3822
3823           if(!(i%8))
3824             count+=printf(" ");
3825         }
3826       else if (n==20)
3827         {
3828           if(!(i%2))
3829             {
3830               if(count+4>79)
3831                 {
3832                   printf("\n%*s",indent," ");
3833                   count=indent;
3834                 }
3835               else
3836                 count+=printf(" ");
3837             }
3838
3839           if(!(i%10))
3840             count+=printf(" ");
3841         }
3842       else
3843         {
3844           if(!(i%4))
3845             {
3846               if(count+8>79)
3847                 {
3848                   printf("\n%*s",indent," ");
3849                   count=indent;
3850                 }
3851               else
3852                 count+=printf(" ");
3853             }
3854         }
3855
3856       count+=printf("%02X",*p);
3857     }
3858
3859   printf("\n");
3860 }
3861
3862 static void
3863 print_hashline( MD_HANDLE md, int algo, const char *fname )
3864 {
3865     int i, n;
3866     const byte *p;
3867     
3868     if ( fname ) {
3869         for (p = fname; *p; p++ ) {
3870             if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
3871                 printf("%%%02X", *p );
3872             else 
3873                 putchar( *p );
3874         }
3875     }
3876     putchar(':');
3877     printf("%d:", algo );
3878     p = md_read( md, algo );
3879     n = md_digest_length(algo);
3880     for(i=0; i < n ; i++, p++ ) 
3881         printf("%02X", *p );
3882     putchar(':');
3883     putchar('\n');
3884 }
3885
3886 static void
3887 print_mds( const char *fname, int algo )
3888 {
3889     FILE *fp;
3890     char buf[1024];
3891     size_t n;
3892     MD_HANDLE md;
3893
3894     if( !fname ) {
3895         fp = stdin;
3896 #ifdef HAVE_DOSISH_SYSTEM
3897         setmode ( fileno(fp) , O_BINARY );
3898 #endif
3899     }
3900     else {
3901         fp = fopen( fname, "rb" );
3902         if (fp && is_secured_file (fileno (fp)))
3903           {
3904             fclose (fp);
3905             fp = NULL;
3906             errno = EPERM;
3907           }
3908     }
3909     if( !fp ) {
3910         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3911         return;
3912     }
3913
3914     md = md_open( 0, 0 );
3915     if( algo )
3916         md_enable( md, algo );
3917     else {
3918         md_enable( md, DIGEST_ALGO_MD5 );
3919         md_enable( md, DIGEST_ALGO_SHA1 );
3920         md_enable( md, DIGEST_ALGO_RMD160 );
3921 #ifdef USE_SHA256
3922         md_enable( md, DIGEST_ALGO_SHA256 );
3923 #endif
3924 #ifdef USE_SHA512
3925         md_enable( md, DIGEST_ALGO_SHA384 );
3926         md_enable( md, DIGEST_ALGO_SHA512 );
3927 #endif
3928     }
3929
3930     while( (n=fread( buf, 1, DIM(buf), fp )) )
3931         md_write( md, buf, n );
3932     if( ferror(fp) )
3933         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3934     else {
3935         md_final(md);
3936         if ( opt.with_colons ) {
3937             if ( algo ) 
3938                 print_hashline( md, algo, fname );
3939             else {
3940                 print_hashline( md, DIGEST_ALGO_MD5, fname );
3941                 print_hashline( md, DIGEST_ALGO_SHA1, fname );
3942                 print_hashline( md, DIGEST_ALGO_RMD160, fname );
3943 #ifdef USE_SHA256
3944                 print_hashline( md, DIGEST_ALGO_SHA256, fname );
3945 #endif
3946 #ifdef USE_SHA512
3947                 print_hashline( md, DIGEST_ALGO_SHA384, fname );
3948                 print_hashline( md, DIGEST_ALGO_SHA512, fname );
3949 #endif
3950             }
3951         }
3952         else {
3953             if( algo )
3954                print_hex(md,-algo,fname);
3955             else {
3956                 print_hex( md, DIGEST_ALGO_MD5, fname );
3957                 print_hex( md, DIGEST_ALGO_SHA1, fname );
3958                 print_hex( md, DIGEST_ALGO_RMD160, fname );
3959 #ifdef USE_SHA256
3960                 print_hex( md, DIGEST_ALGO_SHA256, fname );
3961 #endif
3962 #ifdef USE_SHA512
3963                 print_hex( md, DIGEST_ALGO_SHA384, fname );
3964                 print_hex( md, DIGEST_ALGO_SHA512, fname );
3965 #endif
3966             }
3967         }
3968     }
3969     md_close(md);
3970
3971     if( fp != stdin )
3972         fclose(fp);
3973 }
3974
3975
3976 /****************
3977  * Check the supplied name,value string and add it to the notation
3978  * data to be used for signatures.  which==0 for sig notations, and 1
3979  * for cert notations.
3980 */
3981 static void
3982 add_notation_data( const char *string, int which )
3983 {
3984   struct notation *notation;
3985
3986   notation=string_to_notation(string,utf8_strings);
3987   if(notation)
3988     {
3989       if(which)
3990         {
3991           notation->next=opt.cert_notations;
3992           opt.cert_notations=notation;
3993         }
3994       else
3995         {
3996           notation->next=opt.sig_notations;
3997           opt.sig_notations=notation;
3998         }
3999     }
4000 }
4001
4002 static void
4003 add_policy_url( const char *string, int which )
4004 {
4005   unsigned int i,critical=0;
4006   STRLIST sl;
4007
4008   if(*string=='!')
4009     {
4010       string++;
4011       critical=1;
4012     }
4013
4014   for(i=0;i<strlen(string);i++)
4015     if( !isascii (string[i]) || iscntrl(string[i]))
4016       break;
4017
4018   if(i==0 || i<strlen(string))
4019     {
4020       if(which)
4021         log_error(_("the given certification policy URL is invalid\n"));
4022       else
4023         log_error(_("the given signature policy URL is invalid\n"));
4024     }
4025
4026   if(which)
4027     sl=add_to_strlist( &opt.cert_policy_url, string );
4028   else
4029     sl=add_to_strlist( &opt.sig_policy_url, string );
4030
4031   if(critical)
4032     sl->flags |= 1;    
4033 }
4034
4035 static void
4036 add_keyserver_url( const char *string, int which )
4037 {
4038   unsigned int i,critical=0;
4039   STRLIST sl;
4040
4041   if(*string=='!')
4042     {
4043       string++;
4044       critical=1;
4045     }
4046
4047   for(i=0;i<strlen(string);i++)
4048     if( !isascii (string[i]) || iscntrl(string[i]))
4049       break;
4050
4051   if(i==0 || i<strlen(string))
4052     {
4053       if(which)
4054         BUG();
4055       else
4056         log_error(_("the given preferred keyserver URL is invalid\n"));
4057     }
4058
4059   if(which)
4060     BUG();
4061   else
4062     sl=add_to_strlist( &opt.sig_keyserver_url, string );
4063
4064   if(critical)
4065     sl->flags |= 1;    
4066 }