Merge branch 'master' into stable-5.11

* master: (35 commits)
  [releng] japicmp: update last release version
  IgnoreNode: include path to file for invalid .gitignore patterns
  FastIgnoreRule: include bad pattern in log message
  init: add config option to set default for the initial branch name
  init: allow specifying the initial branch name for the new repository
  Fail clone if initial branch doesn't exist in remote repository
  GPG: fix reading unprotected old-format secret keys
  Update Orbit to S20210216215844
  Add missing bazel dependency for o.e.j.gpg.bc.test
  GPG: handle extended private key format
  dfs: handle short copies
  [GPG] Provide a factory for the BouncyCastleGpgSigner
  Fix boxing warnings
  GPG: compute the keygrip to find a secret key
  GPG signature verification via BouncyCastle
  Post commit hook failure should not cause commit failure
  Allow to define additional Hook classes outside JGit
  GitHook: use default charset for output and error streams
  GitHook: use generic OutputStream instead of PrintStream
  Update jetty to 9.4.36.v20210114
  ...

Change-Id: I1cf5ab262c67b986e82422c48dfc103e335d28cc
This commit is contained in:
Matthias Sohn 2021-02-24 14:54:52 +01:00
commit 1b7eafab13
188 changed files with 6195 additions and 1365 deletions

View File

@ -1 +1 @@
4.0.0rc2
4.0.0

2
BUILD
View File

@ -13,6 +13,8 @@ genrule(
"//org.eclipse.jgit.lfs:jgit-lfs",
"//org.eclipse.jgit.lfs.server:jgit-lfs-server",
"//org.eclipse.jgit.junit:junit",
"//org.eclipse.jgit.ssh.apache:ssh-apache",
"//org.eclipse.jgit.ssh.jsch:ssh-jsch",
],
outs = ["all.zip"],
cmd = " && ".join([

View File

@ -111,26 +111,26 @@ maven_jar(
maven_jar(
name = "httpclient",
artifact = "org.apache.httpcomponents:httpclient:4.5.10",
sha1 = "7ca2e4276f4ef95e4db725a8cd4a1d1e7585b9e5",
artifact = "org.apache.httpcomponents:httpclient:4.5.13",
sha1 = "e5f6cae5ca7ecaac1ec2827a9e2d65ae2869cada",
)
maven_jar(
name = "httpcore",
artifact = "org.apache.httpcomponents:httpcore:4.4.12",
sha1 = "21ebaf6d532bc350ba95bd81938fa5f0e511c132",
artifact = "org.apache.httpcomponents:httpcore:4.4.14",
sha1 = "9dd1a631c082d92ecd4bd8fd4cf55026c720a8c1",
)
maven_jar(
name = "sshd-osgi",
artifact = "org.apache.sshd:sshd-osgi:2.4.0",
sha1 = "fc4551c1eeda35e4671b263297d37d2bca81c4d4",
artifact = "org.apache.sshd:sshd-osgi:2.6.0",
sha1 = "40e365bb799e1bff3d31dc858b1e59a93c123f29",
)
maven_jar(
name = "sshd-sftp",
artifact = "org.apache.sshd:sshd-sftp:2.4.0",
sha1 = "92e1b7d1e19c715efb4a8871d34145da8f87cdb2",
artifact = "org.apache.sshd:sshd-sftp:2.6.0",
sha1 = "6eddfe8fdf59a3d9a49151e4177f8c1bebeb30c9",
)
maven_jar(
@ -237,55 +237,55 @@ maven_jar(
sha1 = "9180733b7df8542621dc12e21e87557e8c99b8cb",
)
JETTY_VER = "9.4.35.v20201120"
JETTY_VER = "9.4.36.v20210114"
maven_jar(
name = "jetty-servlet",
artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
sha1 = "3e61bcb471e1bfc545ce866cbbe33c3aedeec9b1",
src_sha1 = "e237af9dd6556756736fcdc7da00194fa00d3c2b",
sha1 = "b189e52a5ee55ae172e4e99e29c5c314f5daf4b9",
src_sha1 = "3a0fa449772ab0d76625f6afb81f60c32a490613",
)
maven_jar(
name = "jetty-security",
artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
sha1 = "80dc2f422789c78315de76d289b7a5b36c3232d5",
src_sha1 = "3c0d03191fdffd9cf1e46fa206d79eeb9e3adb90",
sha1 = "42030d6ed7dfc0f75818cde0adcf738efc477574",
src_sha1 = "612220a97d45fad3983ccc56b0cb9a271f3fd003",
)
maven_jar(
name = "jetty-server",
artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
sha1 = "513502352fd689d4730b2935421b990ada8cc818",
src_sha1 = "760d3574ebc7f9b9b1ba51242b9c1dda6fe5505b",
sha1 = "88a7d342974aadca658e7386e8d0fcc5c0788f41",
src_sha1 = "4552c0c6db2948e8557db477b6b48d291006e481",
)
maven_jar(
name = "jetty-http",
artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
sha1 = "45d35131a35a1e76991682174421e8cdf765fb9f",
src_sha1 = "491cd5b8abe8fe6f3db0086907a3f12440188e73",
sha1 = "1eee89a55e04ff94df0f85d95200fc48acb43d86",
src_sha1 = "552a784ec789c7ba581c5341ae6d8b6353ed5ace",
)
maven_jar(
name = "jetty-io",
artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
sha1 = "eb9460700b99b71ecd82a53697f5ff99f69b9e1c",
src_sha1 = "fed96a4559a49e7173dbe2d9d8e100d72aee2a10",
sha1 = "84a8faf9031eb45a5a2ddb7681e22c483d81ab3a",
src_sha1 = "72d5fc6d909e28f8720394b25babda80805a46b9",
)
maven_jar(
name = "jetty-util",
artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
sha1 = "ef61b83f9715c3b5355b633d9f01d2834f908ece",
src_sha1 = "8f178bebeb34c8365a06d854daa9b22da1b301d7",
sha1 = "925257fbcca6b501a25252c7447dbedb021f7404",
src_sha1 = "532e8b66044f4e58ca5da3aec19f02a2f3c16ddd",
)
maven_jar(
name = "jetty-util-ajax",
artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER,
sha1 = "ebbb43912c6423bedb3458e44aee28eeb4d66f27",
src_sha1 = "b3acea974a17493afb125a9dfbe783870ce1d2f9",
sha1 = "2f478130c21787073facb64d7242e06f94980c60",
src_sha1 = "7153d7ca38878d971fd90992c303bb7719ba7a21",
)
BOUNCYCASTLE_VER = "1.65"

View File

@ -162,6 +162,7 @@ java_library(
"//org.eclipse.jgit:__pkg__",
"//org.eclipse.jgit.gpg.bc:__pkg__",
"//org.eclipse.jgit.test:__pkg__",
"//org.eclipse.jgit.gpg.bc.test:__pkg__",
],
exports = ["@bcpg//jar"],
)
@ -172,6 +173,7 @@ java_library(
"//org.eclipse.jgit:__pkg__",
"//org.eclipse.jgit.gpg.bc:__pkg__",
"//org.eclipse.jgit.test:__pkg__",
"//org.eclipse.jgit.gpg.bc.test:__pkg__",
],
exports = ["@bcprov//jar"],
)

View File

@ -2,10 +2,15 @@
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="tst">
<classpathentry kind="src" output="bin-tst" path="tst">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin"/>
<classpathentry kind="src" output="bin-tst" path="tst-rsrc">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="bin-tst"/>
</classpath>

View File

@ -1,2 +1,3 @@
/bin
/bin-tst
/target

View File

@ -1,3 +1,8 @@
load(
"@com_googlesource_gerrit_bazlets//tools:genrule2.bzl",
"genrule2",
)
load("@rules_java//java:defs.bzl", "java_import")
load(
"@com_googlesource_gerrit_bazlets//tools:junit.bzl",
"junit_tests",
@ -8,7 +13,23 @@ junit_tests(
srcs = glob(["tst/**/*.java"]),
tags = ["bc"],
deps = [
"//lib:bcpg",
"//lib:bcprov",
"//lib:junit",
"//org.eclipse.jgit:jgit",
"//org.eclipse.jgit.gpg.bc:gpg-bc",
"//org.eclipse.jgit.gpg.bc.test:tst_rsrc",
],
)
java_import(
name = "tst_rsrc",
jars = [":tst_rsrc_jar"],
)
genrule2(
name = "tst_rsrc_jar",
srcs = glob(["tst-rsrc/**"]),
outs = ["tst_rsrc.jar"],
cmd = "o=$$PWD/$@ && tar cf - $(SRCS) | tar -C $$TMP --strip-components=2 -xf - && cd $$TMP && zip -qr $$o .",
)

View File

@ -7,8 +7,18 @@ Bundle-Version: 5.11.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.eclipse.jgit.gpg.bc.internal;version="[5.11.0,5.12.0)",
org.junit;version="[4.13,5.0.0)"
Export-Package: org.eclipse.jgit.gpg.bc.internal;x-internal:=true
Import-Package: org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)",
org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)",
org.eclipse.jgit.gpg.bc.internal;version="[5.11.0,5.12.0)",
org.eclipse.jgit.gpg.bc.internal.keys;version="[5.11.0,5.12.0)",
org.eclipse.jgit.util.sha1;version="[5.11.0,5.12.0)",
org.junit;version="[4.13,5.0.0)",
org.junit.runner;version="[4.13,5.0.0)",
org.junit.runners;version="[4.13,5.0.0)"
Export-Package: org.eclipse.jgit.gpg.bc.internal;x-internal:=true,
org.eclipse.jgit.gpg.bc.internal.keys;x-internal:=true
Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)",
org.hamcrest.library;bundle-version="[1.1.0,2.0.0)"

View File

@ -1,5 +1,5 @@
source.. = tst/
output.. = bin/
output.. = bin-tst/
bin.includes = META-INF/,\
.,\
plugin.properties

View File

@ -85,6 +85,12 @@
<sourceDirectory>src/</sourceDirectory>
<testSourceDirectory>tst/</testSourceDirectory>
<testResources>
<testResource>
<directory>tst-rsrc/</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import static org.junit.Assert.assertEquals;
import java.math.BigInteger;
import java.util.Locale;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.util.sha1.SHA1;
import org.junit.Test;
public class KeyGrip25519Test {
interface Hash {
byte[] hash(SHA1 sha, BigInteger q) throws PGPException;
}
private void assertKeyGrip(String key, String expectedKeyGrip, Hash hash)
throws Exception {
SHA1 grip = SHA1.newInstance();
grip.setDetectCollision(false);
BigInteger pk = new BigInteger(key, 16);
byte[] keyGrip = hash.hash(grip, pk);
assertEquals("Keygrip should match", expectedKeyGrip,
Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT));
}
@Test
public void testCompressed() throws Exception {
assertKeyGrip("40"
+ "773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB",
"9DB6C64A38830F4960701789475520BE8C821F47",
KeyGrip::hashEd25519);
}
@Test
public void testCompressedNoPrefix() throws Exception {
assertKeyGrip(
"773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB",
"9DB6C64A38830F4960701789475520BE8C821F47",
KeyGrip::hashEd25519);
}
@Test
public void testCurve25519() throws Exception {
assertKeyGrip("40"
+ "918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740",
"0F89A565D3EA187CE839332398F5D480677DF49C",
KeyGrip::hashCurve25519);
}
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
import java.util.Iterator;
import java.util.Locale;
import java.util.function.Consumer;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.util.encoders.Hex;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class KeyGripTest {
@BeforeClass
public static void ensureBC() {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
protected static class TestData {
String filename;
String[] expectedKeyGrips;
TestData(String filename, String... keyGrips) {
this.filename = filename;
this.expectedKeyGrips = keyGrips;
}
@Override
public String toString() {
return filename;
}
}
@Parameters(name = "{0}")
public static TestData[] initTestData() {
return new TestData[] {
new TestData("rsa.asc",
"D148210FAF36468055B83D0F5A6DEB83FBC8E864",
"A5E4CD2CBBE44A16E4D6EC05C2E3C3A599DC763C"),
new TestData("dsa-elgamal.asc",
"552286BEB2999F0A9E26A50385B90D9724001187",
"CED7034A8EB5F4CE90DF99147EC33D86FCD3296C"),
new TestData("brainpool256.asc",
"A01BAA22A72F09A0FF0A1D4CBCE70844DD52DDD7",
"C1678B7DE5F144C93B89468D5F9764ACE182ED36"),
new TestData("brainpool384.asc",
"2F25DB025DEBF3EA2715350209B985829B04F50A",
"B6BD8B81F75AF914163D97DF8DE8F6FC64C283F8"),
new TestData("brainpool512.asc",
"5A484F56AB4B8B6583B6365034999F6543FAE1AE",
"9133E4A7E8FC8515518DF444C3F2F247EEBBADEC"),
new TestData("nistp256.asc",
"FC81AECE90BCE6E54D0D637D266109783AC8DAC0",
"A56DC8DB8355747A809037459B4258B8A743EAB5"),
new TestData("nistp384.asc",
"A1338230AED1C9C125663518470B49056C9D1733",
"797A83FE041FFE06A7F4B1D32C6F4AE0F6D87ADF"),
new TestData("nistp521.asc",
"D91B789603EC9138AA20342A2B6DC86C81B70F5D",
"FD048B2CA1919CB241DC8A2C7FA3E742EF343DCA"),
new TestData("secp256k1.asc",
"498B89C485489BA16B40755C0EBA580166393074",
"48FFED40D018747363BDEFFDD404D1F4870F8064"),
new TestData("ed25519.asc",
"940D97D75C306D737A59A98EAFF1272832CEDC0B"),
new TestData("x25519.asc",
"A77DC8173DA6BEE126F5BD6F5A14E01200B52FCE",
"636C983EDB558527BA82780B52CB5DAE011BE46B")
};
}
// Injected by JUnit
@Parameter
public TestData data;
private void readAsc(InputStream in, Consumer<PGPPublicKey> process)
throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator());
Iterator<PGPPublicKeyRing> keyRings = pgpPub.getKeyRings();
while (keyRings.hasNext()) {
PGPPublicKeyRing keyRing = keyRings.next();
Iterator<PGPPublicKey> keys = keyRing.getPublicKeys();
while (keys.hasNext()) {
process.accept(keys.next());
}
}
}
@Test
public void testGrip() throws Exception {
try (InputStream in = this.getClass()
.getResourceAsStream(data.filename)) {
int index[] = { 0 };
readAsc(in, key -> {
byte[] keyGrip = null;
try {
keyGrip = KeyGrip.getKeyGrip(key);
} catch (PGPException e) {
throw new RuntimeException(e);
}
assertTrue("More keys than expected",
index[0] < data.expectedKeyGrips.length);
assertEquals("Wrong keygrip", data.expectedKeyGrips[index[0]++],
Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT));
});
assertEquals("Missing keys", data.expectedKeyGrips.length,
index[0]);
}
}
}

View File

@ -0,0 +1,163 @@
/*
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
import java.util.Iterator;
import javax.crypto.Cipher;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class SecretKeysTest {
@BeforeClass
public static void ensureBC() {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
private static volatile Boolean haveOCB;
private static boolean ocbAvailable() {
Boolean haveIt = haveOCB;
if (haveIt != null) {
return haveIt.booleanValue();
}
try {
Cipher c = Cipher.getInstance("AES/OCB/NoPadding"); //$NON-NLS-1$
if (c == null) {
haveOCB = Boolean.FALSE;
return false;
}
} catch (NoClassDefFoundError | Exception e) {
haveOCB = Boolean.FALSE;
return false;
}
haveOCB = Boolean.TRUE;
return true;
}
private static class TestData {
final String name;
final boolean encrypted;
final boolean keyValue;
TestData(String name, boolean encrypted, boolean keyValue) {
this.name = name;
this.encrypted = encrypted;
this.keyValue = keyValue;
}
@Override
public String toString() {
return name;
}
}
@Parameters(name = "{0}")
public static TestData[] initTestData() {
return new TestData[] {
new TestData("AFDA8EA10E185ACF8C0D0F8885A0EF61A72ECB11", false, false),
new TestData("2FB05DBB70FC07CB84C13431F640CA6CEA1DBF8A", false, true),
new TestData("66CCECEC2AB46A9735B10FEC54EDF9FD0F77BAF9", true, true),
new TestData("F727FAB884DA3BD402B6E0F5472E108D21033124", true, true),
new TestData("faked", false, true) };
}
private static byte[] readTestKey(String filename) throws Exception {
try (InputStream in = new BufferedInputStream(
SecretKeysTest.class.getResourceAsStream(filename))) {
return SecretKeys.keyFromNameValueFormat(in);
}
}
private static PGPPublicKey readAsc(InputStream in)
throws IOException, PGPException {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
PGPUtil.getDecoderStream(in), new JcaKeyFingerprintCalculator());
Iterator<PGPPublicKeyRing> keyRings = pgpPub.getKeyRings();
while (keyRings.hasNext()) {
PGPPublicKeyRing keyRing = keyRings.next();
Iterator<PGPPublicKey> keys = keyRing.getPublicKeys();
if (keys.hasNext()) {
return keys.next();
}
}
return null;
}
// Injected by JUnit
@Parameter
public TestData data;
@Test
public void testKeyRead() throws Exception {
if (data.keyValue) {
byte[] bytes = readTestKey(data.name + ".key");
assertEquals('(', bytes[0]);
assertEquals(')', bytes[bytes.length - 1]);
}
try (InputStream pubIn = this.getClass()
.getResourceAsStream(data.name + ".asc")) {
if (pubIn != null) {
PGPPublicKey publicKey = readAsc(pubIn);
// Do a full test trying to load the secret key.
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
.build();
try (InputStream in = new BufferedInputStream(this.getClass()
.getResourceAsStream(data.name + ".key"))) {
PGPSecretKey secretKey = SecretKeys.readSecretKey(in,
calculatorProvider,
data.encrypted ? () -> "nonsense".toCharArray()
: null,
publicKey);
assertNotNull(secretKey);
} catch (PGPException e) {
// Currently we may not be able to load OCB-encrypted keys.
assertTrue(e.getMessage().contains("OCB"));
assertTrue(data.encrypted);
assertFalse(ocbAvailable());
}
}
}
}
}

View File

@ -8,22 +8,30 @@ Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-Version: 5.11.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.bouncycastle.bcpg;version="[1.65.0,2.0.0)",
Import-Package: org.bouncycastle.asn1;version="[1.65.0,2.0.0)",
org.bouncycastle.asn1.cryptlib;version="[1.65.0,2.0.0)",
org.bouncycastle.asn1.x9;version="[1.65.0,2.0.0)",
org.bouncycastle.bcpg;version="[1.65.0,2.0.0)",
org.bouncycastle.bcpg.sig;version="[1.65.0,2.0.0)",
org.bouncycastle.crypto.ec;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg.keybox;version="[1.65.0,2.0.0)",
org.bouncycastle.gpg.keybox.jcajce;version="[1.65.0,2.0.0)",
org.bouncycastle.jcajce.interfaces;version="[1.65.0,2.0.0)",
org.bouncycastle.jcajce.util;version="[1.65.0,2.0.0)",
org.bouncycastle.jce.provider;version="[1.65.0,2.0.0)",
org.bouncycastle.math.ec;version="[1.65.0,2.0.0)",
org.bouncycastle.math.field;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp.jcajce;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp.operator;version="[1.65.0,2.0.0)",
org.bouncycastle.openpgp.operator.jcajce;version="[1.65.0,2.0.0)",
org.bouncycastle.util;version="[1.65.0,2.0.0)",
org.bouncycastle.util.encoders;version="[1.65.0,2.0.0)",
org.bouncycastle.util.io;version="[1.65.0,2.0.0)",
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)",
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)",
org.eclipse.jgit.errors;version="[5.11.0,5.12.0)",
org.eclipse.jgit.lib;version="[5.11.0,5.12.0)",
org.eclipse.jgit.nls;version="[5.11.0,5.12.0)",
org.eclipse.jgit.transport;version="[5.11.0,5.12.0)",
org.eclipse.jgit.util;version="[5.11.0,5.12.0)",
org.slf4j;version="[1.7.0,2.0.0)"
Export-Package: org.eclipse.jgit.gpg.bc.internal;version="5.11.0";
x-friends:="org.eclipse.jgit.gpg.bc.test"
Export-Package: org.eclipse.jgit.gpg.bc;version="5.11.0",
org.eclipse.jgit.gpg.bc.internal;version="5.11.0";x-friends:="org.eclipse.jgit.gpg.bc.test",
org.eclipse.jgit.gpg.bc.internal.keys;version="5.11.0";x-friends:="org.eclipse.jgit.gpg.bc.test"

View File

@ -11,7 +11,7 @@
margin: 0.25in 0.5in 0.25in 0.5in;
tab-interval: 0.5in;
}
p {
p {
margin-left: auto;
margin-top: 0.5em;
margin-bottom: 0.5em;
@ -36,60 +36,53 @@
<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
<p>All rights reserved.</p>
<p>Redistribution and use in source and binary forms, with or without modification,
<p>Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
<ul><li>Redistributions of source code must retain the above copyright notice,
<ul><li>Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. </li>
<li>Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
<li>Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. </li>
<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission. </li></ul>
</p>
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.</p>
<hr>
<p><b>SHA-1 UbcCheck - MIT</b></p>
<p><b>org.eclipse.jgit.gpg.bc.internal.keys.SExprParser - MIT</b></p>
<p>Copyright (c) 2017:</p>
<div class="ubc-name">
Marc Stevens
Cryptology Group
Centrum Wiskunde & Informatica
P.O. Box 94079, 1090 GB Amsterdam, Netherlands
marc@marc-stevens.nl
</div>
<div class="ubc-name">
Dan Shumow
Microsoft Research
danshu@microsoft.com
</div>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
<p>Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc.
(<a href="https://www.bouncycastle.org">https://www.bouncycastle.org</a>)</p>
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
</p>
<p>
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
</p>
<p>
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</p>
<ul><li>The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.</li></ul>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</p>
</body>

View File

@ -0,0 +1 @@
org.eclipse.jgit.gpg.bc.internal.BouncyCastleGpgSignatureVerifierFactory

View File

@ -1,11 +1,36 @@
corrupt25519Key=Ed25519/Curve25519 public key has wrong length: {0}
credentialPassphrase=Passphrase
gpgFailedToParseSecretKey=Failed to parse secret key file in directory: {0}. Is the entered passphrase correct?
cryptCipherError=Cannot create cipher to decrypt: {0}
cryptWrongDecryptedLength=Decrypted key has wrong length; expected {0} bytes, got only {1} bytes
gpgFailedToParseSecretKey=Failed to parse secret key file {0}. Is the entered passphrase correct?
gpgNoCredentialsProvider=missing credentials provider
gpgNoKeygrip=Cannot find key {0}: cannot determine key grip
gpgNoKeyring=neither pubring.kbx nor secring.gpg files found
gpgNoKeyInLegacySecring=no matching secret key found in legacy secring.gpg for key or user id: {0}
gpgNoPublicKeyFound=Unable to find a public-key with key or user id: {0}
gpgNoSecretKeyForPublicKey=unable to find associated secret key for public key: {0}
gpgNoSuchAlgorithm=Cannot decrypt encrypted secret key: encryption algorithm {0} is not available
gpgNotASigningKey=Secret key ({0}) is not suitable for signing
gpgKeyInfo=GPG Key (fingerprint {0})
gpgSigningCancelled=Signing was cancelled
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
sexprHexOdd=Hex number in s-expression has an odd number of digits
sexprStringInvalidEscape=Invalid escape {0} in s-expression
sexprStringInvalidEscapeAtEnd=Invalid s-expression: quoted string ends with escape character
sexprStringInvalidHexEscape=Invalid hex escape in s-expression
sexprStringInvalidOctalEscape=Invalid octal escape in s-expression
sexprStringNotClosed=String in s-expression not closed
sexprUnhandled=Unhandled token {0} in s-expression
signatureInconsistent=Inconsistent signature; key ID {0} does not match issuer fingerprint {1}
signatureKeyLookupError=Error occurred while looking for public key
signatureNoKeyInfo=No way to determine a public key from the signature
signatureNoPublicKey=No public key found to verify the signature
signatureParseError=Signature cannot be parsed
signatureVerificationError=Signature verification failed
unableToSignCommitNoSecretKey=Unable to sign commit. Signing key not available.
uncompressed25519Key=Cannot handle ed25519 public key with uncompressed data: {0}
unknownCurve=Unknown curve {0}
unknownCurveParameters=Curve {0} does not have a prime field
unknownKeyType=Unknown key type {0}

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc;
import org.eclipse.jgit.gpg.bc.internal.BouncyCastleGpgSigner;
import org.eclipse.jgit.lib.GpgSigner;
/**
* Factory for creating a {@link GpgSigner} based on Bouncy Castle.
*
* @since 5.11
*/
public final class BouncyCastleGpgSignerFactory {
private BouncyCastleGpgSignerFactory() {
// No instantiation
}
/**
* Creates a new {@link GpgSigner}.
*
* @return the {@link GpgSigner}
*/
public static GpgSigner create() {
return new BouncyCastleGpgSigner();
}
}

