aboutsummaryrefslogtreecommitdiffstats
path: root/g10/gpg.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/gpg.c2196
1 files changed, 1446 insertions, 750 deletions
diff --git a/g10/gpg.c b/g10/gpg.c
index 234d13f41..49687fff1 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,6 +1,6 @@
-/* g10.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998,1999,2000,2001,2002,2003
- * 2004 Free Software Foundation, Inc.
+/* gpg.c - The GnuPG utility (main for gpg)
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ * 2006 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -16,7 +16,8 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
*/
#include <config.h>
@@ -33,19 +34,21 @@
#ifdef HAVE_STAT
#include <sys/stat.h> /* for stat() */
#endif
+#include <fcntl.h>
#include <assuan.h>
+#ifdef HAVE_W32_SYSTEM
+#include <windows.h>
+#endif
#define INCLUDED_BY_MAIN_MODULE 1
#include "gpg.h"
#include "packet.h"
-#include "iobuf.h"
-#include "memory.h"
+#include "../common/iobuf.h"
#include "util.h"
#include "main.h"
#include "options.h"
#include "keydb.h"
#include "trustdb.h"
-#include "mpi.h"
#include "cipher.h"
#include "filter.h"
#include "ttyio.h"
@@ -54,15 +57,28 @@
#include "keyserver-internal.h"
#include "exec.h"
-enum cmd_and_opt_values { aNull = 0,
+
+#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
+#define MY_O_BINARY O_BINARY
+#ifndef S_IRGRP
+# define S_IRGRP 0
+# define S_IWGRP 0
+#endif
+#else
+#define MY_O_BINARY 0
+#endif
+
+
+enum cmd_and_opt_values
+ {
+ aNull = 0,
oArmor = 'a',
aDetachedSign = 'b',
aSym = 'c',
aDecrypt = 'd',
aEncr = 'e',
oInteractive = 'i',
- aListKeys = 'k',
- aListSecretKeys = 'K',
+ oKOption = 'k',
oDryRun = 'n',
oOutput = 'o',
oQuiet = 'q',
@@ -70,42 +86,49 @@ enum cmd_and_opt_values { aNull = 0,
oHiddenRecipient = 'R',
aSign = 's',
oTextmodeShort= 't',
- oUser = 'u',
+ oLocalUser = 'u',
oVerbose = 'v',
oCompress = 'z',
oSetNotation = 'N',
+ aListSecretKeys = 'K',
oBatch = 500,
- aGPGConfList,
+ oMaxOutput,
oSigNotation,
oCertNotation,
oShowNotation,
oNoShowNotation,
aEncrFiles,
- aDecryptFiles,
+ aEncrSym,
+ aDecryptFiles,
aClearsign,
aStore,
aKeygen,
aSignEncr,
+ aSignEncrSym,
aSignSym,
aSignKey,
aLSignKey,
- aNRSignKey,
- aNRLSignKey,
+ aListConfig,
+ aGPGConfList,
aListPackets,
aEditKey,
aDeleteKeys,
aDeleteSecretKeys,
aDeleteSecretAndPublicKeys,
+ aKMode,
+ aKModeC,
aImport,
aFastImport,
aVerify,
aVerifyFiles,
+ aListKeys,
aListSigs,
aSendKeys,
aRecvKeys,
aSearchKeys,
+ aRefreshKeys,
+ aFetchKeys,
aExport,
- aExportAll,
aExportSecret,
aExportSecretSub,
aCheckKeys,
@@ -125,9 +148,7 @@ enum cmd_and_opt_values { aNull = 0,
aDeArmor,
aEnArmor,
aGenRandom,
- aPipeMode,
aRebuildKeydbCaches,
- aRefreshKeys,
aCardStatus,
aCardEdit,
aChangePIN,
@@ -136,15 +157,20 @@ enum cmd_and_opt_values { aNull = 0,
oNoTextmode,
oExpert,
oNoExpert,
+ oDefSigExpire,
oAskSigExpire,
oNoAskSigExpire,
+ oDefCertExpire,
oAskCertExpire,
oNoAskCertExpire,
+ oDefCertLevel,
+ oMinCertLevel,
+ oAskCertLevel,
+ oNoAskCertLevel,
oFingerprint,
oWithFingerprint,
oAnswerYes,
oAnswerNo,
- oDefCertCheckLevel,
oKeyring,
oPrimaryKeyring,
oSecretKeyring,
@@ -157,16 +183,11 @@ enum cmd_and_opt_values { aNull = 0,
oDebug,
oDebugLevel,
oDebugAll,
+ oDebugCCIDDriver,
oStatusFD,
-#ifdef __riscos__
oStatusFile,
-#endif /* __riscos__ */
oAttributeFD,
-#ifdef __riscos__
oAttributeFile,
-#endif /* __riscos__ */
- oSKComments,
- oNoSKComments,
oEmitVersion,
oNoEmitVersion,
oCompletesNeeded,
@@ -181,22 +202,26 @@ enum cmd_and_opt_values { aNull = 0,
oPGP6,
oPGP7,
oPGP8,
+ oRFC2440Text,
+ oNoRFC2440Text,
oCipherAlgo,
oDigestAlgo,
oCertDigestAlgo,
oCompressAlgo,
+ oCompressLevel,
+ oBZ2CompressLevel,
+ oBZ2DecompressLowmem,
+ oPasswd,
oPasswdFD,
-#ifdef __riscos__
oPasswdFile,
-#endif /* __riscos__ */
oCommandFD,
-#ifdef __riscos__
oCommandFile,
-#endif /* __riscos__ */
oQuickRandom,
oNoVerbose,
oTrustDBName,
oNoSecmemWarn,
+ oRequireSecmem,
+ oNoRequireSecmem,
oNoPermissionWarn,
oNoMDCWarn,
oNoArmor,
@@ -214,7 +239,6 @@ enum cmd_and_opt_values { aNull = 0,
oAlwaysTrust,
oTrustModel,
oForceOwnertrust,
- oEmuChecksumBug,
oSetFilename,
oForYourEyesOnly,
oNoForYourEyesOnly,
@@ -225,11 +249,12 @@ enum cmd_and_opt_values { aNull = 0,
oNoShowPolicyURL,
oSigKeyserverURL,
oUseEmbeddedFilename,
+ oNoUseEmbeddedFilename,
oComment,
oDefaultComment,
oNoComments,
- oThrowKeyid,
- oNoThrowKeyid,
+ oThrowKeyids,
+ oNoThrowKeyids,
oShowPhotos,
oNoShowPhotos,
oPhotoViewer,
@@ -245,7 +270,7 @@ enum cmd_and_opt_values { aNull = 0,
oS2KDigest,
oS2KCipher,
oSimpleSKChecksum,
- oCharset,
+ oDisplayCharset,
oNotDashEscaped,
oEscapeFrom,
oNoEscapeFrom,
@@ -263,11 +288,8 @@ enum cmd_and_opt_values { aNull = 0,
oEncryptTo,
oHiddenEncryptTo,
oNoEncryptTo,
- oLogFile,
oLoggerFD,
-#ifdef __riscos__
oLoggerFile,
-#endif /* __riscos__ */
oUtf8Strings,
oNoUtf8Strings,
oDisableCipherAlgo,
@@ -309,7 +331,6 @@ enum cmd_and_opt_values { aNull = 0,
oPersonalCipherPreferences,
oPersonalDigestPreferences,
oPersonalCompressPreferences,
- oEmuMDEncodeBug,
oAgentProgram,
oDisplay,
oTTYname,
@@ -317,13 +338,25 @@ enum cmd_and_opt_values { aNull = 0,
oLCctype,
oLCmessages,
oGroup,
+ oUnGroup,
+ oNoGroups,
oStrict,
oNoStrict,
oMangleDosFilenames,
oNoMangleDosFilenames,
- oEnableProgressFilter,
+ oEnableProgressFilter,
oMultifile,
-aTest };
+ oKeyidFormat,
+ oExitOnStatusWriteError,
+ oLimitCardInsertTries,
+ oRequireCrossCert,
+ oNoRequireCrossCert,
+ oAutoKeyLocate,
+ oNoAutoKeyLocate,
+ oAllowMultisigVerification,
+
+ oNoop
+ };
static ARGPARSE_OPTS opts[] = {
@@ -331,7 +364,7 @@ static ARGPARSE_OPTS opts[] = {
{ 300, NULL, 0, N_("@Commands:\n ") },
{ aSign, "sign", 256, N_("|[file]|make a signature")},
- { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
+ { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature")},
{ aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
{ aEncr, "encrypt", 256, N_("encrypt data")},
{ aEncrFiles, "encrypt-files", 256, "@"},
@@ -353,8 +386,6 @@ static ARGPARSE_OPTS opts[] = {
N_("remove keys from the secret keyring")},
{ aSignKey, "sign-key" ,256, N_("sign a key")},
{ aLSignKey, "lsign-key" ,256, N_("sign a key locally")},
- { aNRSignKey, "nrsign-key" ,256, "@"},
- { aNRLSignKey, "nrlsign-key" ,256, "@"},
{ aEditKey, "edit-key" ,256, N_("sign or edit a key")},
{ aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
{ aDesigRevoke, "desig-revoke",256, "@" },
@@ -365,29 +396,32 @@ static ARGPARSE_OPTS opts[] = {
N_("search for keys on a key server") },
{ aRefreshKeys, "refresh-keys", 256,
N_("update all keys from a keyserver")},
- { aExportAll, "export-all" , 256, "@" },
+ { aFetchKeys, "fetch-keys" , 256, "@" },
{ aExportSecret, "export-secret-keys" , 256, "@" },
{ aExportSecretSub, "export-secret-subkeys" , 256, "@" },
{ aImport, "import", 256 , N_("import/merge keys")},
{ aFastImport, "fast-import", 256 , "@"},
+#ifdef ENABLE_CARD_SUPPORT
{ aCardStatus, "card-status", 256, N_("print the card status")},
{ aCardEdit, "card-edit", 256, N_("change data on a card")},
{ aChangePIN, "change-pin", 256, N_("change a card's PIN")},
-
+#endif
+ { aListConfig, "list-config", 256, "@"},
+ { aGPGConfList, "gpgconf-list", 256, "@" },
{ aListPackets, "list-packets",256, "@"},
{ aExportOwnerTrust, "export-ownertrust", 256, "@"},
{ aImportOwnerTrust, "import-ownertrust", 256, "@"},
- { aUpdateTrustDB, "update-trustdb",0 , N_("update the trust database")},
- { aCheckTrustDB, "check-trustdb",0 , "@"},
- { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
- { aDeArmor, "dearmor", 256, "@" },
- { aDeArmor, "dearmour", 256, "@" },
- { aEnArmor, "enarmor", 256, "@" },
- { aEnArmor, "enarmour", 256, "@" },
+ { aUpdateTrustDB,
+ "update-trustdb",0 , N_("update the trust database")},
+ { aCheckTrustDB, "check-trustdb", 0, "@"},
+ { aFixTrustDB, "fix-trustdb", 0, "@"},
+ { aDeArmor, "dearmor", 256, "@"},
+ { aDeArmor, "dearmour", 256, "@"},
+ { aEnArmor, "enarmor", 256, "@"},
+ { aEnArmor, "enarmour", 256, "@"},
{ aPrintMD, "print-md" , 256, N_("|algo [files]|print message digests")},
{ aPrimegen, "gen-prime" , 256, "@" },
{ aGenRandom, "gen-random" , 256, "@" },
- { aGPGConfList, "gpgconf-list", 256, "@" },
{ 301, NULL, 0, N_("@\nOptions:\n ") },
@@ -396,107 +430,117 @@ static ARGPARSE_OPTS opts[] = {
{ oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
{ oHiddenRecipient, "hidden-recipient", 2, "@" },
{ oRecipient, "remote-user", 2, "@"}, /* old option name */
- { oDefRecipient, "default-recipient" ,2, "@" },
- { oDefRecipientSelf, "default-recipient-self" ,0, "@" },
+ { oDefRecipient, "default-recipient", 2, "@"},
+ { oDefRecipientSelf, "default-recipient-self", 0, "@"},
{ oNoDefRecipient, "no-default-recipient", 0, "@" },
{ oTempDir, "temp-directory", 2, "@" },
{ oExecPath, "exec-path", 2, "@" },
{ oEncryptTo, "encrypt-to", 2, "@" },
{ oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
{ oNoEncryptTo, "no-encrypt-to", 0, "@" },
- { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
- { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
+ { oLocalUser, "local-user",2, N_("use this user-id to sign or decrypt")},
+ { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
+ { oCompressLevel, "compress-level", 1, "@" },
+ { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
+ { oBZ2DecompressLowmem, "bzip2-decompress-lowmem", 0, "@" },
{ oTextmodeShort, NULL, 0, "@"},
{ oTextmode, "textmode", 0, N_("use canonical text mode")},
{ oNoTextmode, "no-textmode", 0, "@"},
{ oExpert, "expert", 0, "@"},
{ oNoExpert, "no-expert", 0, "@"},
+ { oDefSigExpire, "default-sig-expire", 2, "@"},
{ oAskSigExpire, "ask-sig-expire", 0, "@"},
{ oNoAskSigExpire, "no-ask-sig-expire", 0, "@"},
+ { oDefCertExpire, "default-cert-expire", 2, "@"},
{ oAskCertExpire, "ask-cert-expire", 0, "@"},
{ oNoAskCertExpire, "no-ask-cert-expire", 0, "@"},
+ { oDefCertLevel, "default-cert-level", 1, "@"},
+ { oMinCertLevel, "min-cert-level", 1, "@"},
+ { oAskCertLevel, "ask-cert-level", 0, "@"},
+ { oNoAskCertLevel, "no-ask-cert-level", 0, "@"},
{ oOutput, "output", 2, N_("use as output file")},
+ { oMaxOutput, "max-output", 16|4, "@" },
{ oVerbose, "verbose", 0, N_("verbose") },
- { oQuiet, "quiet", 0, "@" },
- { oNoTTY, "no-tty", 0, "@" },
- { oLogFile, "log-file" ,2, "@" },
- { oForceV3Sigs, "force-v3-sigs", 0, "@" },
- { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@" },
- { oForceV4Certs, "force-v4-certs", 0, "@" },
- { oNoForceV4Certs, "no-force-v4-certs", 0, "@" },
- { oForceMDC, "force-mdc", 0, "@" },
+ { oQuiet, "quiet", 0, "@"},
+ { oNoTTY, "no-tty", 0, "@"},
+ { oForceV3Sigs, "force-v3-sigs", 0, "@"},
+ { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@"},
+ { oForceV4Certs, "force-v4-certs", 0, "@"},
+ { oNoForceV4Certs, "no-force-v4-certs", 0, "@"},
+ { oForceMDC, "force-mdc", 0, "@"},
{ oNoForceMDC, "no-force-mdc", 0, "@" },
- { oDisableMDC, "disable-mdc", 0, "@" },
+ { oDisableMDC, "disable-mdc", 0, "@"},
{ oNoDisableMDC, "no-disable-mdc", 0, "@" },
{ oDryRun, "dry-run", 0, N_("do not make any changes") },
{ oInteractive, "interactive", 0, N_("prompt before overwriting") },
{ oUseAgent, "use-agent",0, "@"},
{ oNoUseAgent, "no-use-agent",0, "@"},
{ oGpgAgentInfo, "gpg-agent-info",2, "@"},
- { oBatch, "batch", 0, "@"},
- { oAnswerYes, "yes", 0, "@"},
- { oAnswerNo, "no", 0, "@"},
- { oKeyring, "keyring" , 2, "@"},
+ { oBatch, "batch", 0, "@"},
+ { oAnswerYes, "yes", 0, "@"},
+ { oAnswerNo, "no", 0, "@"},
+ { oKeyring, "keyring", 2, "@"},
{ oPrimaryKeyring, "primary-keyring",2, "@" },
- { oSecretKeyring, "secret-keyring" ,2, "@"},
+ { oSecretKeyring, "secret-keyring", 2, "@"},
{ oShowKeyring, "show-keyring", 0, "@"},
- { oDefaultKey, "default-key" , 2, "@"},
- { oKeyServer, "keyserver", 2, "@"},
+ { oDefaultKey, "default-key", 2, "@"},
+ { oKeyServer, "keyserver", 2, "@"},
{ oKeyServerOptions, "keyserver-options",2,"@"},
{ oImportOptions, "import-options",2,"@"},
{ oExportOptions, "export-options",2,"@"},
{ oListOptions, "list-options",2,"@"},
{ oVerifyOptions, "verify-options",2,"@"},
- { oCharset, "charset" , 2, "@" },
- { oOptions, "options" , 2, "@"},
-
+ { oDisplayCharset, "display-charset", 2, "@"},
+ { oDisplayCharset, "charset", 2, "@"},
+ { oOptions, "options", 2, "@"},
{ oDebug, "debug" ,4|16, "@"},
{ oDebugLevel, "debug-level" ,2, "@"},
{ oDebugAll, "debug-all" ,0, "@"},
- { oStatusFD, "status-fd" ,1, "@" },
-#ifdef __riscos__
- { oStatusFile, "status-file" ,2, "@" },
-#endif /* __riscos__ */
+ { oStatusFD, "status-fd" ,1, "@"},
+ { oStatusFile, "status-file" ,2, "@"},
{ oAttributeFD, "attribute-fd" ,1, "@" },
-#ifdef __riscos__
{ oAttributeFile, "attribute-file" ,2, "@" },
-#endif /* __riscos__ */
- { oNoSKComments, "no-sk-comments", 0, "@"},
- { oSKComments, "sk-comments", 0, "@"},
+ { oNoop, "sk-comments", 0, "@"},
+ { oNoop, "no-sk-comments", 0, "@"},
{ oCompletesNeeded, "completes-needed", 1, "@"},
{ oMarginalsNeeded, "marginals-needed", 1, "@"},
{ oMaxCertDepth, "max-cert-depth", 1, "@" },
{ oTrustedKey, "trusted-key", 2, "@"},
- { oLoadExtension, "load-extension" ,2, "@"},
+ { oLoadExtension, "load-extension", 2, "@"},
{ oGnuPG, "gnupg", 0, "@"},
{ oGnuPG, "no-pgp2", 0, "@"},
{ oGnuPG, "no-pgp6", 0, "@"},
{ oGnuPG, "no-pgp7", 0, "@"},
{ oGnuPG, "no-pgp8", 0, "@"},
{ oRFC1991, "rfc1991", 0, "@"},
- { oRFC2440, "rfc2440", 0, "@"},
+ { oRFC2440, "rfc2440", 0, "@" },
{ oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
{ oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
{ oPGP6, "pgp6", 0, "@"},
{ oPGP7, "pgp7", 0, "@"},
{ oPGP8, "pgp8", 0, "@"},
- { oS2KMode, "s2k-mode", 1, "@"},
- { oS2KDigest, "s2k-digest-algo",2, "@"},
- { oS2KCipher, "s2k-cipher-algo",2, "@"},
+ { oRFC2440Text, "rfc2440-text", 0, "@"},
+ { oNoRFC2440Text, "no-rfc2440-text", 0, "@"},
+ { oS2KMode, "s2k-mode", 1, "@"},
+ { oS2KDigest, "s2k-digest-algo", 2, "@"},
+ { oS2KCipher, "s2k-cipher-algo", 2, "@"},
{ oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
- { oCipherAlgo, "cipher-algo", 2 , "@"},
- { oDigestAlgo, "digest-algo", 2 , "@"},
+ { oCipherAlgo, "cipher-algo", 2, "@"},
+ { oDigestAlgo, "digest-algo", 2, "@"},
{ oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
- { oCompressAlgo,"compress-algo",2, "@"},
- { oThrowKeyid, "throw-keyid", 0, "@"},
- { oNoThrowKeyid, "no-throw-keyid", 0, "@" },
+ { oCompressAlgo,"compress-algo", 2, "@"},
+ { oCompressAlgo, "compression-algo", 2, "@"}, /* Alias */
+ { oThrowKeyids, "throw-keyid", 0, "@"},
+ { oThrowKeyids, "throw-keyids", 0, "@"},
+ { oNoThrowKeyids, "no-throw-keyid", 0, "@" },
+ { oNoThrowKeyids, "no-throw-keyids", 0, "@" },
{ oShowPhotos, "show-photos", 0, "@" },
{ oNoShowPhotos, "no-show-photos", 0, "@" },
{ oPhotoViewer, "photo-viewer", 2, "@" },
{ oSetNotation, "set-notation", 2, "@" },
{ oSetNotation, "notation-data", 2, "@" }, /* Alias */
- { oSigNotation, "sig-notation", 2, "@" },
- { oCertNotation, "cert-notation", 2, "@" },
+ { oSigNotation, "sig-notation", 2, "@" },
+ { oCertNotation, "cert-notation", 2, "@" },
{ 302, NULL, 0, N_(
"@\n(See the man page for a complete listing of all commands and options)\n"
@@ -511,24 +555,22 @@ static ARGPARSE_OPTS opts[] = {
/* hidden options */
{ aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
- { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */
{ aPrintMDs, "print-mds" , 256, "@"}, /* old */
{ aListTrustDB, "list-trustdb",0 , "@"},
/* Not yet used */
/* { aListTrustPath, "list-trust-path",0, "@"}, */
- { aPipeMode, "pipemode", 0, "@" },
+ { oKOption, NULL, 0, "@"},
+ { oPasswd, "passphrase",2, "@" },
{ oPasswdFD, "passphrase-fd",1, "@" },
-#ifdef __riscos__
{ oPasswdFile, "passphrase-file",2, "@" },
-#endif /* __riscos__ */
{ oCommandFD, "command-fd",1, "@" },
-#ifdef __riscos__
{ oCommandFile, "command-file",2, "@" },
-#endif /* __riscos__ */
{ oQuickRandom, "quick-random", 0, "@"},
{ oNoVerbose, "no-verbose", 0, "@"},
{ oTrustDBName, "trustdb-name", 2, "@" },
- { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
+ { oNoSecmemWarn, "no-secmem-warning", 0, "@" },
+ { oRequireSecmem,"require-secmem", 0, "@" },
+ { oNoRequireSecmem,"no-require-secmem", 0, "@" },
{ oNoPermissionWarn, "no-permission-warning", 0, "@" },
{ oNoMDCWarn, "no-mdc-warning", 0, "@" },
{ oNoArmor, "no-armor", 0, "@"},
@@ -546,11 +588,10 @@ static ARGPARSE_OPTS opts[] = {
{ oSkipVerify, "skip-verify",0, "@" },
{ oCompressKeys, "compress-keys",0, "@"},
{ oCompressSigs, "compress-sigs",0, "@"},
- { oDefCertCheckLevel, "default-cert-check-level", 1, "@"},
+ { oDefCertLevel, "default-cert-check-level", 1, "@"}, /* Old option */
{ oAlwaysTrust, "always-trust", 0, "@"},
{ oTrustModel, "trust-model", 2, "@"},
{ oForceOwnertrust, "force-ownertrust", 2, "@"},
- { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"},
{ oSetFilename, "set-filename", 2, "@" },
{ oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
{ oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
@@ -559,9 +600,9 @@ static ARGPARSE_OPTS opts[] = {
{ oCertPolicyURL, "cert-policy-url", 2, "@" },
{ oShowPolicyURL, "show-policy-url", 0, "@" },
{ oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
+ { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
{ oShowNotation, "show-notation", 0, "@" },
{ oNoShowNotation, "no-show-notation", 0, "@" },
- { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
{ oComment, "comment", 2, "@" },
{ oDefaultComment, "default-comment", 0, "@" },
{ oNoComments, "no-comments", 0, "@" },
@@ -575,10 +616,9 @@ static ARGPARSE_OPTS opts[] = {
{ oLockMultiple, "lock-multiple", 0, "@" },
{ oLockNever, "lock-never", 0, "@" },
{ oLoggerFD, "logger-fd",1, "@" },
-#ifdef __riscos__
- { oLoggerFile, "logger-file",2, "@" },
-#endif /* __riscos__ */
+ { oLoggerFile, "log-file",2, "@" },
{ oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
+ { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" },
{ oUtf8Strings, "utf8-strings", 0, "@" },
{ oNoUtf8Strings, "no-utf8-strings", 0, "@" },
{ oWithFingerprint, "with-fingerprint", 0, "@" },
@@ -619,7 +659,11 @@ static ARGPARSE_OPTS opts[] = {
{ oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"},
{ oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"},
{ oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"},
- { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
+ /* Aliases. I constantly mistype these, and assume other people
+ do as well. */
+ { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
+ { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
+ { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
{ oAgentProgram, "agent-program", 2 , "@" },
{ oDisplay, "display", 2, "@" },
{ oTTYname, "ttyname", 2, "@" },
@@ -627,14 +671,41 @@ static ARGPARSE_OPTS opts[] = {
{ oLCctype, "lc-ctype", 2, "@" },
{ oLCmessages, "lc-messages", 2, "@" },
{ oGroup, "group", 2, "@" },
+ { oUnGroup, "ungroup", 2, "@" },
+ { oNoGroups, "no-groups", 0, "@" },
{ oStrict, "strict", 0, "@" },
{ oNoStrict, "no-strict", 0, "@" },
{ oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
{ oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
{ oEnableProgressFilter, "enable-progress-filter", 0, "@" },
{ oMultifile, "multifile", 0, "@" },
-{0} };
-
+ { oKeyidFormat, "keyid-format", 2, "@" },
+ { oExitOnStatusWriteError, "exit-on-status-write-error", 0, "@" },
+ { oLimitCardInsertTries, "limit-card-insert-tries", 1, "@"},
+
+ { oAllowMultisigVerification, "allow-multisig-verification", 0, "@"},
+
+ /* These two are aliases to help users of the PGP command line
+ product use gpg with minimal pain. Many commands are common
+ already as they seem to have borrowed commands from us. Now
+ I'm returning the favor. */
+ { oLocalUser, "sign-with", 2, "@" },
+ { oRecipient, "user", 2, "@" },
+ { oRequireCrossCert, "require-backsigs", 0, "@"},
+ { oRequireCrossCert, "require-cross-certification", 0, "@"},
+ { oNoRequireCrossCert, "no-require-backsigs", 0, "@"},
+ { oNoRequireCrossCert, "no-require-cross-certification", 0, "@"},
+ { oAutoKeyLocate, "auto-key-locate", 2, "@"},
+ { oNoAutoKeyLocate, "no-auto-key-locate", 0, "@"},
+ {0,NULL,0,NULL}
+};
+
+
+#ifdef ENABLE_SELINUX_HACKS
+#define ALWAYS_ADD_KEYRINGS 1
+#else
+#define ALWAYS_ADD_KEYRINGS 0
+#endif
int g10_errors_seen = 0;
@@ -652,16 +723,6 @@ static void add_policy_url( const char *string, int which );
static void add_keyserver_url( const char *string, int which );
static void emergency_cleanup (void);
-#ifdef __riscos__
-RISCOS_GLOBAL_STATICS("GnuPG Heap")
-#endif /* __riscos__ */
-
-static int
-pk_test_algo (int algo)
-{
- return openpgp_pk_test_algo (algo, 0);
-}
-
static const char *
my_strusage( int level )
@@ -676,6 +737,19 @@ my_strusage( int level )
case 19: p =
_("Please report bugs to <[email protected]>.\n");
break;
+
+#ifdef IS_DEVELOPMENT_VERSION
+ case 20:
+ p="NOTE: THIS IS A DEVELOPMENT VERSION!";
+ break;
+ case 21:
+ p="It is only intended for test purposes and should NOT be";
+ break;
+ case 22:
+ p="used in a production environment or with production keys!";
+ break;
+#endif
+
case 1:
case 40: p =
_("Usage: gpg [options] [files] (-h for help)");
@@ -694,27 +768,31 @@ my_strusage( int level )
#endif /* __riscos__ */
case 33: p = _("\nSupported algorithms:\n"); break;
case 34:
- if( !pubkeys )
- pubkeys = build_list(_("Pubkey: "), 0, gcry_pk_algo_name,
- pk_test_algo );
+ if (!pubkeys)
+ pubkeys = build_list (_("Pubkey: "), 0,
+ gcry_pk_algo_name,
+ openpgp_pk_test_algo );
p = pubkeys;
break;
case 35:
if( !ciphers )
- ciphers = build_list(_("Cipher: "), 'S', gcry_cipher_algo_name,
+ ciphers = build_list(_("Cipher: "), 'S',
+ gcry_cipher_algo_name,
openpgp_cipher_test_algo );
p = ciphers;
break;
case 36:
if( !digests )
- digests = build_list(_("Hash: "), 'H', gcry_md_algo_name,
- openpgp_md_test_algo );
+ digests = build_list(_("Hash: "), 'H',
+ gcry_md_algo_name,
+ openpgp_md_test_algo );
p = digests;
break;
case 37:
if( !zips )
- zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
- check_compress_algo);
+ zips = build_list(_("Compression: "),'Z',
+ compress_algo_to_string,
+ check_compress_algo);
p = zips;
break;
@@ -733,13 +811,13 @@ build_list( const char *text, char letter,
size_t n=strlen(text)+2;
char *list, *p, *line=NULL;
- if( maybe_setuid )
- gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* drop setuid */
+ if (maybe_setuid)
+ gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* Drop setuid. */
for(i=0; i <= 110; i++ )
if( !chkf(i) && (s=mapf(i)) )
n += strlen(s) + 7 + 2;
- list = xmalloc ( 21 + n ); *list = 0;
+ list = xmalloc( 21 + n ); *list = 0;
for(p=NULL, i=0; i <= 110; i++ ) {
if( !chkf(i) && (s=mapf(i)) ) {
if( !p ) {
@@ -752,7 +830,7 @@ build_list( const char *text, char letter,
if(strlen(line)>60) {
int spaces=strlen(text);
- list = xrealloc(list,n+spaces+1);
+ list=xrealloc(list,n+spaces+1);
/* realloc could move the block, so find the end again */
p=list;
while(*p)
@@ -783,12 +861,12 @@ static void
i18n_init(void)
{
#ifdef USE_SIMPLE_GETTEXT
- set_gettext_file( PACKAGE_GT );
+ set_gettext_file (PACKAGE_GT, "Software\\GNU\\GnuPG");
#else
#ifdef ENABLE_NLS
- setlocale( LC_ALL, "" );
- bindtextdomain( PACKAGE_GT, LOCALEDIR );
- textdomain( PACKAGE_GT );
+ setlocale (LC_ALL, "");
+ bindtextdomain (PACKAGE_GT, LOCALEDIR);
+ textdomain (PACKAGE_GT);
#endif
#endif
}
@@ -803,42 +881,15 @@ wrong_args( const char *text)
}
-static void
-log_set_strict (int yesno)
-{
- /* FIXME-XXX*/
-}
-
static char *
make_username( const char *string )
{
- char *p;
- if( utf8_strings )
- p = xstrdup (string);
- else
- p = native_to_utf8( string );
- return p;
-}
-
-
-/*
- * same as add_to_strlist() but if is_utf8 is *not* set a conversion
- * to UTF8 is done
- */
-static STRLIST
-add_to_strlist2 ( STRLIST *list, const char *string, int is_utf8)
-{
- STRLIST sl;
-
- if (is_utf8)
- sl = add_to_strlist( list, string );
- else
- {
- char *p = native_to_utf8( string );
- sl = add_to_strlist( list, p );
- xfree( p );
- }
- return sl;
+ char *p;
+ if( utf8_strings )
+ p = xstrdup(string);
+ else
+ p = native_to_utf8( string );
+ return p;
}
@@ -878,9 +929,11 @@ set_debug (const char *level)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
if (opt.debug & DBG_IOBUF_VALUE )
iobuf_debug_mode = 1;
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
}
+
/* We need the home directory also in some other directories, so make
sure that both variables are always in sync. */
static void
@@ -888,10 +941,80 @@ set_homedir (const char *dir)
{
if (!dir)
dir = "";
- g10_opt_homedir = opt.homedir = dir;
+ opt.homedir = dir;
}
+/* We set the screen dimensions for UI purposes. Do not allow screens
+ smaller than 80x24 for the sake of simplicity. */
+static void
+set_screen_dimensions(void)
+{
+#ifndef HAVE_W32_SYSTEM
+ char *str;
+
+ str=getenv("COLUMNS");
+ if(str)
+ opt.screen_columns=atoi(str);
+
+ str=getenv("LINES");
+ if(str)
+ opt.screen_lines=atoi(str);
+#endif
+
+ if(opt.screen_columns<80 || opt.screen_columns>255)
+ opt.screen_columns=80;
+
+ if(opt.screen_lines<24 || opt.screen_lines>255)
+ opt.screen_lines=24;
+}
+
+
+/* Helper to open a file FNAME either for reading or writing to be
+ used with --status-file etc functions. Not generally useful but it
+ avoids the riscos specific functions and well some Windows people
+ might like it too. Prints an error message and returns -1 on
+ error. On success the file descriptor is returned. */
+static int
+open_info_file (const char *fname, int for_write)
+{
+#ifdef __riscos__
+ return riscos_fdopenfile (fname, for_write);
+#elif defined (ENABLE_SELINUX_HACKS)
+ /* We can't allow these even when testing for a secured filename
+ because files to be secured might not yet been secured. This is
+ similar to the option file but in that case it is unlikely that
+ sensitive information may be retrieved by means of error
+ messages. */
+ return -1;
+#else
+ int fd;
+
+/* if (is_secured_filename (fname)) */
+/* { */
+/* fd = -1; */
+/* errno = EPERM; */
+/* } */
+/* else */
+/* { */
+ do
+ {
+ if (for_write)
+ fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ else
+ fd = open (fname, O_RDONLY | MY_O_BINARY);
+ }
+ while (fd == -1 && errno == EINTR);
+/* } */
+ if ( fd == -1)
+ log_error ( for_write? _("can't create `%s': %s\n")
+ : _("can't open `%s': %s\n"), fname, strerror(errno));
+
+ return fd;
+#endif
+}
+
static void
set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
{
@@ -907,6 +1030,18 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
cmd = aSignSym;
else if( cmd == aSym && new_cmd == aSign )
cmd = aSignSym;
+ else if( cmd == aSym && new_cmd == aEncr )
+ cmd = aEncrSym;
+ else if( cmd == aEncr && new_cmd == aSym )
+ cmd = aEncrSym;
+ else if( cmd == aKMode && new_cmd == aSym )
+ cmd = aKModeC;
+ else if (cmd == aSignEncr && new_cmd == aSym)
+ cmd = aSignEncrSym;
+ else if (cmd == aSignSym && new_cmd == aEncr)
+ cmd = aSignEncrSym;
+ else if (cmd == aEncrSym && new_cmd == aSign)
+ cmd = aSignEncrSym;
else if( ( cmd == aSign && new_cmd == aClearsign )
|| ( cmd == aClearsign && new_cmd == aSign ) )
cmd = aClearsign;
@@ -919,47 +1054,79 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
}
-static void add_group(char *string)
+static void
+add_group(char *string)
{
char *name,*value;
struct groupitem *item;
- STRLIST values=NULL;
/* Break off the group name */
name=strsep(&string,"=");
if(string==NULL)
{
- log_error(_("no = sign found in group definition \"%s\"\n"),name);
+ log_error(_("no = sign found in group definition `%s'\n"),name);
return;
}
- trim_trailing_ws((unsigned char *)name,strlen(name));
+ trim_trailing_ws(name,strlen(name));
+
+ /* Does this group already exist? */
+ for(item=opt.grouplist;item;item=item->next)
+ if(strcasecmp(item->name,name)==0)
+ break;
+
+ if(!item)
+ {
+ item=xmalloc(sizeof(struct groupitem));
+ item->name=name;
+ item->next=opt.grouplist;
+ item->values=NULL;
+ opt.grouplist=item;
+ }
/* Break apart the values */
while ((value= strsep(&string," \t")))
{
if (*value)
- add_to_strlist2 (&values,value,utf8_strings);
+ add_to_strlist2(&item->values,value,utf8_strings);
}
+}
+
+
+static void
+rm_group(char *name)
+{
+ struct groupitem *item,*last=NULL;
- item=xmalloc (sizeof(struct groupitem));
- item->name=name;
- item->values=values;
- item->next=opt.grouplist;
+ trim_trailing_ws(name,strlen(name));
+
+ for(item=opt.grouplist;item;last=item,item=item->next)
+ {
+ if(strcasecmp(item->name,name)==0)
+ {
+ if(last)
+ last->next=item->next;
+ else
+ opt.grouplist=item->next;
- opt.grouplist=item;
+ free_strlist(item->values);
+ xfree(item);
+ break;
+ }
+ }
}
+
/* We need to check three things.
0) The homedir. It must be x00, a directory, and owned by the
user.
- 1) The options file. Okay unless it or its containing directory is
- group or other writable or not owned by us. disable exec in this
- case.
+ 1) The options/gpg.conf file. Okay unless it or its containing
+ directory is group or other writable or not owned by us. Disable
+ exec in this case.
- 2) Extensions. Same as #2.
+ 2) Extensions. Same as #1.
Returns true if the item is unsafe. */
static int
@@ -986,7 +1153,7 @@ check_permissions(const char *path,int item)
tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
}
else
- tmppath=xstrdup (path);
+ tmppath=xstrdup(path);
/* If the item is located in the homedir, but isn't the homedir,
don't continue if we already checked the homedir itself. This is
@@ -1019,7 +1186,7 @@ check_permissions(const char *path,int item)
goto end;
}
- xfree (dir);
+ xfree(dir);
/* Assume failure */
ret=1;
@@ -1094,55 +1261,55 @@ check_permissions(const char *path,int item)
if(own)
{
if(item==0)
- log_info(_("WARNING: unsafe ownership on "
- "homedir \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe ownership on"
+ " homedir `%s'\n"),tmppath);
else if(item==1)
- log_info(_("WARNING: unsafe ownership on "
- "configuration file \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe ownership on"
+ " configuration file `%s'\n"),tmppath);
else
- log_info(_("WARNING: unsafe ownership on "
- "extension \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe ownership on"
+ " extension `%s'\n"),tmppath);
}
if(perm)
{
if(item==0)
- log_info(_("WARNING: unsafe permissions on "
- "homedir \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe permissions on"
+ " homedir `%s'\n"),tmppath);
else if(item==1)
- log_info(_("WARNING: unsafe permissions on "
- "configuration file \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe permissions on"
+ " configuration file `%s'\n"),tmppath);
else
- log_info(_("WARNING: unsafe permissions on "
- "extension \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe permissions on"
+ " extension `%s'\n"),tmppath);
}
if(enc_dir_own)
{
if(item==0)
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "homedir \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory ownership on"
+ " homedir `%s'\n"),tmppath);
else if(item==1)
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "configuration file \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory ownership on"
+ " configuration file `%s'\n"),tmppath);
else
- log_info(_("WARNING: unsafe enclosing directory ownership on "
- "extension \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory ownership on"
+ " extension `%s'\n"),tmppath);
}
if(enc_dir_perm)
{
if(item==0)
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "homedir \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory permissions on"
+ " homedir `%s'\n"),tmppath);
else if(item==1)
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "configuration file \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory permissions on"
+ " configuration file `%s'\n"),tmppath);
else
- log_info(_("WARNING: unsafe enclosing directory permissions on "
- "extension \"%s\"\n"),tmppath);
+ log_info(_("WARNING: unsafe enclosing directory permissions on"
+ " extension `%s'\n"),tmppath);
}
}
end:
- xfree (tmppath);
+ xfree(tmppath);
if(homedir)
homedir_cache=ret;
@@ -1154,11 +1321,326 @@ check_permissions(const char *path,int item)
return 0;
}
+
+static void
+print_algo_numbers(int (*checker)(int))
+{
+ int i,first=1;
+
+ for(i=0;i<=110;i++)
+ {
+ if(!checker(i))
+ {
+ if(first)
+ first=0;
+ else
+ printf(";");
+ printf("%d",i);
+ }
+ }
+}
+
+
+/* In the future, we can do all sorts of interesting configuration
+ output here. For now, just give "group" as the Enigmail folks need
+ it, and pubkey, cipher, hash, and compress as they may be useful
+ for frontends. */
+static void
+list_config(char *items)
+{
+ int show_all=(items==NULL);
+ char *name=NULL;
+
+ if(!opt.with_colons)
+ return;
+
+ while(show_all || (name=strsep(&items," ")))
+ {
+ int any=0;
+
+ if(show_all || ascii_strcasecmp(name,"group")==0)
+ {
+ struct groupitem *iter;
+
+ for(iter=opt.grouplist;iter;iter=iter->next)
+ {
+ STRLIST sl;
+
+ printf("cfg:group:");
+ print_string(stdout,iter->name,strlen(iter->name),':');
+ printf(":");
+
+ for(sl=iter->values;sl;sl=sl->next)
+ {
+ print_string2(stdout,sl->d,strlen(sl->d),':',';');
+ if(sl->next)
+ printf(";");
+ }
+
+ printf("\n");
+ }
+
+ any=1;
+ }
+
+ if(show_all || ascii_strcasecmp(name,"version")==0)
+ {
+ printf("cfg:version:");
+ print_string(stdout,VERSION,strlen(VERSION),':');
+ printf("\n");
+ any=1;
+ }
+
+ if(show_all || ascii_strcasecmp(name,"pubkey")==0)
+ {
+ printf("cfg:pubkey:");
+ print_algo_numbers (openpgp_pk_test_algo);
+ printf("\n");
+ any=1;
+ }
+
+ if(show_all || ascii_strcasecmp(name,"cipher")==0)
+ {
+ printf("cfg:cipher:");
+ print_algo_numbers(openpgp_cipher_test_algo);
+ printf("\n");
+ any=1;
+ }
+
+ if(show_all
+ || ascii_strcasecmp(name,"digest")==0
+ || ascii_strcasecmp(name,"hash")==0)
+ {
+ printf("cfg:digest:");
+ print_algo_numbers(openpgp_md_test_algo);
+ printf("\n");
+ any=1;
+ }
+
+ if(show_all || ascii_strcasecmp(name,"compress")==0)
+ {
+ printf("cfg:compress:");
+ print_algo_numbers(check_compress_algo);
+ printf("\n");
+ any=1;
+ }
+
+ if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
+ {
+#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
+ char *p, *p2, *list = ccid_get_reader_list ();
+
+ for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
+ {
+ *p2 = 0;
+ printf("cfg:ccid-reader-id:%s\n", p);
+ }
+ free (list);
+#endif
+ any=1;
+ }
+
+ if(show_all)
+ break;
+
+ if(!any)
+ log_error(_("unknown configuration item `%s'\n"),name);
+ }
+}
+
+
+/* List options and default values in the GPG Conf format. This is a
+ new tool distributed with gnupg 1.9.x but we also want some limited
+ support in older gpg versions. The output is the name of the
+ configuration file and a list of options available for editing by
+ gpgconf. */
+static void
+gpgconf_list (const char *configfile)
+{
+ /* The following definitions are taken from gnupg/tools/gpgconf-comp.c. */
+#define GC_OPT_FLAG_NONE 0UL
+#define GC_OPT_FLAG_DEFAULT (1UL << 4)
+
+ printf ("gpgconf-gpg.conf:%lu:\"%s\n",
+ GC_OPT_FLAG_DEFAULT,configfile?configfile:"/dev/null");
+ printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
+ printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
+ printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
+ printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
+}
+
+
+static int
+parse_subpacket_list(char *list)
+{
+ char *tok;
+ byte subpackets[128],i;
+ int count=0;
+
+ if(!list)
+ {
+ /* No arguments means all subpackets */
+ memset(subpackets+1,1,sizeof(subpackets)-1);
+ count=127;
+ }
+ else
+ {
+ memset(subpackets,0,sizeof(subpackets));
+
+ /* Merge with earlier copy */
+ if(opt.show_subpackets)
+ {
+ byte *in;
+
+ for(in=opt.show_subpackets;*in;in++)
+ {
+ if(*in>127 || *in<1)
+ BUG();
+
+ if(!subpackets[*in])
+ count++;
+ subpackets[*in]=1;
+ }
+ }
+
+ while((tok=strsep(&list," ,")))
+ {
+ if(!*tok)
+ continue;
+
+ i=atoi(tok);
+ if(i>127 || i<1)
+ return 0;
+
+ if(!subpackets[i])
+ count++;
+ subpackets[i]=1;
+ }
+ }
+
+ xfree(opt.show_subpackets);
+ opt.show_subpackets=xmalloc(count+1);
+ opt.show_subpackets[count--]=0;
+
+ for(i=1;i<128 && count>=0;i++)
+ if(subpackets[i])
+ opt.show_subpackets[count--]=i;
+
+ return 1;
+}
+
+
+static int
+parse_list_options(char *str)
+{
+ char *subpackets=""; /* something that isn't NULL */
+ struct parse_options lopts[]=
+ {
+ {"show-photos",LIST_SHOW_PHOTOS,NULL,
+ N_("display photo IDs during key listings")},
+ {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL,
+ N_("show policy URLs during signature listings")},
+ {"show-notations",LIST_SHOW_NOTATIONS,NULL,
+ N_("show all notations during signature listings")},
+ {"show-std-notations",LIST_SHOW_STD_NOTATIONS,NULL,
+ N_("show IETF standard notations during signature listings")},
+ {"show-standard-notations",LIST_SHOW_STD_NOTATIONS,NULL,
+ NULL},
+ {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL,
+ N_("show user-supplied notations during signature listings")},
+ {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL,
+ N_("show preferred keyserver URLs during signature listings")},
+ {"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL,
+ N_("show user ID validity during key listings")},
+ {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS,NULL,
+ N_("show revoked and expired user IDs in key listings")},
+ {"show-unusable-subkeys",LIST_SHOW_UNUSABLE_SUBKEYS,NULL,
+ N_("show revoked and expired subkeys in key listings")},
+ {"show-keyring",LIST_SHOW_KEYRING,NULL,
+ N_("show the keyring name in key listings")},
+ {"show-sig-expire",LIST_SHOW_SIG_EXPIRE,NULL,
+ N_("show expiration dates during signature listings")},
+ {"show-sig-subpackets",LIST_SHOW_SIG_SUBPACKETS,NULL,
+ NULL},
+ {NULL,0,NULL,NULL}
+ };
+
+ /* C99 allows for non-constant initializers, but we'd like to
+ compile everywhere, so fill in the show-sig-subpackets argument
+ here. Note that if the parse_options array changes, we'll have
+ to change the subscript here. */
+ lopts[12].value=&subpackets;
+
+ if(parse_options(str,&opt.list_options,lopts,1))
+ {
+ if(opt.list_options&LIST_SHOW_SIG_SUBPACKETS)
+ {
+ /* Unset so users can pass multiple lists in. */
+ opt.list_options&=~LIST_SHOW_SIG_SUBPACKETS;
+ if(!parse_subpacket_list(subpackets))
+ return 0;
+ }
+ else if(subpackets==NULL && opt.show_subpackets)
+ {
+ /* User did 'no-show-subpackets' */
+ xfree(opt.show_subpackets);
+ opt.show_subpackets=NULL;
+ }
+
+ return 1;
+ }
+ else
+ return 0;
+}
+
+
+/* Collapses argc/argv into a single string that must be freed */
+static char *
+collapse_args(int argc,char *argv[])
+{
+ char *str=NULL;
+ int i,first=1,len=0;
+
+ for(i=0;i<argc;i++)
+ {
+ len+=strlen(argv[i])+2;
+ str=xrealloc(str,len);
+ if(first)
+ {
+ str[0]='\0';
+ first=0;
+ }
+ else
+ strcat(str," ");
+
+ strcat(str,argv[i]);
+ }
+
+ return str;
+}
+
+static void
+parse_trust_model(const char *model)
+{
+ if(ascii_strcasecmp(model,"pgp")==0)
+ opt.trust_model=TM_PGP;
+ else if(ascii_strcasecmp(model,"classic")==0)
+ opt.trust_model=TM_CLASSIC;
+ else if(ascii_strcasecmp(model,"always")==0)
+ opt.trust_model=TM_ALWAYS;
+ else if(ascii_strcasecmp(model,"direct")==0)
+ opt.trust_model=TM_DIRECT;
+ else if(ascii_strcasecmp(model,"auto")==0)
+ opt.trust_model=TM_AUTO;
+ else
+ log_error("unknown trust model `%s'\n",model);
+}
+
int
-main( int argc, char **argv )
+main (int argc, char **argv )
{
ARGPARSE_ARGS pargs;
- iobuf_t a;
+ IOBUF a;
int rc=0;
int orig_argc;
char **orig_argv;
@@ -1171,7 +1653,7 @@ main( int argc, char **argv )
int detached_sig = 0;
FILE *configfp = NULL;
char *configname = NULL;
- const char *config_filename = NULL;
+ char *save_configname = NULL;
unsigned configlineno;
int parse_debug = 0;
int default_config = 1;
@@ -1185,7 +1667,7 @@ main( int argc, char **argv )
const char *trustdb_name = NULL;
char *def_cipher_string = NULL;
char *def_digest_string = NULL;
- char *def_compress_string = NULL;
+ char *compress_algo_string = NULL;
char *cert_digest_string = NULL;
char *s2k_cipher_string = NULL;
char *s2k_digest_string = NULL;
@@ -1197,47 +1679,53 @@ main( int argc, char **argv )
int pwfd = -1;
int with_fpr = 0; /* make an option out of --fingerprint */
int any_explicit_recipient = 0;
+ int require_secmem=0,got_secmem=0;
#ifdef __riscos__
- riscos_global_defaults();
opt.lock_once = 1;
#endif /* __riscos__ */
+
+ /* Please note that we may running SUID(ROOT), so be very CAREFUL
+ when adding any stuff between here and the call to
+ secmem_init() somewhere after the option parsing. */
+
trap_unaligned();
set_strusage (my_strusage);
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
/* We don't need any locking in libgcrypt unless we use any kind of
threading. */
gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
- /* Please note that we may running SUID(ROOT), so be very CAREFUL
- * when adding any stuff between here and the call to
- * secmem_init() somewhere after the option parsing
- */
log_set_prefix ("gpg", 1);
- /* check that the libraries are suitable. Do it here because the
- option parse may need services of the library */
+
+ /* Check that the libraries are suitable. Do it right here because the
+ option parsing may need services of the library. */
if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
{
- log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
- NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+ log_fatal ( _("libgcrypt is too old (need %s, have %s)\n"),
+ NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
}
+ /* Put random number into secure memory */
gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
may_coredump = disable_core_dumps();
+
gnupg_init_signals (0, emergency_cleanup);
- create_dotlock (NULL); /* register locking cleanup */
+
+ create_dotlock(NULL); /* Register locking cleanup. */
+
i18n_init();
opt.command_fd = -1; /* no command fd */
- opt.compress = -1; /* defaults to standard compress level */
+ opt.compress_level = -1; /* defaults to standard compress level */
+ opt.bz2_compress_level = -1; /* defaults to standard compress level */
/* note: if you change these lines, look at oOpenPGP */
opt.def_cipher_algo = 0;
opt.def_digest_algo = 0;
opt.cert_digest_algo = 0;
- opt.def_compress_algo = -1;
+ opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
opt.s2k_mode = 3; /* iterated+salted */
- opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
#ifdef USE_CAST5
opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
#else
@@ -1250,23 +1738,24 @@ main( int argc, char **argv )
opt.force_v3_sigs = 1;
opt.escape_from = 1;
opt.import_options=IMPORT_SK2PK;
- opt.export_options=
- EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
+ opt.export_options=EXPORT_ATTRIBUTES;
opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
- opt.keyserver_options.export_options=
- EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
- opt.keyserver_options.include_subkeys=1;
- opt.keyserver_options.include_revoked=1;
- opt.keyserver_options.try_dns_srv=1;
+ opt.keyserver_options.export_options=EXPORT_ATTRIBUTES;
+ opt.keyserver_options.options=
+ KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD;
opt.verify_options=
- VERIFY_SHOW_POLICY|VERIFY_SHOW_NOTATION|VERIFY_SHOW_KEYSERVER;
+ VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
opt.trust_model=TM_AUTO;
- opt.mangle_dos_filenames = 1;
- opt.use_agent = 1;
-
+ opt.mangle_dos_filenames=0;
+ opt.min_cert_level=2;
+ set_screen_dimensions();
+ opt.keyid_format=KF_SHORT;
+ opt.rfc2440_text=1;
+ opt.def_sig_expire="0";
+ opt.def_cert_expire="0";
set_homedir ( default_homedir () );
- /* Check whether we have a config file on the commandline */
+ /* Check whether we have a config file on the command line. */
orig_argc = argc;
orig_argv = argv;
pargs.argc = &argc;
@@ -1304,7 +1793,13 @@ main( int argc, char **argv )
char *d, *buf = xmalloc (strlen (opt.homedir)+1);
const char *s = opt.homedir;
for (d=buf,s=opt.homedir; *s; s++)
+ {
*d++ = *s == '\\'? '/': *s;
+#ifdef HAVE_W32_SYSTEM
+ if (s[1] && IsDBCSLeadByte (*s))
+ *d++ = *++s;
+#endif
+ }
*d = 0;
set_homedir (buf);
}
@@ -1312,19 +1807,28 @@ main( int argc, char **argv )
/* Initialize the secure memory. */
gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0);
+ got_secmem = 1; /* FIXME: gcry_control should return an indicator. */
+#if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
+ /* There should be no way to get to this spot while still carrying
+ setuid privs. Just in case, bomb out if we are. */
+ if(getuid()!=geteuid())
+ BUG();
+#endif
maybe_setuid = 0;
+
/* Okay, we are now working under our real uid */
/* malloc hooks go here ... */
assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
+
set_native_charset (NULL); /* Try to auto set the character set */
/* Try for a version specific config file first */
if( default_config )
{
- char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
- char *ver = name + strlen("gpg" EXTSEP_S "conf-");
+ char *name=xstrdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
+ char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
do
{
@@ -1332,22 +1836,25 @@ main( int argc, char **argv )
{
char *tok;
- xfree (configname);
+ xfree(configname);
configname=NULL;
- if((tok=strrchr (ver,SAFE_VERSION_DASH)))
+ if((tok=strrchr(ver,SAFE_VERSION_DASH)))
*tok='\0';
- else if((tok=strrchr (ver,SAFE_VERSION_DOT)))
+ else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
*tok='\0';
else
break;
}
- configname = make_filename (opt.homedir, name, NULL);
+ configname = make_filename(opt.homedir,name,NULL);
}
- while ( access(configname,R_OK) );
+ while(access(configname,R_OK));
+
xfree(name);
+ if(!configname)
+ configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
if (!access (configname, R_OK))
{ /* Print a warning when both config files are present. */
char *p = make_filename(opt.homedir, "options", NULL );
@@ -1385,6 +1892,12 @@ main( int argc, char **argv )
configlineno = 0;
configfp = fopen( configname, "r" );
+ if (configfp && is_secured_file (fileno (configfp)))
+ {
+ fclose (configfp);
+ configfp = NULL;
+ errno = EPERM;
+ }
if( !configfp ) {
if( default_config ) {
if( parse_debug )
@@ -1396,7 +1909,7 @@ main( int argc, char **argv )
configname, strerror(errno) );
g10_exit(2);
}
- xfree (configname); configname = NULL;
+ xfree(configname); configname = NULL;
}
if( parse_debug && configname )
log_info(_("reading options from `%s'\n"), configname );
@@ -1404,24 +1917,32 @@ main( int argc, char **argv )
}
while( optfile_parse( configfp, configname, &configlineno,
- &pargs, opts) ) {
- switch( pargs.r_opt ) {
- case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
- case aListPackets: set_cmd( &cmd, aListPackets); break;
- case aImport: set_cmd( &cmd, aImport); break;
- case aFastImport: set_cmd( &cmd, aFastImport); break;
- case aSendKeys: set_cmd( &cmd, aSendKeys); break;
- case aRecvKeys: set_cmd( &cmd, aRecvKeys); break;
- case aSearchKeys: set_cmd( &cmd, aSearchKeys); break;
- case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break;
- case aExport: set_cmd( &cmd, aExport); break;
- case aExportAll: set_cmd( &cmd, aExportAll); break;
+ &pargs, opts) )
+ {
+ switch( pargs.r_opt )
+ {
+ case aCheckKeys:
+ case aListConfig:
+ case aGPGConfList:
+ case aListPackets:
+ case aImport:
+ case aFastImport:
+ case aSendKeys:
+ case aRecvKeys:
+ case aSearchKeys:
+ case aRefreshKeys:
+ case aFetchKeys:
+ case aExport:
+ set_cmd (&cmd, pargs.r_opt);
+ break;
case aListKeys: set_cmd( &cmd, aListKeys); break;
case aListSigs: set_cmd( &cmd, aListSigs); break;
case aExportSecret: set_cmd( &cmd, aExportSecret); break;
case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
- case aDeleteSecretKeys: set_cmd( &cmd, aDeleteSecretKeys);
- greeting=1; break;
+ case aDeleteSecretKeys:
+ set_cmd( &cmd, aDeleteSecretKeys);
+ greeting=1;
+ break;
case aDeleteSecretAndPublicKeys:
set_cmd( &cmd, aDeleteSecretAndPublicKeys);
greeting=1;
@@ -1431,7 +1952,7 @@ main( int argc, char **argv )
case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
case aSym: set_cmd( &cmd, aSym); break;
- case aDecryptFiles: multifile=1; /* fall through */
+ case aDecryptFiles: multifile=1; /* fall through */
case aDecrypt: set_cmd( &cmd, aDecrypt); break;
case aEncrFiles: multifile=1; /* fall through */
@@ -1444,14 +1965,11 @@ main( int argc, char **argv )
case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
case aSignKey: set_cmd( &cmd, aSignKey); break;
case aLSignKey: set_cmd( &cmd, aLSignKey); break;
- case aNRSignKey: set_cmd( &cmd, aNRSignKey); break;
- case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break;
case aStore: set_cmd( &cmd, aStore); break;
case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
case aClearsign: set_cmd( &cmd, aClearsign); break;
case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
-
case aPrimegen: set_cmd( &cmd, aPrimegen); break;
case aGenRandom: set_cmd( &cmd, aGenRandom); break;
case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@@ -1468,28 +1986,23 @@ main( int argc, char **argv )
"--list-ownertrust","--export-ownertrust","");
case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
- case aPipeMode: set_cmd( &cmd, aPipeMode); break;
case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
- case aCardStatus: set_cmd (&cmd, aCardStatus); break;
- case aCardEdit: set_cmd (&cmd, aCardEdit); break;
- case aChangePIN: set_cmd (&cmd, aChangePIN); break;
- case aGPGConfList:
- set_cmd (&cmd, aGPGConfList);
- nogreeting = 1;
- break;
-
case oArmor: opt.armor = 1; opt.no_armor=0; break;
case oOutput: opt.outfile = pargs.r.ret_str; break;
+ case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
case oQuiet: opt.quiet = 1; break;
case oNoTTY: tty_no_terminal(1); break;
case oDryRun: opt.dry_run = 1; break;
case oInteractive: opt.interactive = 1; break;
- case oVerbose: g10_opt_verbose++;
- opt.verbose++; opt.list_sigs=1; break;
+ case oVerbose:
+ opt.verbose++;
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
+ opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
+ opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
+ break;
+ case oKOption: set_cmd( &cmd, aKMode ); break;
- case oLogFile: logfile = pargs.r.ret_str; break;
-
case oBatch: opt.batch = 1; nogreeting = 1; break;
case oUseAgent:
#ifndef __riscos__
@@ -1508,58 +2021,60 @@ main( int argc, char **argv )
sl=append_to_strlist( &nrings, pargs.r.ret_str);
sl->flags=2;
break;
- case oShowKeyring: opt.list_options|=LIST_SHOW_KEYRING; break;
+ case oShowKeyring:
+ deprecated_warning(configname,configlineno,"--show-keyring",
+ "--list-options ","show-keyring");
+ opt.list_options|=LIST_SHOW_KEYRING;
+ break;
+
case oDebug: opt.debug |= pargs.r.ret_ulong; break;
case oDebugAll: opt.debug = ~0; break;
case oDebugLevel: debug_level = pargs.r.ret_str; break;
+
case oStatusFD:
set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
break;
-#ifdef __riscos__
case oStatusFile:
- set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
+ set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
break;
-#endif /* __riscos__ */
case oAttributeFD:
set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
break;
-#ifdef __riscos__
case oAttributeFile:
- set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
+ set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
break;
-#endif /* __riscos__ */
case oLoggerFD:
log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1));
break;
-#ifdef __riscos__
- case oLoggerFile:
- log_set_logfile( NULL,
- iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
+ case oLoggerFile:
+ logfile = pargs.r.ret_str;
break;
-#endif /* __riscos__ */
+
case oWithFingerprint:
opt.with_fingerprint = 1;
with_fpr=1; /*fall thru*/
case oFingerprint: opt.fingerprint++; break;
- case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
+ case oSecretKeyring:
+ append_to_strlist( &sec_nrings, pargs.r.ret_str);
+ break;
case oOptions:
/* config files may not be nested (silently ignore them) */
if( !configfp ) {
- xfree (configname);
- configname = xstrdup (pargs.r.ret_str);
+ xfree(configname);
+ configname = xstrdup(pargs.r.ret_str);
goto next_pass;
}
break;
case oNoArmor: opt.no_armor=1; opt.armor=0; break;
case oNoDefKeyring: default_keyring = 0; break;
- case oDefCertCheckLevel: opt.def_cert_check_level=pargs.r.ret_int; break;
case oNoGreeting: nogreeting = 1; break;
- case oNoVerbose: g10_opt_verbose = 0;
- opt.verbose = 0; opt.list_sigs=0; break;
- /* disabled for now:
- case oQuickRandom: quick_random_gen(1); break; */
- case oSKComments: opt.sk_comments=1; break;
- case oNoSKComments: opt.sk_comments=0; break;
+ case oNoVerbose:
+ opt.verbose = 0;
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
+ opt.list_sigs=0;
+ break;
+ /* Disabled for now:
+ case oQuickRandom: quick_random_gen(1); break;*/
case oEmitVersion: opt.no_version=0; break;
case oNoEmitVersion: opt.no_version=1; break;
case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
@@ -1572,11 +2087,11 @@ main( int argc, char **argv )
opt.def_recipient = make_username(pargs.r.ret_str);
break;
case oDefRecipientSelf:
- xfree (opt.def_recipient); opt.def_recipient = NULL;
+ xfree(opt.def_recipient); opt.def_recipient = NULL;
opt.def_recipient_self = 1;
break;
case oNoDefRecipient:
- xfree (opt.def_recipient); opt.def_recipient = NULL;
+ xfree(opt.def_recipient); opt.def_recipient = NULL;
opt.def_recipient_self = 0;
break;
case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
@@ -1593,16 +2108,7 @@ main( int argc, char **argv )
time. */
case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
case oTrustModel:
- if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0)
- opt.trust_model=TM_PGP;
- else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0)
- opt.trust_model=TM_CLASSIC;
- else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0)
- opt.trust_model=TM_ALWAYS;
- else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0)
- opt.trust_model=TM_AUTO;
- else
- log_error("unknown trust model \"%s\"\n",pargs.r.ret_str);
+ parse_trust_model(pargs.r.ret_str);
break;
case oForceOwnertrust:
log_info(_("NOTE: %s is not for normal use!\n"),
@@ -1610,7 +2116,7 @@ main( int argc, char **argv )
opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
if(opt.force_ownertrust==-1)
{
- log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str);
+ log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
opt.force_ownertrust=0;
}
break;
@@ -1618,8 +2124,8 @@ main( int argc, char **argv )
#ifndef __riscos__
#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
if(check_permissions(pargs.r.ret_str,2))
- log_info(_("cipher extension \"%s\" not loaded due to "
- "unsafe permissions\n"),pargs.r.ret_str);
+ log_info(_("cipher extension `%s' not loaded due to"
+ " unsafe permissions\n"),pargs.r.ret_str);
else
register_cipher_extension(orig_argc? *orig_argv:NULL,
pargs.r.ret_str);
@@ -1633,23 +2139,24 @@ main( int argc, char **argv )
opt.force_v4_certs = 0;
opt.escape_from = 1;
break;
- case oRFC2440:
case oOpenPGP:
- /* TODO: When 2440bis becomes a RFC, these may need
- changing. */
+ case oRFC2440:
+ /* TODO: When 2440bis becomes a RFC, set new values for
+ oOpenPGP. */
+ opt.rfc2440_text=1;
opt.compliance = CO_RFC2440;
opt.allow_non_selfsigned_uid = 1;
opt.allow_freeform_uid = 1;
opt.pgp2_workarounds = 0;
opt.escape_from = 0;
opt.force_v3_sigs = 0;
- opt.compress_keys = 0; /* not mandated but we do it */
+ opt.compress_keys = 0; /* not mandated, but we do it */
opt.compress_sigs = 0; /* ditto. */
opt.not_dash_escaped = 0;
opt.def_cipher_algo = 0;
opt.def_digest_algo = 0;
opt.cert_digest_algo = 0;
- opt.def_compress_algo = -1;
+ opt.compress_algo = -1;
opt.s2k_mode = 3; /* iterated+salted */
opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
@@ -1659,8 +2166,9 @@ main( int argc, char **argv )
case oPGP7: opt.compliance = CO_PGP7; break;
case oPGP8: opt.compliance = CO_PGP8; break;
case oGnuPG: opt.compliance = CO_GNUPG; break;
- case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
case oCompressSigs: opt.compress_sigs = 1; break;
+ case oRFC2440Text: opt.rfc2440_text=1; break;
+ case oNoRFC2440Text: opt.rfc2440_text=0; break;
case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
case oForYourEyesOnly: eyes_only = 1; break;
case oNoForYourEyesOnly: eyes_only = 0; break;
@@ -1671,17 +2179,28 @@ main( int argc, char **argv )
case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
case oShowPolicyURL:
- opt.list_options|=LIST_SHOW_POLICY;
- opt.verify_options|=VERIFY_SHOW_POLICY;
+ deprecated_warning(configname,configlineno,"--show-policy-url",
+ "--list-options ","show-policy-urls");
+ deprecated_warning(configname,configlineno,"--show-policy-url",
+ "--verify-options ","show-policy-urls");
+ opt.list_options|=LIST_SHOW_POLICY_URLS;
+ opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
break;
case oNoShowPolicyURL:
- opt.list_options&=~LIST_SHOW_POLICY;
- opt.verify_options&=~VERIFY_SHOW_POLICY;
+ deprecated_warning(configname,configlineno,"--no-show-policy-url",
+ "--list-options ","no-show-policy-urls");
+ deprecated_warning(configname,configlineno,"--no-show-policy-url",
+ "--verify-options ","no-show-policy-urls");
+ opt.list_options&=~LIST_SHOW_POLICY_URLS;
+ opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
break;
case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
-
- case oComment: add_to_strlist(&opt.comments,pargs.r.ret_str); break;
+ case oNoUseEmbeddedFilename: opt.use_embedded_filename = 0; break;
+ case oComment:
+ if(pargs.r.ret_str[0])
+ append_to_strlist(&opt.comments,pargs.r.ret_str);
+ break;
case oDefaultComment:
deprecated_warning(configname,configlineno,
"--default-comment","--no-comments","");
@@ -1690,14 +2209,21 @@ main( int argc, char **argv )
free_strlist(opt.comments);
opt.comments=NULL;
break;
-
- case oThrowKeyid: opt.throw_keyid = 1; break;
- case oNoThrowKeyid: opt.throw_keyid = 0; break;
- case oShowPhotos:
+ case oThrowKeyids: opt.throw_keyid = 1; break;
+ case oNoThrowKeyids: opt.throw_keyid = 0; break;
+ case oShowPhotos:
+ deprecated_warning(configname,configlineno,"--show-photos",
+ "--list-options ","show-photos");
+ deprecated_warning(configname,configlineno,"--show-photos",
+ "--verify-options ","show-photos");
opt.list_options|=LIST_SHOW_PHOTOS;
opt.verify_options|=VERIFY_SHOW_PHOTOS;
break;
case oNoShowPhotos:
+ deprecated_warning(configname,configlineno,"--no-show-photos",
+ "--list-options ","no-show-photos");
+ deprecated_warning(configname,configlineno,"--no-show-photos",
+ "--verify-options ","no-show-photos");
opt.list_options&=~LIST_SHOW_PHOTOS;
opt.verify_options&=~VERIFY_SHOW_PHOTOS;
break;
@@ -1711,8 +2237,8 @@ main( int argc, char **argv )
case oDisableMDC: opt.disable_mdc = 1; break;
case oNoDisableMDC: opt.disable_mdc = 0; break;
case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break;
- case oS2KDigest: s2k_digest_string = xstrdup (pargs.r.ret_str); break;
- case oS2KCipher: s2k_cipher_string = xstrdup (pargs.r.ret_str); break;
+ case oS2KDigest: s2k_digest_string = xstrdup(pargs.r.ret_str); break;
+ case oS2KCipher: s2k_cipher_string = xstrdup(pargs.r.ret_str); break;
case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
case oEncryptTo: /* store the recipient in the second list */
@@ -1737,33 +2263,66 @@ main( int argc, char **argv )
case oNoTextmode: opt.textmode=0; break;
case oExpert: opt.expert = 1; break;
case oNoExpert: opt.expert = 0; break;
+ case oDefSigExpire:
+ if(*pargs.r.ret_str!='\0')
+ {
+ if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
+ log_error(_("`%s' is not a valid signature expiration\n"),
+ pargs.r.ret_str);
+ else
+ opt.def_sig_expire=pargs.r.ret_str;
+ }
+ break;
case oAskSigExpire: opt.ask_sig_expire = 1; break;
case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
+ case oDefCertExpire:
+ if(*pargs.r.ret_str!='\0')
+ {
+ if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
+ log_error(_("`%s' is not a valid signature expiration\n"),
+ pargs.r.ret_str);
+ else
+ opt.def_cert_expire=pargs.r.ret_str;
+ }
+ break;
case oAskCertExpire: opt.ask_cert_expire = 1; break;
case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
- case oUser: /* store the local users */
+ case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
+ case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
+ case oAskCertLevel: opt.ask_cert_level = 1; break;
+ case oNoAskCertLevel: opt.ask_cert_level = 0; break;
+ case oLocalUser: /* store the local users */
add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
break;
- case oCompress: opt.compress = pargs.r.ret_int; break;
+ case oCompress:
+ /* this is the -z command line option */
+ opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
+ break;
+ case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
+ case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
+ case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
+ case oPasswd:
+ set_passphrase_from_string(pargs.r.ret_str);
+ break;
case oPasswdFD:
pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
opt.use_agent = 0;
break;
-#ifdef __riscos__
case oPasswdFile:
- pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
+ pwfd = open_info_file (pargs.r.ret_str, 0);
break;
-#endif /* __riscos__ */
case oCommandFD:
opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
break;
-#ifdef __riscos__
case oCommandFile:
- opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
+ opt.command_fd = open_info_file (pargs.r.ret_str, 0);
+ break;
+ case oCipherAlgo:
+ def_cipher_string = xstrdup(pargs.r.ret_str);
+ break;
+ case oDigestAlgo:
+ def_digest_string = xstrdup(pargs.r.ret_str);
break;
-#endif /* __riscos__ */
- case oCipherAlgo: def_cipher_string = xstrdup (pargs.r.ret_str); break;
- case oDigestAlgo: def_digest_string = xstrdup (pargs.r.ret_str); break;
case oCompressAlgo:
/* If it is all digits, stick a Z in front of it for
later. This is for backwards compatibility with
@@ -1772,7 +2331,7 @@ main( int argc, char **argv )
char *pt=pargs.r.ret_str;
while(*pt)
{
- if(!isdigit(*pt))
+ if (!isascii (*pt) || !isdigit (*pt))
break;
pt++;
@@ -1780,30 +2339,32 @@ main( int argc, char **argv )
if(*pt=='\0')
{
- def_compress_string=xmalloc (strlen(pargs.r.ret_str)+2);
- strcpy(def_compress_string,"Z");
- strcat(def_compress_string,pargs.r.ret_str);
+ compress_algo_string=xmalloc(strlen(pargs.r.ret_str)+2);
+ strcpy(compress_algo_string,"Z");
+ strcat(compress_algo_string,pargs.r.ret_str);
}
else
- def_compress_string = xstrdup (pargs.r.ret_str);
+ compress_algo_string = xstrdup(pargs.r.ret_str);
}
break;
- case oCertDigestAlgo: cert_digest_string = xstrdup (pargs.r.ret_str); break;
- case oNoSecmemWarn:
- gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
- break;
+ case oCertDigestAlgo: cert_digest_string = xstrdup(pargs.r.ret_str); break;
+ case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
+ case oRequireSecmem: require_secmem=1; break;
+ case oNoRequireSecmem: require_secmem=0; break;
case oNoPermissionWarn: opt.no_perm_warn=1; break;
case oNoMDCWarn: opt.no_mdc_warn=1; break;
- case oCharset:
+ case oDisplayCharset:
if( set_native_charset( pargs.r.ret_str ) )
- log_error(_("%s is not a valid character set\n"),
- pargs.r.ret_str);
+ log_error(_("`%s' is not a valid character set\n"),
+ pargs.r.ret_str);
break;
case oNotDashEscaped: opt.not_dash_escaped = 1; break;
case oEscapeFrom: opt.escape_from = 1; break;
case oNoEscapeFrom: opt.escape_from = 0; break;
case oLockOnce: opt.lock_once = 1; break;
- case oLockNever: disable_dotlock(); break;
+ case oLockNever:
+ disable_dotlock ();
+ break;
case oLockMultiple:
#ifndef __riscos__
opt.lock_once = 0;
@@ -1812,15 +2373,31 @@ main( int argc, char **argv )
#endif /* __riscos__ */
break;
case oKeyServer:
- opt.keyserver_uri=xstrdup (pargs.r.ret_str);
- if(parse_keyserver_uri(pargs.r.ret_str,configname,configlineno))
- log_error(_("could not parse keyserver URI\n"));
+ {
+ struct keyserver_spec *keyserver;
+ keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
+ configname,configlineno);
+ if(!keyserver)
+ log_error(_("could not parse keyserver URL\n"));
+ else
+ {
+ keyserver->next=opt.keyserver;
+ opt.keyserver=keyserver;
+ }
+ }
break;
case oKeyServerOptions:
- parse_keyserver_options(pargs.r.ret_str);
+ if(!parse_keyserver_options(pargs.r.ret_str))
+ {
+ if(configname)
+ log_error(_("%s:%d: invalid keyserver options\n"),
+ configname,configlineno);
+ else
+ log_error(_("invalid keyserver options\n"));
+ }
break;
case oImportOptions:
- if(!parse_import_options(pargs.r.ret_str,&opt.import_options))
+ if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
{
if(configname)
log_error(_("%s:%d: invalid import options\n"),
@@ -1830,7 +2407,7 @@ main( int argc, char **argv )
}
break;
case oExportOptions:
- if(!parse_export_options(pargs.r.ret_str,&opt.export_options))
+ if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
{
if(configname)
log_error(_("%s:%d: invalid export options\n"),
@@ -1840,44 +2417,45 @@ main( int argc, char **argv )
}
break;
case oListOptions:
- {
- struct parse_options lopts[]=
- {
- {"show-photos",LIST_SHOW_PHOTOS},
- {"show-policy-url",LIST_SHOW_POLICY},
- {"show-notation",LIST_SHOW_NOTATION},
- {"show-keyserver-url",LIST_SHOW_KEYSERVER},
- {"show-validity",LIST_SHOW_VALIDITY},
- {"show-long-keyid",LIST_SHOW_LONG_KEYID},
- {"show-keyring",LIST_SHOW_KEYRING},
- {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
- {NULL,0}
- };
-
- if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts))
- {
- if(configname)
- log_error(_("%s:%d: invalid list options\n"),
- configname,configlineno);
- else
- log_error(_("invalid list options\n"));
- }
- }
+ if(!parse_list_options(pargs.r.ret_str))
+ {
+ if(configname)
+ log_error(_("%s:%d: invalid list options\n"),
+ configname,configlineno);
+ else
+ log_error(_("invalid list options\n"));
+ }
break;
case oVerifyOptions:
{
struct parse_options vopts[]=
{
- {"show-photos",VERIFY_SHOW_PHOTOS},
- {"show-policy-url",VERIFY_SHOW_POLICY},
- {"show-notation",VERIFY_SHOW_NOTATION},
- {"show-keyserver-url",VERIFY_SHOW_KEYSERVER},
- {"show-validity",VERIFY_SHOW_VALIDITY},
- {"show-long-keyid",VERIFY_SHOW_LONG_KEYID},
- {NULL,0}
+ {"show-photos",VERIFY_SHOW_PHOTOS,NULL,
+ N_("display photo IDs during signature verification")},
+ {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL,
+ N_("show policy URLs during signature verification")},
+ {"show-notations",VERIFY_SHOW_NOTATIONS,NULL,
+ N_("show all notations during signature verification")},
+ {"show-std-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
+ N_("show IETF standard notations during signature verification")},
+ {"show-standard-notations",VERIFY_SHOW_STD_NOTATIONS,NULL,
+ NULL},
+ {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL,
+ N_("show user-supplied notations during signature verification")},
+ {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL,
+ N_("show preferred keyserver URLs during signature verification")},
+ {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL,
+ N_("show user ID validity during signature verification")},
+ {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL,
+ N_("show revoked and expired user IDs in signature verification")},
+ {"pka-lookups",VERIFY_PKA_LOOKUPS,NULL,
+ N_("validate signatures with PKA data")},
+ {"pka-trust-increase",VERIFY_PKA_TRUST_INCREASE,NULL,
+ N_("elevate the trust of signatures with valid PKA data")},
+ {NULL,0,NULL,NULL}
};
- if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts))
+ if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
{
if(configname)
log_error(_("%s:%d: invalid verify options\n"),
@@ -1889,7 +2467,7 @@ main( int argc, char **argv )
break;
case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
case oExecPath:
- if(set_exec_path(pargs.r.ret_str,0))
+ if(set_exec_path(pargs.r.ret_str))
log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
else
opt.exec_path_set=1;
@@ -1901,27 +2479,33 @@ main( int argc, char **argv )
case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
case oShowNotation:
- opt.list_options|=LIST_SHOW_NOTATION;
- opt.verify_options|=VERIFY_SHOW_NOTATION;
+ deprecated_warning(configname,configlineno,"--show-notation",
+ "--list-options ","show-notations");
+ deprecated_warning(configname,configlineno,"--show-notation",
+ "--verify-options ","show-notations");
+ opt.list_options|=LIST_SHOW_NOTATIONS;
+ opt.verify_options|=VERIFY_SHOW_NOTATIONS;
break;
case oNoShowNotation:
- opt.list_options&=~LIST_SHOW_NOTATION;
- opt.verify_options&=~VERIFY_SHOW_NOTATION;
+ deprecated_warning(configname,configlineno,"--no-show-notation",
+ "--list-options ","no-show-notations");
+ deprecated_warning(configname,configlineno,"--no-show-notation",
+ "--verify-options ","no-show-notations");
+ opt.list_options&=~LIST_SHOW_NOTATIONS;
+ opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
break;
case oUtf8Strings: utf8_strings = 1; break;
case oNoUtf8Strings: utf8_strings = 0; break;
case oDisableCipherAlgo:
{
int algo = gcry_cipher_map_name (pargs.r.ret_str);
- gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO,
- &algo, sizeof algo);
+ gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
}
break;
case oDisablePubkeyAlgo:
{
int algo = gcry_pk_map_name (pargs.r.ret_str);
- gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,
- &algo, sizeof algo );
+ gcry_pk_ctl (GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
}
break;
case oNoSigCache: opt.no_sig_cache = 1; break;
@@ -1933,11 +2517,10 @@ main( int argc, char **argv )
case oNoLiteral: opt.no_literal = 1; break;
case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
case oHonorHttpProxy:
- opt.keyserver_options.honor_http_proxy = 1;
+ add_to_strlist(&opt.keyserver_options.other,"http-proxy");
deprecated_warning(configname,configlineno,
"--honor-http-proxy",
- "--keyserver-options ",
- "honor-http-proxy");
+ "--keyserver-options ","http-proxy");
break;
case oFastListMode: opt.fast_list_mode = 1; break;
case oFixedListMode: opt.fixed_list_mode = 1; break;
@@ -1949,8 +2532,11 @@ main( int argc, char **argv )
case oNoRandomSeedFile: use_random_seed = 0; break;
case oAutoKeyRetrieve:
case oNoAutoKeyRetrieve:
- opt.keyserver_options.auto_key_retrieve=
- (pargs.r_opt==oAutoKeyRetrieve);
+ if(pargs.r_opt==oAutoKeyRetrieve)
+ opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
+ else
+ opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
+
deprecated_warning(configname,configlineno,
pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
"--no-auto-key-retrieve","--keyserver-options ",
@@ -1961,7 +2547,11 @@ main( int argc, char **argv )
case oOverrideSessionKey:
opt.override_session_key = pargs.r.ret_str;
break;
- case oMergeOnly: opt.merge_only = 1; break;
+ case oMergeOnly:
+ deprecated_warning(configname,configlineno,"--merge-only",
+ "--import-options ","merge-only");
+ opt.import_options|=IMPORT_MERGE_ONLY;
+ break;
case oAllowSecretKeyImport: /* obsolete */ break;
case oTryAllSecrets: opt.try_all_secrets = 1; break;
case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
@@ -1991,30 +2581,95 @@ main( int argc, char **argv )
case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
case oGroup: add_group(pargs.r.ret_str); break;
+ case oUnGroup: rm_group(pargs.r.ret_str); break;
+ case oNoGroups:
+ while(opt.grouplist)
+ {
+ struct groupitem *iter=opt.grouplist;
+ free_strlist(iter->values);
+ opt.grouplist=opt.grouplist->next;
+ xfree(iter);
+ }
+ break;
case oStrict: opt.strict=1; log_set_strict(1); break;
case oNoStrict: opt.strict=0; log_set_strict(0); break;
-
case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
-
case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
- case oMultifile: multifile=1; break;
+ case oMultifile: multifile=1; break;
+ case oKeyidFormat:
+ if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
+ opt.keyid_format=KF_SHORT;
+ else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
+ opt.keyid_format=KF_LONG;
+ else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
+ opt.keyid_format=KF_0xSHORT;
+ else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
+ opt.keyid_format=KF_0xLONG;
+ else
+ log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
+ break;
+
+ case oExitOnStatusWriteError:
+ opt.exit_on_status_write_error = 1;
+ break;
+
+ case oLimitCardInsertTries:
+ opt.limit_card_insert_tries = pargs.r.ret_int;
+ break;
+
+ case oRequireCrossCert: opt.flags.require_cross_cert=1; break;
+ case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
+
+ case oAutoKeyLocate:
+ if(!parse_auto_key_locate(pargs.r.ret_str))
+ {
+ if(configname)
+ log_error(_("%s:%d: invalid auto-key-locate list\n"),
+ configname,configlineno);
+ else
+ log_error(_("invalid auto-key-locate list\n"));
+ }
+ break;
+ case oNoAutoKeyLocate:
+ release_akl();
+ break;
+
+ case oAllowMultisigVerification:
+ opt.allow_multisig_verification = 1;
+ break;
+
+ case oNoop: break;
default : pargs.err = configfp? 1:2; break;
- }
- }
+ }
+ }
+
if( configfp ) {
fclose( configfp );
configfp = NULL;
- config_filename = configname; /* Keep a copy of the config
- file name. */
- configname = NULL;
+ /* Remember the first config file name. */
+ if (!save_configname)
+ save_configname = configname;
+ else
+ xfree(configname);
+ configname = NULL;
goto next_pass;
}
- xfree ( configname ); configname = NULL;
+ xfree( configname ); configname = NULL;
if( log_get_errorcount(0) )
g10_exit(2);
+
+ /* The command --gpgconf-list is pretty simple and may be called
+ directly after the option parsing. */
+ if (cmd == aGPGConfList)
+ {
+ gpgconf_list (save_configname);
+ g10_exit (0);
+ }
+ xfree (save_configname);
+
if( nogreeting )
greeting = 0;
@@ -2024,20 +2679,23 @@ main( int argc, char **argv )
fprintf(stderr, "%s\n", strusage(15) );
}
#ifdef IS_DEVELOPMENT_VERSION
- if( !opt.batch ) {
- log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
- log_info("It is only intended for test purposes and should NOT be\n");
- log_info("used in a production environment or with production keys!\n");
- }
+ if( !opt.batch )
+ {
+ const char *s;
+
+ if((s=strusage(20)))
+ log_info("%s\n",s);
+ if((s=strusage(21)))
+ log_info("%s\n",s);
+ if((s=strusage(22)))
+ log_info("%s\n",s);
+ }
#endif
- log_info ("WARNING: This version of gpg is not very matured and\n");
- log_info ("WARNING: only intended for testing. Please keep using\n");
- log_info ("WARNING: gpg 1.2.x, 1.3.x or 1.4.x for OpenPGP\n");
-
- /* FIXME: We should use the lggging to a file only in server mode;
- however we have not yet implemetyed that thus we try to get
- away with --batch as indication for logging to file required. */
+ /* FIXME: We should use logging to a file only in server mode;
+ however we have not yet implemetyed that. Thus we try to get
+ away with --batch as indication for logging to file
+ required. */
if (logfile && opt.batch)
{
log_set_file (logfile);
@@ -2069,12 +2727,21 @@ main( int argc, char **argv )
"--no-literal" );
}
+
if (opt.set_filesize)
log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
if( opt.batch )
tty_batchmode( 1 );
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ if(require_secmem && !got_secmem)
+ {
+ log_info(_("will not run with insecure memory due to %s\n"),
+ "--require-secmem");
+ g10_exit(2);
+ }
+
set_debug (debug_level);
/* Do these after the switch(), so they can override settings. */
@@ -2107,7 +2774,7 @@ main( int argc, char **argv )
preference, but those have their own error
messages). */
- if(openpgp_cipher_test_algo (CIPHER_ALGO_IDEA))
+ if (openpgp_cipher_test_algo(CIPHER_ALGO_IDEA))
{
log_info(_("encrypting a message in --pgp2 mode requires "
"the IDEA cipher\n"));
@@ -2119,8 +2786,8 @@ main( int argc, char **argv )
/* This only sets IDEA for symmetric encryption
since it is set via select_algo_from_prefs for
pk encryption. */
- xfree (def_cipher_string);
- def_cipher_string = xstrdup ("idea");
+ xfree(def_cipher_string);
+ def_cipher_string = xstrdup("idea");
}
/* PGP2 can't handle the output from the textmode
@@ -2137,27 +2804,26 @@ main( int argc, char **argv )
else
{
opt.force_v4_certs = 0;
- opt.sk_comments = 0;
opt.escape_from = 1;
opt.force_v3_sigs = 1;
opt.pgp2_workarounds = 1;
opt.ask_sig_expire = 0;
opt.ask_cert_expire = 0;
- xfree (def_digest_string);
- def_digest_string = xstrdup ("md5");
- opt.def_compress_algo = 1;
+ xfree(def_digest_string);
+ def_digest_string = xstrdup("md5");
+ xfree(s2k_digest_string);
+ s2k_digest_string = xstrdup("md5");
+ opt.compress_algo = COMPRESS_ALGO_ZIP;
}
}
else if(PGP6)
{
- opt.sk_comments=0;
opt.escape_from=1;
opt.force_v3_sigs=1;
opt.ask_sig_expire=0;
}
else if(PGP7)
{
- opt.sk_comments=0;
opt.escape_from=1;
opt.force_v3_sigs=1;
opt.ask_sig_expire=0;
@@ -2167,54 +2833,57 @@ main( int argc, char **argv )
opt.escape_from=1;
}
- /* must do this after dropping setuid, because string_to...
- * may try to load an module */
+
if( def_cipher_string ) {
opt.def_cipher_algo = gcry_cipher_map_name (def_cipher_string);
if(opt.def_cipher_algo==0 &&
(ascii_strcasecmp(def_cipher_string,"idea")==0
|| ascii_strcasecmp(def_cipher_string,"s1")==0))
idea_cipher_warn(1);
- xfree (def_cipher_string); def_cipher_string = NULL;
- if( openpgp_cipher_test_algo (opt.def_cipher_algo) )
+ xfree(def_cipher_string); def_cipher_string = NULL;
+ if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
log_error(_("selected cipher algorithm is invalid\n"));
}
if( def_digest_string ) {
opt.def_digest_algo = gcry_md_map_name (def_digest_string);
- xfree (def_digest_string); def_digest_string = NULL;
- if( openpgp_md_test_algo (opt.def_digest_algo) )
+ xfree(def_digest_string); def_digest_string = NULL;
+ if ( openpgp_md_test_algo (opt.def_digest_algo) )
log_error(_("selected digest algorithm is invalid\n"));
}
- if( def_compress_string ) {
- opt.def_compress_algo = string_to_compress_algo(def_compress_string);
- xfree (def_compress_string); def_compress_string = NULL;
- if( check_compress_algo(opt.def_compress_algo) )
- log_error(_("selected compression algorithm is invalid\n"));
+ if( compress_algo_string ) {
+ opt.compress_algo = string_to_compress_algo(compress_algo_string);
+ xfree(compress_algo_string); compress_algo_string = NULL;
+ if( check_compress_algo(opt.compress_algo) )
+ log_error(_("selected compression algorithm is invalid\n"));
}
if( cert_digest_string ) {
opt.cert_digest_algo = gcry_md_map_name (cert_digest_string);
- xfree (cert_digest_string); cert_digest_string = NULL;
- if( openpgp_md_test_algo(opt.cert_digest_algo) )
- log_error(_("selected certification digest algorithm is invalid\n"));
+ xfree(cert_digest_string); cert_digest_string = NULL;
+ if (openpgp_md_test_algo(opt.cert_digest_algo))
+ log_error(_("selected certification digest algorithm is invalid\n"));
}
if( s2k_cipher_string ) {
opt.s2k_cipher_algo = gcry_cipher_map_name (s2k_cipher_string);
- xfree (s2k_cipher_string); s2k_cipher_string = NULL;
- if( openpgp_cipher_test_algo (opt.s2k_cipher_algo) )
- log_error(_("selected cipher algorithm is invalid\n"));
+ xfree(s2k_cipher_string); s2k_cipher_string = NULL;
+ if (openpgp_cipher_test_algo (opt.s2k_cipher_algo))
+ log_error(_("selected cipher algorithm is invalid\n"));
}
if( s2k_digest_string ) {
opt.s2k_digest_algo = gcry_md_map_name (s2k_digest_string);
- xfree (s2k_digest_string); s2k_digest_string = NULL;
- if( openpgp_md_test_algo (opt.s2k_digest_algo) )
- log_error(_("selected digest algorithm is invalid\n"));
+ xfree(s2k_digest_string); s2k_digest_string = NULL;
+ if (openpgp_md_test_algo(opt.s2k_digest_algo))
+ log_error(_("selected digest algorithm is invalid\n"));
}
if( opt.completes_needed < 1 )
- log_error(_("completes-needed must be greater than 0\n"));
+ log_error(_("completes-needed must be greater than 0\n"));
if( opt.marginals_needed < 2 )
- log_error(_("marginals-needed must be greater than 1\n"));
+ log_error(_("marginals-needed must be greater than 1\n"));
if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
- log_error(_("max-cert-depth must be in range 1 to 255\n"));
+ log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
+ if(opt.def_cert_level<0 || opt.def_cert_level>3)
+ log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
+ if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
+ log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
switch( opt.s2k_mode ) {
case 0:
log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
@@ -2224,16 +2893,14 @@ main( int argc, char **argv )
log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
}
- if(opt.def_cert_check_level<0 || opt.def_cert_check_level>3)
- log_error(_("invalid default-check-level; must be 0, 1, 2, or 3\n"));
-
/* This isn't actually needed, but does serve to error out if the
string is invalid. */
if(opt.def_preference_list &&
keygen_set_std_prefs(opt.def_preference_list,0))
log_error(_("invalid default preferences\n"));
- /* We provide defaults for the personal digest list */
+ /* We provide defaults for the personal digest list. This is
+ SHA-1. */
if(!pers_digest_list)
pers_digest_list="h2";
@@ -2253,7 +2920,7 @@ main( int argc, char **argv )
if(multifile)
{
char *cmdname;
-
+
switch(cmd)
{
case aSign:
@@ -2268,6 +2935,9 @@ main( int argc, char **argv )
case aSym:
cmdname="--symmetric";
break;
+ case aEncrSym:
+ cmdname="--symmetric --encrypt";
+ break;
case aStore:
cmdname="--store";
break;
@@ -2283,6 +2953,9 @@ main( int argc, char **argv )
if( log_get_errorcount(0) )
g10_exit(2);
+ if(opt.compress_level==0)
+ opt.compress_algo=COMPRESS_ALGO_NONE;
+
/* Check our chosen algorithms against the list of legal
algorithms. */
@@ -2291,48 +2964,48 @@ main( int argc, char **argv )
const char *badalg=NULL;
preftype_t badtype=PREFTYPE_NONE;
- if (opt.def_cipher_algo
- && !algo_available (PREFTYPE_SYM,opt.def_cipher_algo,NULL))
+ if(opt.def_cipher_algo
+ && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
{
badalg = gcry_cipher_algo_name (opt.def_cipher_algo);
badtype = PREFTYPE_SYM;
}
- else if (opt.def_digest_algo
- && !algo_available (PREFTYPE_HASH,opt.def_digest_algo,NULL))
+ else if(opt.def_digest_algo
+ && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
{
badalg = gcry_md_algo_name (opt.def_digest_algo);
badtype = PREFTYPE_HASH;
}
- else if (opt.cert_digest_algo
- && !algo_available (PREFTYPE_HASH,opt.cert_digest_algo,NULL))
+ else if(opt.cert_digest_algo
+ && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
{
badalg = gcry_md_algo_name (opt.cert_digest_algo);
badtype = PREFTYPE_HASH;
}
- else if (opt.def_compress_algo!=-1
- && !algo_available (PREFTYPE_ZIP,opt.def_compress_algo,NULL))
+ else if(opt.compress_algo!=-1
+ && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
{
- badalg = compress_algo_to_string (opt.def_compress_algo);
+ badalg = compress_algo_to_string(opt.compress_algo);
badtype = PREFTYPE_ZIP;
}
- if (badalg)
+ if(badalg)
{
switch(badtype)
{
case PREFTYPE_SYM:
- log_info(_("you may not use cipher algorithm \"%s\" "
- "while in %s mode\n"),
+ log_info(_("you may not use cipher algorithm `%s'"
+ " while in %s mode\n"),
badalg,compliance_option_string());
break;
case PREFTYPE_HASH:
- log_info(_("you may not use digest algorithm \"%s\" "
- "while in %s mode\n"),
+ log_info(_("you may not use digest algorithm `%s'"
+ " while in %s mode\n"),
badalg,compliance_option_string());
break;
case PREFTYPE_ZIP:
- log_info(_("you may not use compression algorithm \"%s\" "
- "while in %s mode\n"),
+ log_info(_("you may not use compression algorithm `%s'"
+ " while in %s mode\n"),
badalg,compliance_option_string());
break;
default:
@@ -2343,20 +3016,33 @@ main( int argc, char **argv )
}
}
- /* set the random seed file */
+ /* Set the random seed file. */
if( use_random_seed ) {
char *p = make_filename(opt.homedir, "random_seed", NULL );
+ set_random_seed_file(p);
gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
- xfree (p);
+ if (!access (p, F_OK))
+ register_secured_file (p);
+ xfree(p);
}
if( !cmd && opt.fingerprint && !with_fpr ) {
set_cmd( &cmd, aListKeys);
}
- /* Compression algorithm 0 means no compression at all */
- if( opt.def_compress_algo == 0)
- opt.compress = 0;
+ if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
+ if( cmd == aKModeC ) {
+ opt.fingerprint = 1;
+ cmd = aKMode;
+ }
+ opt.list_sigs = 0;
+ if( opt.verbose > 2 )
+ opt.check_sigs++;
+ if( opt.verbose > 1 )
+ opt.list_sigs++;
+
+ opt.verbose = opt.verbose > 1;
+ }
/* kludge to let -sat generate a clear text signature */
if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
@@ -2365,22 +3051,29 @@ main( int argc, char **argv )
if( opt.verbose > 1 )
set_packet_list_mode(1);
- /* Add the keyrings, but not for some special commands. Also
- avoid adding the secret keyring for a couple of commands to
- avoid unneeded access in case the secrings are stored on a
- floppy */
- if( cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfList )
+ /* Add the keyrings, but not for some special commands and not in
+ case of "-kvv userid keyring". Also avoid adding the secret
+ keyring for a couple of commands to avoid unneeded access in
+ case the secrings are stored on a floppy.
+
+ We always need to add the keyrings if we are running under
+ SELinux, this is so that the rings are added to the list of
+ secured files. */
+ if( ALWAYS_ADD_KEYRINGS
+ || (cmd != aDeArmor && cmd != aEnArmor
+ && !(cmd == aKMode && argc == 2 )) )
{
- if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
- && cmd != aVerify && cmd != aSym)
+ if (ALWAYS_ADD_KEYRINGS
+ || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
+ && cmd != aVerify && cmd != aSym))
{
if (!sec_nrings || default_keyring) /* add default secret rings */
- keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
+ keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
for (sl = sec_nrings; sl; sl = sl->next)
keydb_add_resource ( sl->d, 0, 1 );
}
if( !nrings || default_keyring ) /* add default ring */
- keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
+ keydb_add_resource ("pubring" EXTSEP_S "gpg", 4, 0);
for(sl = nrings; sl; sl = sl->next )
keydb_add_resource ( sl->d, sl->flags, 0 );
}
@@ -2401,20 +3094,17 @@ main( int argc, char **argv )
case aDeArmor:
case aEnArmor:
case aFixTrustDB:
- case aCardStatus:
- case aCardEdit:
- case aChangePIN:
- case aGPGConfList:
break;
case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
default: rc = setup_trustdb(1, trustdb_name ); break;
}
if( rc )
- log_error(_("failed to initialize the TrustDB: %s\n"), gpg_strerror (rc));
+ log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
- switch (cmd) {
+ switch (cmd)
+ {
case aStore:
case aSym:
case aSign:
@@ -2426,22 +3116,23 @@ main( int argc, char **argv )
break;
default:
break;
- }
+ }
- switch( cmd ) {
+ switch( cmd )
+ {
case aStore: /* only store the file */
if( argc > 1 )
wrong_args(_("--store [filename]"));
if( (rc = encode_store(fname)) )
- log_error ("\b%s: store failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
+ log_error ("storing `%s' failed: %s\n",
+ print_fname_stdin(fname),g10_errstr(rc) );
break;
case aSym: /* encrypt the given file only with the symmetric cipher */
if( argc > 1 )
wrong_args(_("--symmetric [filename]"));
if( (rc = encode_symmetric(fname)) )
- log_error ("\b%s: symmetric encryption failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
+ log_error (_("symmetric encryption of `%s' failed: %s\n"),
+ print_fname_stdin(fname),g10_errstr(rc) );
break;
case aEncr: /* encrypt the given file */
@@ -2449,12 +3140,33 @@ main( int argc, char **argv )
encode_crypt_files(argc, argv, remusr);
else
{
- if( argc > 1 )
- wrong_args(_("--encrypt [filename]"));
- if( (rc = encode_crypt(fname,remusr)) )
- log_error("%s: encryption failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
- }
+ if( argc > 1 )
+ wrong_args(_("--encrypt [filename]"));
+ if( (rc = encode_crypt(fname,remusr,0)) )
+ log_error("%s: encryption failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
+ }
+ break;
+
+ case aEncrSym:
+ /* This works with PGP 8 in the sense that it acts just like a
+ symmetric message. It doesn't work at all with 2 or 6. It
+ might work with 7, but alas, I don't have a copy to test
+ with right now. */
+ if( argc > 1 )
+ wrong_args(_("--symmetric --encrypt [filename]"));
+ else if(opt.s2k_mode==0)
+ log_error(_("you cannot use --symmetric --encrypt"
+ " with --s2k-mode 0\n"));
+ else if(PGP2 || PGP6 || PGP7 || RFC1991)
+ log_error(_("you cannot use --symmetric --encrypt"
+ " while in %s mode\n"),compliance_option_string());
+ else
+ {
+ if( (rc = encode_crypt(fname,remusr,1)) )
+ log_error("%s: encryption failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
+ }
break;
case aSign: /* sign the given file */
@@ -2467,12 +3179,12 @@ main( int argc, char **argv )
if( argc > 1 )
wrong_args(_("--sign [filename]"));
if( argc ) {
- sl = xcalloc (1, sizeof *sl + strlen(fname));
+ sl = xmalloc_clear( sizeof *sl + strlen(fname));
strcpy(sl->d, fname);
}
}
if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
- log_error("signing failed: %s\n", gpg_strerror (rc) );
+ log_error("signing failed: %s\n", g10_errstr(rc) );
free_strlist(sl);
break;
@@ -2480,23 +3192,49 @@ main( int argc, char **argv )
if( argc > 1 )
wrong_args(_("--sign --encrypt [filename]"));
if( argc ) {
- sl = xcalloc (1, sizeof *sl + strlen(fname));
+ sl = xmalloc_clear( sizeof *sl + strlen(fname));
strcpy(sl->d, fname);
}
else
sl = NULL;
if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
- log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), gpg_strerror (rc) );
+ log_error("%s: sign+encrypt failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
free_strlist(sl);
break;
+ case aSignEncrSym: /* sign and encrypt the given file */
+ if( argc > 1 )
+ wrong_args(_("--symmetric --sign --encrypt [filename]"));
+ else if(opt.s2k_mode==0)
+ log_error(_("you cannot use --symmetric --sign --encrypt"
+ " with --s2k-mode 0\n"));
+ else if(PGP2 || PGP6 || PGP7 || RFC1991)
+ log_error(_("you cannot use --symmetric --sign --encrypt"
+ " while in %s mode\n"),compliance_option_string());
+ else
+ {
+ if( argc )
+ {
+ sl = xmalloc_clear( sizeof *sl + strlen(fname));
+ strcpy(sl->d, fname);
+ }
+ else
+ sl = NULL;
+ if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
+ log_error("%s: symmetric+sign+encrypt failed: %s\n",
+ print_fname_stdin(fname), g10_errstr(rc) );
+ free_strlist(sl);
+ }
+ break;
+
case aSignSym: /* sign and conventionally encrypt the given file */
if (argc > 1)
wrong_args(_("--sign --symmetric [filename]"));
rc = sign_symencrypt_file (fname, locusr);
if (rc)
log_error("%s: sign+symmetric failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
+ print_fname_stdin(fname), g10_errstr(rc) );
break;
case aClearsign: /* make a clearsig */
@@ -2504,65 +3242,58 @@ main( int argc, char **argv )
wrong_args(_("--clearsign [filename]"));
if( (rc = clearsign_file(fname, locusr, NULL)) )
log_error("%s: clearsign failed: %s\n",
- print_fname_stdin(fname), gpg_strerror (rc) );
+ print_fname_stdin(fname), g10_errstr(rc) );
break;
case aVerify:
- if(multifile)
+ if(multifile)
{
if( (rc = verify_files( argc, argv ) ))
- log_error("verify files failed: %s\n", gpg_strerror (rc) );
+ log_error("verify files failed: %s\n", g10_errstr(rc) );
+ }
+ else
+ {
+ if( (rc = verify_signatures( argc, argv ) ))
+ log_error("verify signatures failed: %s\n", g10_errstr(rc) );
}
- else
- {
- if( (rc = verify_signatures( argc, argv ) ))
- log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
- }
break;
case aDecrypt:
if(multifile)
decrypt_messages(argc, argv);
else
- {
- if( argc > 1 )
- wrong_args(_("--decrypt [filename]"));
- if( (rc = decrypt_message( fname ) ))
- log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
- }
+ {
+ if( argc > 1 )
+ wrong_args(_("--decrypt [filename]"));
+ if( (rc = decrypt_message( fname ) ))
+ log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
+ }
break;
-
- case aSignKey: /* sign the key given as argument */
+
+ case aSignKey:
if( argc != 1 )
- wrong_args(_("--sign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 1 );
- xfree (username);
- break;
-
+ wrong_args(_("--sign-key user-id"));
+ /* fall through */
case aLSignKey:
if( argc != 1 )
- wrong_args(_("--lsign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 2 );
- xfree (username);
- break;
+ wrong_args(_("--lsign-key user-id"));
+ /* fall through */
- case aNRSignKey:
- if( argc != 1 )
- wrong_args(_("--nrsign-key user-id"));
- username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 3 );
- xfree (username);
- break;
+ sl=NULL;
- case aNRLSignKey:
- if( argc != 1 )
- wrong_args(_("--nrlsign-key user-id"));
+ if(cmd==aSignKey)
+ append_to_strlist(&sl,"sign");
+ else if(cmd==aLSignKey)
+ append_to_strlist(&sl,"lsign");
+ else
+ BUG();
+
+ append_to_strlist( &sl, "save" );
username = make_username( fname );
- keyedit_menu(fname, locusr, NULL, 4 );
- xfree (username);
- break;
+ keyedit_menu(fname, locusr, sl, 0, 0 );
+ xfree(username);
+ free_strlist(sl);
+ break;
case aEditKey: /* Edit a key signature */
if( !argc )
@@ -2572,12 +3303,12 @@ main( int argc, char **argv )
sl = NULL;
for( argc--, argv++ ; argc; argc--, argv++ )
append_to_strlist( &sl, *argv );
- keyedit_menu( username, locusr, sl, 0 );
+ keyedit_menu( username, locusr, sl, 0, 1 );
free_strlist(sl);
}
else
- keyedit_menu(username, locusr, NULL, 0 );
- xfree (username);
+ keyedit_menu(username, locusr, NULL, 0, 1 );
+ xfree(username);
break;
case aDeleteKeys:
@@ -2612,27 +3343,54 @@ main( int argc, char **argv )
free_strlist(sl);
break;
+ case aKMode: /* list keyring -- NOTE: This will be removed soon */
+ if( argc < 2 ) { /* -kv [userid] */
+ sl = NULL;
+ if (argc && **argv)
+ add_to_strlist2( &sl, *argv, utf8_strings );
+ public_key_list( sl );
+ free_strlist(sl);
+ }
+ else if( argc == 2 ) { /* -kv userid keyring */
+ if( access( argv[1], R_OK ) ) {
+ log_error(_("can't open `%s': %s\n"),
+ print_fname_stdin(argv[1]), strerror(errno));
+ }
+ else {
+ /* add keyring (default keyrings are not registered in this
+ * special case */
+ keydb_add_resource( argv[1], 0, 0 );
+ sl = NULL;
+ if (**argv)
+ add_to_strlist2( &sl, *argv, utf8_strings );
+ public_key_list( sl );
+ free_strlist(sl);
+ }
+ }
+ else
+ wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
+ break;
+
case aKeygen: /* generate a key */
if( opt.batch ) {
if( argc > 1 )
wrong_args("--gen-key [parameterfile]");
- generate_keypair( argc? *argv : NULL, NULL );
+ generate_keypair( argc? *argv : NULL, NULL, NULL );
}
else {
if( argc )
wrong_args("--gen-key");
- generate_keypair(NULL, NULL);
+ generate_keypair(NULL, NULL, NULL);
}
break;
case aFastImport:
- opt.import_options |= IMPORT_FAST_IMPORT;
+ opt.import_options |= IMPORT_FAST;
case aImport:
import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
break;
case aExport:
- case aExportAll:
case aSendKeys:
case aRecvKeys:
sl = NULL;
@@ -2647,11 +3405,11 @@ main( int argc, char **argv )
if(rc)
{
if(cmd==aSendKeys)
- log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc));
+ log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
else if(cmd==aRecvKeys)
- log_error(_("keyserver receive failed: %s\n"),gpg_strerror (rc));
+ log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
else
- log_error(_("key export failed: %s\n"),gpg_strerror (rc));
+ log_error(_("key export failed: %s\n"),g10_errstr(rc));
}
free_strlist(sl);
break;
@@ -2659,20 +3417,10 @@ main( int argc, char **argv )
case aSearchKeys:
sl = NULL;
for( ; argc; argc--, argv++ )
- {
- if (utf8_strings)
- sl = append_to_strlist ( &sl, *argv );
- else
- {
- char *p = native_to_utf8 ( *argv );
- sl = append_to_strlist( &sl, p );
- xfree( p );
- }
- }
-
+ append_to_strlist2( &sl, *argv, utf8_strings );
rc=keyserver_search( sl );
if(rc)
- log_error(_("keyserver search failed: %s\n"),gpg_strerror (rc));
+ log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
free_strlist(sl);
break;
@@ -2682,7 +3430,17 @@ main( int argc, char **argv )
add_to_strlist2( &sl, *argv, utf8_strings );
rc=keyserver_refresh(sl);
if(rc)
- log_error(_("keyserver refresh failed: %s\n"),gpg_strerror (rc));
+ log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
+ free_strlist(sl);
+ break;
+
+ case aFetchKeys:
+ sl = NULL;
+ for( ; argc; argc--, argv++ )
+ add_to_strlist2( &sl, *argv, utf8_strings );
+ rc=keyserver_fetch(sl);
+ if(rc)
+ log_error("key fetch failed: %s\n",g10_errstr(rc));
free_strlist(sl);
break;
@@ -2707,15 +3465,15 @@ main( int argc, char **argv )
wrong_args("--gen-revoke user-id");
username = make_username(*argv);
gen_revoke( username );
- xfree ( username );
+ xfree( username );
break;
case aDesigRevoke:
if( argc != 1 )
wrong_args("--desig-revoke user-id");
username = make_username(*argv);
- gen_desig_revoke( username );
- xfree ( username );
+ gen_desig_revoke( username, locusr );
+ xfree( username );
break;
case aDeArmor:
@@ -2723,7 +3481,7 @@ main( int argc, char **argv )
wrong_args("--dearmor [file]");
rc = dearmor_file( argc? *argv: NULL );
if( rc )
- log_error(_("dearmoring failed: %s\n"), gpg_strerror (rc));
+ log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
break;
case aEnArmor:
@@ -2731,12 +3489,12 @@ main( int argc, char **argv )
wrong_args("--enarmor [file]");
rc = enarmor_file( argc? *argv: NULL );
if( rc )
- log_error(_("enarmoring failed: %s\n"), gpg_strerror (rc));
+ log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
break;
case aPrimegen:
-#if 0 /*FIXME-XXX*/
+#if 0 /*FIXME*/
{ int mode = argc < 2 ? 0 : atoi(*argv);
if( mode == 1 && argc == 2 ) {
@@ -2748,7 +3506,7 @@ main( int argc, char **argv )
atoi(argv[2]), NULL,NULL ), 1);
}
else if( mode == 3 && argc == 3 ) {
- gcry_mpi_t *factors;
+ MPI *factors;
mpi_print( stdout, generate_elg_prime(
1, atoi(argv[1]),
atoi(argv[2]), NULL,&factors ), 1);
@@ -2756,7 +3514,7 @@ main( int argc, char **argv )
mpi_print( stdout, factors[0], 1 ); /* print q */
}
else if( mode == 4 && argc == 3 ) {
- gcry_mpi_t g = mpi_alloc(1);
+ MPI g = mpi_alloc(1);
mpi_print( stdout, generate_elg_prime(
0, atoi(argv[1]),
atoi(argv[2]), g, NULL ), 1);
@@ -2769,6 +3527,7 @@ main( int argc, char **argv )
putchar('\n');
}
#endif
+ wrong_args("--gen-prime not yet supported ");
break;
case aGenRandom:
@@ -2803,7 +3562,7 @@ main( int argc, char **argv )
} else {
fwrite( p, n, 1, stdout );
}
- xfree (p);
+ xfree(p);
if( !endless )
count -= n;
}
@@ -2874,7 +3633,7 @@ main( int argc, char **argv )
for( ; argc; argc--, argv++ ) {
username = make_username( *argv );
list_trust_path( username );
- xfree (username);
+ xfree(username);
}
break;
@@ -2890,84 +3649,48 @@ main( int argc, char **argv )
import_ownertrust( argc? *argv:NULL );
break;
- case aPipeMode:
- if ( argc )
- wrong_args ("--pipemode");
- run_in_pipemode ();
- break;
-
case aRebuildKeydbCaches:
if (argc)
wrong_args ("--rebuild-keydb-caches");
- keydb_rebuild_caches ();
+ keydb_rebuild_caches (1);
break;
- case aCardStatus:
- if (argc)
- wrong_args ("--card-status");
- card_status (stdout, NULL, 0);
- break;
+#ifdef ENABLE_CARD_SUPPORT
+ case aCardStatus:
+ if (argc)
+ wrong_args ("--card-status");
+ card_status (stdout, NULL, 0);
+ break;
- case aCardEdit:
- if (argc)
- {
- sl = NULL;
- for (argc--, argv++ ; argc; argc--, argv++)
- append_to_strlist (&sl, *argv);
- card_edit (sl);
- free_strlist (sl);
+ case aCardEdit:
+ if (argc) {
+ sl = NULL;
+ for (argc--, argv++ ; argc; argc--, argv++)
+ append_to_strlist (&sl, *argv);
+ card_edit (sl);
+ free_strlist (sl);
}
- else
- card_edit (NULL);
- break;
+ else
+ card_edit (NULL);
+ break;
- case aChangePIN:
- if (!argc)
- change_pin (0,1);
- else if (argc == 1)
- change_pin ( atoi (*argv), 1);
- else
+ case aChangePIN:
+ if (!argc)
+ change_pin (0,1);
+ else if (argc == 1)
+ change_pin (atoi (*argv),1);
+ else
wrong_args ("--change-pin [no]");
- break;
-
- case aGPGConfList:
- { /* List options and default values in the GPG Conf format. */
-
- /* The following list is taken from gnupg/tools/gpgconf-comp.c. */
- /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
- FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE. */
-#define GC_OPT_FLAG_NONE 0UL
- /* The RUNTIME flag for an option indicates that the option can be
- changed at runtime. */
-#define GC_OPT_FLAG_RUNTIME (1UL << 3)
- /* The DEFAULT flag for an option indicates that the option has a
- default value. */
-#define GC_OPT_FLAG_DEFAULT (1UL << 4)
- /* The DEF_DESC flag for an option indicates that the option has a
- default, which is described by the value of the default field. */
-#define GC_OPT_FLAG_DEF_DESC (1UL << 5)
- /* The NO_ARG_DESC flag for an option indicates that the argument has
- a default, which is described by the value of the ARGDEF field. */
-#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
-
- if (!config_filename)
- config_filename = make_filename (opt.homedir, "gpg.conf", NULL);
-
- printf ("gpgconf-gpg.conf:%lu:\"%s\n",
- GC_OPT_FLAG_DEFAULT, config_filename);
-
- printf ("verbose:%lu:\n"
- "quiet:%lu:\n"
- "debug-level:%lu:\"none:\n"
- "log-file:%lu:\n",
- GC_OPT_FLAG_NONE,
- GC_OPT_FLAG_NONE,
- GC_OPT_FLAG_DEFAULT,
- GC_OPT_FLAG_NONE );
- printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
+ break;
+#endif /* ENABLE_CARD_SUPPORT*/
- }
- break;
+ case aListConfig:
+ {
+ char *str=collapse_args(argc,argv);
+ list_config(str);
+ xfree(str);
+ }
+ break;
case aListPackets:
opt.list_packets=2;
@@ -2979,7 +3702,14 @@ main( int argc, char **argv )
&& isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
log_info(_("Go ahead and type your message ...\n"));
- if( !(a = iobuf_open(fname)) )
+ a = iobuf_open(fname);
+ if (a && is_secured_file (iobuf_get_fd (a)))
+ {
+ iobuf_close (a);
+ a = NULL;
+ errno = EPERM;
+ }
+ if( !a )
log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
else {
@@ -2995,11 +3725,11 @@ main( int argc, char **argv )
}
rc = proc_packets(NULL, a );
if( rc )
- log_error("processing message failed: %s\n", gpg_strerror (rc) );
+ log_error("processing message failed: %s\n", g10_errstr(rc) );
iobuf_close(a);
}
break;
- }
+ }
/* cleanup */
FREE_STRLIST(remusr);
@@ -3008,6 +3738,7 @@ main( int argc, char **argv )
return 8; /*NEVER REACHED*/
}
+
/* Note: This function is used by signal handlers!. */
static void
emergency_cleanup (void)
@@ -3019,18 +3750,23 @@ emergency_cleanup (void)
void
g10_exit( int rc )
{
+#ifdef ENABLE_CARD_SUPPORT
+ card_close ();
+#endif
+
gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
- if (opt.debug & DBG_MEMSTAT_VALUE)
+ if ( (opt.debug & DBG_MEMSTAT_VALUE) )
{
- gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
- gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
+ gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
+ gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
}
if (opt.debug)
gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
+
emergency_cleanup ();
- rc = rc? rc : log_get_errorcount(0)? 2 :
- g10_errors_seen? 1 : 0;
- exit (rc );
+
+ rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
+ exit (rc);
}
@@ -3038,7 +3774,7 @@ g10_exit( int rc )
display, but there are a few other similar assumptions in the
display code. */
static void
-print_hex( MD_HANDLE md, int algo, const char *fname )
+print_hex( gcry_md_hd_t md, int algo, const char *fname )
{
int i,n,count,indent=0;
const byte *p;
@@ -3064,7 +3800,7 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
p = gcry_md_read (md, algo);
n = gcry_md_get_algo_dlen (algo);
- count+=printf("%02X",*p++);
+ count += printf ("%02X",*p++);
for(i=1;i<n;i++,p++)
{
@@ -3118,13 +3854,13 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
}
static void
-print_hashline( MD_HANDLE md, int algo, const char *fname )
+print_hashline( gcry_md_hd_t md, int algo, const char *fname )
{
int i, n;
const byte *p;
if ( fname ) {
- for (p = (const unsigned char *)fname; *p; p++ ) {
+ for (p = fname; *p; p++ ) {
if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
printf("%%%02X", *p );
else
@@ -3133,7 +3869,7 @@ print_hashline( MD_HANDLE md, int algo, const char *fname )
}
putchar(':');
printf("%d:", algo );
- p = gcry_md_read (md, algo );
+ p = gcry_md_read (md, algo);
n = gcry_md_get_algo_dlen (algo);
for(i=0; i < n ; i++, p++ )
printf("%02X", *p );
@@ -3147,7 +3883,7 @@ print_mds( const char *fname, int algo )
FILE *fp;
char buf[1024];
size_t n;
- MD_HANDLE md;
+ gcry_md_hd_t md;
if( !fname ) {
fp = stdin;
@@ -3157,25 +3893,31 @@ print_mds( const char *fname, int algo )
}
else {
fp = fopen( fname, "rb" );
+ if (fp && is_secured_file (fileno (fp)))
+ {
+ fclose (fp);
+ fp = NULL;
+ errno = EPERM;
+ }
}
if( !fp ) {
log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
return;
}
- gcry_md_open (&md, 0, 0 );
+ gcry_md_open (&md, 0, 0);
if( algo )
- gcry_md_enable ( md, algo );
+ gcry_md_enable (md, algo);
else {
- gcry_md_enable (md, GCRY_MD_MD5 );
- gcry_md_enable (md, GCRY_MD_SHA1 );
- gcry_md_enable (md, GCRY_MD_RMD160 );
+ gcry_md_enable (md, GCRY_MD_MD5);
+ gcry_md_enable (md, GCRY_MD_SHA1);
+ gcry_md_enable (md, GCRY_MD_RMD160);
#ifdef USE_SHA256
- gcry_md_enable (md, GCRY_MD_SHA256 );
+ gcry_md_enable (md, GCRY_MD_SHA256);
#endif
#ifdef USE_SHA512
- gcry_md_enable (md, GCRY_MD_SHA384 );
- gcry_md_enable (md, GCRY_MD_SHA512 );
+ gcry_md_enable (md, GCRY_MD_SHA384);
+ gcry_md_enable (md, GCRY_MD_SHA512);
#endif
}
@@ -3218,7 +3960,7 @@ print_mds( const char *fname, int algo )
}
}
}
- gcry_md_close (md);
+ gcry_md_close(md);
if( fp != stdin )
fclose(fp);
@@ -3233,71 +3975,28 @@ print_mds( const char *fname, int algo )
static void
add_notation_data( const char *string, int which )
{
- const char *s;
- STRLIST sl,*notation_data;
- int critical=0;
- int highbit=0;
- int saw_at=0;
-
- if(which)
- notation_data=&opt.cert_notation_data;
- else
- notation_data=&opt.sig_notation_data;
-
- if( *string == '!' ) {
- critical = 1;
- string++;
- }
-
- /* If and when the IETF assigns some official name tags, we'll
- have to add them here. */
-
- for( s=string ; *s != '='; s++ )
- {
- if( *s=='@')
- saw_at=1;
-
- if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) )
- {
- log_error(_("a notation name must have only printable characters "
- "or spaces, and end with an '='\n") );
- return;
- }
- }
+ struct notation *notation;
- if(!saw_at && !opt.expert)
- {
- log_error(
- _("a user notation name must contain the '@' character\n"));
- return;
- }
-
- /* we only support printable text - therefore we enforce the use
- * of only printable characters (an empty value is valid) */
- for( s++; *s ; s++ ) {
- if( *s & 0x80 )
- highbit = 1;
- else if( iscntrl(*s) ) {
- log_error(_("a notation value must not use "
- "any control characters\n") );
- return;
+ notation=string_to_notation(string,utf8_strings);
+ if(notation)
+ {
+ if(which)
+ {
+ notation->next=opt.cert_notations;
+ opt.cert_notations=notation;
+ }
+ else
+ {
+ notation->next=opt.sig_notations;
+ opt.sig_notations=notation;
}
}
-
- if( highbit ) /* must use UTF8 encoding */
- sl = add_to_strlist2( notation_data, string, utf8_strings );
- else
- sl = add_to_strlist( notation_data, string );
-
- if( critical )
- sl->flags |= 1;
}
-
static void
add_policy_url( const char *string, int which )
{
- int i,critical=0;
+ unsigned int i,critical=0;
STRLIST sl;
if(*string=='!')
@@ -3307,7 +4006,7 @@ add_policy_url( const char *string, int which )
}
for(i=0;i<strlen(string);i++)
- if(string[i]&0x80 || iscntrl(string[i]))
+ if( !isascii (string[i]) || iscntrl(string[i]))
break;
if(i==0 || i<strlen(string))
@@ -3327,11 +4026,10 @@ add_policy_url( const char *string, int which )
sl->flags |= 1;
}
-
static void
add_keyserver_url( const char *string, int which )
{
- int i,critical=0;
+ unsigned int i,critical=0;
STRLIST sl;
if(*string=='!')
@@ -3341,7 +4039,7 @@ add_keyserver_url( const char *string, int which )
}
for(i=0;i<strlen(string);i++)
- if(string[i]&0x80 || iscntrl(string[i]))
+ if( !isascii (string[i]) || iscntrl(string[i]))
break;
if(i==0 || i<strlen(string))
@@ -3349,8 +4047,7 @@ add_keyserver_url( const char *string, int which )
if(which)
BUG();
else
- log_error(_("the given signature preferred"
- " keyserver URL is invalid\n"));
+ log_error(_("the given preferred keyserver URL is invalid\n"));
}
if(which)
@@ -3361,4 +4058,3 @@ add_keyserver_url( const char *string, int which )
if(critical)
sl->flags |= 1;
}
-