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