aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.gpg.bc
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2021-08-10 23:26:42 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2021-08-18 08:57:14 +0200
commitca7a30f231201cdc5acc567f3ef08d1dd4369b44 (patch)
treef68982e9315d3e409592bc78fc2201a8976374e3 /org.eclipse.jgit.gpg.bc
parentaad1bde5220fa3a645c77ab2ba9c81c756c6ae84 (diff)
downloadjgit-ca7a30f231201cdc5acc567f3ef08d1dd4369b44.tar.gz
jgit-ca7a30f231201cdc5acc567f3ef08d1dd4369b44.zip
[gpg] Better GPG home directory determination
GPG can use customized directories instead of the standard ~/.gnupg or %APPDATA%\gnupg directories: * Environment variable GNUPGHOME can define the location. * On Windows, a registry key may define the location (but this is deprecated). * Portable installations may use a directory defined via a file "gpgconf.ctl". * GPG programs may take a --homedir command-line argument, which overrides anything. Implement handling of environment variable GNUPGHOME. The other ways of GPG to get its home directory are outside the reach of JGit. Provide a system property "jgit.gpg.home" that the user can set in such cases. Do tilde replacement for the system property and for GNUPGHOME. Note that on VMS, the default directory would be ~/gnupg (without dot). This is not accounted for, but a user on VMS could now use either the system property or GNUPGHOME to direct JGit to the right directory. Bug: 575327 Change-Id: Id5ea04a85d58dba0c0df7a705777630d36042467 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.gpg.bc')
-rw-r--r--org.eclipse.jgit.gpg.bc/resources/org/eclipse/jgit/gpg/bc/internal/BCText.properties2
-rw-r--r--org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BCText.java2
-rw-r--r--org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java57
3 files changed, 46 insertions, 15 deletions
diff --git a/org.eclipse.jgit.gpg.bc/resources/org/eclipse/jgit/gpg/bc/internal/BCText.properties b/org.eclipse.jgit.gpg.bc/resources/org/eclipse/jgit/gpg/bc/internal/BCText.properties
index e4b1baba1f..ab83298c15 100644
--- a/org.eclipse.jgit.gpg.bc/resources/org/eclipse/jgit/gpg/bc/internal/BCText.properties
+++ b/org.eclipse.jgit.gpg.bc/resources/org/eclipse/jgit/gpg/bc/internal/BCText.properties
@@ -13,6 +13,8 @@ gpgNoSuchAlgorithm=Cannot decrypt encrypted secret key: encryption algorithm {0}
gpgNotASigningKey=Secret key ({0}) is not suitable for signing
gpgKeyInfo=GPG Key (fingerprint {0})
gpgSigningCancelled=Signing was cancelled
+logWarnGnuPGHome=Cannot access GPG home directory given by environment variable GNUPGHOME={}
+logWarnGpgHomeProperty=Cannot access GPG home directory given by Java system property jgit.gpg.home={}
nonSignatureError=Signature does not decode into a signature object
secretKeyTooShort=Secret key file corrupt; only {0} bytes read
sexprHexNotClosed=Hex number in s-expression not closed
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BCText.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BCText.java
index aedf8a5be5..68ee2fd5de 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BCText.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BCText.java
@@ -42,6 +42,8 @@ public final class BCText extends TranslationBundle {
/***/ public String gpgNotASigningKey;
/***/ public String gpgKeyInfo;
/***/ public String gpgSigningCancelled;
+ /***/ public String logWarnGnuPGHome;
+ /***/ public String logWarnGpgHomeProperty;
/***/ public String nonSignatureError;
/***/ public String secretKeyTooShort;
/***/ public String sexprHexNotClosed;
diff --git a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
index cf4d3d2340..8cd03bd36f 100644
--- a/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
+++ b/org.eclipse.jgit.gpg.bc/src/org/eclipse/jgit/gpg/bc/internal/BouncyCastleGpgKeyLocator.java
@@ -29,6 +29,8 @@ import java.security.NoSuchProviderException;
import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Locale;
+import java.util.function.Consumer;
+import java.util.function.Function;
import org.bouncycastle.gpg.keybox.BlobType;
import org.bouncycastle.gpg.keybox.KeyBlob;
@@ -98,29 +100,54 @@ public class BouncyCastleGpgKeyLocator {
private static Path findGpgDirectory() {
SystemReader system = SystemReader.getInstance();
+ Function<String, Path> resolveTilde = s -> {
+ if (s.startsWith("~/") || s.startsWith("~" + File.separatorChar)) { //$NON-NLS-1$ //$NON-NLS-2$
+ return new File(FS.DETECTED.userHome(), s.substring(2))
+ .getAbsoluteFile().toPath();
+ }
+ return Paths.get(s);
+ };
+ Path path = checkDirectory(system.getProperty("jgit.gpg.home"), //$NON-NLS-1$
+ resolveTilde,
+ s -> log.warn(BCText.get().logWarnGpgHomeProperty, s));
+ if (path != null) {
+ return path;
+ }
+ path = checkDirectory(system.getenv("GNUPGHOME"), resolveTilde, //$NON-NLS-1$
+ s -> log.warn(BCText.get().logWarnGnuPGHome, s));
+ if (path != null) {
+ return path;
+ }
if (system.isWindows()) {
// On Windows prefer %APPDATA%\gnupg if it exists, even if Cygwin is
// used.
- String appData = system.getenv("APPDATA"); //$NON-NLS-1$
- if (appData != null && !appData.isEmpty()) {
- try {
- Path directory = Paths.get(appData).resolve("gnupg"); //$NON-NLS-1$
- if (Files.isDirectory(directory)) {
- return directory;
- }
- } catch (SecurityException | InvalidPathException e) {
- // Ignore and return the default location below.
- }
+ path = checkDirectory(system.getenv("APPDATA"), //$NON-NLS-1$
+ s -> Paths.get(s).resolve("gnupg"), null); //$NON-NLS-1$
+ if (path != null) {
+ return path;
}
}
// All systems, including Cygwin and even Windows if
// %APPDATA%\gnupg doesn't exist: ~/.gnupg
- File home = FS.DETECTED.userHome();
- if (home == null) {
- // Oops. What now?
- home = new File(".").getAbsoluteFile(); //$NON-NLS-1$
+ return resolveTilde.apply("~/.gnupg"); //$NON-NLS-1$
+ }
+
+ private static Path checkDirectory(String dir,
+ Function<String, Path> toPath, Consumer<String> warn) {
+ if (!StringUtils.isEmptyOrNull(dir)) {
+ try {
+ Path directory = toPath.apply(dir);
+ if (Files.isDirectory(directory)) {
+ return directory;
+ }
+ } catch (SecurityException | InvalidPathException e) {
+ // Ignore, warn, and try other known directories
+ }
+ if (warn != null) {
+ warn.accept(dir);
+ }
}
- return home.toPath().resolve(".gnupg"); //$NON-NLS-1$
+ return null;
}
/**