diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-08-10 23:26:42 +0200 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-08-18 08:57:14 +0200 |
commit | ca7a30f231201cdc5acc567f3ef08d1dd4369b44 (patch) | |
tree | f68982e9315d3e409592bc78fc2201a8976374e3 /org.eclipse.jgit.gpg.bc | |
parent | aad1bde5220fa3a645c77ab2ba9c81c756c6ae84 (diff) | |
download | jgit-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')
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; } /** |