View File

@ -1,3 +1,12 @@
/*
* Copyright (C) 2018, 2021 Salesforce and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal;
import org.eclipse.jgit.nls.NLS;
@ -18,16 +27,41 @@ public static BCText get() {
}
// @formatter:off
/***/ public String corrupt25519Key;
/***/ public String credentialPassphrase;
/***/ public String cryptCipherError;
/***/ public String cryptWrongDecryptedLength;
/***/ public String gpgFailedToParseSecretKey;
/***/ public String gpgNoCredentialsProvider;
/***/ public String gpgNoKeygrip;
/***/ public String gpgNoKeyring;
/***/ public String gpgNoKeyInLegacySecring;
/***/ public String gpgNoPublicKeyFound;
/***/ public String gpgNoSecretKeyForPublicKey;
/***/ public String gpgNoSuchAlgorithm;
/***/ public String gpgNotASigningKey;
/***/ public String gpgKeyInfo;
/***/ public String gpgSigningCancelled;
/***/ public String nonSignatureError;
/***/ public String secretKeyTooShort;
/***/ public String sexprHexNotClosed;
/***/ public String sexprHexOdd;
/***/ public String sexprStringInvalidEscape;
/***/ public String sexprStringInvalidEscapeAtEnd;
/***/ public String sexprStringInvalidHexEscape;
/***/ public String sexprStringInvalidOctalEscape;
/***/ public String sexprStringNotClosed;
/***/ public String sexprUnhandled;
/***/ public String signatureInconsistent;
/***/ public String signatureKeyLookupError;
/***/ public String signatureNoKeyInfo;
/***/ public String signatureNoPublicKey;
/***/ public String signatureParseError;
/***/ public String signatureVerificationError;
/***/ public String unableToSignCommitNoSecretKey;
/***/ public String uncompressed25519Key;
/***/ public String unknownCurve;
/***/ public String unknownCurveParameters;
/***/ public String unknownKeyType;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, 2020 Salesforce and others
* Copyright (C) 2018, 2021 Salesforce and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@ -14,25 +14,22 @@
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.InvalidPathException;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.bouncycastle.gpg.SExprParser;
import org.bouncycastle.gpg.keybox.BlobType;
import org.bouncycastle.gpg.keybox.KeyBlob;
import org.bouncycastle.gpg.keybox.KeyBox;
@ -50,15 +47,15 @@
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcaKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory;
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.gpg.bc.internal.keys.KeyGrip;
import org.eclipse.jgit.gpg.bc.internal.keys.SecretKeys;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
@ -78,17 +75,10 @@ private static class NoOpenPgpKeyException extends Exception {
}
/** Thrown if we try to read an encrypted private key without password. */
private static class EncryptedPgpKeyException extends RuntimeException {
private static final long serialVersionUID = 1L;
}
private static final Logger log = LoggerFactory
.getLogger(BouncyCastleGpgKeyLocator.class);
private static final Path GPG_DIRECTORY = findGpgDirectory();
static final Path GPG_DIRECTORY = findGpgDirectory();
private static final Path USER_KEYBOX_PATH = GPG_DIRECTORY
.resolve("pubring.kbx"); //$NON-NLS-1$
@ -155,16 +145,13 @@ public BouncyCastleGpgKeyLocator(String signingKey,
private PGPSecretKey attemptParseSecretKey(Path keyFile,
PGPDigestCalculatorProvider calculatorProvider,
PBEProtectionRemoverFactory passphraseProvider,
PGPPublicKey publicKey) {
SecretKeys.PassphraseSupplier passphraseSupplier,
PGPPublicKey publicKey)
throws IOException, PGPException, CanceledException,
UnsupportedCredentialItem, URISyntaxException {
try (InputStream in = newInputStream(keyFile)) {
return new SExprParser(calculatorProvider).parseSecretKey(
new BufferedInputStream(in), passphraseProvider, publicKey);
} catch (IOException | PGPException | ClassCastException e) {
if (log.isDebugEnabled())
log.debug("Ignoring unreadable file '{}': {}", keyFile, //$NON-NLS-1$
e.getMessage(), e);
return null;
return SecretKeys.readSecretKey(in, calculatorProvider,
passphraseSupplier, publicKey);
}
}
@ -247,16 +234,32 @@ private static boolean containsIgnoreCase(String a, String b) {
return false;
}
private String toFingerprint(String keyId) {
private static String toFingerprint(String keyId) {
if (keyId.startsWith("0x")) { //$NON-NLS-1$
return keyId.substring(2);
}
return keyId;
}
private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob)
static PGPPublicKey findPublicKey(String fingerprint, String keySpec)
throws IOException, PGPException {
PGPPublicKey result = findPublicKeyInPubring(USER_PGP_PUBRING_FILE,
fingerprint, keySpec);
if (result == null && exists(USER_KEYBOX_PATH)) {
try {
result = findPublicKeyInKeyBox(USER_KEYBOX_PATH, fingerprint,
keySpec);
} catch (NoSuchAlgorithmException | NoSuchProviderException
| IOException | NoOpenPgpKeyException e) {
log.error(e.getMessage(), e);
}
}
return result;
}
private static PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob,
String keyId)
throws IOException {
String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT);
if (keyId.isEmpty()) {
return null;
}
@ -270,10 +273,11 @@ private PGPPublicKey findPublicKeyByKeyId(KeyBlob keyBlob)
return null;
}
private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob)
private static PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob,
String keySpec)
throws IOException {
for (UserID userID : keyBlob.getUserIds()) {
if (containsSigningKey(userID.getUserIDAsString(), signingKey)) {
if (containsSigningKey(userID.getUserIDAsString(), keySpec)) {
return getSigningPublicKey(keyBlob);
}
}
@ -285,6 +289,10 @@ private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob)
*
* @param keyboxFile
* the KeyBox file
* @param keyId
* to look for, may be null
* @param keySpec
* to look for
* @return publicKey the public key (maybe <code>null</code>)
* @throws IOException
* in case of problems reading the file
@ -293,19 +301,22 @@ private PGPPublicKey findPublicKeyByUserId(KeyBlob keyBlob)
* @throws NoOpenPgpKeyException
* if the file does not contain any OpenPGP key
*/
private PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile)
private static PGPPublicKey findPublicKeyInKeyBox(Path keyboxFile,
String keyId, String keySpec)
throws IOException, NoSuchAlgorithmException,
NoSuchProviderException, NoOpenPgpKeyException {
KeyBox keyBox = readKeyBoxFile(keyboxFile);
String id = keyId != null ? keyId
: toFingerprint(keySpec).toLowerCase(Locale.ROOT);
boolean hasOpenPgpKey = false;
for (KeyBlob keyBlob : keyBox.getKeyBlobs()) {
if (keyBlob.getType() == BlobType.OPEN_PGP_BLOB) {
hasOpenPgpKey = true;
PGPPublicKey key = findPublicKeyByKeyId(keyBlob);
PGPPublicKey key = findPublicKeyByKeyId(keyBlob, id);
if (key != null) {
return key;
}
key = findPublicKeyByUserId(keyBlob);
key = findPublicKeyByUserId(keyBlob, keySpec);
if (key != null) {
return key;
}
@ -349,7 +360,8 @@ public BouncyCastleGpgKey findSecretKey() throws IOException,
// pubring.gpg also try secring.gpg to find the secret key.
if (exists(USER_KEYBOX_PATH)) {
try {
publicKey = findPublicKeyInKeyBox(USER_KEYBOX_PATH);
publicKey = findPublicKeyInKeyBox(USER_KEYBOX_PATH, null,
signingKey);
if (publicKey != null) {
key = findSecretKeyForKeyBoxPublicKey(publicKey,
USER_KEYBOX_PATH);
@ -372,7 +384,8 @@ public BouncyCastleGpgKey findSecretKey() throws IOException,
}
}
if (exists(USER_PGP_PUBRING_FILE)) {
publicKey = findPublicKeyInPubring(USER_PGP_PUBRING_FILE);
publicKey = findPublicKeyInPubring(USER_PGP_PUBRING_FILE, null,
signingKey);
if (publicKey != null) {
// GPG < 2.1 may have both; the agent using the directory
// and gpg using secring.gpg. GPG >= 2.1 delegates all
@ -444,67 +457,59 @@ private BouncyCastleGpgKey findSecretKeyForKeyBoxPublicKey(
PGPPublicKey publicKey, Path userKeyboxPath)
throws PGPException, CanceledException, UnsupportedCredentialItem,
URISyntaxException {
/*
* this is somewhat brute-force but there doesn't seem to be another
* way; we have to walk all private key files we find and try to open
* them
*/
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
.build();
try (Stream<Path> keyFiles = Files.walk(USER_SECRET_KEY_DIR)) {
List<Path> allPaths = keyFiles.filter(Files::isRegularFile)
.collect(Collectors.toCollection(ArrayList::new));
if (allPaths.isEmpty()) {
return null;
byte[] keyGrip = null;
try {
keyGrip = KeyGrip.getKeyGrip(publicKey);
} catch (PGPException e) {
throw new PGPException(
MessageFormat.format(BCText.get().gpgNoKeygrip,
Hex.toHexString(publicKey.getFingerprint())),
e);
}
String filename = Hex.toHexString(keyGrip).toUpperCase(Locale.ROOT)
+ ".key"; //$NON-NLS-1$
Path keyFile = USER_SECRET_KEY_DIR.resolve(filename);
if (!Files.exists(keyFile)) {
return null;
}
boolean clearPrompt = false;
try {
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
.build();
clearPrompt = true;
PGPSecretKey secretKey = null;
try {
secretKey = attemptParseSecretKey(keyFile, calculatorProvider,
() -> passphrasePrompt.getPassphrase(
publicKey.getFingerprint(), userKeyboxPath),
publicKey);
} catch (PGPException e) {
throw new PGPException(MessageFormat.format(
BCText.get().gpgFailedToParseSecretKey,
keyFile.toAbsolutePath()), e);
}
PBEProtectionRemoverFactory passphraseProvider = p -> {
throw new EncryptedPgpKeyException();
};
for (int attempts = 0; attempts < 2; attempts++) {
// Second pass will traverse only the encrypted keys with a real
// passphrase provider.
Iterator<Path> pathIterator = allPaths.iterator();
while (pathIterator.hasNext()) {
Path keyFile = pathIterator.next();
try {
PGPSecretKey secretKey = attemptParseSecretKey(keyFile,
calculatorProvider, passphraseProvider,
publicKey);
pathIterator.remove();
if (secretKey != null) {
if (!secretKey.isSigningKey()) {
throw new PGPException(MessageFormat.format(
BCText.get().gpgNotASigningKey,
signingKey));
}
return new BouncyCastleGpgKey(secretKey,
userKeyboxPath);
}
} catch (EncryptedPgpKeyException e) {
// Ignore; we'll try again.
}
if (secretKey != null) {
if (!secretKey.isSigningKey()) {
throw new PGPException(MessageFormat.format(
BCText.get().gpgNotASigningKey, signingKey));
}
if (attempts > 0 || allPaths.isEmpty()) {
break;
}
// allPaths contains only the encrypted keys now.
passphraseProvider = new JcePBEProtectionRemoverFactory(
passphrasePrompt.getPassphrase(
publicKey.getFingerprint(), userKeyboxPath));
clearPrompt = false;
return new BouncyCastleGpgKey(secretKey, userKeyboxPath);
}
passphrasePrompt.clear();
return null;
} catch (RuntimeException e) {
passphrasePrompt.clear();
throw e;
} catch (FileNotFoundException | NoSuchFileException e) {
clearPrompt = false;
return null;
} catch (IOException e) {
passphrasePrompt.clear();
throw new PGPException(MessageFormat.format(
BCText.get().gpgFailedToParseSecretKey,
USER_SECRET_KEY_DIR.toAbsolutePath()), e);
keyFile.toAbsolutePath()), e);
} finally {
if (clearPrompt) {
passphrasePrompt.clear();
}
}
}
@ -562,6 +567,11 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
* Return the first public key matching the key id ({@link #signingKey}.
*
* @param pubringFile
* to search
* @param keyId
* to look for, may be null
* @param keySpec
* to look for
*
* @return the PGP public key, or {@code null} if none found
* @throws IOException
@ -569,14 +579,16 @@ private PGPSecretKey findSecretKeyInLegacySecring(String signingkey,
* @throws PGPException
* on BouncyCastle errors
*/
private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
private static PGPPublicKey findPublicKeyInPubring(Path pubringFile,
String keyId, String keySpec)
throws IOException, PGPException {
try (InputStream in = newInputStream(pubringFile)) {
PGPPublicKeyRingCollection pgpPub = new PGPPublicKeyRingCollection(
new BufferedInputStream(in),
new JcaKeyFingerprintCalculator());
String keyId = toFingerprint(signingKey).toLowerCase(Locale.ROOT);
String id = keyId != null ? keyId
: toFingerprint(keySpec).toLowerCase(Locale.ROOT);
Iterator<PGPPublicKeyRing> keyrings = pgpPub.getKeyRings();
while (keyrings.hasNext()) {
PGPPublicKeyRing keyRing = keyrings.next();
@ -586,30 +598,33 @@ private PGPPublicKey findPublicKeyInPubring(Path pubringFile)
// try key id
String fingerprint = Hex.toHexString(key.getFingerprint())
.toLowerCase(Locale.ROOT);
if (fingerprint.endsWith(keyId)) {
if (fingerprint.endsWith(id)) {
return key;
}
// try user id
Iterator<String> userIDs = key.getUserIDs();
while (userIDs.hasNext()) {
String userId = userIDs.next();
if (containsSigningKey(userId, signingKey)) {
if (containsSigningKey(userId, keySpec)) {
return key;
}
}
}
}
} catch (FileNotFoundException | NoSuchFileException e) {
// Ignore and return null
}
return null;
}
private PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint)
private static PGPPublicKey getPublicKey(KeyBlob blob, byte[] fingerprint)
throws IOException {
return ((PublicKeyRingBlob) blob).getPGPPublicKeyRing()
.getPublicKey(fingerprint);
}
private PGPPublicKey getSigningPublicKey(KeyBlob blob) throws IOException {
private static PGPPublicKey getSigningPublicKey(KeyBlob blob)
throws IOException {
PGPPublicKey masterKey = null;
Iterator<PGPPublicKey> keys = ((PublicKeyRingBlob) blob)
.getPGPPublicKeyRing().getPublicKeys();
@ -629,7 +644,7 @@ private PGPPublicKey getSigningPublicKey(KeyBlob blob) throws IOException {
return masterKey;
}
private boolean isSigningKey(PGPPublicKey key) {
private static boolean isSigningKey(PGPPublicKey key) {
Iterator signatures = key.getSignatures();
while (signatures.hasNext()) {
PGPSignature sig = (PGPSignature) signatures.next();
@ -641,7 +656,7 @@ private boolean isSigningKey(PGPPublicKey key) {
return false;
}
private KeyBox readKeyBoxFile(Path keyboxFile) throws IOException,
private static KeyBox readKeyBoxFile(Path keyboxFile) throws IOException,
NoSuchAlgorithmException, NoSuchProviderException,
NoOpenPgpKeyException {
if (keyboxFile.toFile().length() == 0) {

View File

@ -17,8 +17,8 @@
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.transport.CredentialItem.CharArrayType;
import org.eclipse.jgit.transport.CredentialItem.InformationalMessage;
import org.eclipse.jgit.transport.CredentialItem.Password;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;
@ -31,7 +31,7 @@
*/
class BouncyCastleGpgKeyPassphrasePrompt implements AutoCloseable {
private CharArrayType passphrase;
private Password passphrase;
private CredentialsProvider credentialsProvider;
@ -78,8 +78,7 @@ public char[] getPassphrase(byte[] keyFingerprint, Path keyLocation)
throws PGPException, CanceledException, UnsupportedCredentialItem,
URISyntaxException {
if (passphrase == null) {
passphrase = new CharArrayType(BCText.get().credentialPassphrase,
true);
passphrase = new Password(BCText.get().credentialPassphrase);
}
if (credentialsProvider == null) {

View File

@ -0,0 +1,388 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.Locale;
import org.bouncycastle.bcpg.sig.IssuerFingerprint;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openpgp.PGPCompressedData;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureList;
import org.bouncycastle.openpgp.PGPSignatureSubpacketVector;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.jcajce.JcaPGPObjectFactory;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentVerifierBuilderProvider;
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.lib.GpgConfig;
import org.eclipse.jgit.lib.GpgSignatureVerifier;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.util.LRUMap;
import org.eclipse.jgit.util.RawParseUtils;
import org.eclipse.jgit.util.StringUtils;
/**
* A {@link GpgSignatureVerifier} to verify GPG signatures using BouncyCastle.
*/
public class BouncyCastleGpgSignatureVerifier implements GpgSignatureVerifier {
private static void registerBouncyCastleProviderIfNecessary() {
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
Security.addProvider(new BouncyCastleProvider());
}
}
/**
* Creates a new instance and registers the BouncyCastle security provider
* if needed.
*/
public BouncyCastleGpgSignatureVerifier() {
registerBouncyCastleProviderIfNecessary();
}
// To support more efficient signature verification of multiple objects we
// cache public keys once found in a LRU cache.
private static final Object NO_KEY = new Object();
private LRUMap<String, Object> byFingerprint = new LRUMap<>(16, 200);
private LRUMap<String, Object> bySigner = new LRUMap<>(16, 200);
@Override
public String getName() {
return "bc"; //$NON-NLS-1$
}
@Override
@Nullable
public SignatureVerification verifySignature(@NonNull RevObject object,
@NonNull GpgConfig config) throws IOException {
if (object instanceof RevCommit) {
RevCommit commit = (RevCommit) object;
byte[] signatureData = commit.getRawGpgSignature();
if (signatureData == null) {
return null;
}
byte[] raw = commit.getRawBuffer();
// Now remove the GPG signature
byte[] header = { 'g', 'p', 'g', 's', 'i', 'g' };
int start = RawParseUtils.headerStart(header, raw, 0);
if (start < 0) {
return null;
}
int end = RawParseUtils.headerEnd(raw, start);
// start is at the beginning of the header's content
start -= header.length + 1;
// end is on the terminating LF; we need to skip that, too
if (end < raw.length) {
end++;
}
byte[] data = new byte[raw.length - (end - start)];
System.arraycopy(raw, 0, data, 0, start);
System.arraycopy(raw, end, data, start, raw.length - end);
return verify(data, signatureData);
} else if (object instanceof RevTag) {
RevTag tag = (RevTag) object;
byte[] signatureData = tag.getRawGpgSignature();
if (signatureData == null) {
return null;
}
byte[] raw = tag.getRawBuffer();
// The signature is just tacked onto the end of the message, which
// is last in the buffer.
byte[] data = Arrays.copyOfRange(raw, 0,
raw.length - signatureData.length);
return verify(data, signatureData);
}
return null;
}
static PGPSignature parseSignature(InputStream in)
throws IOException, PGPException {
try (InputStream sigIn = PGPUtil.getDecoderStream(in)) {
JcaPGPObjectFactory pgpFactory = new JcaPGPObjectFactory(sigIn);
Object obj = pgpFactory.nextObject();
if (obj instanceof PGPCompressedData) {
obj = new JcaPGPObjectFactory(
((PGPCompressedData) obj).getDataStream()).nextObject();
}
if (obj instanceof PGPSignatureList) {
return ((PGPSignatureList) obj).get(0);
}
return null;
}
}
@Override
public SignatureVerification verify(byte[] data, byte[] signatureData)
throws IOException {
PGPSignature signature = null;
String fingerprint = null;
String signer = null;
String keyId = null;
try (InputStream sigIn = new ByteArrayInputStream(signatureData)) {
signature = parseSignature(sigIn);
if (signature != null) {
// Try to figure out something to find the public key with.
if (signature.hasSubpackets()) {
PGPSignatureSubpacketVector packets = signature
.getHashedSubPackets();
IssuerFingerprint fingerprintPacket = packets
.getIssuerFingerprint();
if (fingerprintPacket != null) {
fingerprint = Hex
.toHexString(fingerprintPacket.getFingerprint())
.toLowerCase(Locale.ROOT);
}
signer = packets.getSignerUserID();
if (signer != null) {
signer = BouncyCastleGpgSigner.extractSignerId(signer);
}
}
keyId = Long.toUnsignedString(signature.getKeyID(), 16)
.toLowerCase(Locale.ROOT);
} else {
throw new JGitInternalException(BCText.get().nonSignatureError);
}
} catch (PGPException e) {
throw new JGitInternalException(BCText.get().signatureParseError,
e);
}
Date signatureCreatedAt = signature.getCreationTime();
if (fingerprint == null && signer == null && keyId == null) {
return new VerificationResult(signatureCreatedAt, null, null, null,
false, false, TrustLevel.UNKNOWN,
BCText.get().signatureNoKeyInfo);
}
if (fingerprint != null && keyId != null
&& !fingerprint.endsWith(keyId)) {
return new VerificationResult(signatureCreatedAt, signer, fingerprint,
null, false, false, TrustLevel.UNKNOWN,
MessageFormat.format(BCText.get().signatureInconsistent,
keyId, fingerprint));
}
if (fingerprint == null && keyId != null) {
fingerprint = keyId;
}
// Try to find the public key
String keySpec = '<' + signer + '>';
Object cached = null;
PGPPublicKey publicKey = null;
try {
cached = byFingerprint.get(fingerprint);
if (cached != null) {
if (cached instanceof PGPPublicKey) {
publicKey = (PGPPublicKey) cached;
}
} else if (!StringUtils.isEmptyOrNull(signer)) {
cached = bySigner.get(signer);
if (cached != null) {
if (cached instanceof PGPPublicKey) {
publicKey = (PGPPublicKey) cached;
}
}
}
if (cached == null) {
publicKey = BouncyCastleGpgKeyLocator.findPublicKey(fingerprint,
keySpec);
}
} catch (IOException | PGPException e) {
throw new JGitInternalException(
BCText.get().signatureKeyLookupError, e);
}
if (publicKey == null) {
if (cached == null) {
byFingerprint.put(fingerprint, NO_KEY);
byFingerprint.put(keyId, NO_KEY);
if (signer != null) {
bySigner.put(signer, NO_KEY);
}
}
return new VerificationResult(signatureCreatedAt, signer,
fingerprint, null, false, false, TrustLevel.UNKNOWN,
BCText.get().signatureNoPublicKey);
}
if (cached == null) {
byFingerprint.put(fingerprint, publicKey);
byFingerprint.put(keyId, publicKey);
if (signer != null) {
bySigner.put(signer, publicKey);
}
}
String user = null;
Iterator<String> userIds = publicKey.getUserIDs();
if (!StringUtils.isEmptyOrNull(signer)) {
while (userIds.hasNext()) {
String userId = userIds.next();
if (BouncyCastleGpgKeyLocator.containsSigningKey(userId,
keySpec)) {
user = userId;
break;
}
}
}
if (user == null) {
userIds = publicKey.getUserIDs();
if (userIds.hasNext()) {
user = userIds.next();
}
}
boolean expired = false;
long validFor = publicKey.getValidSeconds();
if (validFor > 0 && signatureCreatedAt != null) {
Instant expiredAt = publicKey.getCreationTime().toInstant()
.plusSeconds(validFor);
expired = expiredAt.isBefore(signatureCreatedAt.toInstant());
}
// Trust data is not defined in OpenPGP; the format is implementation
// specific. We don't use the GPG trustdb but simply the trust packet
// on the public key, if present. Even if present, it may or may not
// be set.
byte[] trustData = publicKey.getTrustData();
TrustLevel trust = parseGpgTrustPacket(trustData);
boolean verified = false;
try {
signature.init(
new JcaPGPContentVerifierBuilderProvider()
.setProvider(BouncyCastleProvider.PROVIDER_NAME),
publicKey);
signature.update(data);
verified = signature.verify();
} catch (PGPException e) {
throw new JGitInternalException(
BCText.get().signatureVerificationError, e);
}
return new VerificationResult(signatureCreatedAt, signer, fingerprint, user,
verified, expired, trust, null);
}
private TrustLevel parseGpgTrustPacket(byte[] packet) {
if (packet == null || packet.length < 6) {
// A GPG trust packet has at least 6 bytes.
return TrustLevel.UNKNOWN;
}
if (packet[2] != 'g' || packet[3] != 'p' || packet[4] != 'g') {
// Not a GPG trust packet
return TrustLevel.UNKNOWN;
}
int trust = packet[0] & 0x0F;
switch (trust) {
case 0: // No determined/set
case 1: // Trust expired; i.e., calculation outdated or key expired
case 2: // Undefined: not enough information to set
return TrustLevel.UNKNOWN;
case 3:
return TrustLevel.NEVER;
case 4:
return TrustLevel.MARGINAL;
case 5:
return TrustLevel.FULL;
case 6:
return TrustLevel.ULTIMATE;
default:
return TrustLevel.UNKNOWN;
}
}
@Override
public void clear() {
byFingerprint.clear();
bySigner.clear();
}
private static class VerificationResult implements SignatureVerification {
private final Date creationDate;
private final String signer;
private final String keyUser;
private final String fingerprint;
private final boolean verified;
private final boolean expired;
private final @NonNull TrustLevel trustLevel;
private final String message;
public VerificationResult(Date creationDate, String signer,
String fingerprint, String user, boolean verified,
boolean expired, @NonNull TrustLevel trust, String message) {
this.creationDate = creationDate;
this.signer = signer;
this.fingerprint = fingerprint;
this.keyUser = user;
this.verified = verified;
this.expired = expired;
this.trustLevel = trust;
this.message = message;
}
@Override
public Date getCreationDate() {
return creationDate;
}
@Override
public String getSigner() {
return signer;
}
@Override
public String getKeyUser() {
return keyUser;
}
@Override
public String getKeyFingerprint() {
return fingerprint;
}
@Override
public boolean isExpired() {
return expired;
}
@Override
public TrustLevel getTrustLevel() {
return trustLevel;
}
@Override
public String getMessage() {
return message;
}
@Override
public boolean getVerified() {
return verified;
}
}
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal;
import org.eclipse.jgit.lib.GpgSignatureVerifier;
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory;
/**
* A {@link GpgSignatureVerifierFactory} that creates
* {@link GpgSignatureVerifier} instances that verify GPG signatures using
* BouncyCastle and that do cache public keys.
*/
public final class BouncyCastleGpgSignatureVerifierFactory
extends GpgSignatureVerifierFactory {
@Override
public GpgSignatureVerifier getVerifier() {
return new BouncyCastleGpgSignatureVerifier();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, 2020, Salesforce and others
* Copyright (C) 2018, 2021, Salesforce and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@ -34,18 +34,22 @@
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.UnsupportedSigningFormatException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.GpgConfig;
import org.eclipse.jgit.lib.GpgObjectSigner;
import org.eclipse.jgit.lib.GpgSignature;
import org.eclipse.jgit.lib.GpgSigner;
import org.eclipse.jgit.lib.GpgObjectSigner;
import org.eclipse.jgit.lib.ObjectBuilder;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.GpgConfig.GpgFormat;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.util.StringUtils;
/**
* GPG Signer using BouncyCastle library
* GPG Signer using the BouncyCastle library.
*/
public class BouncyCastleGpgSigner extends GpgSigner
implements GpgObjectSigner {
@ -70,13 +74,32 @@ public BouncyCastleGpgSigner() {
public boolean canLocateSigningKey(@Nullable String gpgSigningKey,
PersonIdent committer, CredentialsProvider credentialsProvider)
throws CanceledException {
try {
return canLocateSigningKey(gpgSigningKey, committer,
credentialsProvider, null);
} catch (UnsupportedSigningFormatException e) {
// Cannot occur with a null config
return false;
}
}
@Override
public boolean canLocateSigningKey(@Nullable String gpgSigningKey,
PersonIdent committer, CredentialsProvider credentialsProvider,
GpgConfig config)
throws CanceledException, UnsupportedSigningFormatException {
if (config != null && config.getKeyFormat() != GpgFormat.OPENPGP) {
throw new UnsupportedSigningFormatException(
JGitText.get().onlyOpenPgpSupportedForSigning);
}
try (BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt = new BouncyCastleGpgKeyPassphrasePrompt(
credentialsProvider)) {
BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey,
committer, passphrasePrompt);
return gpgKey != null;
} catch (PGPException | IOException | NoSuchAlgorithmException
| NoSuchProviderException | URISyntaxException e) {
} catch (CanceledException e) {
throw e;
} catch (Exception e) {
return false;
}
}
@ -101,17 +124,28 @@ private BouncyCastleGpgKey locateSigningKey(@Nullable String gpgSigningKey,
public void sign(@NonNull CommitBuilder commit,
@Nullable String gpgSigningKey, @NonNull PersonIdent committer,
CredentialsProvider credentialsProvider) throws CanceledException {
signObject(commit, gpgSigningKey, committer, credentialsProvider);
try {
signObject(commit, gpgSigningKey, committer, credentialsProvider,
null);
} catch (UnsupportedSigningFormatException e) {
// Cannot occur with a null config
}
}
@Override
public void signObject(@NonNull ObjectBuilder object,
@Nullable String gpgSigningKey, @NonNull PersonIdent committer,
CredentialsProvider credentialsProvider) throws CanceledException {
CredentialsProvider credentialsProvider, GpgConfig config)
throws CanceledException, UnsupportedSigningFormatException {
if (config != null && config.getKeyFormat() != GpgFormat.OPENPGP) {
throw new UnsupportedSigningFormatException(
JGitText.get().onlyOpenPgpSupportedForSigning);
}
try (BouncyCastleGpgKeyPassphrasePrompt passphrasePrompt = new BouncyCastleGpgKeyPassphrasePrompt(
credentialsProvider)) {
BouncyCastleGpgKey gpgKey = locateSigningKey(gpgSigningKey,
committer, passphrasePrompt);
committer,
passphrasePrompt);
PGPSecretKey secretKey = gpgKey.getSecretKey();
if (secretKey == null) {
throw new JGitInternalException(
@ -178,7 +212,7 @@ public void signObject(@NonNull ObjectBuilder object,
}
}
private String extractSignerId(String pgpUserId) {
static String extractSignerId(String pgpUserId) {
int from = pgpUserId.indexOf('<');
if (from >= 0) {
int to = pgpUserId.indexOf('>', from + 1);

View File

@ -0,0 +1,322 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Arrays;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.cryptlib.CryptlibObjectIdentifiers;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.bcpg.DSAPublicBCPGKey;
import org.bouncycastle.bcpg.ECPublicBCPGKey;
import org.bouncycastle.bcpg.ElGamalPublicBCPGKey;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.math.ec.ECAlgorithms;
import org.bouncycastle.math.field.FiniteField;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.util.encoders.Hex;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.gpg.bc.internal.BCText;
import org.eclipse.jgit.util.sha1.SHA1;
/**
* Utilities to compute the <em>keygrip</em> of a key. A keygrip is a SHA1 hash
* over the public key parameters and is used internally by the gpg-agent to
* find the secret key belonging to a public key: the secret key is stored in a
* file under ~/.gnupg/private-keys-v1.d/ with a name "&lt;keygrip>.key". While
* this storage organization is an implementation detail of GPG, the way
* keygrips are computed is not; they are computed by libgcrypt and their
* definition is stable.
*/
public final class KeyGrip {
// Some OIDs apparently unknown to BouncyCastle.
private static String OID_OPENPGP_ED25519 = "1.3.6.1.4.1.11591.15.1"; //$NON-NLS-1$
private static String OID_RFC8410_CURVE25519 = "1.3.101.110"; //$NON-NLS-1$
private static String OID_RFC8410_ED25519 = "1.3.101.112"; //$NON-NLS-1$
private KeyGrip() {
// No instantiation
}
/**
* Computes the keygrip for a {@link PGPPublicKey}.
*
* @param publicKey
* to get the keygrip of
* @return the keygrip
* @throws PGPException
* if an unknown key type is encountered.
*/
@NonNull
public static byte[] getKeyGrip(PGPPublicKey publicKey)
throws PGPException {
SHA1 grip = SHA1.newInstance();
grip.setDetectCollision(false);
switch (publicKey.getAlgorithm()) {
case PublicKeyAlgorithmTags.RSA_GENERAL:
case PublicKeyAlgorithmTags.RSA_ENCRYPT:
case PublicKeyAlgorithmTags.RSA_SIGN:
BigInteger modulus = ((RSAPublicBCPGKey) publicKey
.getPublicKeyPacket().getKey()).getModulus();
hash(grip, modulus.toByteArray());
break;
case PublicKeyAlgorithmTags.DSA:
DSAPublicBCPGKey dsa = (DSAPublicBCPGKey) publicKey
.getPublicKeyPacket().getKey();
hash(grip, dsa.getP().toByteArray(), 'p', true);
hash(grip, dsa.getQ().toByteArray(), 'q', true);
hash(grip, dsa.getG().toByteArray(), 'g', true);
hash(grip, dsa.getY().toByteArray(), 'y', true);
break;
case PublicKeyAlgorithmTags.ELGAMAL_GENERAL:
case PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT:
ElGamalPublicBCPGKey eg = (ElGamalPublicBCPGKey) publicKey
.getPublicKeyPacket().getKey();
hash(grip, eg.getP().toByteArray(), 'p', true);
hash(grip, eg.getG().toByteArray(), 'g', true);
hash(grip, eg.getY().toByteArray(), 'y', true);
break;
case PublicKeyAlgorithmTags.ECDH:
case PublicKeyAlgorithmTags.ECDSA:
case PublicKeyAlgorithmTags.EDDSA:
ECPublicBCPGKey ec = (ECPublicBCPGKey) publicKey
.getPublicKeyPacket().getKey();
ASN1ObjectIdentifier curveOID = ec.getCurveOID();
// BC doesn't know these OIDs.
if (OID_OPENPGP_ED25519.equals(curveOID.getId())
|| OID_RFC8410_ED25519.equals(curveOID.getId())) {
return hashEd25519(grip, ec.getEncodedPoint());
} else if (CryptlibObjectIdentifiers.curvey25519.equals(curveOID)
|| OID_RFC8410_CURVE25519.equals(curveOID.getId())) {
// curvey25519 actually is the OpenPGP OID for Curve25519 and is
// known to BC, but the parameters are for the short Weierstrass
// form. See https://github.com/bcgit/bc-java/issues/399 .
// libgcrypt uses Montgomery form.
return hashCurve25519(grip, ec.getEncodedPoint());
}
X9ECParameters params = getX9Parameters(curveOID);
if (params == null) {
throw new PGPException(MessageFormat
.format(BCText.get().unknownCurve, curveOID.getId()));
}
// Need to write p, a, b, g, n, q
BigInteger q = ec.getEncodedPoint();
byte[] g = params.getG().getEncoded(false);
BigInteger a = params.getCurve().getA().toBigInteger();
BigInteger b = params.getCurve().getB().toBigInteger();
BigInteger n = params.getN();
BigInteger p = null;
FiniteField field = params.getCurve().getField();
if (ECAlgorithms.isFpField(field)) {
p = field.getCharacteristic();
}
if (p == null) {
// Don't know...
throw new PGPException(MessageFormat.format(
BCText.get().unknownCurveParameters, curveOID.getId()));
}
hash(grip, p.toByteArray(), 'p', false);
hash(grip, a.toByteArray(), 'a', false);
hash(grip, b.toByteArray(), 'b', false);
hash(grip, g, 'g', false);
hash(grip, n.toByteArray(), 'n', false);
if (publicKey.getAlgorithm() == PublicKeyAlgorithmTags.EDDSA) {
hashQ25519(grip, q);
} else {
hash(grip, q.toByteArray(), 'q', false);
}
break;
default:
throw new PGPException(
MessageFormat.format(BCText.get().unknownKeyType,
Integer.toString(publicKey.getAlgorithm())));
}
return grip.digest();
}
private static void hash(SHA1 grip, byte[] data) {
// Need to skip leading zero bytes
int i = 0;
while (i < data.length && data[i] == 0) {
i++;
}
int length = data.length - i;
if (i < data.length) {
if ((data[i] & 0x80) != 0) {
grip.update((byte) 0);
}
grip.update(data, i, length);
}
}
private static void hash(SHA1 grip, byte[] data, char id, boolean zeroPad) {
// Need to skip leading zero bytes
int i = 0;
while (i < data.length && data[i] == 0) {
i++;
}
int length = data.length - i;
boolean addZero = false;
if (i < data.length && zeroPad && (data[i] & 0x80) != 0) {
addZero = true;
}
// libgcrypt includes an SExp in the hash
String prefix = "(1:" + id + (addZero ? length + 1 : length) + ':'; //$NON-NLS-1$
grip.update(prefix.getBytes(StandardCharsets.US_ASCII));
// For some items, gcrypt prepends a zero byte if the high bit is set
if (addZero) {
grip.update((byte) 0);
}
if (i < data.length) {
grip.update(data, i, length);
}
grip.update((byte) ')');
}
private static void hashQ25519(SHA1 grip, BigInteger q)
throws PGPException {
byte[] data = q.toByteArray();
switch (data[0]) {
case 0x04:
if (data.length != 65) {
throw new PGPException(MessageFormat.format(
BCText.get().corrupt25519Key, Hex.toHexString(data)));
}
// Uncompressed: should not occur with ed25519 or curve25519
throw new PGPException(MessageFormat.format(
BCText.get().uncompressed25519Key, Hex.toHexString(data)));
case 0x40:
if (data.length != 33) {
throw new PGPException(MessageFormat.format(
BCText.get().corrupt25519Key, Hex.toHexString(data)));
}
// Compressed; normal case. Skip prefix.
hash(grip, Arrays.copyOfRange(data, 1, data.length), 'q', false);
break;
default:
if (data.length != 32) {
throw new PGPException(MessageFormat.format(
BCText.get().corrupt25519Key, Hex.toHexString(data)));
}
// Compressed format without prefix. Should not occur?
hash(grip, data, 'q', false);
break;
}
}
/**
* Computes the keygrip for an ed25519 public key.
* <p>
* Package-visible for tests only.
* </p>
*
* @param grip
* initialized {@link SHA1}
* @param q
* the public key's EC point
* @return the keygrip
* @throws PGPException
* if q indicates uncompressed format
*/
@SuppressWarnings("nls")
static byte[] hashEd25519(SHA1 grip, BigInteger q) throws PGPException {
// For the values, see RFC 7748: https://tools.ietf.org/html/rfc7748
// p = 2^255 - 19
hash(grip, Hex.decodeStrict(
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"),
'p', false);
// Field: a = 1
hash(grip, new byte[] { 0x01 }, 'a', false);
// Field: b = 121665/121666 (mod p)
// See Berstein et.al., "Twisted Edwards Curves",
// https://doi.org/10.1007/978-3-540-68164-9_26
hash(grip, Hex.decodeStrict(
"2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A"),
'b', false);
// Generator point with affine X,Y
// @formatter:off
// X(P) = 15112221349535400772501151409588531511454012693041857206046113283949847762202
// Y(P) = 46316835694926478169428394003475163141307993866256225615783033603165251855960
// the "04" signifies uncompressed format.
// @formatter:on
hash(grip, Hex.decodeStrict("04"
+ "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+ "6666666666666666666666666666666666666666666666666666666666666658"),
'g', false);
// order = 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed
hash(grip, Hex.decodeStrict(
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"),
'n', false);
hashQ25519(grip, q);
return grip.digest();
}
/**
* Computes the keygrip for a curve25519 public key.
* <p>
* Package-visible for tests only.
* </p>
*
* @param grip
* initialized {@link SHA1}
* @param q
* the public key's EC point
* @return the keygrip
* @throws PGPException
* if q indicates uncompressed format
*/
@SuppressWarnings("nls")
static byte[] hashCurve25519(SHA1 grip, BigInteger q) throws PGPException {
hash(grip, Hex.decodeStrict(
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED"),
'p', false);
// Unclear: RFC 7748 says A = 486662. This value here is (A-2)/4 =
// 121665. Compare ecc-curves.c in libgcrypt:
// https://github.com/gpg/libgcrypt/blob/361a058/cipher/ecc-curves.c#L146
hash(grip, new byte[] { 0x01, (byte) 0xDB, 0x41 }, 'a', false);
hash(grip, new byte[] { 0x01 }, 'b', false);
// libgcrypt uses the old g.y value before the erratum to RFC 7748 for
// the keygrip. The new value would be
// 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14. See
// https://www.rfc-editor.org/errata/eid4730 and
// https://github.com/gpg/libgcrypt/commit/f67b6492e0b0
hash(grip, Hex.decodeStrict("04"
+ "0000000000000000000000000000000000000000000000000000000000000009"
+ "20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9"),
'g', false);
hash(grip, Hex.decodeStrict(
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED"),
'n', false);
hashQ25519(grip, q);
return grip.digest();
}
private static X9ECParameters getX9Parameters(
ASN1ObjectIdentifier curveOID) {
X9ECParameters params = CustomNamedCurves.getByOID(curveOID);
if (params == null) {
params = ECNamedCurveTable.getByOID(curveOID);
}
return params;
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import java.security.NoSuchAlgorithmException;
import java.text.MessageFormat;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPUtil;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.util.Arrays;
import org.eclipse.jgit.gpg.bc.internal.BCText;
/**
* A {@link PBEProtectionRemoverFactory} using AES/OCB/NoPadding for decryption.
* It accepts an AAD in the factory's constructor, so the factory can be used to
* create a {@link PBESecretKeyDecryptor} only for a particular input.
* <p>
* For JGit's needs, this is sufficient, but for a general upstream
* implementation that limitation might not be acceptable.
* </p>
*/
class OCBPBEProtectionRemoverFactory
implements PBEProtectionRemoverFactory {
private final PGPDigestCalculatorProvider calculatorProvider;
private final char[] passphrase;
private final byte[] aad;
/**
* Creates a new factory instance with the given parameters.
* <p>
* Because the AAD is given at factory level, the {@link PBESecretKeyDecryptor}s
* created by the factory can be used to decrypt only a particular input
* matching this AAD.
* </p>
*
* @param passphrase to use for secret key derivation
* @param calculatorProvider for computing digests
* @param aad for the OCB decryption
*/
OCBPBEProtectionRemoverFactory(char[] passphrase,
PGPDigestCalculatorProvider calculatorProvider, byte[] aad) {
this.calculatorProvider = calculatorProvider;
this.passphrase = passphrase;
this.aad = aad;
}
@Override
public PBESecretKeyDecryptor createDecryptor(String protection)
throws PGPException {
return new PBESecretKeyDecryptor(passphrase, calculatorProvider) {
@Override
public byte[] recoverKeyData(int encAlgorithm, byte[] key,
byte[] iv, byte[] encrypted, int encryptedOffset,
int encryptedLength) throws PGPException {
String algorithmName = PGPUtil
.getSymmetricCipherName(encAlgorithm);
byte[] decrypted = null;
try {
Cipher c = Cipher
.getInstance(algorithmName + "/OCB/NoPadding"); //$NON-NLS-1$
SecretKey secretKey = new SecretKeySpec(key, algorithmName);
c.init(Cipher.DECRYPT_MODE, secretKey,
new IvParameterSpec(iv));
c.updateAAD(aad);
decrypted = new byte[c.getOutputSize(encryptedLength)];
int decryptedLength = c.update(encrypted, encryptedOffset,
encryptedLength, decrypted);
// doFinal() for OCB will check the MAC and throw an
// exception if it doesn't match
decryptedLength += c.doFinal(decrypted, decryptedLength);
if (decryptedLength != decrypted.length) {
throw new PGPException(MessageFormat.format(
BCText.get().cryptWrongDecryptedLength,
Integer.valueOf(decryptedLength),
Integer.valueOf(decrypted.length)));
}
byte[] result = decrypted;
decrypted = null; // Don't clear in finally
return result;
} catch (NoClassDefFoundError e) {
String msg = MessageFormat.format(
BCText.get().gpgNoSuchAlgorithm,
algorithmName + "/OCB"); //$NON-NLS-1$
throw new PGPException(msg,
new NoSuchAlgorithmException(msg, e));
} catch (PGPException e) {
throw e;
} catch (Exception e) {
throw new PGPException(
MessageFormat.format(BCText.get().cryptCipherError,
e.getLocalizedMessage()),
e);
} finally {
if (decrypted != null) {
// Prevent halfway decrypted data leaking.
Arrays.fill(decrypted, (byte) 0);
}
}
}
};
}
}

View File

@ -0,0 +1,826 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
*including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* </p>
* <p>
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
* </p>
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </p>
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Date;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.bcpg.DSAPublicBCPGKey;
import org.bouncycastle.bcpg.DSASecretBCPGKey;
import org.bouncycastle.bcpg.ECDSAPublicBCPGKey;
import org.bouncycastle.bcpg.ECPublicBCPGKey;
import org.bouncycastle.bcpg.ECSecretBCPGKey;
import org.bouncycastle.bcpg.ElGamalPublicBCPGKey;
import org.bouncycastle.bcpg.ElGamalSecretBCPGKey;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyPacket;
import org.bouncycastle.bcpg.RSAPublicBCPGKey;
import org.bouncycastle.bcpg.RSASecretBCPGKey;
import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.bcpg.SecretKeyPacket;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Strings;
/**
* A parser for secret keys stored in s-expressions. Original BouncyCastle code
* modified by the JGit team to:
* <ul>
* <li>handle unencrypted DSA, EC, and ElGamal keys (upstream only handles
* unencrypted RSA), and</li>
* <li>handle secret keys using AES/OCB as encryption (those don't have a
* hash).</li>
* </ul>
*/
@SuppressWarnings("nls")
public class SExprParser {
private final PGPDigestCalculatorProvider digestProvider;
/**
* Base constructor.
*
* @param digestProvider
* a provider for digest calculations. Used to confirm key
* protection hashes.
*/
public SExprParser(PGPDigestCalculatorProvider digestProvider) {
this.digestProvider = digestProvider;
}
/**
* Parse a secret key from one of the GPG S expression keys associating it
* with the passed in public key.
*
* @param inputStream
* to read from
* @param keyProtectionRemoverFactory
* for decrypting encrypted keys
* @param pubKey
* the private key should belong to
*
* @return a secret key object.
* @throws IOException
* @throws PGPException
*/
public PGPSecretKey parseSecretKey(InputStream inputStream,
PBEProtectionRemoverFactory keyProtectionRemoverFactory,
PGPPublicKey pubKey) throws IOException, PGPException {
SXprUtils.skipOpenParenthesis(inputStream);
String type;
type = SXprUtils.readString(inputStream, inputStream.read());
if (type.equals("protected-private-key")
|| type.equals("private-key")) {
SXprUtils.skipOpenParenthesis(inputStream);
String keyType = SXprUtils.readString(inputStream,
inputStream.read());
if (keyType.equals("ecc")) {
SXprUtils.skipOpenParenthesis(inputStream);
String curveID = SXprUtils.readString(inputStream,
inputStream.read());
String curveName = SXprUtils.readString(inputStream,
inputStream.read());
SXprUtils.skipCloseParenthesis(inputStream);
byte[] qVal;
SXprUtils.skipOpenParenthesis(inputStream);
type = SXprUtils.readString(inputStream, inputStream.read());
if (type.equals("q")) {
qVal = SXprUtils.readBytes(inputStream, inputStream.read());
} else {
throw new PGPException("no q value found");
}
SXprUtils.skipCloseParenthesis(inputStream);
BigInteger d = processECSecretKey(inputStream, curveID,
curveName, qVal, keyProtectionRemoverFactory);
if (curveName.startsWith("NIST ")) {
curveName = curveName.substring("NIST ".length());
}
ECPublicBCPGKey basePubKey = new ECDSAPublicBCPGKey(
ECNamedCurveTable.getOID(curveName),
new BigInteger(1, qVal));
ECPublicBCPGKey assocPubKey = (ECPublicBCPGKey) pubKey
.getPublicKeyPacket().getKey();
if (!basePubKey.getCurveOID().equals(assocPubKey.getCurveOID())
|| !basePubKey.getEncodedPoint()
.equals(assocPubKey.getEncodedPoint())) {
throw new PGPException(
"passed in public key does not match secret key");
}
return new PGPSecretKey(
new SecretKeyPacket(pubKey.getPublicKeyPacket(),
SymmetricKeyAlgorithmTags.NULL, null, null,
new ECSecretBCPGKey(d).getEncoded()),
pubKey);
} else if (keyType.equals("dsa")) {
BigInteger p = readBigInteger("p", inputStream);
BigInteger q = readBigInteger("q", inputStream);
BigInteger g = readBigInteger("g", inputStream);
BigInteger y = readBigInteger("y", inputStream);
BigInteger x = processDSASecretKey(inputStream, p, q, g, y,
keyProtectionRemoverFactory);
DSAPublicBCPGKey basePubKey = new DSAPublicBCPGKey(p, q, g, y);
DSAPublicBCPGKey assocPubKey = (DSAPublicBCPGKey) pubKey
.getPublicKeyPacket().getKey();
if (!basePubKey.getP().equals(assocPubKey.getP())
|| !basePubKey.getQ().equals(assocPubKey.getQ())
|| !basePubKey.getG().equals(assocPubKey.getG())
|| !basePubKey.getY().equals(assocPubKey.getY())) {
throw new PGPException(
"passed in public key does not match secret key");
}
return new PGPSecretKey(
new SecretKeyPacket(pubKey.getPublicKeyPacket(),
SymmetricKeyAlgorithmTags.NULL, null, null,
new DSASecretBCPGKey(x).getEncoded()),
pubKey);
} else if (keyType.equals("elg")) {
BigInteger p = readBigInteger("p", inputStream);
BigInteger g = readBigInteger("g", inputStream);
BigInteger y = readBigInteger("y", inputStream);
BigInteger x = processElGamalSecretKey(inputStream, p, g, y,
keyProtectionRemoverFactory);
ElGamalPublicBCPGKey basePubKey = new ElGamalPublicBCPGKey(p, g,
y);
ElGamalPublicBCPGKey assocPubKey = (ElGamalPublicBCPGKey) pubKey
.getPublicKeyPacket().getKey();
if (!basePubKey.getP().equals(assocPubKey.getP())
|| !basePubKey.getG().equals(assocPubKey.getG())
|| !basePubKey.getY().equals(assocPubKey.getY())) {
throw new PGPException(
"passed in public key does not match secret key");
}
return new PGPSecretKey(
new SecretKeyPacket(pubKey.getPublicKeyPacket(),
SymmetricKeyAlgorithmTags.NULL, null, null,
new ElGamalSecretBCPGKey(x).getEncoded()),
pubKey);
} else if (keyType.equals("rsa")) {
BigInteger n = readBigInteger("n", inputStream);
BigInteger e = readBigInteger("e", inputStream);
BigInteger[] values = processRSASecretKey(inputStream, n, e,
keyProtectionRemoverFactory);
// TODO: type of RSA key?
RSAPublicBCPGKey basePubKey = new RSAPublicBCPGKey(n, e);
RSAPublicBCPGKey assocPubKey = (RSAPublicBCPGKey) pubKey
.getPublicKeyPacket().getKey();
if (!basePubKey.getModulus().equals(assocPubKey.getModulus())
|| !basePubKey.getPublicExponent()
.equals(assocPubKey.getPublicExponent())) {
throw new PGPException(
"passed in public key does not match secret key");
}
return new PGPSecretKey(new SecretKeyPacket(
pubKey.getPublicKeyPacket(),
SymmetricKeyAlgorithmTags.NULL, null, null,
new RSASecretBCPGKey(values[0], values[1], values[2])
.getEncoded()),
pubKey);
} else {
throw new PGPException("unknown key type: " + keyType);
}
}
throw new PGPException("unknown key type found");
}
/**
* Parse a secret key from one of the GPG S expression keys.
*
* @param inputStream
* to read from
* @param keyProtectionRemoverFactory
* for decrypting encrypted keys
* @param fingerPrintCalculator
* for calculating key fingerprints
*
* @return a secret key object.
* @throws IOException
* @throws PGPException
*/
public PGPSecretKey parseSecretKey(InputStream inputStream,
PBEProtectionRemoverFactory keyProtectionRemoverFactory,
KeyFingerPrintCalculator fingerPrintCalculator)
throws IOException, PGPException {
SXprUtils.skipOpenParenthesis(inputStream);
String type;
type = SXprUtils.readString(inputStream, inputStream.read());
if (type.equals("protected-private-key")
|| type.equals("private-key")) {
SXprUtils.skipOpenParenthesis(inputStream);
String keyType = SXprUtils.readString(inputStream,
inputStream.read());
if (keyType.equals("ecc")) {
SXprUtils.skipOpenParenthesis(inputStream);
String curveID = SXprUtils.readString(inputStream,
inputStream.read());
String curveName = SXprUtils.readString(inputStream,
inputStream.read());
if (curveName.startsWith("NIST ")) {
curveName = curveName.substring("NIST ".length());
}
SXprUtils.skipCloseParenthesis(inputStream);
byte[] qVal;
SXprUtils.skipOpenParenthesis(inputStream);
type = SXprUtils.readString(inputStream, inputStream.read());
if (type.equals("q")) {
qVal = SXprUtils.readBytes(inputStream, inputStream.read());
} else {
throw new PGPException("no q value found");
}
PublicKeyPacket pubPacket = new PublicKeyPacket(
PublicKeyAlgorithmTags.ECDSA, new Date(),
new ECDSAPublicBCPGKey(
ECNamedCurveTable.getOID(curveName),
new BigInteger(1, qVal)));
SXprUtils.skipCloseParenthesis(inputStream);
BigInteger d = processECSecretKey(inputStream, curveID,
curveName, qVal, keyProtectionRemoverFactory);
return new PGPSecretKey(
new SecretKeyPacket(pubPacket,
SymmetricKeyAlgorithmTags.NULL, null, null,
new ECSecretBCPGKey(d).getEncoded()),
new PGPPublicKey(pubPacket, fingerPrintCalculator));
} else if (keyType.equals("dsa")) {
BigInteger p = readBigInteger("p", inputStream);
BigInteger q = readBigInteger("q", inputStream);
BigInteger g = readBigInteger("g", inputStream);
BigInteger y = readBigInteger("y", inputStream);
BigInteger x = processDSASecretKey(inputStream, p, q, g, y,
keyProtectionRemoverFactory);
PublicKeyPacket pubPacket = new PublicKeyPacket(
PublicKeyAlgorithmTags.DSA, new Date(),
new DSAPublicBCPGKey(p, q, g, y));
return new PGPSecretKey(
new SecretKeyPacket(pubPacket,
SymmetricKeyAlgorithmTags.NULL, null, null,
new DSASecretBCPGKey(x).getEncoded()),
new PGPPublicKey(pubPacket, fingerPrintCalculator));
} else if (keyType.equals("elg")) {
BigInteger p = readBigInteger("p", inputStream);
BigInteger g = readBigInteger("g", inputStream);
BigInteger y = readBigInteger("y", inputStream);
BigInteger x = processElGamalSecretKey(inputStream, p, g, y,
keyProtectionRemoverFactory);
PublicKeyPacket pubPacket = new PublicKeyPacket(
PublicKeyAlgorithmTags.ELGAMAL_ENCRYPT, new Date(),
new ElGamalPublicBCPGKey(p, g, y));
return new PGPSecretKey(
new SecretKeyPacket(pubPacket,
SymmetricKeyAlgorithmTags.NULL, null, null,
new ElGamalSecretBCPGKey(x).getEncoded()),
new PGPPublicKey(pubPacket, fingerPrintCalculator));
} else if (keyType.equals("rsa")) {
BigInteger n = readBigInteger("n", inputStream);
BigInteger e = readBigInteger("e", inputStream);
BigInteger[] values = processRSASecretKey(inputStream, n, e,
keyProtectionRemoverFactory);
// TODO: type of RSA key?
PublicKeyPacket pubPacket = new PublicKeyPacket(
PublicKeyAlgorithmTags.RSA_GENERAL, new Date(),
new RSAPublicBCPGKey(n, e));
return new PGPSecretKey(
new SecretKeyPacket(pubPacket,
SymmetricKeyAlgorithmTags.NULL, null, null,
new RSASecretBCPGKey(values[0], values[1],
values[2]).getEncoded()),
new PGPPublicKey(pubPacket, fingerPrintCalculator));
} else {
throw new PGPException("unknown key type: " + keyType);
}
}
throw new PGPException("unknown key type found");
}
private BigInteger readBigInteger(String expectedType,
InputStream inputStream) throws IOException, PGPException {
SXprUtils.skipOpenParenthesis(inputStream);
String type = SXprUtils.readString(inputStream, inputStream.read());
if (!type.equals(expectedType)) {
throw new PGPException(expectedType + " value expected");
}
byte[] nBytes = SXprUtils.readBytes(inputStream, inputStream.read());
BigInteger v = new BigInteger(1, nBytes);
SXprUtils.skipCloseParenthesis(inputStream);
return v;
}
private static byte[][] extractData(InputStream inputStream,
PBEProtectionRemoverFactory keyProtectionRemoverFactory)
throws PGPException, IOException {
byte[] data;
byte[] protectedAt = null;
SXprUtils.skipOpenParenthesis(inputStream);
String type = SXprUtils.readString(inputStream, inputStream.read());
if (type.equals("protected")) {
String protection = SXprUtils.readString(inputStream,
inputStream.read());
SXprUtils.skipOpenParenthesis(inputStream);
S2K s2k = SXprUtils.parseS2K(inputStream);
byte[] iv = SXprUtils.readBytes(inputStream, inputStream.read());
SXprUtils.skipCloseParenthesis(inputStream);
byte[] secKeyData = SXprUtils.readBytes(inputStream,
inputStream.read());
SXprUtils.skipCloseParenthesis(inputStream);
PBESecretKeyDecryptor keyDecryptor = keyProtectionRemoverFactory
.createDecryptor(protection);
// TODO: recognise other algorithms
byte[] key = keyDecryptor.makeKeyFromPassPhrase(
SymmetricKeyAlgorithmTags.AES_128, s2k);
data = keyDecryptor.recoverKeyData(
SymmetricKeyAlgorithmTags.AES_128, key, iv, secKeyData, 0,
secKeyData.length);
// check if protected at is present
if (inputStream.read() == '(') {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
bOut.write('(');
int ch;
while ((ch = inputStream.read()) >= 0 && ch != ')') {
bOut.write(ch);
}
if (ch != ')') {
throw new IOException("unexpected end to SExpr");
}
bOut.write(')');
protectedAt = bOut.toByteArray();
}
SXprUtils.skipCloseParenthesis(inputStream);
SXprUtils.skipCloseParenthesis(inputStream);
} else if (type.equals("d") || type.equals("x")) {
// JGit modification: unencrypted DSA or ECC keys can have an "x"
// here
return null;
} else {
throw new PGPException("protected block not found");
}
return new byte[][] { data, protectedAt };
}
private BigInteger processDSASecretKey(InputStream inputStream,
BigInteger p, BigInteger q, BigInteger g, BigInteger y,
PBEProtectionRemoverFactory keyProtectionRemoverFactory)
throws IOException, PGPException {
String type;
byte[][] basicData = extractData(inputStream,
keyProtectionRemoverFactory);
// JGit modification: handle unencrypted DSA keys
if (basicData == null) {
byte[] nBytes = SXprUtils.readBytes(inputStream,
inputStream.read());
BigInteger x = new BigInteger(1, nBytes);
SXprUtils.skipCloseParenthesis(inputStream);
return x;
}
byte[] keyData = basicData[0];
byte[] protectedAt = basicData[1];
//
// parse the secret key S-expr
//
InputStream keyIn = new ByteArrayInputStream(keyData);
SXprUtils.skipOpenParenthesis(keyIn);
SXprUtils.skipOpenParenthesis(keyIn);
BigInteger x = readBigInteger("x", keyIn);
SXprUtils.skipCloseParenthesis(keyIn);
// JGit modification: OCB-encrypted keys don't have and don't need a
// hash
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) {
return x;
}
SXprUtils.skipOpenParenthesis(keyIn);
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("hash")) {
throw new PGPException("hash keyword expected");
}
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("sha1")) {
throw new PGPException("hash keyword expected");
}
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read());
SXprUtils.skipCloseParenthesis(keyIn);
if (digestProvider != null) {
PGPDigestCalculator digestCalculator = digestProvider
.get(HashAlgorithmTags.SHA1);
OutputStream dOut = digestCalculator.getOutputStream();
dOut.write(Strings.toByteArray("(3:dsa"));
writeCanonical(dOut, "p", p);
writeCanonical(dOut, "q", q);
writeCanonical(dOut, "g", g);
writeCanonical(dOut, "y", y);
writeCanonical(dOut, "x", x);
// check protected-at
if (protectedAt != null) {
dOut.write(protectedAt);
}
dOut.write(Strings.toByteArray(")"));
byte[] check = digestCalculator.getDigest();
if (!Arrays.constantTimeAreEqual(check, hashBytes)) {
throw new PGPException(
"checksum on protected data failed in SExpr");
}
}
return x;
}
private BigInteger processElGamalSecretKey(InputStream inputStream,
BigInteger p, BigInteger g, BigInteger y,
PBEProtectionRemoverFactory keyProtectionRemoverFactory)
throws IOException, PGPException {
String type;
byte[][] basicData = extractData(inputStream,
keyProtectionRemoverFactory);
// JGit modification: handle unencrypted EC keys
if (basicData == null) {
byte[] nBytes = SXprUtils.readBytes(inputStream,
inputStream.read());
BigInteger x = new BigInteger(1, nBytes);
SXprUtils.skipCloseParenthesis(inputStream);
return x;
}
byte[] keyData = basicData[0];
byte[] protectedAt = basicData[1];
//
// parse the secret key S-expr
//
InputStream keyIn = new ByteArrayInputStream(keyData);
SXprUtils.skipOpenParenthesis(keyIn);
SXprUtils.skipOpenParenthesis(keyIn);
BigInteger x = readBigInteger("x", keyIn);
SXprUtils.skipCloseParenthesis(keyIn);
// JGit modification: OCB-encrypted keys don't have and don't need a
// hash
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) {
return x;
}
SXprUtils.skipOpenParenthesis(keyIn);
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("hash")) {
throw new PGPException("hash keyword expected");
}
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("sha1")) {
throw new PGPException("hash keyword expected");
}
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read());
SXprUtils.skipCloseParenthesis(keyIn);
if (digestProvider != null) {
PGPDigestCalculator digestCalculator = digestProvider
.get(HashAlgorithmTags.SHA1);
OutputStream dOut = digestCalculator.getOutputStream();
dOut.write(Strings.toByteArray("(3:elg"));
writeCanonical(dOut, "p", p);
writeCanonical(dOut, "g", g);
writeCanonical(dOut, "y", y);
writeCanonical(dOut, "x", x);
// check protected-at
if (protectedAt != null) {
dOut.write(protectedAt);
}
dOut.write(Strings.toByteArray(")"));
byte[] check = digestCalculator.getDigest();
if (!Arrays.constantTimeAreEqual(check, hashBytes)) {
throw new PGPException(
"checksum on protected data failed in SExpr");
}
}
return x;
}
private BigInteger processECSecretKey(InputStream inputStream,
String curveID, String curveName, byte[] qVal,
PBEProtectionRemoverFactory keyProtectionRemoverFactory)
throws IOException, PGPException {
String type;
byte[][] basicData = extractData(inputStream,
keyProtectionRemoverFactory);
// JGit modification: handle unencrypted EC keys
if (basicData == null) {
byte[] nBytes = SXprUtils.readBytes(inputStream,
inputStream.read());
BigInteger d = new BigInteger(1, nBytes);
SXprUtils.skipCloseParenthesis(inputStream);
return d;
}
byte[] keyData = basicData[0];
byte[] protectedAt = basicData[1];
//
// parse the secret key S-expr
//
InputStream keyIn = new ByteArrayInputStream(keyData);
SXprUtils.skipOpenParenthesis(keyIn);
SXprUtils.skipOpenParenthesis(keyIn);
BigInteger d = readBigInteger("d", keyIn);
SXprUtils.skipCloseParenthesis(keyIn);
// JGit modification: OCB-encrypted keys don't have and don't need a
// hash
if (keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) {
return d;
}
SXprUtils.skipOpenParenthesis(keyIn);
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("hash")) {
throw new PGPException("hash keyword expected");
}
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("sha1")) {
throw new PGPException("hash keyword expected");
}
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read());
SXprUtils.skipCloseParenthesis(keyIn);
if (digestProvider != null) {
PGPDigestCalculator digestCalculator = digestProvider
.get(HashAlgorithmTags.SHA1);
OutputStream dOut = digestCalculator.getOutputStream();
dOut.write(Strings.toByteArray("(3:ecc"));
dOut.write(Strings.toByteArray("(" + curveID.length() + ":"
+ curveID + curveName.length() + ":" + curveName + ")"));
writeCanonical(dOut, "q", qVal);
writeCanonical(dOut, "d", d);
// check protected-at
if (protectedAt != null) {
dOut.write(protectedAt);
}
dOut.write(Strings.toByteArray(")"));
byte[] check = digestCalculator.getDigest();
if (!Arrays.constantTimeAreEqual(check, hashBytes)) {
throw new PGPException(
"checksum on protected data failed in SExpr");
}
}
return d;
}
private BigInteger[] processRSASecretKey(InputStream inputStream,
BigInteger n, BigInteger e,
PBEProtectionRemoverFactory keyProtectionRemoverFactory)
throws IOException, PGPException {
String type;
byte[][] basicData = extractData(inputStream,
keyProtectionRemoverFactory);
byte[] keyData;
byte[] protectedAt = null;
InputStream keyIn;
BigInteger d;
if (basicData == null) {
keyIn = inputStream;
byte[] nBytes = SXprUtils.readBytes(inputStream,
inputStream.read());
d = new BigInteger(1, nBytes);
SXprUtils.skipCloseParenthesis(inputStream);
} else {
keyData = basicData[0];
protectedAt = basicData[1];
keyIn = new ByteArrayInputStream(keyData);
SXprUtils.skipOpenParenthesis(keyIn);
SXprUtils.skipOpenParenthesis(keyIn);
d = readBigInteger("d", keyIn);
}
//
// parse the secret key S-expr
//
BigInteger p = readBigInteger("p", keyIn);
BigInteger q = readBigInteger("q", keyIn);
BigInteger u = readBigInteger("u", keyIn);
// JGit modification: OCB-encrypted keys don't have and don't need a
// hash
if (basicData == null
|| keyProtectionRemoverFactory instanceof OCBPBEProtectionRemoverFactory) {
return new BigInteger[] { d, p, q, u };
}
SXprUtils.skipCloseParenthesis(keyIn);
SXprUtils.skipOpenParenthesis(keyIn);
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("hash")) {
throw new PGPException("hash keyword expected");
}
type = SXprUtils.readString(keyIn, keyIn.read());
if (!type.equals("sha1")) {
throw new PGPException("hash keyword expected");
}
byte[] hashBytes = SXprUtils.readBytes(keyIn, keyIn.read());
SXprUtils.skipCloseParenthesis(keyIn);
if (digestProvider != null) {
PGPDigestCalculator digestCalculator = digestProvider
.get(HashAlgorithmTags.SHA1);
OutputStream dOut = digestCalculator.getOutputStream();
dOut.write(Strings.toByteArray("(3:rsa"));
writeCanonical(dOut, "n", n);
writeCanonical(dOut, "e", e);
writeCanonical(dOut, "d", d);
writeCanonical(dOut, "p", p);
writeCanonical(dOut, "q", q);
writeCanonical(dOut, "u", u);
// check protected-at
if (protectedAt != null) {
dOut.write(protectedAt);
}
dOut.write(Strings.toByteArray(")"));
byte[] check = digestCalculator.getDigest();
if (!Arrays.constantTimeAreEqual(check, hashBytes)) {
throw new PGPException(
"checksum on protected data failed in SExpr");
}
}
return new BigInteger[] { d, p, q, u };
}
private void writeCanonical(OutputStream dOut, String label, BigInteger i)
throws IOException {
writeCanonical(dOut, label, i.toByteArray());
}
private void writeCanonical(OutputStream dOut, String label, byte[] data)
throws IOException {
dOut.write(Strings.toByteArray(
"(" + label.length() + ":" + label + data.length + ":"));
dOut.write(data);
dOut.write(Strings.toByteArray(")"));
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000-2021 The Legion of the Bouncy Castle Inc. (https://www.bouncycastle.org)
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
*including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
* </p>
* <p>
* The above copyright notice and this permission notice shall be included in all copies or substantial
* portions of the Software.
* </p>
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </p>
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
// This class is an unmodified copy from Bouncy Castle; needed because it's package-visible only and used by SExprParser.
import java.io.IOException;
import java.io.InputStream;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.S2K;
import org.bouncycastle.util.io.Streams;
/**
* Utility functions for looking a S-expression keys. This class will move when
* it finds a better home!
* <p>
* Format documented here:
* http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob;f=agent/keyformat.txt;h=42c4b1f06faf1bbe71ffadc2fee0fad6bec91a97;hb=refs/heads/master
* </p>
*/
class SXprUtils {
private static int readLength(InputStream in, int ch) throws IOException {
int len = ch - '0';
while ((ch = in.read()) >= 0 && ch != ':') {
len = len * 10 + ch - '0';
}
return len;
}
static String readString(InputStream in, int ch) throws IOException {
int len = readLength(in, ch);
char[] chars = new char[len];
for (int i = 0; i != chars.length; i++) {
chars[i] = (char) in.read();
}
return new String(chars);
}
static byte[] readBytes(InputStream in, int ch) throws IOException {
int len = readLength(in, ch);
byte[] data = new byte[len];
Streams.readFully(in, data);
return data;
}
static S2K parseS2K(InputStream in) throws IOException {
skipOpenParenthesis(in);
// Algorithm is hard-coded to SHA1 below anyway.
readString(in, in.read());
byte[] iv = readBytes(in, in.read());
final long iterationCount = Long.parseLong(readString(in, in.read()));
skipCloseParenthesis(in);
// we have to return the actual iteration count provided.
S2K s2k = new S2K(HashAlgorithmTags.SHA1, iv, (int) iterationCount) {
@Override
public long getIterationCount() {
return iterationCount;
}
};
return s2k;
}
static void skipOpenParenthesis(InputStream in) throws IOException {
int ch = in.read();
if (ch != '(') {
throw new IOException(
"unknown character encountered: " + (char) ch); //$NON-NLS-1$
}
}
static void skipCloseParenthesis(InputStream in) throws IOException {
int ch = in.read();
if (ch != ')') {
throw new IOException("unknown character encountered"); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,597 @@
/*
* Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.gpg.bc.internal.keys;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamCorruptedException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Arrays;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPSecretKey;
import org.bouncycastle.openpgp.operator.PBEProtectionRemoverFactory;
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
import org.bouncycastle.openpgp.operator.jcajce.JcePBEProtectionRemoverFactory;
import org.bouncycastle.util.io.Streams;
import org.eclipse.jgit.api.errors.CanceledException;
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.gpg.bc.internal.BCText;
import org.eclipse.jgit.util.RawParseUtils;
/**
* Utilities for reading GPG secret keys from a gpg-agent key file.
*/
public final class SecretKeys {
private SecretKeys() {
// No instantiation.
}
/**
* Something that can supply a passphrase to decrypt an encrypted secret
* key.
*/
public interface PassphraseSupplier {
/**
* Supplies a passphrase.
*
* @return the passphrase
* @throws PGPException
* if no passphrase can be obtained
* @throws CanceledException
* if the user canceled passphrase entry
* @throws UnsupportedCredentialItem
* if an internal error occurred
* @throws URISyntaxException
* if an internal error occurred
*/
char[] getPassphrase() throws PGPException, CanceledException,
UnsupportedCredentialItem, URISyntaxException;
}
private static final byte[] PROTECTED_KEY = "protected-private-key" //$NON-NLS-1$
.getBytes(StandardCharsets.US_ASCII);
private static final byte[] OCB_PROTECTED = "openpgp-s2k3-ocb-aes" //$NON-NLS-1$
.getBytes(StandardCharsets.US_ASCII);
/**
* Reads a GPG secret key from the given stream.
*
* @param in
* {@link InputStream} to read from, doesn't need to be buffered
* @param calculatorProvider
* for checking digests
* @param passphraseSupplier
* for decrypting encrypted keys
* @param publicKey
* the secret key should be for
* @return the secret key
* @throws IOException
* if the stream cannot be parsed
* @throws PGPException
* if thrown by the underlying S-Expression parser, for instance
* when the passphrase is wrong
* @throws CanceledException
* if thrown by the {@code passphraseSupplier}
* @throws UnsupportedCredentialItem
* if thrown by the {@code passphraseSupplier}
* @throws URISyntaxException
* if thrown by the {@code passphraseSupplier}
*/
public static PGPSecretKey readSecretKey(InputStream in,
PGPDigestCalculatorProvider calculatorProvider,
PassphraseSupplier passphraseSupplier, PGPPublicKey publicKey)
throws IOException, PGPException, CanceledException,
UnsupportedCredentialItem, URISyntaxException {
byte[] data = Streams.readAll(in);
if (data.length == 0) {
throw new EOFException();
} else if (data.length < 4 + PROTECTED_KEY.length) {
// +4 for "(21:" for a binary protected key
throw new IOException(
MessageFormat.format(BCText.get().secretKeyTooShort,
Integer.toUnsignedString(data.length)));
}
SExprParser parser = new SExprParser(calculatorProvider);
byte firstChar = data[0];
try {
if (firstChar == '(') {
// Binary format.
PBEProtectionRemoverFactory decryptor = null;
if (matches(data, 4, PROTECTED_KEY)) {
// AES/CBC encrypted.
decryptor = new JcePBEProtectionRemoverFactory(
passphraseSupplier.getPassphrase(),
calculatorProvider);
}
try (InputStream sIn = new ByteArrayInputStream(data)) {
return parser.parseSecretKey(sIn, decryptor, publicKey);
}
}
// Assume it's the new key-value format.
try (ByteArrayInputStream keyIn = new ByteArrayInputStream(data)) {
byte[] rawData = keyFromNameValueFormat(keyIn);
if (!matches(rawData, 1, PROTECTED_KEY)) {
// Not encrypted human-readable format.
try (InputStream sIn = new ByteArrayInputStream(
convertSexpression(rawData))) {
return parser.parseSecretKey(sIn, null, publicKey);
}
}
// An encrypted key from a key-value file. Most likely AES/OCB
// encrypted.
boolean isOCB[] = { false };
byte[] sExp = convertSexpression(rawData, isOCB);
PBEProtectionRemoverFactory decryptor;
if (isOCB[0]) {
decryptor = new OCBPBEProtectionRemoverFactory(
passphraseSupplier.getPassphrase(),
calculatorProvider, getAad(sExp));
} else {
decryptor = new JcePBEProtectionRemoverFactory(
passphraseSupplier.getPassphrase(),
calculatorProvider);
}
try (InputStream sIn = new ByteArrayInputStream(sExp)) {
return parser.parseSecretKey(sIn, decryptor, publicKey);
}
}
} catch (IOException e) {
throw new PGPException(e.getLocalizedMessage(), e);
}
}
/**
* Extract the AAD for the OCB decryption from an s-expression.
*
* @param sExp
* buffer containing a valid binary s-expression
* @return the AAD
*/
private static byte[] getAad(byte[] sExp) {
// Given a key
// @formatter:off
// (protected-private-key (rsa ... (protected openpgp-s2k3-ocb-aes ... )(protected-at ...)))
// A B C D
// The AAD is [A..B)[C..D). (From the binary serialized form.)
// @formatter:on
int i = 1; // Skip initial '('
while (sExp[i] != '(') {
i++;
}
int aadStart = i++;
int aadEnd = skip(sExp, aadStart);
byte[] protectedPrefix = "(9:protected" //$NON-NLS-1$
.getBytes(StandardCharsets.US_ASCII);
while (!matches(sExp, i, protectedPrefix)) {
i++;
}
int protectedStart = i;
int protectedEnd = skip(sExp, protectedStart);
byte[] aadData = new byte[aadEnd - aadStart
- (protectedEnd - protectedStart)];
System.arraycopy(sExp, aadStart, aadData, 0, protectedStart - aadStart);
System.arraycopy(sExp, protectedEnd, aadData, protectedStart - aadStart,
aadEnd - protectedEnd);
return aadData;
}
/**
* Skips a list including nested lists.
*
* @param sExp
* buffer containing valid binary s-expression data
* @param start
* index of the opening '(' of the list to skip
* @return the index after the closing ')' of the skipped list
*/
private static int skip(byte[] sExp, int start) {
int i = start + 1;
int depth = 1;
while (depth > 0) {
switch (sExp[i]) {
case '(':
depth++;
break;
case ')':
depth--;
break;
default:
// We must be on a length
int j = i;
while (sExp[j] >= '0' && sExp[j] <= '9') {
j++;
}
// j is on the colon
int length = Integer.parseInt(
new String(sExp, i, j - i, StandardCharsets.US_ASCII));
i = j + length;
}
i++;
}
return i;
}
/**
* Checks whether the {@code needle} matches {@code src} at offset
* {@code from}.
*
* @param src
* to match against {@code needle}
* @param from
* position in {@code src} to start matching
* @param needle
* to match against
* @return {@code true} if {@code src} contains {@code needle} at position
* {@code from}, {@code false} otherwise
*/
private static boolean matches(byte[] src, int from, byte[] needle) {
if (from < 0 || from + needle.length > src.length) {
return false;
}
return org.bouncycastle.util.Arrays.constantTimeAreEqual(needle.length,
src, from, needle, 0);
}
/**
* Converts a human-readable serialized s-expression into a binary
* serialized s-expression.
*
* @param humanForm
* to convert
* @return the converted s-expression
* @throws IOException
* if the conversion fails
*/
private static byte[] convertSexpression(byte[] humanForm)
throws IOException {
boolean[] isOCB = { false };
return convertSexpression(humanForm, isOCB);
}
/**
* Converts a human-readable serialized s-expression into a binary
* serialized s-expression.
*
* @param humanForm
* to convert
* @param isOCB
* returns whether the s-expression specified AES/OCB encryption
* @return the converted s-expression
* @throws IOException
* if the conversion fails
*/
private static byte[] convertSexpression(byte[] humanForm, boolean[] isOCB)
throws IOException {
int pos = 0;
try (ByteArrayOutputStream out = new ByteArrayOutputStream(
humanForm.length)) {
while (pos < humanForm.length) {
byte b = humanForm[pos];
if (b == '(' || b == ')') {
out.write(b);
pos++;
} else if (isGpgSpace(b)) {
pos++;
} else if (b == '#') {
// Hex value follows up to the next #
int i = ++pos;
while (i < humanForm.length && isHex(humanForm[i])) {
i++;
}
if (i == pos || humanForm[i] != '#') {
throw new StreamCorruptedException(
BCText.get().sexprHexNotClosed);
}
if ((i - pos) % 2 != 0) {
throw new StreamCorruptedException(
BCText.get().sexprHexOdd);
}
int l = (i - pos) / 2;
out.write(Integer.toString(l)
.getBytes(StandardCharsets.US_ASCII));
out.write(':');
while (pos < i) {
int x = (nibble(humanForm[pos]) << 4)
| nibble(humanForm[pos + 1]);
pos += 2;
out.write(x);
}
pos = i + 1;
} else if (isTokenChar(b)) {
// Scan the token
int start = pos++;
while (pos < humanForm.length
&& isTokenChar(humanForm[pos])) {
pos++;
}
int l = pos - start;
if (pos - start == OCB_PROTECTED.length
&& matches(humanForm, start, OCB_PROTECTED)) {
isOCB[0] = true;
}
out.write(Integer.toString(l)
.getBytes(StandardCharsets.US_ASCII));
out.write(':');
out.write(humanForm, start, pos - start);
} else if (b == '"') {
// Potentially quoted string.
int start = ++pos;
boolean escaped = false;
while (pos < humanForm.length
&& (escaped || humanForm[pos] != '"')) {
int ch = humanForm[pos++];
escaped = !escaped && ch == '\\';
}
if (pos >= humanForm.length) {
throw new StreamCorruptedException(
BCText.get().sexprStringNotClosed);
}
// start is on the first character of the string, pos on the
// closing quote.
byte[] dq = dequote(humanForm, start, pos);
out.write(Integer.toString(dq.length)
.getBytes(StandardCharsets.US_ASCII));
out.write(':');
out.write(dq);
pos++;
} else {
throw new StreamCorruptedException(
MessageFormat.format(BCText.get().sexprUnhandled,
Integer.toHexString(b & 0xFF)));
}
}
return out.toByteArray();
}
}
/**
* GPG-style string de-quoting, which is basically C-style, with some
* literal CR/LF escaping.
*
* @param in
* buffer containing the quoted string
* @param from
* index after the opening quote in {@code in}
* @param to
* index of the closing quote in {@code in}
* @return the dequoted raw string value
* @throws StreamCorruptedException
*/
private static byte[] dequote(byte[] in, int from, int to)
throws StreamCorruptedException {
// Result must be shorter or have the same length
byte[] out = new byte[to - from];
int j = 0;
int i = from;
while (i < to) {
byte b = in[i++];
if (b != '\\') {
out[j++] = b;
continue;
}
if (i == to) {
throw new StreamCorruptedException(
BCText.get().sexprStringInvalidEscapeAtEnd);
}
b = in[i++];
switch (b) {
case 'b':
out[j++] = '\b';
break;
case 'f':
out[j++] = '\f';
break;
case 'n':
out[j++] = '\n';
break;
case 'r':
out[j++] = '\r';
break;
case 't':
out[j++] = '\t';
break;
case 'v':
out[j++] = 0x0B;
break;
case '"':
case '\'':
case '\\':
out[j++] = b;
break;
case '\r':
// Escaped literal line end. If an LF is following, skip that,
// too.
if (i < to && in[i] == '\n') {
i++;
}
break;
case '\n':
// Same for LF possibly followed by CR.
if (i < to && in[i] == '\r') {
i++;
}
break;
case 'x':
if (i + 1 >= to || !isHex(in[i]) || !isHex(in[i + 1])) {
throw new StreamCorruptedException(
BCText.get().sexprStringInvalidHexEscape);
}
out[j++] = (byte) ((nibble(in[i]) << 4) | nibble(in[i + 1]));
i += 2;
break;
case '0':
case '1':
case '2':
case '3':
if (i + 2 >= to || !isOctal(in[i]) || !isOctal(in[i + 1])
|| !isOctal(in[i + 2])) {
throw new StreamCorruptedException(
BCText.get().sexprStringInvalidOctalEscape);
}
out[j++] = (byte) (((((in[i] - '0') << 3)
| (in[i + 1] - '0')) << 3) | (in[i + 2] - '0'));
i += 3;
break;
default:
throw new StreamCorruptedException(MessageFormat.format(
BCText.get().sexprStringInvalidEscape,
Integer.toHexString(b & 0xFF)));
}
}
return Arrays.copyOf(out, j);
}
/**
* Extracts the key from a GPG name-value-pair key file.
* <p>
* Package-visible for tests only.
* </p>
*
* @param in
* {@link InputStream} to read from; should be buffered
* @return the raw key data as extracted from the file
* @throws IOException
* if the {@code in} stream cannot be read or does not contain a
* key
*/
static byte[] keyFromNameValueFormat(InputStream in) throws IOException {
// It would be nice if we could use RawParseUtils here, but GPG compares
// names case-insensitively. We're only interested in the "Key:"
// name-value pair.
int[] nameLow = { 'k', 'e', 'y', ':' };
int[] nameCap = { 'K', 'E', 'Y', ':' };
int nameIdx = 0;
for (;;) {
int next = in.read();
if (next < 0) {
throw new EOFException();
}
if (next == '\n') {
nameIdx = 0;
} else if (nameIdx >= 0) {
if (nameLow[nameIdx] == next || nameCap[nameIdx] == next) {
nameIdx++;
if (nameIdx == nameLow.length) {
break;
}
} else {
nameIdx = -1;
}
}
}
// We're after "Key:". Read the value as continuation lines.
int last = ':';
byte[] rawData;
try (ByteArrayOutputStream out = new ByteArrayOutputStream(8192)) {
for (;;) {
int next = in.read();
if (next < 0) {
break;
}
if (last == '\n') {
if (next == ' ' || next == '\t') {
// Continuation line; skip this whitespace
last = next;
continue;
}
break; // Not a continuation line
}
out.write(next);
last = next;
}
rawData = out.toByteArray();
}
// GPG trims off trailing whitespace, and a line having only whitespace
// is a single LF.
try (ByteArrayOutputStream out = new ByteArrayOutputStream(
rawData.length)) {
int lineStart = 0;
boolean trimLeading = true;
while (lineStart < rawData.length) {
int nextLineStart = RawParseUtils.nextLF(rawData, lineStart);
if (trimLeading) {
while (lineStart < nextLineStart
&& isGpgSpace(rawData[lineStart])) {
lineStart++;
}
}
// Trim trailing
int i = nextLineStart - 1;
while (lineStart < i && isGpgSpace(rawData[i])) {
i--;
}
if (i <= lineStart) {
// Empty line signifies LF
out.write('\n');
trimLeading = true;
} else {
out.write(rawData, lineStart, i - lineStart + 1);
trimLeading = false;
}
lineStart = nextLineStart;
}
return out.toByteArray();
}
}
private static boolean isGpgSpace(int ch) {
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
}
private static boolean isTokenChar(int ch) {
switch (ch) {
case '-':
case '.':
case '/':
case '_':
case ':':
case '*':
case '+':
case '=':
return true;
default:
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
|| (ch >= '0' && ch <= '9')) {
return true;
}
return false;
}
}
private static boolean isHex(int ch) {
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')
|| (ch >= 'a' && ch <= 'f');
}
private static boolean isOctal(int ch) {
return (ch >= '0' && ch <= '7');
}
private static int nibble(int ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
} else if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
}
return -1;
}
}

View File

@ -20,7 +20,7 @@
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
import org.eclipse.jgit.internal.storage.file.PackFile;
import org.eclipse.jgit.internal.storage.file.Pack;
import org.eclipse.jgit.lib.ObjectDatabase;
/** Sends the current list of pack files, sorted most recent first. */
@ -38,7 +38,7 @@ private static String packList(HttpServletRequest req) {
final StringBuilder out = new StringBuilder();
final ObjectDatabase db = getRepository(req).getObjectDatabase();
if (db instanceof ObjectDirectory) {
for (PackFile pack : ((ObjectDirectory) db).getPacks()) {
for (Pack pack : ((ObjectDirectory) db).getPacks()) {
out.append("P ");
out.append(pack.getPackFile().getName());
out.append('\n');

View File

@ -8,28 +8,31 @@ Bundle-Localization: plugin
Bundle-Vendor: %Bundle-Vendor
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.apache.sshd.common;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)",
org.apache.sshd.common.file.virtualfs;version="[2.4.0,2.5.0)",
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)",
org.apache.sshd.common.io;version="[2.4.0,2.5.0)",
org.apache.sshd.common.kex;version="[2.4.0,2.5.0)",
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)",
org.apache.sshd.common.session;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.threads;version="[2.4.0,2.5.0)",
org.apache.sshd.server;version="[2.4.0,2.5.0)",
org.apache.sshd.server.auth;version="[2.4.0,2.5.0)",
org.apache.sshd.server.auth.gss;version="[2.4.0,2.5.0)",
org.apache.sshd.server.auth.keyboard;version="[2.4.0,2.5.0)",
org.apache.sshd.server.auth.password;version="[2.4.0,2.5.0)",
org.apache.sshd.server.command;version="[2.4.0,2.5.0)",
org.apache.sshd.server.session;version="[2.4.0,2.5.0)",
org.apache.sshd.server.shell;version="[2.4.0,2.5.0)",
org.apache.sshd.server.subsystem;version="[2.4.0,2.5.0)",
org.apache.sshd.server.subsystem.sftp;version="[2.4.0,2.5.0)",
Import-Package: org.apache.sshd.common;version="[2.6.0,2.7.0)",
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)",
org.apache.sshd.common.file.virtualfs;version="[2.6.0,2.7.0)",
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)",
org.apache.sshd.common.io;version="[2.6.0,2.7.0)",
org.apache.sshd.common.kex;version="[2.6.0,2.7.0)",
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)",
org.apache.sshd.common.session;version="[2.6.0,2.7.0)",
org.apache.sshd.common.signature;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.threads;version="[2.6.0,2.7.0)",
org.apache.sshd.core;version="[2.6.0,2.7.0)",
org.apache.sshd.server;version="[2.6.0,2.7.0)",
org.apache.sshd.server.auth;version="[2.6.0,2.7.0)",
org.apache.sshd.server.auth.gss;version="[2.6.0,2.7.0)",
org.apache.sshd.server.auth.keyboard;version="[2.6.0,2.7.0)",
org.apache.sshd.server.auth.password;version="[2.6.0,2.7.0)",
org.apache.sshd.server.command;version="[2.6.0,2.7.0)",
org.apache.sshd.server.session;version="[2.6.0,2.7.0)",
org.apache.sshd.server.shell;version="[2.6.0,2.7.0)",
org.apache.sshd.server.subsystem;version="[2.6.0,2.7.0)",
org.apache.sshd.sftp;version="[2.6.0,2.7.0)",
org.apache.sshd.sftp.server;version="[2.6.0,2.7.0)",
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)",
org.eclipse.jgit.api;version="[5.11.0,5.12.0)",
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)",

View File

@ -9,6 +9,9 @@
*/
package org.eclipse.jgit.junit.ssh;
import static org.apache.sshd.core.CoreModuleProperties.SERVER_EXTRA_IDENTIFICATION_LINES;
import static org.apache.sshd.core.CoreModuleProperties.SERVER_EXTRA_IDENT_LINES_SEPARATOR;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
@ -21,26 +24,28 @@
import java.security.PublicKey;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.signature.BuiltinSignatures;
import org.apache.sshd.common.signature.Signature;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.threads.CloseableExecutorService;
import org.apache.sshd.common.util.threads.ThreadUtils;
import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.ServerBuilder;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.UserAuth;
import org.apache.sshd.server.auth.UserAuthFactory;
@ -52,7 +57,7 @@
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.shell.UnknownCommand;
import org.apache.sshd.server.subsystem.SubsystemFactory;
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
import org.apache.sshd.sftp.server.SftpSubsystemFactory;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Repository;
@ -162,7 +167,9 @@ public SshTestGitServer(@NonNull String testUser,
this.testUser = testUser;
setTestUserPublicKey(testKey);
this.repository = repository;
server = SshServer.setUpDefaultServer();
ServerBuilder builder = ServerBuilder.builder()
.signatureFactories(getSignatureFactories());
server = builder.build();
hostKeys.add(hostKey);
server.setKeyPairProvider((session) -> hostKeys);
@ -187,6 +194,37 @@ public SshTestGitServer(@NonNull String testUser,
});
}
/**
* Apache MINA sshd 2.6.0 has removed DSA, DSA_CERT and RSA_CERT. We have to
* set it up explicitly to still allow users to connect with DSA keys.
*
* @return a list of supported signature factories
*/
@SuppressWarnings("deprecation")
private static List<NamedFactory<Signature>> getSignatureFactories() {
// @formatter:off
return Arrays.asList(
BuiltinSignatures.nistp256_cert,
BuiltinSignatures.nistp384_cert,
BuiltinSignatures.nistp521_cert,
BuiltinSignatures.ed25519_cert,
BuiltinSignatures.rsaSHA512_cert,
BuiltinSignatures.rsaSHA256_cert,
BuiltinSignatures.rsa_cert,
BuiltinSignatures.nistp256,
BuiltinSignatures.nistp384,
BuiltinSignatures.nistp521,
BuiltinSignatures.ed25519,
BuiltinSignatures.sk_ecdsa_sha2_nistp256,
BuiltinSignatures.sk_ssh_ed25519,
BuiltinSignatures.rsaSHA512,
BuiltinSignatures.rsaSHA256,
BuiltinSignatures.rsa,
BuiltinSignatures.dsa_cert,
BuiltinSignatures.dsa);
// @formatter:on
}
private static PublicKey readPublicKey(Path key)
throws IOException, GeneralSecurityException {
return AuthorizedKeyEntry.readAuthorizedKeys(key).get(0)
@ -278,14 +316,8 @@ public boolean validateInitialUser(ServerSession session,
@NonNull
protected List<SubsystemFactory> configureSubsystems() {
// SFTP.
server.setFileSystemFactory(new VirtualFileSystemFactory() {
@Override
protected Path computeRootDir(Session session) throws IOException {
return SshTestGitServer.this.repository.getDirectory()
.getParentFile().getAbsoluteFile().toPath();
}
});
server.setFileSystemFactory(new VirtualFileSystemFactory(repository
.getDirectory().getParentFile().getAbsoluteFile().toPath()));
return Collections
.singletonList((new SftpSubsystemFactory.Builder()).build());
}
@ -434,9 +466,8 @@ public void setTestUserPublicKey(@NonNull PublicKey key) {
*/
public void setPreamble(String... lines) {
if (lines != null && lines.length > 0) {
PropertyResolverUtils.updateProperty(this.server,
ServerFactoryManager.SERVER_EXTRA_IDENTIFICATION_LINES,
String.join("|", lines));
SERVER_EXTRA_IDENTIFICATION_LINES.set(server, String.join(
String.valueOf(SERVER_EXTRA_IDENT_LINES_SEPARATOR), lines));
}
}

View File

@ -9,10 +9,10 @@
*/
package org.eclipse.jgit.junit;
import static java.lang.ClassLoader.getSystemClassLoader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
@ -40,7 +40,13 @@ public SeparateClassloaderTestRunner(Class<?> klass)
private static Class<?> loadNewClass(Class<?> klass)
throws InitializationError {
try {
URL[] urls = ((URLClassLoader) getSystemClassLoader()).getURLs();
String pathSeparator = System.getProperty("path.separator");
String[] classPathEntries = System.getProperty("java.class.path")
.split(pathSeparator);
URL[] urls = new URL[classPathEntries.length];
for (int i = 0; i < classPathEntries.length; i++) {
urls[i] = Paths.get(classPathEntries[i]).toUri().toURL();
}
ClassLoader testClassLoader = new URLClassLoader(urls) {
@Override
@ -54,7 +60,7 @@ public Class<?> loadClass(String name)
}
};
return Class.forName(klass.getName(), true, testClassLoader);
} catch (ClassNotFoundException e) {
} catch (ClassNotFoundException | MalformedURLException e) {
throw new InitializationError(e);
}
}

View File

@ -43,7 +43,7 @@
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.internal.storage.file.LockFile;
import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
import org.eclipse.jgit.internal.storage.file.PackFile;
import org.eclipse.jgit.internal.storage.file.Pack;
import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry;
import org.eclipse.jgit.internal.storage.pack.PackWriter;
import org.eclipse.jgit.lib.AnyObjectId;
@ -773,7 +773,7 @@ protected void writeFile(String name, byte[] bin)
rw.writeInfoRefs();
final StringBuilder w = new StringBuilder();
for (PackFile p : fr.getObjectDatabase().getPacks()) {
for (Pack p : fr.getObjectDatabase().getPacks()) {
w.append("P ");
w.append(p.getPackFile().getName());
w.append('\n');
@ -954,7 +954,7 @@ public void close() {
}
private static void prunePacked(ObjectDirectory odb) throws IOException {
for (PackFile p : odb.getPacks()) {
for (Pack p : odb.getPacks()) {
for (MutableEntry e : p)
FileUtils.delete(odb.fileFor(e.toObjectId()));
}

View File

@ -241,6 +241,7 @@ public void testCompareToEquals() throws Exception {
}
@Test
@SuppressWarnings("SelfComparison")
public void testCompareToSame() throws Exception {
AnyLongObjectId id = LongObjectId.fromString(TEST_SHA256);
LfsPointer lfs = new LfsPointer(id, 4);

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.10" sequenceNumber="1610487371">
<target name="jgit-4.10" sequenceNumber="1613861945">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.10" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2018-12/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.11" sequenceNumber="1610487371">
<target name="jgit-4.11" sequenceNumber="1613862033">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.11" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2019-03/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.12" sequenceNumber="1610487371">
<target name="jgit-4.12" sequenceNumber="1613862033">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.12" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2019-06/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.13" sequenceNumber="1610487371">
<target name="jgit-4.13" sequenceNumber="1613862034">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.13" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2019-09/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.14" sequenceNumber="1610487371">
<target name="jgit-4.14" sequenceNumber="1613862030">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.14" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2019-12/201912181000/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.15" sequenceNumber="1610487371">
<target name="jgit-4.15" sequenceNumber="1613862030">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.15" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2020-03/202003181000/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.16" sequenceNumber="1610487371">
<target name="jgit-4.16" sequenceNumber="1613862033">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.16" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2020-06/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.17" sequenceNumber="1610487371">
<target name="jgit-4.17" sequenceNumber="1613862034">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.17" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2020-09/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.18" sequenceNumber="1610487371">
<target name="jgit-4.18" sequenceNumber="1613862034">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.18" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2020-12/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.19-staging" sequenceNumber="1610487085">
<target name="jgit-4.19-staging" sequenceNumber="1613862034">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.19-staging" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/staging/2021-03/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.6" sequenceNumber="1610487371">
<target name="jgit-4.6" sequenceNumber="1613862049">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.6" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/neon/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.7" sequenceNumber="1610487371">
<target name="jgit-4.7" sequenceNumber="1613862039">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.7" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/oxygen/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.8" sequenceNumber="1610487371">
<target name="jgit-4.8" sequenceNumber="1613862034">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.8" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/photon/" {
org.eclipse.osgi lazy

View File

@ -1,28 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.9" sequenceNumber="1610487371">
<target name="jgit-4.9" sequenceNumber="1613862033">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.35.v20201120"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.35.v20201120"/>
<repository id="jetty-9.4.30" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/"/>
<unit id="org.eclipse.jetty.client" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.36.v20210114"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.36.v20210114"/>
<repository id="jetty-9.4.36" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.6.v20201231-1626"/>
@ -49,16 +49,16 @@
<unit id="org.apache.commons.compress.source" version="1.19.0.v20200106-2343"/>
<unit id="org.apache.commons.logging" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.commons.logging.source" version="1.2.0.v20180409-1502"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.10.v20200830-2311"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.12.v20200108-1212"/>
<unit id="org.apache.httpcomponents.httpclient" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpclient.source" version="4.5.13.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.httpcomponents.httpcore.source" version="4.4.14.v20210128-2225"/>
<unit id="org.apache.log4j" version="1.2.15.v201012070815"/>
<unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/>
<unit id="org.apache.sshd.osgi" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.osgi.source" version="2.4.0.v20200318-1614"/>
<unit id="org.apache.sshd.sftp" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.sftp.source" version="2.4.0.v20200319-1547"/>
<unit id="org.apache.sshd.osgi" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.osgi.source" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp" version="2.6.0.v20210201-2003"/>
<unit id="org.apache.sshd.sftp.source" version="2.6.0.v20210201-2003"/>
<unit id="org.assertj" version="3.14.0.v20200120-1926"/>
<unit id="org.assertj.source" version="3.14.0.v20200120-1926"/>
<unit id="org.bouncycastle.bcpg" version="1.65.0.v20200527-1955"/>
@ -86,7 +86,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.8.0.v20180207-1613"/>
<unit id="org.tukaani.xz.source" version="1.8.0.v20180207-1613"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>

View File

@ -1,7 +1,7 @@
target "jgit-4.9" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/S20210105214148.tpd"
include "orbit/S20210216215844.tpd"
location "https://download.eclipse.org/releases/2018-09/" {
org.eclipse.osgi lazy

View File

@ -1,7 +1,7 @@
target "S20210105214148" with source configurePhase
target "S20210216215844" with source configurePhase
// see https://download.eclipse.org/tools/orbit/downloads/
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210105214148/repository" {
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20210216215844/repository" {
com.google.gson [2.8.6.v20201231-1626,2.8.6.v20201231-1626]
com.google.gson.source [2.8.6.v20201231-1626,2.8.6.v20201231-1626]
com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
@ -26,16 +26,16 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/S202101052141
org.apache.commons.compress.source [1.19.0.v20200106-2343,1.19.0.v20200106-2343]
org.apache.commons.logging [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
org.apache.commons.logging.source [1.2.0.v20180409-1502,1.2.0.v20180409-1502]
org.apache.httpcomponents.httpclient [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
org.apache.httpcomponents.httpclient.source [4.5.10.v20200830-2311,4.5.10.v20200830-2311]
org.apache.httpcomponents.httpcore [4.4.12.v20200108-1212,4.4.12.v20200108-1212]
org.apache.httpcomponents.httpcore.source [4.4.12.v20200108-1212,4.4.12.v20200108-1212]
org.apache.httpcomponents.httpclient [4.5.13.v20210128-2225,4.5.13.v20210128-2225]
org.apache.httpcomponents.httpclient.source [4.5.13.v20210128-2225,4.5.13.v20210128-2225]
org.apache.httpcomponents.httpcore [4.4.14.v20210128-2225,4.4.14.v20210128-2225]
org.apache.httpcomponents.httpcore.source [4.4.14.v20210128-2225,4.4.14.v20210128-2225]
org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815]
org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815]
org.apache.sshd.osgi [2.4.0.v20200318-1614,2.4.0.v20200318-1614]
org.apache.sshd.osgi.source [2.4.0.v20200318-1614,2.4.0.v20200318-1614]
org.apache.sshd.sftp [2.4.0.v20200319-1547,2.4.0.v20200319-1547]
org.apache.sshd.sftp.source [2.4.0.v20200319-1547,2.4.0.v20200319-1547]
org.apache.sshd.osgi [2.6.0.v20210201-2003,2.6.0.v20210201-2003]
org.apache.sshd.osgi.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003]
org.apache.sshd.sftp [2.6.0.v20210201-2003,2.6.0.v20210201-2003]
org.apache.sshd.sftp.source [2.6.0.v20210201-2003,2.6.0.v20210201-2003]
org.assertj [3.14.0.v20200120-1926,3.14.0.v20200120-1926]
org.assertj.source [3.14.0.v20200120-1926,3.14.0.v20200120-1926]
org.bouncycastle.bcpg [1.65.0.v20200527-1955,1.65.0.v20200527-1955]

View File

@ -1,22 +1,22 @@
target "jetty-9.4.x" with source configurePhase
location jetty-9.4.30 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.35.v20201120/" {
org.eclipse.jetty.client [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.client.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.continuation [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.continuation.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.http [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.http.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.io [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.io.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.security [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.security.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.server [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.server.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.servlet [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.servlet.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.util [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.util.source [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.util.ajax [9.4.35.v20201120,9.4.35.v20201120]
org.eclipse.jetty.util.ajax.source [9.4.35.v20201120,9.4.35.v20201120]
location jetty-9.4.36 "https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.36.v20210114/" {
org.eclipse.jetty.client [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.client.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.continuation [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.continuation.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.http [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.http.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.io [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.io.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.security [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.security.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.server [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.server.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.servlet [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.servlet.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.util [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.util.source [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.util.ajax [9.4.36.v20210114,9.4.36.v20210114]
org.eclipse.jetty.util.ajax.source [9.4.36.v20210114,9.4.36.v20210114]
}

View File

@ -11,7 +11,9 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import java.io.File;
@ -25,6 +27,7 @@
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.transport.RefSpec;
@ -64,6 +67,45 @@ public void testClone() throws Exception {
assertEquals("expected 1 branch", 1, branches.size());
}
@Test
public void testCloneInitialBranch() throws Exception {
createInitialCommit();
File gitDir = db.getDirectory();
String sourceURI = gitDir.toURI().toString();
File target = createTempDirectory("target");
String cmd = "git clone --branch master " + sourceURI + " "
+ shellQuote(target.getPath());
String[] result = execute(cmd);
assertArrayEquals(new String[] {
"Cloning into '" + target.getPath() + "'...", "", "" }, result);
Git git2 = Git.open(target);
List<Ref> branches = git2.branchList().call();
assertEquals("expected 1 branch", 1, branches.size());
Repository db2 = git2.getRepository();
ObjectId head = db2.resolve("HEAD");
assertNotNull(head);
assertNotEquals(ObjectId.zeroId(), head);
ObjectId master = db2.resolve("master");
assertEquals(head, master);
}
@Test
public void testCloneInitialBranchMissing() throws Exception {
createInitialCommit();
File gitDir = db.getDirectory();
String sourceURI = gitDir.toURI().toString();
File target = createTempDirectory("target");
String cmd = "git clone --branch foo " + sourceURI + " "
+ shellQuote(target.getPath());
Die e = assertThrows(Die.class, () -> execute(cmd));
assertEquals("Remote branch 'foo' not found in upstream origin",
e.getMessage());
}
private RevCommit createInitialCommit() throws Exception {
JGitTestUtil.writeTrashFile(db, "hello.txt", "world");
git.add().addFilepattern("hello.txt").call();

View File

@ -11,11 +11,14 @@
package org.eclipse.jgit.pgm;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import java.io.File;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@ -54,4 +57,22 @@ public void testInitDirectory() throws Exception {
assertArrayEquals(expecteds, result);
}
@Test
public void testInitDirectoryInitialBranch() throws Exception {
File workDirectory = tempFolder.getRoot();
File gitDirectory = new File(workDirectory, Constants.DOT_GIT);
String[] result = execute(
"git init -b main '" + workDirectory.getCanonicalPath() + "'");
String[] expecteds = new String[] {
"Initialized empty Git repository in "
+ gitDirectory.getCanonicalPath(),
"" };
assertArrayEquals(expecteds, result);
try (Repository repo = new FileRepository(gitDirectory)) {
assertEquals("refs/heads/main", repo.getFullBranch());
}
}
}

View File

@ -77,14 +77,15 @@ invalidHttpProxyOnlyHttpSupported=Invalid http_proxy: {0}: Only http supported.
invalidRecurseSubmodulesMode=Invalid recurse submodules mode: {0}
invalidUntrackedFilesMode=Invalid untracked files mode ''{0}''
jgitVersion=jgit version {0}
lineFormat={0}
listeningOn=Listening on {0}
lfsNoAccessKey=No accessKey in {0}
lfsNoSecretKey=No secretKey in {0}
lfsProtocolUrl=LFS protocol URL: {0}
lfsStoreDirectory=LFS objects stored in: {0}
lfsStoreUrl=LFS store URL: {0}
lfsUnknownStoreType="Unknown LFS store type: {0}"
lineFormat={0}
listeningOn=Listening on {0}
logNoSignatureVerifier="No signature verifier available"
mergeConflict=CONFLICT(content): Merge conflict in {0}
mergeCheckoutConflict=error: Your local changes to the following files would be overwritten by merge:
mergeFailed=Automatic merge failed; fix conflicts and then commit the result
@ -411,6 +412,7 @@ usage_show=Display one commit
usage_showRefNamesMatchingCommits=Show ref names matching commits
usage_showPatch=display patch
usage_showNotes=Add this ref to the list of note branches from which notes are displayed
usage_showSignature=Verify signatures of signed commits in the log
usage_showTimeInMilliseconds=Show mtime in milliseconds
usage_squash=Squash commits as if a real merge happened, but do not make a commit or move the HEAD.
usage_srcPrefix=show the source prefix instead of "a/"
@ -424,11 +426,13 @@ usage_tagLocalUser=create a signed annotated tag using the specified GPG key ID
usage_tagMessage=create an annotated tag with the given message, unsigned unless -s or -u are given, or config tag.gpgSign is true, or tar.forceSignAnnotated is true and -a is not given
usage_tagSign=create a signed annotated tag
usage_tagNoSign=suppress signing the tag
usage_tagVerify=Verify the GPG signature
usage_untrackedFilesMode=show untracked files
usage_updateRef=reference to update
usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository
usage_useNameInsteadOfOriginToTrackUpstream=use <name> instead of 'origin' to track upstream
usage_checkoutBranchAfterClone=check out named branch instead of remote's HEAD
usage_initialBranch=initial branch of the newly created repository (default 'master', can be configured via config option init.defaultBranch)
usage_viewCommitHistory=View commit history
usage_orphan=Create a new orphan branch. The first commit made on this new branch will have no parents and it will be the root of a new history totally disconnected from other branches and commits.
usernameFor=Username for {0}:

View File

@ -18,6 +18,7 @@
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.TextProgressMonitor;
@ -110,6 +111,8 @@ protected void run() throws Exception {
db = command.call().getRepository();
if (msgs && db.resolve(Constants.HEAD) == null)
outw.println(CLIText.get().clonedEmptyRepository);
} catch (TransportException e) {
throw die(e.getMessage(), e);
} catch (InvalidRemoteException e) {
throw die(MessageFormat.format(CLIText.get().doesNotExist,
sourceUri), e);

View File

@ -24,6 +24,7 @@
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.util.StringUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@ -32,6 +33,10 @@ class Init extends TextBuiltin {
@Option(name = "--bare", usage = "usage_CreateABareRepository")
private boolean bare;
@Option(name = "--initial-branch", aliases = { "-b" },
metaVar = "metaVar_branchName", usage = "usage_initialBranch")
private String branch;
@Argument(index = 0, metaVar = "metaVar_directory")
private String directory;
@ -54,6 +59,9 @@ protected void run() {
}
Repository repository;
try {
if (!StringUtils.isEmptyOrNull(branch)) {
command.setInitialBranch(branch);
}
repository = command.call().getRepository();
outw.println(MessageFormat.format(
CLIText.get().initializedEmptyGitRepositoryIn,

View File

@ -1,7 +1,7 @@
/*
* Copyright (C) 2010, Google Inc.
* Copyright (C) 2006-2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
* Copyright (C) 2006, 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, 2021, Shawn O. Pearce <spearce@spearce.org> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@ -31,12 +31,17 @@
import org.eclipse.jgit.errors.LargeObjectException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.GpgConfig;
import org.eclipse.jgit.lib.GpgSignatureVerifier;
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification;
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.internal.VerificationUtils;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.util.GitDateFormatter;
@ -68,6 +73,9 @@ void addAdditionalNoteRef(String notesRef) {
additionalNoteRefs.add(notesRef);
}
@Option(name = "--show-signature", usage = "usage_showSignature")
private boolean showSignature;
@Option(name = "--date", usage = "usage_date")
void dateFormat(String date) {
if (date.toLowerCase(Locale.ROOT).equals(date))
@ -147,6 +155,10 @@ void noPrefix(@SuppressWarnings("unused") boolean on) {
// END -- Options shared with Diff
private GpgSignatureVerifier verifier;
private GpgConfig config;
Log() {
dateFormatter = new GitDateFormatter(Format.DEFAULT);
}
@ -161,6 +173,7 @@ protected void init(Repository repository, String gitDir) {
/** {@inheritDoc} */
@Override
protected void run() {
config = new GpgConfig(db.getConfig());
diffFmt.setRepository(db);
try {
diffFmt.setPathFilter(pathFilter);
@ -197,6 +210,9 @@ protected void run() {
throw die(e.getMessage(), e);
} finally {
diffFmt.close();
if (verifier != null) {
verifier.clear();
}
}
}
@ -229,6 +245,9 @@ protected void show(RevCommit c) throws Exception {
}
outw.println();
if (showSignature) {
showSignature(c);
}
final PersonIdent author = c.getAuthorIdent();
outw.println(MessageFormat.format(CLIText.get().authorInfo, author.getName(), author.getEmailAddress()));
outw.println(MessageFormat.format(CLIText.get().dateInfo,
@ -252,6 +271,27 @@ protected void show(RevCommit c) throws Exception {
outw.flush();
}
private void showSignature(RevCommit c) throws IOException {
if (c.getRawGpgSignature() == null) {
return;
}
if (verifier == null) {
GpgSignatureVerifierFactory factory = GpgSignatureVerifierFactory
.getDefault();
if (factory == null) {
throw die(CLIText.get().logNoSignatureVerifier, null);
}
verifier = factory.getVerifier();
}
SignatureVerification verification = verifier.verifySignature(c,
config);
if (verification == null) {
return;
}
VerificationUtils.writeVerification(outw, verification,
verifier.getName(), c.getCommitterIdent());
}
/**
* @param c
* @return <code>true</code> if at least one note was printed,

View File

@ -29,10 +29,15 @@
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.GpgConfig;
import org.eclipse.jgit.lib.GpgSignatureVerifier;
import org.eclipse.jgit.lib.GpgSignatureVerifierFactory;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.internal.VerificationUtils;
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
@ -59,6 +64,9 @@ class Show extends TextBuiltin {
@Option(name = "--", metaVar = "metaVar_path", handler = PathTreeFilterHandler.class)
protected TreeFilter pathFilter = TreeFilter.ALL;
@Option(name = "--show-signature", usage = "usage_showSignature")
private boolean showSignature;
// BEGIN -- Options shared with Diff
@Option(name = "-p", usage = "usage_showPatch")
boolean showPatch;
@ -220,13 +228,16 @@ private void show(RevTag tag) throws IOException {
}
outw.println();
String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$
for (String s : lines) {
outw.println(s);
String fullMessage = tag.getFullMessage();
if (!fullMessage.isEmpty()) {
String[] lines = tag.getFullMessage().split("\n"); //$NON-NLS-1$
for (String s : lines) {
outw.println(s);
}
}
byte[] rawSignature = tag.getRawGpgSignature();
if (rawSignature != null) {
lines = RawParseUtils.decode(rawSignature).split("\n"); //$NON-NLS-1$
String[] lines = RawParseUtils.decode(rawSignature).split("\n"); //$NON-NLS-1$
for (String s : lines) {
outw.println(s);
}
@ -258,6 +269,10 @@ private void show(RevWalk rw, RevCommit c) throws IOException {
c.getId().copyTo(outbuffer, outw);
outw.println();
if (showSignature) {
showSignature(c);
}
final PersonIdent author = c.getAuthorIdent();
outw.println(MessageFormat.format(CLIText.get().authorInfo,
author.getName(), author.getEmailAddress()));
@ -296,4 +311,28 @@ private void showDiff(RevCommit c) throws IOException {
}
outw.println();
}
private void showSignature(RevCommit c) throws IOException {
if (c.getRawGpgSignature() == null) {
return;
}
GpgSignatureVerifierFactory factory = GpgSignatureVerifierFactory
.getDefault();
if (factory == null) {
throw die(CLIText.get().logNoSignatureVerifier, null);
}
GpgSignatureVerifier verifier = factory.getVerifier();
GpgConfig config = new GpgConfig(db.getConfig());
try {
SignatureVerification verification = verifier.verifySignature(c,
config);
if (verification == null) {
return;
}
VerificationUtils.writeVerification(outw, verification,
verifier.getName(), c.getCommitterIdent());
} finally {
verifier.clear();
}
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2008, Charles O'Farrell <charleso@charleso.org>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg.lists@dewire.com>
* Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, 2020 Shawn O. Pearce <spearce@spearce.org> and others
* Copyright (C) 2008, 2021 Shawn O. Pearce <spearce@spearce.org> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@ -22,43 +22,60 @@
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.ListTagCommand;
import org.eclipse.jgit.api.TagCommand;
import org.eclipse.jgit.api.VerificationResult;
import org.eclipse.jgit.api.VerifySignatureCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.internal.VerificationUtils;
import org.eclipse.jgit.revwalk.RevTag;
import org.eclipse.jgit.revwalk.RevWalk;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@Command(common = true, usage = "usage_CreateATag")
class Tag extends TextBuiltin {
@Option(name = "-f", usage = "usage_forceReplacingAnExistingTag")
@Option(name = "--force", aliases = { "-f" }, forbids = { "--delete",
"--verify" }, usage = "usage_forceReplacingAnExistingTag")
private boolean force;
@Option(name = "-d", usage = "usage_tagDelete")
@Option(name = "--delete", aliases = { "-d" }, forbids = {
"--verify" }, usage = "usage_tagDelete")
private boolean delete;
@Option(name = "--annotate", aliases = {
"-a" }, usage = "usage_tagAnnotated")
"-a" }, forbids = { "--delete",
"--verify" }, usage = "usage_tagAnnotated")
private boolean annotated;
@Option(name = "-m", metaVar = "metaVar_message", usage = "usage_tagMessage")
@Option(name = "-m", forbids = { "--delete",
"--verify" }, metaVar = "metaVar_message", usage = "usage_tagMessage")
private String message;
@Option(name = "--sign", aliases = { "-s" }, forbids = {
"--no-sign" }, usage = "usage_tagSign")
"--no-sign", "--delete", "--verify" }, usage = "usage_tagSign")
private boolean sign;
@Option(name = "--no-sign", usage = "usage_tagNoSign", forbids = {
"--sign" })
"--sign", "--delete", "--verify" })
private boolean noSign;
@Option(name = "--local-user", aliases = {
"-u" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser")
"-u" }, forbids = { "--delete",
"--verify" }, metaVar = "metaVar_tagLocalUser", usage = "usage_tagLocalUser")
private String gpgKeyId;
@Option(name = "--verify", aliases = { "-v" }, forbids = { "--delete",
"--force", "--annotate", "-m", "--sign", "--no-sign",
"--local-user" }, usage = "usage_tagVerify")
private boolean verify;
@Argument(index = 0, metaVar = "metaVar_name")
private String tagName;
@ -70,7 +87,25 @@ class Tag extends TextBuiltin {
protected void run() {
try (Git git = new Git(db)) {
if (tagName != null) {
if (delete) {
if (verify) {
VerifySignatureCommand verifySig = git.verifySignature()
.setMode(VerifySignatureCommand.VerifyMode.TAGS)
.addName(tagName);
VerificationResult verification = verifySig.call()
.get(tagName);
if (verification == null) {
showUnsigned(git, tagName);
} else {
Throwable error = verification.getException();
if (error != null) {
throw die(error.getMessage(), error);
}
writeVerification(verifySig.getVerifier().getName(),
(RevTag) verification.getObject(),
verification.getVerification());
}
} else if (delete) {
List<String> deletedTags = git.tagDelete().setTags(tagName)
.call();
if (deletedTags.isEmpty()) {
@ -116,4 +151,36 @@ protected void run() {
throw die(e.getMessage(), e);
}
}
private void showUnsigned(Git git, String wantedTag) throws IOException {
ObjectId id = git.getRepository().resolve(wantedTag);
if (id != null && !ObjectId.zeroId().equals(id)) {
try (RevWalk walk = new RevWalk(git.getRepository())) {
showTag(walk.parseTag(id));
}
} else {
throw die(
MessageFormat.format(CLIText.get().tagNotFound, wantedTag));
}
}
private void showTag(RevTag tag) throws IOException {
outw.println("object " + tag.getObject().name()); //$NON-NLS-1$
outw.println("type " + Constants.typeString(tag.getObject().getType())); //$NON-NLS-1$
outw.println("tag " + tag.getTagName()); //$NON-NLS-1$
outw.println("tagger " + tag.getTaggerIdent().toExternalString()); //$NON-NLS-1$
outw.println();
outw.print(tag.getFullMessage());
}
private void writeVerification(String name, RevTag tag,
SignatureVerification verification) throws IOException {
showTag(tag);
if (verification == null) {
outw.println();
return;
}
VerificationUtils.writeVerification(outw, verification, name,
tag.getTaggerIdent());
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (C) 2010, 2013 Sasa Zivkov <sasa.zivkov@sap.com>
* Copyright (C) 2013, Obeo and others
* Copyright (C) 2013, 2021 Obeo and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@ -163,6 +163,7 @@ public static String fatalError(String message) {
/***/ public String lfsUnknownStoreType;
/***/ public String lineFormat;
/***/ public String listeningOn;
/***/ public String logNoSignatureVerifier;
/***/ public String mergeCheckoutConflict;
/***/ public String mergeConflict;
/***/ public String mergeFailed;

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.pgm.internal;
import java.io.IOException;
import org.eclipse.jgit.lib.GpgSignatureVerifier.SignatureVerification;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.util.GitDateFormatter;
import org.eclipse.jgit.util.SignatureUtils;
import org.eclipse.jgit.util.io.ThrowingPrintWriter;
/**
* Utilities for signature verification.
*/
public final class VerificationUtils {
private VerificationUtils() {
// No instantiation
}
/**
* Writes information about a signature verification to the given writer.
*
* @param out
* to write to
* @param verification
* to show
* @param name
* of the verifier used
* @param creator
* of the object verified; used for time zone information
* @throws IOException
* if writing fails
*/
public static void writeVerification(ThrowingPrintWriter out,
SignatureVerification verification, String name,
PersonIdent creator) throws IOException {
String[] text = SignatureUtils
.toString(verification, creator,
new GitDateFormatter(GitDateFormatter.Format.LOCALE))
.split("\n"); //$NON-NLS-1$
for (String line : text) {
out.print(name);
out.print(": "); //$NON-NLS-1$
out.println(line);
}
}
}

View File

@ -7,17 +7,18 @@ Bundle-Version: 5.11.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)",
org.apache.sshd.common;version="[2.4.0,2.5.0)",
org.apache.sshd.common.auth;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)",
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)",
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)",
org.apache.sshd.common.session;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
org.apache.sshd.server;version="[2.4.0,2.5.0)",
org.apache.sshd.server.forward;version="[2.4.0,2.5.0)",
Import-Package: org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)",
org.apache.sshd.common;version="[2.6.0,2.7.0)",
org.apache.sshd.common.auth;version="[2.6.0,2.7.0)",
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)",
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)",
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)",
org.apache.sshd.common.session;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)",
org.apache.sshd.core;version="[2.6.0,2.7.0)",
org.apache.sshd.server;version="[2.6.0,2.7.0)",
org.apache.sshd.server.forward;version="[2.6.0,2.7.0)",
org.eclipse.jgit.api;version="[5.11.0,5.12.0)",
org.eclipse.jgit.api.errors;version="[5.11.0,5.12.0)",
org.eclipse.jgit.internal.transport.sshd.proxy;version="[5.11.0,5.12.0)",

View File

@ -9,6 +9,7 @@
*/
package org.eclipse.jgit.transport.sshd;
import static org.apache.sshd.core.CoreModuleProperties.MAX_CONCURRENT_SESSIONS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@ -33,7 +34,6 @@
import org.apache.sshd.client.config.hosts.KnownHostEntry;
import org.apache.sshd.client.config.hosts.KnownHostHashValue;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.config.keys.PublicKeyEntry;
@ -41,7 +41,6 @@
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.forward.StaticDecisionForwardingFilter;
import org.eclipse.jgit.api.Git;
@ -216,8 +215,8 @@ public void testHugePreamble() throws Exception {
*/
@Test
public void testCloneAndFetchWithSessionLimit() throws Exception {
PropertyResolverUtils.updateProperty(server.getPropertyResolver(),
ServerFactoryManager.MAX_CONCURRENT_SESSIONS, 2);
MAX_CONCURRENT_SESSIONS
.set(server.getPropertyResolver(), Integer.valueOf(2));
File localClone = cloneWith("ssh://localhost/doesntmatter",
defaultCloneDir, null, //
"Host localhost", //

View File

@ -33,49 +33,51 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="5.11.0";x-inte
org.apache.sshd.client.session,
org.apache.sshd.client.keyverifier"
Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
org.apache.sshd.agent;version="[2.4.0,2.5.0)",
org.apache.sshd.client;version="[2.4.0,2.5.0)",
org.apache.sshd.client.auth;version="[2.4.0,2.5.0)",
org.apache.sshd.client.auth.keyboard;version="[2.4.0,2.5.0)",
org.apache.sshd.client.auth.password;version="[2.4.0,2.5.0)",
org.apache.sshd.client.auth.pubkey;version="[2.4.0,2.5.0)",
org.apache.sshd.client.channel;version="[2.4.0,2.5.0)",
org.apache.sshd.client.config.hosts;version="[2.4.0,2.5.0)",
org.apache.sshd.client.config.keys;version="[2.4.0,2.5.0)",
org.apache.sshd.client.future;version="[2.4.0,2.5.0)",
org.apache.sshd.client.keyverifier;version="[2.4.0,2.5.0)",
org.apache.sshd.client.session;version="[2.4.0,2.5.0)",
org.apache.sshd.client.session.forward;version="[2.4.0,2.5.0)",
org.apache.sshd.client.subsystem.sftp;version="[2.4.0,2.5.0)",
org.apache.sshd.common;version="[2.4.0,2.5.0)",
org.apache.sshd.common.auth;version="[2.4.0,2.5.0)",
org.apache.sshd.common.channel;version="[2.4.0,2.5.0)",
org.apache.sshd.common.compression;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys.loader;version="[2.4.0,2.5.0)",
org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.4.0,2.5.0)",
org.apache.sshd.common.digest;version="[2.4.0,2.5.0)",
org.apache.sshd.common.forward;version="[2.4.0,2.5.0)",
org.apache.sshd.common.future;version="[2.4.0,2.5.0)",
org.apache.sshd.common.helpers;version="[2.4.0,2.5.0)",
org.apache.sshd.common.io;version="[2.4.0,2.5.0)",
org.apache.sshd.common.kex;version="[2.4.0,2.5.0)",
org.apache.sshd.common.keyprovider;version="[2.4.0,2.5.0)",
org.apache.sshd.common.mac;version="[2.4.0,2.5.0)",
org.apache.sshd.common.random;version="[2.4.0,2.5.0)",
org.apache.sshd.common.session;version="[2.4.0,2.5.0)",
org.apache.sshd.common.session.helpers;version="[2.4.0,2.5.0)",
org.apache.sshd.common.signature;version="[2.4.0,2.5.0)",
org.apache.sshd.common.subsystem.sftp;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.buffer;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.closeable;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.io;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.io.resource;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.logging;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.net;version="[2.4.0,2.5.0)",
org.apache.sshd.common.util.security;version="[2.4.0,2.5.0)",
org.apache.sshd.server.auth;version="[2.4.0,2.5.0)",
org.apache.sshd.agent;version="[2.6.0,2.7.0)",
org.apache.sshd.client;version="[2.6.0,2.7.0)",
org.apache.sshd.client.auth;version="[2.6.0,2.7.0)",
org.apache.sshd.client.auth.keyboard;version="[2.6.0,2.7.0)",
org.apache.sshd.client.auth.password;version="[2.6.0,2.7.0)",
org.apache.sshd.client.auth.pubkey;version="[2.6.0,2.7.0)",
org.apache.sshd.client.channel;version="[2.6.0,2.7.0)",
org.apache.sshd.client.config.hosts;version="[2.6.0,2.7.0)",
org.apache.sshd.client.config.keys;version="[2.6.0,2.7.0)",
org.apache.sshd.client.future;version="[2.6.0,2.7.0)",
org.apache.sshd.client.keyverifier;version="[2.6.0,2.7.0)",
org.apache.sshd.client.session;version="[2.6.0,2.7.0)",
org.apache.sshd.client.session.forward;version="[2.6.0,2.7.0)",
org.apache.sshd.common;version="[2.6.0,2.7.0)",
org.apache.sshd.common.auth;version="[2.6.0,2.7.0)",
org.apache.sshd.common.channel;version="[2.6.0,2.7.0)",
org.apache.sshd.common.compression;version="[2.6.0,2.7.0)",
org.apache.sshd.common.config.keys;version="[2.6.0,2.7.0)",
org.apache.sshd.common.config.keys.loader;version="[2.6.0,2.7.0)",
org.apache.sshd.common.config.keys.loader.openssh.kdf;version="[2.6.0,2.7.0)",
org.apache.sshd.common.digest;version="[2.6.0,2.7.0)",
org.apache.sshd.common.forward;version="[2.6.0,2.7.0)",
org.apache.sshd.common.future;version="[2.6.0,2.7.0)",
org.apache.sshd.common.helpers;version="[2.6.0,2.7.0)",
org.apache.sshd.common.io;version="[2.6.0,2.7.0)",
org.apache.sshd.common.kex;version="[2.6.0,2.7.0)",
org.apache.sshd.common.keyprovider;version="[2.6.0,2.7.0)",
org.apache.sshd.common.mac;version="[2.6.0,2.7.0)",
org.apache.sshd.common.random;version="[2.6.0,2.7.0)",
org.apache.sshd.common.session;version="[2.6.0,2.7.0)",
org.apache.sshd.common.session.helpers;version="[2.6.0,2.7.0)",
org.apache.sshd.common.signature;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.buffer;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.closeable;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.io;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.io.resource;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.logging;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.net;version="[2.6.0,2.7.0)",
org.apache.sshd.common.util.security;version="[2.6.0,2.7.0)",
org.apache.sshd.core;version="[2.6.0,2.7.0)",
org.apache.sshd.server.auth;version="[2.6.0,2.7.0)",
org.apache.sshd.sftp;version="[2.6.0,2.7.0)",
org.apache.sshd.sftp.client;version="[2.6.0,2.7.0)",
org.apache.sshd.sftp.common;version="[2.6.0,2.7.0)",
org.eclipse.jgit.annotations;version="[5.11.0,5.12.0)",
org.eclipse.jgit.errors;version="[5.11.0,5.12.0)",
org.eclipse.jgit.fnmatch;version="[5.11.0,5.12.0)",

View File

@ -10,6 +10,7 @@
package org.eclipse.jgit.internal.transport.sshd;
import static java.text.MessageFormat.format;
import static org.apache.sshd.core.CoreModuleProperties.MAX_IDENTIFICATION_SIZE;
import java.io.IOException;
import java.io.StreamCorruptedException;
@ -29,19 +30,14 @@
import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.future.AuthFuture;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientSessionImpl;
import org.apache.sshd.client.session.ClientUserAuthService;
import org.apache.sshd.common.AttributeRepository;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexState;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.buffer.Buffer;
import org.eclipse.jgit.errors.InvalidPatternException;
@ -66,7 +62,8 @@ public class JGitClientSession extends ClientSessionImpl {
* protocol version exchange. 64kb is what OpenSSH < 8.0 read; OpenSSH 8.0
* changed it to 8Mb, but that seems excessive for the purpose stated in RFC
* 4253. The Apache MINA sshd default in
* {@link FactoryManager#DEFAULT_MAX_IDENTIFICATION_SIZE} is 16kb.
* {@link org.apache.sshd.core.CoreModuleProperties#MAX_IDENTIFICATION_SIZE}
* is 16kb.
*/
private static final int DEFAULT_MAX_IDENTIFICATION_SIZE = 64 * 1024;
@ -76,17 +73,6 @@ public class JGitClientSession extends ClientSessionImpl {
private volatile StatefulProxyConnector proxyHandler;
/**
* Work-around for bug 565394 / SSHD-1050; remove when using sshd 2.6.0.
*/
private volatile AuthFuture authFuture;
/** Records exceptions before there is an authFuture. */
private List<Throwable> earlyErrors = new ArrayList<>();
/** Guards setting an earlyError and the authFuture together. */
private final Object errorLock = new Object();
/**
* @param manager
* @param session
@ -97,125 +83,6 @@ public JGitClientSession(ClientFactoryManager manager, IoSession session)
super(manager, session);
}
// BEGIN Work-around for bug 565394 / SSHD-1050
// Remove when using sshd 2.6.0.
@Override
public AuthFuture auth() throws IOException {
if (getUsername() == null) {
throw new IllegalStateException(
SshdText.get().sessionWithoutUsername);
}
ClientUserAuthService authService = getUserAuthService();
String serviceName = nextServiceName();
List<Throwable> errors = null;
AuthFuture future;
// Guard both getting early errors and setting authFuture
synchronized (errorLock) {
future = authService.auth(serviceName);
if (future == null) {
// Internal error; no translation.
throw new IllegalStateException(
"No auth future generated by service '" //$NON-NLS-1$
+ serviceName + '\'');
}
errors = earlyErrors;
earlyErrors = null;
authFuture = future;
}
if (errors != null && !errors.isEmpty()) {
Iterator<Throwable> iter = errors.iterator();
Throwable first = iter.next();
iter.forEachRemaining(t -> {
if (t != first && t != null) {
first.addSuppressed(t);
}
});
// Mark the future as having had an exception; just to be on the
// safe side. Actually, there shouldn't be anyone waiting on this
// future yet.
future.setException(first);
if (log.isDebugEnabled()) {
log.debug("auth({}) early exception type={}: {}", //$NON-NLS-1$
this, first.getClass().getSimpleName(),
first.getMessage());
}
if (first instanceof SshException) {
throw new SshException(
((SshException) first).getDisconnectCode(),
first.getMessage(), first);
}
throw new IOException(first.getMessage(), first);
}
return future;
}
@Override
protected void signalAuthFailure(AuthFuture future, Throwable t) {
signalAuthFailure(t);
}
private void signalAuthFailure(Throwable t) {
AuthFuture future = authFuture;
if (future == null) {
synchronized (errorLock) {
if (earlyErrors != null) {
earlyErrors.add(t);
}
future = authFuture;
}
}
if (future != null) {
future.setException(t);
}
if (log.isDebugEnabled()) {
boolean signalled = future != null && t == future.getException();
log.debug("signalAuthFailure({}) type={}, signalled={}: {}", this, //$NON-NLS-1$
t.getClass().getSimpleName(), Boolean.valueOf(signalled),
t.getMessage());
}
}
@Override
public void exceptionCaught(Throwable t) {
signalAuthFailure(t);
super.exceptionCaught(t);
}
@Override
protected void preClose() {
signalAuthFailure(
new SshException(SshdText.get().authenticationOnClosedSession));
super.preClose();
}
@Override
protected void handleDisconnect(int code, String msg, String lang,
Buffer buffer) throws Exception {
signalAuthFailure(new SshException(code, msg));
super.handleDisconnect(code, msg, lang, buffer);
}
@Override
protected <C extends Collection<ClientSessionEvent>> C updateCurrentSessionState(
C newState) {
if (closeFuture.isClosed()) {
newState.add(ClientSessionEvent.CLOSED);
}
if (isAuthenticated()) { // authFuture.isSuccess()
newState.add(ClientSessionEvent.AUTHED);
}
if (KexState.DONE.equals(getKexState())) {
AuthFuture future = authFuture;
if (future == null || future.isFailure()) {
newState.add(ClientSessionEvent.WAIT_AUTH);
}
}
return newState;
}
// END Work-around for bug 565394 / SSHD-1050
/**
* Retrieves the {@link HostConfigEntry} this session was created for.
*
@ -331,22 +198,6 @@ public void messageReceived(Readable buffer) throws Exception {
}
}
@Override
protected void checkKeys() throws SshException {
ServerKeyVerifier serverKeyVerifier = getServerKeyVerifier();
// The super implementation always uses
// getIoSession().getRemoteAddress(). In case of a proxy connection,
// that would be the address of the proxy!
SocketAddress remoteAddress = getConnectAddress();
PublicKey serverKey = getKex().getServerKey();
if (!serverKeyVerifier.verifyServerKey(this, remoteAddress,
serverKey)) {
throw new SshException(
org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
SshdText.get().kexServerKeyInvalid);
}
}
@Override
protected String resolveAvailableSignaturesProposal(
FactoryManager manager) {
@ -477,9 +328,15 @@ protected List<String> doReadIdentification(Buffer buffer, boolean server)
throw new IllegalStateException(
"doReadIdentification of client called with server=true"); //$NON-NLS-1$
}
int maxIdentSize = PropertyResolverUtils.getIntProperty(this,
FactoryManager.MAX_IDENTIFICATION_SIZE,
DEFAULT_MAX_IDENTIFICATION_SIZE);
Integer maxIdentLength = MAX_IDENTIFICATION_SIZE.get(this).orElse(null);
int maxIdentSize;
if (maxIdentLength == null || maxIdentLength
.intValue() < DEFAULT_MAX_IDENTIFICATION_SIZE) {
maxIdentSize = DEFAULT_MAX_IDENTIFICATION_SIZE;
MAX_IDENTIFICATION_SIZE.set(this, Integer.valueOf(maxIdentSize));
} else {
maxIdentSize = maxIdentLength.intValue();
}
int current = buffer.rpos();
int end = current + buffer.available();
if (current >= end) {

View File

@ -9,7 +9,8 @@
*/
package org.eclipse.jgit.internal.transport.sshd;
import org.apache.sshd.client.ClientAuthenticationManager;
import static org.apache.sshd.core.CoreModuleProperties.PASSWORD_PROMPTS;
import org.apache.sshd.client.auth.keyboard.UserInteraction;
import org.apache.sshd.client.auth.password.UserAuthPassword;
import org.apache.sshd.client.session.ClientSession;
@ -29,9 +30,7 @@ public class JGitPasswordAuthentication extends UserAuthPassword {
public void init(ClientSession session, String service) throws Exception {
super.init(session, service);
maxAttempts = Math.max(1,
session.getIntProperty(
ClientAuthenticationManager.PASSWORD_PROMPTS,
ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS));
PASSWORD_PROMPTS.getRequired(session).intValue());
attempts = 0;
}

Some files were not shown because too many files have changed in this diff Show More