Merge branch 'master' into stable-6.0

* master:
  Make BinaryBlobException stackless
  Typo fix in o.e.j.ssh.{jsch,apache}/README.md
  ssh: Handle "ProxyJump none" from SSH config file
  ssh: use a single SecureRandom instance for hashing hostnames
  OpenSshConfigFile: line comments and quoted strings
  OpenSshConfigFile: update token replacements
  Add missing .gitignore in o.e.j.ssh.apache.agent
  Upgrade plexus-compiler version to 2.9.0
  [sshd agent] Introduce ConnectorDescriptor
  Update version of last release defining the API baseline to 5.13.0
  Update Orbit to S20211108222137
  Update README
  Update jetty to 9.4.44.v20210927
  Simplify SshdFtpChannel
  [test] test OpenSshConfigFile directly, not via the JSch config
  sshd: add support for ssh-agent
  sshd: prepare for using an SSH agent
  [releng] bazel: Enable errorprone on o.e.j.ssh.apache
  [releng] Make the bazel build use Java 11
  Fix target platforms
  [doc] Add README and package-info to the SSH bundles
  Binary and CR-LF detection: lone CRs -> binary
  Factor out parsing git-style size numbers to StringUtils
  Make the buffer size for text/binary detection configurable

Change-Id: I5c78eeca3abfc3e0a659ed8a258c4e96e9469713
This commit is contained in:
Matthias Sohn 2021-11-17 01:44:52 +01:00
commit f684dc6f8b
117 changed files with 5225 additions and 561 deletions

1
BUILD
View File

@ -14,6 +14,7 @@ genrule(
"//org.eclipse.jgit.lfs.server:jgit-lfs-server",
"//org.eclipse.jgit.junit:junit",
"//org.eclipse.jgit.ssh.apache:ssh-apache",
"//org.eclipse.jgit.ssh.apache.agent:ssh-apache-agent",
"//org.eclipse.jgit.ssh.jsch:ssh-jsch",
],
outs = ["all.zip"],

View File

@ -56,9 +56,13 @@ The CI builds use Maven and run on [Jenkins](https://ci.eclipse.org/jgit/).
- __org.eclipse.jgit.ssh.apache__
Client support for the ssh protocol based on
Client support for the SSH protocol based on
[Apache Mina sshd](https://mina.apache.org/sshd-project/).
- __org.eclipse.jgit.ssh.apache.agent__
Optional support for SSH agents for org.eclipse.jgit.ssh.apache.
- __org.eclipse.jgit.ui__
Simple UI for displaying git log.
@ -83,7 +87,7 @@ __org.eclipse.jgit.junit.ssh__: Helpers for unit testing
- Only the timestamp of the index is used by JGit if the index is
dirty.
- JGit requires at least a Java 8 JDK.
- JGit 6.0 and newer requires at least Java 11. Older versions require at least Java 1.8.
- CRLF conversion is performed depending on the `core.autocrlf` setting,
however Git for Windows by default stores that setting during
@ -123,7 +127,7 @@ __org.eclipse.jgit.junit.ssh__: Helpers for unit testing
- Object transport
Fetch via ssh, git, http, Amazon S3 and bundles.
Push via ssh, git and Amazon S3. JGit does not yet deltify
Push via ssh, git, http, and Amazon S3. JGit does not yet deltify
the pushed packs so they may be a lot larger than C Git packs.
- Garbage collection
@ -145,9 +149,17 @@ __org.eclipse.jgit.junit.ssh__: Helpers for unit testing
There are some missing features:
- verifying signed commits
- signing tags
- signing push
- shallow and partial cloning
- support for remote helpers
- support for credential helpers
- support for multiple working trees (git-worktree)
- using external diff tools
- support for HTTPS client certificates
- SHA-256 object IDs
- git protocol V2 (client side): packfile-uris
- multi-pack index
- split index
## Support

View File

@ -105,8 +105,8 @@ maven_jar(
maven_jar(
name = "javaewah",
artifact = "com.googlecode.javaewah:JavaEWAH:1.1.12",
sha1 = "9feecc2b24d6bc9ff865af8d082f192238a293eb",
artifact = "com.googlecode.javaewah:JavaEWAH:1.1.13",
sha1 = "32cd724a42dc73f99ca08453d11a4bb83e0034c7",
)
maven_jar(
@ -133,6 +133,18 @@ maven_jar(
sha1 = "0c9eff7145e20b338c1dd6aca36ba93ed7c0147c",
)
maven_jar(
name = "jna",
artifact = "net.java.dev.jna:jna:5.8.0",
sha1 = "3551d8d827e54858214107541d3aff9c615cb615",
)
maven_jar(
name = "jna-platform",
artifact = "net.java.dev.jna:jna-platform:5.8.0",
sha1 = "2f12f6d7f7652270d13624cef1b82d8cd9a5398e",
)
maven_jar(
name = "commons-codec",
artifact = "commons-codec:commons-codec:1.14",
@ -165,8 +177,8 @@ maven_jar(
maven_jar(
name = "commons-compress",
artifact = "org.apache.commons:commons-compress:1.20",
sha1 = "b8df472b31e1f17c232d2ad78ceb1c84e00c641b",
artifact = "org.apache.commons:commons-compress:1.21",
sha1 = "4ec95b60d4e86b5c95a0e919cb172a0af98011ef",
)
maven_jar(
@ -183,8 +195,8 @@ maven_jar(
maven_jar(
name = "junit",
artifact = "junit:junit:4.13",
sha1 = "e49ccba652b735c93bd6e6f59760d8254cf597dd",
artifact = "junit:junit:4.13.2",
sha1 = "8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12",
)
maven_jar(
@ -227,59 +239,59 @@ maven_jar(
maven_jar(
name = "gson",
artifact = "com.google.code.gson:gson:2.8.7",
sha1 = "69d9503ea0a40ee16f0bcdac7e3eaf83d0fa914a",
artifact = "com.google.code.gson:gson:2.8.8",
sha1 = "431fc3cbc0ff81abdbfde070062741089c3ba874",
)
JETTY_VER = "9.4.43.v20210629"
JETTY_VER = "9.4.44.v20210927"
maven_jar(
name = "jetty-servlet",
artifact = "org.eclipse.jetty:jetty-servlet:" + JETTY_VER,
sha1 = "ee000c7dcdbe7b4ef94e3fa67be8f56a46915944",
src_sha1 = "50236764fe1d3619ca07f346e148189c4f5b801a",
sha1 = "1cb43a0d74b7395c7207dbf3dc2ca97eac89f5fd",
src_sha1 = "2bbc54fc1835c963744a4e82ba2541e94fcbcf9b",
)
maven_jar(
name = "jetty-security",
artifact = "org.eclipse.jetty:jetty-security:" + JETTY_VER,
sha1 = "ae1958da077c46bac61be9b8de2b45a3aa112353",
src_sha1 = "6e5271e91da37e381f566e0db07ab4d936d86104",
sha1 = "ecb80b8e008daa46e95e5691b2611d4007922497",
src_sha1 = "d67d4705a08d9b76592b3e177e2bb1aac968d832",
)
maven_jar(
name = "jetty-server",
artifact = "org.eclipse.jetty:jetty-server:" + JETTY_VER,
sha1 = "8ba04f6b5d00223983684a563a3edaa12282bcf0",
src_sha1 = "51600567dbd082fb03feeb9c786f5e7cc9e0a17d",
sha1 = "0bf2de0d31925a8ca71ad80f721236850b636e0d",
src_sha1 = "3582cbf081cf3652f6507093585c2a0f3b8738bb",
)
maven_jar(
name = "jetty-http",
artifact = "org.eclipse.jetty:jetty-http:" + JETTY_VER,
sha1 = "5171466337a6da7efbf317490b9c4574c0b4b640",
src_sha1 = "52f477161fd0fc90869f48a145aa2c86624c496e",
sha1 = "37f0e30cdc02128e40d095ad63cb18e10ecb7726",
src_sha1 = "7f1a6e3ab54e541f33b8ed100d553d4034d2e3a9",
)
maven_jar(
name = "jetty-io",
artifact = "org.eclipse.jetty:jetty-io:" + JETTY_VER,
sha1 = "acf672c64ac21851069c5b5b789e5c185a25933f",
src_sha1 = "824d5cffce7a72af7c11d9cd87f86184e2a05c17",
sha1 = "a2ec01e2b5552b777a3d7085163f80756ef8c1ce",
src_sha1 = "6262966b3cd10ff6b98f0bed428640bbbe4f7e79",
)
maven_jar(
name = "jetty-util",
artifact = "org.eclipse.jetty:jetty-util:" + JETTY_VER,
sha1 = "97306fd3c76171602caad2acc54ca779c9240d5f",
src_sha1 = "dffff7271c248d4e21e2b1629c57896b8e631051",
sha1 = "3c7151c5a04a93119988b48a1577a972d90f8990",
src_sha1 = "f7f0420221772bc63ebae21571bb9925ca971a82",
)
maven_jar(
name = "jetty-util-ajax",
artifact = "org.eclipse.jetty:jetty-util-ajax:" + JETTY_VER,
sha1 = "2500d180c6e8e28eb3b75372b6ea9d457cf37658",
src_sha1 = "682470f5ad074e64fc0e9c93bdc2784482f79362",
sha1 = "ed2f30e8eef939ab2825e607d83f82f85167e2c0",
src_sha1 = "1a48ae7a45683d20afb90784d1db314be2c73c92",
)
BOUNCYCASTLE_VER = "1.69"

View File

@ -76,6 +76,7 @@ java_library(
visibility = [
"//org.eclipse.jgit.junit.ssh:__pkg__",
"//org.eclipse.jgit.ssh.apache:__pkg__",
"//org.eclipse.jgit.ssh.apache.agent:__pkg__",
"//org.eclipse.jgit.ssh.apache.test:__pkg__",
"//org.eclipse.jgit.test:__pkg__",
],
@ -93,6 +94,22 @@ java_library(
exports = ["@sshd-sftp//jar"],
)
java_library(
name = "jna",
visibility = [
"//org.eclipse.jgit.ssh.apache.agent:__pkg__",
],
exports = ["@jna//jar"],
)
java_library(
name = "jna-platform",
visibility = [
"//org.eclipse.jgit.ssh.apache.agent:__pkg__",
],
exports = ["@jna-platform//jar"],
)
java_library(
name = "javaewah",
visibility = ["//visibility:public"],

View File

@ -38,7 +38,6 @@
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.11</version>
</dependency>
</dependencies>

View File

@ -45,6 +45,19 @@
<artifactId>org.eclipse.jgit.ui</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -57,6 +57,18 @@
<bundle id="com.jcraft.jzlib.source">
<category name="JGit-dependency-bundles"/>
</bundle>
<bundle id="com.sun.jna">
<category name="JGit-dependency-bundles"/>
</bundle>
<bundle id="com.sun.jna.source">
<category name="JGit-dependency-bundles"/>
</bundle>
<bundle id="com.sun.jna.platform">
<category name="JGit-dependency-bundles"/>
</bundle>
<bundle id="com.sun.jna.platform.source">
<category name="JGit-dependency-bundles"/>
</bundle>
<bundle id="javaewah">
<category name="JGit-dependency-bundles"/>
</bundle>

View File

@ -91,7 +91,12 @@
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
<version>${project.version}</version>

View File

@ -110,6 +110,13 @@
version="0.0.0"
unpack="false"/>
<plugin
id="org.eclipse.jgit.ssh.apache.agent.source"
download-size="0"
install-size="0"
version="0.0.0"
unpack="false"/>
<plugin
id="org.eclipse.jgit.ssh.jsch.source"
download-size="0"

View File

@ -33,4 +33,12 @@
version="0.0.0"
unpack="false"/>
<plugin
id="org.eclipse.jgit.ssh.apache.agent"
download-size="0"
install-size="0"
version="0.0.0"
fragment="true"
unpack="false"/>
</feature>

View File

@ -39,6 +39,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,52 +1,56 @@
<?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="1630003272">
<target name="jgit-4.17" sequenceNumber="1636551936">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.43.v20210629"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.43.v20210629/"/>
<unit id="org.eclipse.jetty.client" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.44.v20210927"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson.source" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson" version="2.8.8.v20211029-0838"/>
<unit id="com.google.gson.source" version="2.8.8.v20211029-0838"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.12.v20210622-2206"/>
<unit id="javaewah.source" version="1.1.12.v20210622-2206"/>
<unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
<unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
<unit id="javaewah" version="1.1.13.v20211029-0839"/>
<unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.11.v20210720-1445"/>
<unit id="org.apache.ant.source" version="1.10.11.v20210720-1445"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
<unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress.source" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
<unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
<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.13.v20210128-2225"/>
@ -65,8 +69,8 @@
<unit id="org.bouncycastle.bcpg.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcutil" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcutil.source" version="1.69.0.v20210713-1924"/>
<unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
@ -75,8 +79,8 @@
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.junit" version="4.13.2.v20211018-1956"/>
<unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
@ -89,7 +93,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
<unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210825222808/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/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/R20210825222808-2021-09.tpd"
include "orbit/S20211108222137.tpd"
location "https://download.eclipse.org/releases/2020-09/" {
org.eclipse.osgi lazy

View File

@ -1,52 +1,56 @@
<?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="1630003272">
<target name="jgit-4.18" sequenceNumber="1636551936">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.43.v20210629"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.43.v20210629/"/>
<unit id="org.eclipse.jetty.client" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.44.v20210927"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson.source" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson" version="2.8.8.v20211029-0838"/>
<unit id="com.google.gson.source" version="2.8.8.v20211029-0838"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.12.v20210622-2206"/>
<unit id="javaewah.source" version="1.1.12.v20210622-2206"/>
<unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
<unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
<unit id="javaewah" version="1.1.13.v20211029-0839"/>
<unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.11.v20210720-1445"/>
<unit id="org.apache.ant.source" version="1.10.11.v20210720-1445"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
<unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress.source" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
<unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
<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.13.v20210128-2225"/>
@ -65,8 +69,8 @@
<unit id="org.bouncycastle.bcpg.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcutil" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcutil.source" version="1.69.0.v20210713-1924"/>
<unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
@ -75,8 +79,8 @@
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.junit" version="4.13.2.v20211018-1956"/>
<unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
@ -89,7 +93,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
<unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210825222808/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/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/R20210825222808-2021-09.tpd"
include "orbit/S20211108222137.tpd"
location "https://download.eclipse.org/releases/2020-12/" {
org.eclipse.osgi lazy

View File

@ -1,52 +1,56 @@
<?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="1630003272">
<target name="jgit-4.19-staging" sequenceNumber="1636551936">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.43.v20210629"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.43.v20210629/"/>
<unit id="org.eclipse.jetty.client" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.44.v20210927"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson.source" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson" version="2.8.8.v20211029-0838"/>
<unit id="com.google.gson.source" version="2.8.8.v20211029-0838"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.12.v20210622-2206"/>
<unit id="javaewah.source" version="1.1.12.v20210622-2206"/>
<unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
<unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
<unit id="javaewah" version="1.1.13.v20211029-0839"/>
<unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.11.v20210720-1445"/>
<unit id="org.apache.ant.source" version="1.10.11.v20210720-1445"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
<unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress.source" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
<unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
<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.13.v20210128-2225"/>
@ -65,8 +69,8 @@
<unit id="org.bouncycastle.bcpg.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcutil" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcutil.source" version="1.69.0.v20210713-1924"/>
<unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
@ -75,8 +79,8 @@
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.junit" version="4.13.2.v20211018-1956"/>
<unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
@ -89,7 +93,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
<unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210825222808/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/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/R20210825222808-2021-09.tpd"
include "orbit/S20211108222137.tpd"
location "https://download.eclipse.org/staging/2021-03/" {
org.eclipse.osgi lazy

View File

@ -1,52 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.20" sequenceNumber="1630003272">
<target name="jgit-4.20" sequenceNumber="1636551936">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.43.v20210629"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.43.v20210629/"/>
<unit id="org.eclipse.jetty.client" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.44.v20210927"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson.source" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson" version="2.8.8.v20211029-0838"/>
<unit id="com.google.gson.source" version="2.8.8.v20211029-0838"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.12.v20210622-2206"/>
<unit id="javaewah.source" version="1.1.12.v20210622-2206"/>
<unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
<unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
<unit id="javaewah" version="1.1.13.v20211029-0839"/>
<unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.11.v20210720-1445"/>
<unit id="org.apache.ant.source" version="1.10.11.v20210720-1445"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
<unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress.source" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
<unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
<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.13.v20210128-2225"/>
@ -65,8 +69,8 @@
<unit id="org.bouncycastle.bcpg.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcutil" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcutil.source" version="1.69.0.v20210713-1924"/>
<unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
@ -75,8 +79,8 @@
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.junit" version="4.13.2.v20211018-1956"/>
<unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
@ -89,7 +93,7 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
<unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210825222808/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/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.20" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/R20210825222808-2021-09.tpd"
include "orbit/S20211108222137.tpd"
location "https://download.eclipse.org/releases/2021-06/" {
org.eclipse.osgi lazy

View File

@ -1,52 +1,56 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/eclipse-cbi/targetplatform-dsl -->
<target name="jgit-4.21" sequenceNumber="1630003272">
<target name="jgit-4.21" sequenceNumber="1636551936">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.43.v20210629"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.43.v20210629"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.43.v20210629/"/>
<unit id="org.eclipse.jetty.client" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.client.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.http.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.io.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.security.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.server.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.source" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax" version="9.4.44.v20210927"/>
<unit id="org.eclipse.jetty.util.ajax.source" version="9.4.44.v20210927"/>
<repository id="jetty-9.4.x" location="https://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.4.44.v20210927/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="com.google.gson" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson.source" version="2.8.7.v20210624-1215"/>
<unit id="com.google.gson" version="2.8.8.v20211029-0838"/>
<unit id="com.google.gson.source" version="2.8.8.v20211029-0838"/>
<unit id="com.jcraft.jsch" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jsch.source" version="0.1.55.v20190404-1902"/>
<unit id="com.jcraft.jzlib" version="1.1.1.v201205102305"/>
<unit id="com.jcraft.jzlib.source" version="1.1.1.v201205102305"/>
<unit id="javaewah" version="1.1.12.v20210622-2206"/>
<unit id="javaewah.source" version="1.1.12.v20210622-2206"/>
<unit id="com.sun.jna" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.source" version="5.8.0.v20210503-0343"/>
<unit id="com.sun.jna.platform" version="5.8.0.v20210406-1004"/>
<unit id="com.sun.jna.platform.source" version="5.8.0.v20210406-1004"/>
<unit id="javaewah" version="1.1.13.v20211029-0839"/>
<unit id="javaewah.source" version="1.1.13.v20211029-0839"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="net.bytebuddy.byte-buddy" version="1.9.0.v20181107-1410"/>
<unit id="net.bytebuddy.byte-buddy-agent" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy-agent.source" version="1.9.0.v20181106-1534"/>
<unit id="net.bytebuddy.byte-buddy.source" version="1.9.0.v20181107-1410"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20181102-1323"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20181102-1323"/>
<unit id="org.apache.ant" version="1.10.11.v20210720-1445"/>
<unit id="org.apache.ant.source" version="1.10.11.v20210720-1445"/>
<unit id="net.i2p.crypto.eddsa" version="0.3.0.v20210923-1401"/>
<unit id="net.i2p.crypto.eddsa.source" version="0.3.0.v20210923-1401"/>
<unit id="org.apache.ant" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.ant.source" version="1.10.12.v20211102-1452"/>
<unit id="org.apache.commons.codec" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.codec.source" version="1.14.0.v20200818-1422"/>
<unit id="org.apache.commons.compress" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress.source" version="1.20.0.v20210713-1928"/>
<unit id="org.apache.commons.compress" version="1.21.0.v20211103-2100"/>
<unit id="org.apache.commons.compress.source" version="1.21.0.v20211103-2100"/>
<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.13.v20210128-2225"/>
@ -65,8 +69,8 @@
<unit id="org.bouncycastle.bcpg.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcpkix.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcprov" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcprov.source" version="1.69.0.v20210923-1401"/>
<unit id="org.bouncycastle.bcutil" version="1.69.0.v20210713-1924"/>
<unit id="org.bouncycastle.bcutil.source" version="1.69.0.v20210713-1924"/>
<unit id="org.hamcrest" version="2.2.0.v20210711-0821"/>
@ -75,8 +79,8 @@
<unit id="org.hamcrest.core.source" version="1.3.0.v20180420-1519"/>
<unit id="org.hamcrest.library" version="1.3.0.v20180524-2246"/>
<unit id="org.hamcrest.library.source" version="1.3.0.v20180524-2246"/>
<unit id="org.junit" version="4.13.0.v20200204-1500"/>
<unit id="org.junit.source" version="4.13.0.v20200204-1500"/>
<unit id="org.junit" version="4.13.2.v20211018-1956"/>
<unit id="org.junit.source" version="4.13.2.v20211018-1956"/>
<unit id="org.kohsuke.args4j" version="2.33.0.v20160323-2218"/>
<unit id="org.kohsuke.args4j.source" version="2.33.0.v20160323-2218"/>
<unit id="org.mockito" version="2.23.0.v20200310-1642"/>
@ -89,11 +93,11 @@
<unit id="org.slf4j.binding.log4j12.source" version="1.7.30.v20201108-2042"/>
<unit id="org.tukaani.xz" version="1.9.0.v20210624-1259"/>
<unit id="org.tukaani.xz.source" version="1.9.0.v20210624-1259"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/R20210825222808/repository"/>
<repository location="https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/repository"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.osgi" version="0.0.0"/>
<repository location="https://download.eclipse.org/staging/2021-09/"/>
<repository location="https://download.eclipse.org/releases/2021-09/"/>
</location>
</locations>
</target>

View File

@ -1,8 +1,8 @@
target "jgit-4.21" with source configurePhase
include "projects/jetty-9.4.x.tpd"
include "orbit/R20210825222808-2021-09.tpd"
include "orbit/S20211108222137.tpd"
location "https://download.eclipse.org/staging/2021-09/" {
location "https://download.eclipse.org/releases/2021-09/" {
org.eclipse.osgi lazy
}

View File

@ -8,6 +8,10 @@ location "https://download.eclipse.org/tools/orbit/downloads/drops/R202108252228
com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
com.sun.jna [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
com.sun.jna.source [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
com.sun.jna.platform [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
com.sun.jna.platform.source [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
javaewah [1.1.12.v20210622-2206,1.1.12.v20210622-2206]
javaewah.source [1.1.12.v20210622-2206,1.1.12.v20210622-2206]
javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]

View File

@ -0,0 +1,73 @@
target "S20211108222137" with source configurePhase
// see https://download.eclipse.org/tools/orbit/downloads/
location "https://download.eclipse.org/tools/orbit/downloads/drops/S20211108222137/repository" {
com.google.gson [2.8.8.v20211029-0838,2.8.8.v20211029-0838]
com.google.gson.source [2.8.8.v20211029-0838,2.8.8.v20211029-0838]
com.jcraft.jsch [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
com.jcraft.jsch.source [0.1.55.v20190404-1902,0.1.55.v20190404-1902]
com.jcraft.jzlib [1.1.1.v201205102305,1.1.1.v201205102305]
com.jcraft.jzlib.source [1.1.1.v201205102305,1.1.1.v201205102305]
com.sun.jna [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
com.sun.jna.source [5.8.0.v20210503-0343,5.8.0.v20210503-0343]
com.sun.jna.platform [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
com.sun.jna.platform.source [5.8.0.v20210406-1004,5.8.0.v20210406-1004]
javaewah [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
javaewah.source [1.1.13.v20211029-0839,1.1.13.v20211029-0839]
javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
net.bytebuddy.byte-buddy [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
net.bytebuddy.byte-buddy-agent [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
net.bytebuddy.byte-buddy-agent.source [1.9.0.v20181106-1534,1.9.0.v20181106-1534]
net.bytebuddy.byte-buddy.source [1.9.0.v20181107-1410,1.9.0.v20181107-1410]
net.i2p.crypto.eddsa [0.3.0.v20210923-1401,0.3.0.v20210923-1401]
net.i2p.crypto.eddsa.source [0.3.0.v20210923-1401,0.3.0.v20210923-1401]
org.apache.ant [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
org.apache.ant.source [1.10.12.v20211102-1452,1.10.12.v20211102-1452]
org.apache.commons.codec [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
org.apache.commons.codec.source [1.14.0.v20200818-1422,1.14.0.v20200818-1422]
org.apache.commons.compress [1.21.0.v20211103-2100,1.21.0.v20211103-2100]
org.apache.commons.compress.source [1.21.0.v20211103-2100,1.21.0.v20211103-2100]
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.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.7.0.v20210623-0618,2.7.0.v20210623-0618]
org.apache.sshd.osgi.source [2.7.0.v20210623-0618,2.7.0.v20210623-0618]
org.apache.sshd.sftp [2.7.0.v20210623-0618,2.7.0.v20210623-0618]
org.apache.sshd.sftp.source [2.7.0.v20210623-0618,2.7.0.v20210623-0618]
org.assertj [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
org.assertj.source [3.20.2.v20210706-1104,3.20.2.v20210706-1104]
org.bouncycastle.bcpg [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.bouncycastle.bcpg.source [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.bouncycastle.bcpkix [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.bouncycastle.bcpkix.source [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.bouncycastle.bcprov [1.69.0.v20210923-1401,1.69.0.v20210923-1401]
org.bouncycastle.bcprov.source [1.69.0.v20210923-1401,1.69.0.v20210923-1401]
org.bouncycastle.bcutil [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.bouncycastle.bcutil.source [1.69.0.v20210713-1924,1.69.0.v20210713-1924]
org.hamcrest [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
org.hamcrest.source [2.2.0.v20210711-0821,2.2.0.v20210711-0821]
org.hamcrest.core [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
org.hamcrest.core.source [1.3.0.v20180420-1519,1.3.0.v20180420-1519]
org.hamcrest.library [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
org.hamcrest.library.source [1.3.0.v20180524-2246,1.3.0.v20180524-2246]
org.junit [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
org.junit.source [4.13.2.v20211018-1956,4.13.2.v20211018-1956]
org.kohsuke.args4j [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
org.kohsuke.args4j.source [2.33.0.v20160323-2218,2.33.0.v20160323-2218]
org.mockito [2.23.0.v20200310-1642,2.23.0.v20200310-1642]
org.mockito.source [2.23.0.v20200310-1642,2.23.0.v20200310-1642]
org.objenesis [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
org.objenesis.source [2.6.0.v20180420-1519,2.6.0.v20180420-1519]
org.slf4j.api [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
org.slf4j.api.source [1.7.30.v20200204-2150,1.7.30.v20200204-2150]
org.slf4j.binding.log4j12 [1.7.30.v20201108-2042,1.7.30.v20201108-2042]
org.slf4j.binding.log4j12.source [1.7.30.v20201108-2042,1.7.30.v20201108-2042]
org.tukaani.xz [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
org.tukaani.xz.source [1.9.0.v20210624-1259,1.9.0.v20210624-1259]
}

View File

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

View File

@ -147,6 +147,12 @@
<version>${project.version}</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>

View File

@ -79,6 +79,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.jsch</artifactId>

View File

@ -173,7 +173,7 @@ private void run(Repository repo) throws Exception {
} catch (LargeObjectException tooBig) {
continue;
}
if (RawText.isBinary(raw0))
if (RawText.isBinary(raw0, raw0.length, true))
continue;
byte[] raw1;
@ -183,7 +183,7 @@ private void run(Repository repo) throws Exception {
} catch (LargeObjectException tooBig) {
continue;
}
if (RawText.isBinary(raw1))
if (RawText.isBinary(raw1, raw1.length, true))
continue;
RawText txt0 = new RawText(raw0);

View File

@ -286,7 +286,7 @@ private void run(Repository repo) throws Exception {
continue;
}
if (RawText.isBinary(raw))
if (RawText.isBinary(raw, raw.length, true))
continue;
RawText txt = new RawText(raw);

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="resources"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,125 @@
#FindBugs User Preferences
#Mon May 04 16:24:13 PDT 2009
detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
detectorBadAppletConstructor=BadAppletConstructor|false
detectorBadResultSetAccess=BadResultSetAccess|true
detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
detectorBadUseOfReturnValue=BadUseOfReturnValue|true
detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
detectorBooleanReturnNull=BooleanReturnNull|true
detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true
detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
detectorCheckTypeQualifiers=CheckTypeQualifiers|true
detectorCloneIdiom=CloneIdiom|false
detectorComparatorIdiom=ComparatorIdiom|true
detectorConfusedInheritance=ConfusedInheritance|true
detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
detectorCrossSiteScripting=CrossSiteScripting|true
detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
detectorDontUseEnum=DontUseEnum|true
detectorDroppedException=DroppedException|true
detectorDumbMethodInvocations=DumbMethodInvocations|true
detectorDumbMethods=DumbMethods|true
detectorDuplicateBranches=DuplicateBranches|true
detectorEmptyZipFileEntry=EmptyZipFileEntry|true
detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
detectorFinalizerNullsFields=FinalizerNullsFields|true
detectorFindBadCast2=FindBadCast2|true
detectorFindBadForLoop=FindBadForLoop|true
detectorFindCircularDependencies=FindCircularDependencies|false
detectorFindDeadLocalStores=FindDeadLocalStores|true
detectorFindDoubleCheck=FindDoubleCheck|true
detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
detectorFindFinalizeInvocations=FindFinalizeInvocations|true
detectorFindFloatEquality=FindFloatEquality|true
detectorFindHEmismatch=FindHEmismatch|true
detectorFindInconsistentSync2=FindInconsistentSync2|true
detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
detectorFindMaskedFields=FindMaskedFields|true
detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
detectorFindNakedNotify=FindNakedNotify|true
detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
detectorFindNonShortCircuit=FindNonShortCircuit|true
detectorFindNullDeref=FindNullDeref|true
detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
detectorFindOpenStream=FindOpenStream|true
detectorFindPuzzlers=FindPuzzlers|true
detectorFindRefComparison=FindRefComparison|true
detectorFindReturnRef=FindReturnRef|true
detectorFindRunInvocations=FindRunInvocations|true
detectorFindSelfComparison=FindSelfComparison|true
detectorFindSelfComparison2=FindSelfComparison2|true
detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
detectorFindSpinLoop=FindSpinLoop|true
detectorFindSqlInjection=FindSqlInjection|true
detectorFindTwoLockWait=FindTwoLockWait|true
detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
detectorFindUnconditionalWait=FindUnconditionalWait|true
detectorFindUninitializedGet=FindUninitializedGet|true
detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
detectorFindUnreleasedLock=FindUnreleasedLock|true
detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
detectorFindUnsyncGet=FindUnsyncGet|true
detectorFindUselessControlFlow=FindUselessControlFlow|true
detectorFormatStringChecker=FormatStringChecker|true
detectorHugeSharedStringConstants=HugeSharedStringConstants|true
detectorIDivResultCastToDouble=IDivResultCastToDouble|true
detectorIncompatMask=IncompatMask|true
detectorInconsistentAnnotations=InconsistentAnnotations|true
detectorInefficientMemberAccess=InefficientMemberAccess|false
detectorInefficientToArray=InefficientToArray|true
detectorInfiniteLoop=InfiniteLoop|true
detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
detectorInitializationChain=InitializationChain|true
detectorInstantiateStaticClass=InstantiateStaticClass|true
detectorInvalidJUnitTest=InvalidJUnitTest|true
detectorIteratorIdioms=IteratorIdioms|true
detectorLazyInit=LazyInit|true
detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
detectorMethodReturnCheck=MethodReturnCheck|true
detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
detectorMutableLock=MutableLock|true
detectorMutableStaticFields=MutableStaticFields|true
detectorNaming=Naming|true
detectorNumberConstructor=NumberConstructor|true
detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
detectorPublicSemaphores=PublicSemaphores|false
detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
detectorRedundantInterfaces=RedundantInterfaces|true
detectorRepeatedConditionals=RepeatedConditionals|true
detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
detectorSerializableIdiom=SerializableIdiom|true
detectorStartInConstructor=StartInConstructor|true
detectorStaticCalendarDetector=StaticCalendarDetector|true
detectorStringConcatenation=StringConcatenation|true
detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
detectorSwitchFallthrough=SwitchFallthrough|true
detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
detectorURLProblems=URLProblems|true
detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
detectorUnnecessaryMath=UnnecessaryMath|true
detectorUnreadFields=UnreadFields|true
detectorUseObjectEquals=UseObjectEquals|false
detectorUselessSubclassMethod=UselessSubclassMethod|false
detectorVarArgsProblems=VarArgsProblems|true
detectorVolatileUsage=VolatileUsage|true
detectorWaitInLoop=WaitInLoop|true
detectorWrongMapIterator=WrongMapIterator|true
detectorXMLFactoryBypass=XMLFactoryBypass|true
detector_threshold=2
effort=default
excludefilter0=findBugs/FindBugsExcludeFilter.xml
filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
run_at_full_build=true

View File

@ -0,0 +1,2 @@
/bin
/target

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.jgit.ssh.apache.agent</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,3 @@
#Mon Aug 11 16:46:12 PDT 2008
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,3 @@
#Mon Mar 24 18:55:50 EDT 2008
eclipse.preferences.version=1
line.separator=\n

View File

@ -0,0 +1,518 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=enabled
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jgit.annotations.NonNull
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jgit.annotations.NonNullByDefault
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.Nullable
org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=11
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=warning
org.eclipse.jdt.core.compiler.problem.comparingIdentical=error
org.eclipse.jdt.core.compiler.problem.deadCode=error
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=warning
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=error
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=error
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=error
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=error
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=protected
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=error
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
org.eclipse.jdt.core.compiler.problem.nullReference=error
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=ignore
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
org.eclipse.jdt.core.compiler.problem.potentialNullReference=error
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=error
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedImport=error
org.eclipse.jdt.core.compiler.problem.unusedLabel=error
org.eclipse.jdt.core.compiler.problem.unusedLocal=error
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=warning
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
org.eclipse.jdt.core.compiler.release=enabled
org.eclipse.jdt.core.compiler.source=11
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
org.eclipse.jdt.core.formatter.align_with_spaces=false
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_enum_constant=0
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=49
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable=49
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method=49
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package=49
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter=0
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type=49
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_assertion_message=0
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_record_components=16
org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
org.eclipse.jdt.core.formatter.alignment_for_type_annotations=0
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
org.eclipse.jdt.core.formatter.comment.format_comments=true
org.eclipse.jdt.core.formatter.comment.format_header=false
org.eclipse.jdt.core.formatter.comment.format_html=true
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
org.eclipse.jdt.core.formatter.comment.format_source_code=true
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
org.eclipse.jdt.core.formatter.comment.line_length=80
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
org.eclipse.jdt.core.formatter.compact_else_if=true
org.eclipse.jdt.core.formatter.continuation_indentation=2
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_empty_lines=false
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
org.eclipse.jdt.core.formatter.indentation.size=4
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
org.eclipse.jdt.core.formatter.lineSplit=80
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
org.eclipse.jdt.core.formatter.tabulation.char=tab
org.eclipse.jdt.core.formatter.tabulation.size=4
org.eclipse.jdt.core.formatter.text_block_indentation=0
org.eclipse.jdt.core.formatter.use_on_off_tags=true
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
org.eclipse.jdt.core.formatter.wrap_before_assertion_message_operator=true
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true

View File

@ -0,0 +1,66 @@
eclipse.preferences.version=1
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
formatter_profile=_JGit Format
formatter_settings_version=21
org.eclipse.jdt.ui.ignorelowercasenames=true
org.eclipse.jdt.ui.importorder=java;javax;org;com;
org.eclipse.jdt.ui.ondemandthreshold=99
org.eclipse.jdt.ui.staticondemandthreshold=99
org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
sp_cleanup.add_default_serial_version_id=true
sp_cleanup.add_generated_serial_version_id=false
sp_cleanup.add_missing_annotations=true
sp_cleanup.add_missing_deprecated_annotations=true
sp_cleanup.add_missing_methods=false
sp_cleanup.add_missing_nls_tags=false
sp_cleanup.add_missing_override_annotations=true
sp_cleanup.add_missing_override_annotations_interface_methods=true
sp_cleanup.add_serial_version_id=false
sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=false
sp_cleanup.format_source_code=true
sp_cleanup.format_source_code_changes_only=true
sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=false
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
sp_cleanup.on_save_use_additional_actions=true
sp_cleanup.organize_imports=false
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
sp_cleanup.remove_redundant_type_arguments=true
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
sp_cleanup.remove_unnecessary_casts=true
sp_cleanup.remove_unnecessary_nls_tags=true
sp_cleanup.remove_unused_imports=false
sp_cleanup.remove_unused_local_variables=false
sp_cleanup.remove_unused_private_fields=true
sp_cleanup.remove_unused_private_members=false
sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
sp_cleanup.use_lambda=false
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true

View File

@ -0,0 +1,4 @@
#Tue Jul 19 20:11:28 CEST 2011
eclipse.preferences.version=1
project.repository.kind=bugzilla
project.repository.url=https\://bugs.eclipse.org/bugs

View File

@ -0,0 +1,3 @@
#Tue Jul 19 20:11:28 CEST 2011
commit.comment.template=${task.description} \n\nBug\: ${task.key}
eclipse.preferences.version=1

View File

@ -0,0 +1,104 @@
ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
API_USE_SCAN_FIELD_SEVERITY=Error
API_USE_SCAN_METHOD_SEVERITY=Error
API_USE_SCAN_TYPE_SEVERITY=Error
CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
ILLEGAL_EXTEND=Warning
ILLEGAL_IMPLEMENT=Warning
ILLEGAL_INSTANTIATE=Warning
ILLEGAL_OVERRIDE=Warning
ILLEGAL_REFERENCE=Warning
INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
INVALID_ANNOTATION=Ignore
INVALID_JAVADOC_TAG=Ignore
INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
LEAK_EXTEND=Warning
LEAK_FIELD_DECL=Warning
LEAK_IMPLEMENT=Warning
LEAK_METHOD_PARAM=Warning
LEAK_METHOD_RETURN_TYPE=Warning
METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
MISSING_EE_DESCRIPTIONS=Warning
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
UNUSED_PROBLEM_FILTERS=Warning
automatically_removed_unused_problem_filters=false
changed_execution_env=Error
eclipse.preferences.version=1
incompatible_api_component_version=Error
incompatible_api_component_version_include_major_without_breaking_change=Disabled
incompatible_api_component_version_include_minor_without_api_change=Disabled
incompatible_api_component_version_report_major_without_breaking_change=Warning
incompatible_api_component_version_report_minor_without_api_change=Ignore
invalid_since_tag_version=Error
malformed_since_tag=Error
missing_since_tag=Error
report_api_breakage_when_major_version_incremented=Disabled
report_resolution_errors_api_component=Warning

View File

@ -0,0 +1,3 @@
#Thu Jan 14 14:34:32 CST 2010
eclipse.preferences.version=1
resolve.requirebundle=false

View File

@ -0,0 +1,22 @@
load("@rules_java//java:defs.bzl", "java_library")
package(default_visibility = ["//visibility:public"])
SRCS = glob(["src/**/*.java"])
RESOURCES = glob(["resources/**"])
java_library(
name = "ssh-apache-agent",
srcs = SRCS,
resource_strip_prefix = "org.eclipse.jgit.ssh.apache.agent/resources",
resources = RESOURCES,
deps = [
"//lib:jna",
"//lib:jna-platform",
"//lib:slf4j-api",
"//lib:sshd-osgi",
"//org.eclipse.jgit:jgit",
"//org.eclipse.jgit.ssh.apache:ssh-apache"
],
)

View File

@ -0,0 +1,16 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent;singleton:=true
Bundle-Version: 6.0.0.qualifier
Bundle-Vendor: %Bundle-Vendor
Fragment-Host: org.eclipse.jgit.ssh.apache;bundle-version="[6.0.0,6.1.0)"
Bundle-ActivationPolicy: lazy
Automatic-Module-Name: org.eclipse.jgit.ssh.apache.agent
Bundle-RequiredExecutionEnvironment: JavaSE-11
Import-Package: org.eclipse.jgit.transport.sshd;version="[6.0.0,6.1.0)",
org.eclipse.jgit.nls;version="[6.0.0,6.1.0)",
org.eclipse.jgit.util;version="[6.0.0,6.1.0)"
Require-Bundle: com.sun.jna;bundle-version="[5.8.0,6.0.0)",
com.sun.jna.platform;bundle-version="[5.8.0,6.0.0)"
Export-Package: org.eclipse.jgit.internal.transport.sshd.agent.connector;version="6.0.0";x-internal:=true

View File

@ -0,0 +1,7 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: org.eclipse.jgit.ssh.apache.agent - Sources
Bundle-SymbolicName: org.eclipse.jgit.ssh.apache.agent.source
Bundle-Vendor: Eclipse.org - JGit
Bundle-Version: 6.0.0.qualifier
Eclipse-SourceBundle: org.eclipse.jgit.ssh.apache.agent;version="6.0.0.qualifier";roots="."

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Distribution License - Version 1.0</title>
<style type="text/css">
body {
size: 8.5in 11.0in;
margin: 0.25in 0.5in 0.25in 0.5in;
tab-interval: 0.5in;
}
p {
margin-left: auto;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
p.list {
margin-left: 0.5in;
margin-top: 0.05em;
margin-bottom: 0.05em;
}
.ubc-name {
margin-left: 0.5in;
white-space: pre;
}
</style>
</head>
<body lang="EN-US">
<p><b>Eclipse Distribution License - v 1.0</b></p>
<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,
are permitted provided that the following conditions are met:
<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
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
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
POSSIBILITY OF SUCH DAMAGE.</p>
<hr>
<p><b>SHA-1 UbcCheck - 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>
<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>
</html>

View File

@ -0,0 +1,7 @@
source.. = src/,\
resources/
output.. = bin/
bin.includes = META-INF/,\
.,\
plugin.properties,\
about.html

View File

@ -0,0 +1,2 @@
Bundle-Name=JGit Unix SSH agent client for Apache MINA sshd
Bundle-Vendor=Eclipse JGit

View File

@ -0,0 +1,227 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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
http://www.eclipse.org/org/documents/edl-v10.php.
SPDX-License-Identifier: BSD-3-Clause
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit-parent</artifactId>
<version>6.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.eclipse.jgit.ssh.apache.agent</artifactId>
<name>JGit - Apache sshd SSH agent support</name>
<description>
Support for ssh-agent for the Apache MINA sshd SSH connector
</description>
<properties>
<jna-version>5.8.0</jna-version>
<translate-qualifier/>
<source-bundle-manifest>${project.build.directory}/META-INF/SOURCE-MANIFEST.MF</source-bundle-manifest>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>${jna-version}</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>${jna-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/</sourceDirectory>
<resources>
<resource>
<directory>.</directory>
<includes>
<include>plugin.properties</include>
<include>about.html</include>
</includes>
</resource>
<resource>
<directory>resources/</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>translate-source-qualifier</id>
<phase>generate-resources</phase>
<configuration>
<target>
<copy file="META-INF/SOURCE-MANIFEST.MF" tofile="${source-bundle-manifest}" overwrite="true" />
<replace file="${source-bundle-manifest}">
<replacefilter token=".qualifier" value=".${maven.build.timestamp}" />
</replace>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<inherited>true</inherited>
<executions>
<execution>
<id>attach-sources</id>
<phase>process-classes</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifestFile>${source-bundle-manifest}</manifestFile>
</archive>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${bundle-manifest}</manifestFile>
</archive>
</configuration>
</plugin>
<!-- New in 6.0; uncomment in 6.1
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<version>${japicmp-version}</version>
<configuration>
<oldVersion>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${jgit-last-release-version}</version>
</dependency>
</oldVersion>
<newVersion>
<file>
<path>${project.build.directory}/${project.artifactId}-${project.version}.jar</path>
</file>
</newVersion>
<parameter>
<onlyModified>true</onlyModified>
<includes>
<include>org.eclipse.jgit.*</include>
</includes>
<accessModifier>public</accessModifier>
<breakBuildOnModifications>false</breakBuildOnModifications>
<breakBuildOnBinaryIncompatibleModifications>false</breakBuildOnBinaryIncompatibleModifications>
<onlyBinaryIncompatible>false</onlyBinaryIncompatible>
<includeSynthetic>false</includeSynthetic>
<ignoreMissingClasses>false</ignoreMissingClasses>
<skipPomModules>true</skipPomModules>
</parameter>
<skip>false</skip>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>cmp</goal>
</goals>
</execution>
</executions>
</plugin>
-->
</plugins>
</build>
<!-- New in 6.0, uncomment in 6.1
<reporting>
<plugins>
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<version>${japicmp-version}</version>
<reportSets>
<reportSet>
<reports>
<report>cmp-report</report>
</reports>
</reportSet>
</reportSets>
<configuration>
<oldVersion>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${jgit-last-release-version}</version>
</dependency>
</oldVersion>
<newVersion>
<file>
<path>${project.build.directory}/${project.artifactId}-${project.version}.jar</path>
</file>
</newVersion>
<parameter>
<onlyModified>true</onlyModified>
<includes>
<include>org.eclipse.jgit.*</include>
</includes>
<accessModifier>public</accessModifier>
<breakBuildOnModifications>false</breakBuildOnModifications>
<breakBuildOnBinaryIncompatibleModifications>false</breakBuildOnBinaryIncompatibleModifications>
<onlyBinaryIncompatible>false</onlyBinaryIncompatible>
<includeSynthetic>false</includeSynthetic>
<ignoreMissingClasses>false</ignoreMissingClasses>
<skipPomModules>true</skipPomModules>
</parameter>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</reporting>
-->
</project>

View File

@ -0,0 +1 @@
org.eclipse.jgit.internal.transport.sshd.agent.connector.Factory

View File

@ -0,0 +1,17 @@
errCloseMappedFile=Cannot close mapped file: {0} - {1}
errLastError=System message for error {0} could not be retrieved, got {1}
errReleaseSharedMemory=Cannot release shared memory: {0} - {1}
errUnknown=unknown error
logErrorLoadLibrary=Cannot load socket library; SSH agent support is switched off
msgCloseFailed=Cannot close SSH agent socket {0}
msgConnectFailed=Could not connect to SSH agent via socket ''{0}''
msgNoMappedFile=Could not create file mapping: {0} - {1}
msgNoSharedMemory=Could not initialize shared memory: {0} - {1}
msgPageantUnavailable=Could not connect to Pageant
msgReadFailed=Reading {0} bytes from the SSH agent failed
msgSendFailed=Sending {0} bytes to SSH agent failed; {0} bytes not written
msgSendFailed2=Sending {0} bytes to SSH agent failed: {1} - {2}
msgSharedMemoryFailed=Could not set up shared memory for communicating with Pageant
msgShortRead=Short read from SSH agent, expected {0} bytes, got {1} bytes; last read() returned {2}
pageant=Pageant
unixDefaultAgent=ssh-agent

View File

@ -0,0 +1,68 @@
/*
* 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.internal.transport.sshd.agent.connector;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import org.eclipse.jgit.transport.sshd.agent.Connector;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
import org.eclipse.jgit.util.SystemReader;
/**
* An {@link ConnectorFactory} for connecting to an OpenSSH SSH agent.
*/
public class Factory implements ConnectorFactory {
private static final String NAME = "jgit-builtin"; //$NON-NLS-1$
@Override
public Connector create(String identityAgent, File homeDir)
throws IOException {
if (SystemReader.getInstance().isWindows()) {
return new PageantConnector();
}
return new UnixDomainSocketConnector(identityAgent);
}
@Override
public boolean isSupported() {
return true;
}
@Override
public String getName() {
return NAME;
}
/**
* {@inheritDoc}
* <p>
* This factory returns on Windows a
* {@link org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor
* ConnectorDescriptor} for the internal name "pageant"; on Unix one for
* "SSH_AUTH_SOCK".
* </p>
*/
@Override
public Collection<ConnectorDescriptor> getSupportedConnectors() {
return Collections.singleton(getDefaultConnector());
}
@Override
public ConnectorDescriptor getDefaultConnector() {
if (SystemReader.getInstance().isWindows()) {
return PageantConnector.DESCRIPTOR;
}
return UnixDomainSocketConnector.DESCRIPTOR;
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.internal.transport.sshd.agent.connector;
import java.text.MessageFormat;
import com.sun.jna.LastErrorException;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.User32;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Delay loading the native libraries until needed.
*/
class LibraryHolder {
private static final Logger LOG = LoggerFactory
.getLogger(LibraryHolder.class);
private static LibraryHolder INSTANCE;
private static boolean libraryLoaded = false;
public static synchronized LibraryHolder getLibrary() {
if (!libraryLoaded) {
libraryLoaded = true;
try {
INSTANCE = new LibraryHolder();
} catch (Exception | UnsatisfiedLinkError
| NoClassDefFoundError e) {
LOG.error(Texts.get().logErrorLoadLibrary, e);
}
}
return INSTANCE;
}
User32 user;
Kernel32 kernel;
private LibraryHolder() {
user = User32.INSTANCE;
kernel = Kernel32.INSTANCE;
}
String systemError(String pattern) {
int lastError = kernel.GetLastError();
String msg;
try {
msg = Kernel32Util.formatMessageFromLastErrorCode(lastError);
} catch (Exception e) {
String err = e instanceof LastErrorException
? Integer.toString(((LastErrorException) e).getErrorCode())
: Texts.get().errUnknown;
msg = MessageFormat.format(Texts.get().errLastError,
Integer.toString(lastError), err);
LOG.error(msg, e);
}
return MessageFormat.format(pattern, Integer.toString(lastError), msg);
}
}

View File

@ -0,0 +1,73 @@
/*
* 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.internal.transport.sshd.agent.connector;
import java.io.IOException;
import org.eclipse.jgit.transport.sshd.agent.AbstractConnector;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor;
/**
* A connector using Pageant's shared memory IPC mechanism.
*/
public class PageantConnector extends AbstractConnector {
/**
* {@link ConnectorDescriptor} for the {@link PageantConnector}.
*/
public static final ConnectorDescriptor DESCRIPTOR = new ConnectorDescriptor() {
@Override
public String getIdentityAgent() {
return "pageant"; //$NON-NLS-1$
}
@Override
public String getDisplayName() {
return Texts.get().pageant;
}
};
private final PageantLibrary lib;
/**
* Creates a new {@link PageantConnector}.
*/
public PageantConnector() {
super(); // Use default maximum message size
this.lib = new PageantLibrary();
}
@Override
public boolean connect() throws IOException {
return lib.isPageantAvailable();
}
@Override
public void close() throws IOException {
// Nothing to do
}
@Override
public byte[] rpc(byte command, byte[] message) throws IOException {
try (PageantLibrary.Pipe pipe = lib
.createPipe(getClass().getSimpleName(),
getMaximumMessageLength())) {
prepareMessage(command, message);
pipe.send(message);
byte[] lengthBuf = new byte[4];
pipe.receive(lengthBuf);
int length = toLength(command, lengthBuf);
byte[] payload = new byte[length];
pipe.receive(payload);
return payload;
}
}
}

View File

@ -0,0 +1,240 @@
/*
* 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.internal.transport.sshd.agent.connector;
import java.io.Closeable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;
import com.sun.jna.platform.win32.WinUser;
/**
* The {@link PageantLibrary} encapsulates the shared memory access and provides
* a simple pipe abstraction.
*/
public final class PageantLibrary {
private static final Logger LOG = LoggerFactory
.getLogger(PageantLibrary.class);
/** Pageant's "class" and "window name". */
private static final String PAGEANT = "Pageant"; //$NON-NLS-1$
/**
* Magic constant from Pageant; ID for the CopyStruct used in SendMessage.
*
* @see <a href=
* "https://git.tartarus.org/?p=simon/putty.git;a=blob;f=windows/pageant.c;h=0e25cc5d48f0#l33">"random goop"</a>
*/
private static final int PAGEANT_ID = 0x804e_50ba;
/**
* Determines whether Pageant is currently running.
*
* @return {@code true} if Pageant is running, {@code false} otherwise
*/
boolean isPageantAvailable() {
LibraryHolder libs = LibraryHolder.getLibrary();
if (libs == null) {
return false;
}
HWND window = libs.user.FindWindow(PAGEANT, PAGEANT);
return window != null && !window.equals(WinBase.INVALID_HANDLE_VALUE);
}
/**
* An abstraction for a bi-directional pipe.
*/
interface Pipe extends Closeable {
/**
* Send the given message.
*
* @param message
* to send
* @throws IOException
* on errors
*/
void send(byte[] message) throws IOException;
/**
* Reads bytes from the pipe until {@code data} is full.
*
* @param data
* to read
* @throws IOException
* on errors
*/
void receive(byte[] data) throws IOException;
}
/**
* Windows' COPYDATASTRUCT. Must be public for JNA.
*/
public static class CopyStruct extends Structure {
/** Must be set the {@link #PAGEANT_ID}. */
public int dwData = PAGEANT_ID;
/** Data length; number of bytes in {@link #lpData}. */
public long cbData;
/** Points to {@link #cbData} bytes. */
public Pointer lpData;
@Override
protected List<String> getFieldOrder() {
return List.of("dwData", "cbData", "lpData"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
private static class PipeImpl implements Pipe {
private final LibraryHolder libs;
private final HWND window;
private final byte[] name;
private final HANDLE file;
private final Pointer memory;
private long readPos = 0;
PipeImpl(LibraryHolder libs, HWND window, String name, HANDLE file,
Pointer memory) {
this.libs = libs;
this.window = window;
this.name = name.getBytes(StandardCharsets.US_ASCII);
this.file = file;
this.memory = memory;
}
@Override
public void close() throws IOException {
PageantLibrary.close(libs, file, memory, false);
}
private Pointer init(CopyStruct c) {
c.cbData = name.length + 1;
c.lpData = new Memory(c.cbData);
c.lpData.write(0, name, 0, name.length);
c.lpData.setByte(name.length, (byte) 0);
c.write();
return c.getPointer();
}
@Override
public void send(byte[] message) throws IOException {
memory.write(0, message, 0, message.length);
CopyStruct c = new CopyStruct();
Pointer p = init(c);
LRESULT result = libs.user.SendMessage(window, WinUser.WM_COPYDATA,
null, new LPARAM(Pointer.nativeValue(p)));
if (result == null || result.longValue() == 0) {
throw new IOException(
libs.systemError(Texts.get().msgSendFailed2));
}
}
@Override
public void receive(byte[] data) throws IOException {
// Relies on Pageant handling the request synchronously, i.e.,
// SendMessage() above returning successfully only once Pageant
// has indeed written into the shared memory.
memory.read(readPos, data, 0, data.length);
readPos += data.length;
}
}
/**
* Creates a new {@link Pipe}.
*
* @param name
* for the pipe
* @param maxSize
* maximum size for messages
* @return the {@link Pipe}, or {@code null} if none created
* @throws IOException on errors
*/
Pipe createPipe(String name, int maxSize) throws IOException {
LibraryHolder libs = LibraryHolder.getLibrary();
if (libs == null) {
throw new IllegalStateException("Libraries were not loaded"); //$NON-NLS-1$
}
HWND window = libs.user.FindWindow(PAGEANT, PAGEANT);
if (window == null || window.equals(WinBase.INVALID_HANDLE_VALUE)) {
throw new IOException(Texts.get().msgPageantUnavailable);
}
String fileName = name + libs.kernel.GetCurrentThreadId();
HANDLE file = null;
Pointer sharedMemory = null;
try {
file = libs.kernel.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE,
null, WinNT.PAGE_READWRITE, 0, maxSize, fileName);
if (file == null || file.equals(WinBase.INVALID_HANDLE_VALUE)) {
throw new IOException(
libs.systemError(Texts.get().msgNoMappedFile));
}
sharedMemory = libs.kernel.MapViewOfFile(file,
WinNT.SECTION_MAP_WRITE, 0, 0, 0);
if (sharedMemory == null) {
throw new IOException(
libs.systemError(Texts.get().msgNoSharedMemory));
}
return new PipeImpl(libs, window, fileName, file, sharedMemory);
} catch (IOException e) {
close(libs, file, sharedMemory, true);
throw e;
} catch (Throwable e) {
close(libs, file, sharedMemory, true);
throw new IOException(Texts.get().msgSharedMemoryFailed, e);
}
}
private static void close(LibraryHolder libs, HANDLE file, Pointer memory,
boolean silent) throws IOException {
if (memory != null) {
if (!libs.kernel.UnmapViewOfFile(memory)) {
String msg = libs
.systemError(Texts.get().errReleaseSharedMemory);
if (silent) {
LOG.error(msg);
} else {
throw new IOException(msg);
}
}
}
if (file != null) {
if (!libs.kernel.CloseHandle(file)) {
String msg = libs.systemError(Texts.get().errCloseMappedFile);
if (silent) {
LOG.error(msg);
} else {
throw new IOException(msg);
}
}
}
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.internal.transport.sshd.agent.connector;
import java.nio.charset.Charset;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
/**
* Common things for socket communication.
*/
public final class Sockets {
private Sockets() {
// No instantiation
}
/**
* Default SSH agent socket environment variable name.
*/
public static final String ENV_SSH_AUTH_SOCK = "SSH_AUTH_SOCK"; //$NON-NLS-1$
/**
* Domain for Unix domain sockets.
*/
public static final int AF_UNIX = 1;
/**
* Socket type for duplex sockets.
*/
public static final int SOCK_STREAM = 1;
/**
* Default protocol selector.
*/
public static final int DEFAULT_PROTOCOL = 0;
/**
* Very simple representation of the C SockAddr type.
*/
@FieldOrder(value = { "sa_family", "sa_data" })
public static class SockAddr extends Structure {
// This is a "variable length struct" in C.
// Why 108 is apparently lost in time. But the file path for a Unix
// domain socket cannot be longer (including the terminating NUL).
private static final int MAX_DATA_LENGTH = 108;
/** Socket family */
public short sa_family = AF_UNIX;
/** Unix domain socket path. */
public byte[] sa_data = new byte[MAX_DATA_LENGTH];
/**
* Creates a new {@link SockAddr} for the given {@code path}.
*
* @param path
* for the Socket
* @param encoding
* to use to decode the {@code path} to a byte sequence
*/
public SockAddr(String path, Charset encoding) {
byte[] bytes = path.getBytes(encoding);
int toCopy = Math.min(sa_data.length - 1, bytes.length);
System.arraycopy(bytes, 0, sa_data, 0, toCopy);
sa_data[toCopy] = 0;
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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.internal.transport.sshd.agent.connector;
import org.eclipse.jgit.nls.NLS;
import org.eclipse.jgit.nls.TranslationBundle;
/**
* Externalized text messages for localization.
*/
public final class Texts extends TranslationBundle {
/**
* Get an instance of this translation bundle.
*
* @return an instance of this translation bundle
*/
public static Texts get() {
return NLS.getBundleFor(Texts.class);
}
// @formatter:off
/***/ public String errCloseMappedFile;
/***/ public String errLastError;
/***/ public String errReleaseSharedMemory;
/***/ public String errUnknown;
/***/ public String logErrorLoadLibrary;
/***/ public String msgCloseFailed;
/***/ public String msgConnectFailed;
/***/ public String msgNoMappedFile;
/***/ public String msgNoSharedMemory;
/***/ public String msgPageantUnavailable;
/***/ public String msgReadFailed;
/***/ public String msgSendFailed;
/***/ public String msgSendFailed2;
/***/ public String msgSharedMemoryFailed;
/***/ public String msgShortRead;
/***/ public String pageant;
/***/ public String unixDefaultAgent;
}

View File

@ -0,0 +1,235 @@
/*
* 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.internal.transport.sshd.agent.connector;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.Sockets.AF_UNIX;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.Sockets.DEFAULT_PROTOCOL;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.Sockets.ENV_SSH_AUTH_SOCK;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.Sockets.SOCK_STREAM;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.UnixSockets.FD_CLOEXEC;
import static org.eclipse.jgit.internal.transport.sshd.agent.connector.UnixSockets.F_SETFD;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sshd.common.SshException;
import org.eclipse.jgit.transport.sshd.agent.AbstractConnector;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
import com.sun.jna.platform.unix.LibCAPI;
/**
* JNA-based implementation of communication through a Unix domain socket.
*/
public class UnixDomainSocketConnector extends AbstractConnector {
/**
* {@link ConnectorDescriptor} for the {@link UnixDomainSocketConnector}.
*/
public static final ConnectorDescriptor DESCRIPTOR = new ConnectorDescriptor() {
@Override
public String getIdentityAgent() {
return ENV_SSH_AUTH_SOCK;
}
@Override
public String getDisplayName() {
return Texts.get().unixDefaultAgent;
}
};
private static final Logger LOG = LoggerFactory
.getLogger(UnixDomainSocketConnector.class);
private static UnixSockets library;
private static boolean libraryLoaded = false;
private static synchronized UnixSockets getLibrary() {
if (!libraryLoaded) {
libraryLoaded = true;
try {
library = Native.load(UnixSockets.LIBRARY_NAME, UnixSockets.class);
} catch (Exception | UnsatisfiedLinkError
| NoClassDefFoundError e) {
LOG.error(Texts.get().logErrorLoadLibrary, e);
}
}
return library;
}
private final String socketFile;
private AtomicBoolean connected = new AtomicBoolean();
private volatile int socketFd = -1;
/**
* Creates a new instance.
*
* @param socketFile
* to use; if {@code null} or empty, use environment variable
* SSH_AUTH_SOCK
*/
public UnixDomainSocketConnector(String socketFile) {
super();
String file = socketFile;
if (StringUtils.isEmptyOrNull(file)) {
file = SystemReader.getInstance().getenv(ENV_SSH_AUTH_SOCK);
}
this.socketFile = file;
}
@Override
public boolean connect() throws IOException {
if (StringUtils.isEmptyOrNull(socketFile)) {
return false;
}
int fd = socketFd;
synchronized (this) {
if (connected.get()) {
return true;
}
UnixSockets sockets = getLibrary();
if (sockets == null) {
return false;
}
try {
fd = sockets.socket(AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL);
// OS X apparently doesn't have SOCK_CLOEXEC, so we can't set it
// atomically. Set it via fcntl, which exists on all systems
// we're interested in.
sockets.fcntl(fd, F_SETFD, FD_CLOEXEC);
Sockets.SockAddr sockAddr = new Sockets.SockAddr(socketFile,
StandardCharsets.UTF_8);
sockets.connect(fd, sockAddr, sockAddr.size());
connected.set(true);
} catch (LastErrorException e) {
if (fd >= 0) {
try {
sockets.close(fd);
} catch (LastErrorException e1) {
e.addSuppressed(e1);
}
}
throw new IOException(MessageFormat
.format(Texts.get().msgConnectFailed, socketFile), e);
}
}
socketFd = fd;
return connected.get();
}
@Override
public synchronized void close() throws IOException {
int fd = socketFd;
if (connected.getAndSet(false) && fd >= 0) {
socketFd = -1;
try {
getLibrary().close(fd);
} catch (LastErrorException e) {
throw new IOException(MessageFormat.format(
Texts.get().msgCloseFailed, Integer.toString(fd)), e);
}
}
}
@Override
public byte[] rpc(byte command, byte[] message) throws IOException {
prepareMessage(command, message);
int fd = socketFd;
if (!connected.get() || fd < 0) {
// No translation, internal error
throw new IllegalStateException("Not connected to SSH agent"); //$NON-NLS-1$
}
writeFully(fd, message);
// Now receive the reply
byte[] lengthBuf = new byte[4];
readFully(fd, lengthBuf);
int length = toLength(command, lengthBuf);
byte[] payload = new byte[length];
readFully(fd, payload);
return payload;
}
private void writeFully(int fd, byte[] message) throws IOException {
int toWrite = message.length;
try {
byte[] buf = message;
while (toWrite > 0) {
int written = getLibrary()
.write(fd, buf, new LibCAPI.size_t(buf.length))
.intValue();
if (written < 0) {
throw new IOException(
MessageFormat.format(Texts.get().msgSendFailed,
Integer.toString(message.length),
Integer.toString(toWrite)));
}
toWrite -= written;
if (written > 0 && toWrite > 0) {
buf = Arrays.copyOfRange(buf, written, buf.length);
}
}
} catch (LastErrorException e) {
throw new IOException(
MessageFormat.format(Texts.get().msgSendFailed,
Integer.toString(message.length),
Integer.toString(toWrite)),
e);
}
}
private void readFully(int fd, byte[] data) throws IOException {
int n = 0;
int offset = 0;
while (offset < data.length
&& (n = read(fd, data, offset, data.length - offset)) > 0) {
offset += n;
}
if (offset < data.length) {
throw new SshException(
MessageFormat.format(Texts.get().msgShortRead,
Integer.toString(data.length),
Integer.toString(offset), Integer.toString(n)));
}
}
private int read(int fd, byte[] buffer, int offset, int length)
throws IOException {
try {
LibCAPI.size_t toRead = new LibCAPI.size_t(length);
if (offset == 0) {
return getLibrary().read(fd, buffer, toRead).intValue();
}
byte[] data = new byte[length];
int read = getLibrary().read(fd, data, toRead).intValue();
if (read > 0) {
System.arraycopy(data, 0, buffer, offset, read);
}
return read;
} catch (LastErrorException e) {
throw new IOException(
MessageFormat.format(Texts.get().msgReadFailed,
Integer.toString(length)),
e);
}
}
}

View File

@ -0,0 +1,122 @@
/*
* 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.internal.transport.sshd.agent.connector;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Structure;
import com.sun.jna.platform.unix.LibCAPI;
/**
* Low-level Unix/Linux JNA socket API.
*/
interface UnixSockets extends LibCAPI, Library {
/**
* Library to load. These functions live in libc.
*/
String LIBRARY_NAME = "c"; //$NON-NLS-1$
/**
* Command to set the close-on-exec flag on a file descriptor via
* {@link #fcntl(int, int, int)}.
*/
int F_SETFD = 2;
/**
* Specifies that a file descriptor shall not be inherited by child
* processes.
*/
int FD_CLOEXEC = 1;
/**
* Creates a socket and returns a file descriptor for it.
*
* @param domain
* socket domain; use {@link Sockets#AF_UNIX}
* @param type
* socket type; use {@link Sockets#SOCK_STREAM}
* @param protocol
* socket communication protocol; use
* {@link Sockets#DEFAULT_PROTOCOL}.
* @return file descriptor for the socket; should be closed eventually, or
* -1 on error.
* @throws LastErrorException
* on errors
* @see LibCAPI#close(int)
*/
int socket(int domain, int type, int protocol) throws LastErrorException;
/**
* Simple binding to fcntl; used to set the FD_CLOEXEC flag. On OS X, we
* cannot include SOCK_CLOEXEC in the socket() call.
*
* @param fd
* file descriptor to operate on
* @param command
* set to {@link #F_SETFD}
* @param flag
* zero to clear the close-on-exec flag, {@link #FD_CLOEXEC} to
* set it
* @return -1 on error, otherwise a value >= 0
* @throws LastErrorException
*/
int fcntl(int fd, int command, int flag) throws LastErrorException;
/**
* Connects a file descriptor, which must refer to a socket, to a
* {@link Sockets.SockAddr}.
*
* @param fd
* file descriptor of the socket, as returned by
* {@link #socket(int, int, int)}
* @param addr
* address to connect to
* @param addrLen
* Length of {@code addr}, use {@link Structure#size()}
* @return 0 on success; -1 otherwise
* @throws LastErrorException
* on errors
*/
int connect(int fd, Sockets.SockAddr addr, int addrLen)
throws LastErrorException;
/**
* Read data from a file descriptor.
*
* @param fd
* file descriptor to read from
* @param buf
* buffer to read into
* @param bufLen
* maximum number of bytes to read; at most length of {@code buf}
* @return number of bytes actually read; zero for EOF, -1 on error
* @throws LastErrorException
* on errors
*/
LibCAPI.ssize_t read(int fd, byte[] buf, LibCAPI.size_t bufLen)
throws LastErrorException;
/**
* Write data to a file descriptor.
*
* @param fd
* file descriptor to write to
* @param data
* data to write
* @param dataLen
* number of bytes to write
* @return number of bytes actually written; -1 on error
* @throws LastErrorException
* on errors
*/
LibCAPI.ssize_t write(int fd, byte[] data, LibCAPI.size_t dataLen)
throws LastErrorException;
}

View File

@ -29,6 +29,7 @@ Import-Package: org.apache.sshd.client.config.hosts;version="[2.7.0,2.8.0)",
org.eclipse.jgit.lib;version="[6.0.0,6.1.0)",
org.eclipse.jgit.transport;version="[6.0.0,6.1.0)",
org.eclipse.jgit.transport.sshd;version="[6.0.0,6.1.0)",
org.eclipse.jgit.transport.sshd.agent;version="[6.0.0,6.1.0)",
org.eclipse.jgit.util;version="[6.0.0,6.1.0)",
org.hamcrest;version="[1.1.0,3.0.0)",
org.junit;version="[4.13,5.0.0)",

View File

@ -26,12 +26,15 @@ public class ApacheSshProtocol2Test extends SshBasicTestBase {
@Override
protected SshSessionFactory createSessionFactory() {
SshdSessionFactory result = new SshdSessionFactory(new JGitKeyCache(),
null);
// The home directory is mocked at this point!
result.setHomeDirectory(FS.DETECTED.userHome());
result.setSshDirectory(sshDir);
return result;
return new SshdSessionFactoryBuilder()
// No proxies in tests
.setProxyDataFactory(null)
// No ssh-agent in tests
.setConnectorFactory(null)
// The home directory is mocked at this point!
.setHomeDirectory(FS.DETECTED.userHome())
.setSshDirectory(sshDir)
.build(new JGitKeyCache());
}
@Override

View File

@ -65,12 +65,15 @@ public class ApacheSshTest extends SshTestBase {
@Override
protected SshSessionFactory createSessionFactory() {
SshdSessionFactory result = new SshdSessionFactory(new JGitKeyCache(),
null);
// The home directory is mocked at this point!
result.setHomeDirectory(FS.DETECTED.userHome());
result.setSshDirectory(sshDir);
return result;
return new SshdSessionFactoryBuilder()
// No proxies in tests
.setProxyDataFactory(null)
// No ssh-agent in tests
.setConnectorFactory(null)
// The home directory is mocked at this point!
.setHomeDirectory(FS.DETECTED.userHome())
.setSshDirectory(sshDir)
.build(new JGitKeyCache());
}
@Override
@ -351,6 +354,21 @@ public void testJumpHost() throws Exception {
}
}
@Test
public void testJumpHostNone() throws Exception {
// Should not try to go through the non-existing proxy
cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
"Host server", //
"HostName localhost", //
"Port " + testPort, //
"User " + TEST_USER, //
"IdentityFile " + privateKey1.getAbsolutePath(), //
"ProxyJump none", //
"", //
"Host *", //
"ProxyJump " + TEST_USER + "@localhost:1234");
}
@Test
public void testJumpHostWrongKeyAtProxy() throws Exception {
// Test that we find the proxy server's URI in the exception message

View File

@ -50,6 +50,10 @@ public class NoFilesSshBuilderTest extends SshTestHarness {
@Override
protected SshSessionFactory createSessionFactory() {
return new SshdSessionFactoryBuilder() //
// No proxies in tests
.setProxyDataFactory(null)
// No ssh-agent in tests
.setConnectorFactory(null)
.setConfigStoreFactory((h, f, u) -> null)
.setDefaultKeysProvider(f -> new KeyAuthenticator())
.setServerKeyDatabase((h, s) -> new ServerKeyDatabase() {

View File

@ -33,6 +33,7 @@
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
import org.eclipse.jgit.util.FS;
import org.junit.After;
import org.junit.Test;
@ -80,6 +81,12 @@ public boolean accept(String connectAddress,
};
}
@Override
protected ConnectorFactory getConnectorFactory() {
// No ssh-agent in tests
return null;
}
@Override
protected Iterable<KeyPair> getDefaultKeys(File dir) {
// This would work for this simple test case:

View File

@ -23,6 +23,7 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.0.0";x-inter
org.apache.sshd.common.signature,
org.apache.sshd.common.util.buffer,
org.eclipse.jgit.transport",
org.eclipse.jgit.internal.transport.sshd.agent;version="6.0.0";x-internal:=true,
org.eclipse.jgit.internal.transport.sshd.auth;version="6.0.0";x-internal:=true,
org.eclipse.jgit.internal.transport.sshd.proxy;version="6.0.0";x-friends:="org.eclipse.jgit.ssh.apache.test",
org.eclipse.jgit.transport.sshd;version="6.0.0";
@ -31,7 +32,8 @@ Export-Package: org.eclipse.jgit.internal.transport.sshd;version="6.0.0";x-inter
org.apache.sshd.common.keyprovider,
org.eclipse.jgit.util,
org.apache.sshd.client.session,
org.apache.sshd.client.keyverifier"
org.apache.sshd.client.keyverifier",
org.eclipse.jgit.transport.sshd.agent;version="6.0.0"
Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
org.apache.sshd.agent;version="[2.7.0,2.8.0)",
org.apache.sshd.client;version="[2.7.0,2.8.0)",
@ -71,6 +73,7 @@ Import-Package: net.i2p.crypto.eddsa;version="[0.3.0,0.4.0)",
org.apache.sshd.common.util.buffer;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.closeable;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io.functors;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.io.resource;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.logging;version="[2.7.0,2.8.0)",
org.apache.sshd.common.util.net;version="[2.7.0,2.8.0)",

View File

@ -0,0 +1,61 @@
# JGit SSH support via Apache MINA sshd
This bundle provides an implementation of git transport over SSH implemented via
[Apache MINA sshd](https://mina.apache.org/sshd-project/).
## Service registration
This bundle declares a service for the `java.util.ServiceLoader` for interface
`org.eclipse.jgit.transport.ssh.SshSessionFactory`. The core JGit bundle uses the service
loader to pick up an implementation of that interface.
Note that JGit simply uses the first `SshSessionFactory` provided by the `ServiceLoader`.
If the service loader cannot find the session factory, either ensure that the service
declaration is on the Classpath of bundle `org.eclipse.jgit`, or set the factory explicitly
(see below).
In an OSGi environment, one might need a service loader bridge, or have a little OSGi
fragment for bundle `org.eclipse.jgit` that puts the right service declaration onto the
Classpath of that bundle. (OSGi fragments become part of the Classpath of their host
bundle.)
## Configuring an SSH implementation for JGit
The simplest way to set an SSH implementation for JGit is to install it globally via
`SshSessionFactory.setInstance()`. This instance will be used by JGit for all SSH
connections by default.
It is also possible to set the SSH implementation individually for any git command
that needs a transport (`TransportCommand`) via a `org.eclipse.jgit.api.TransportConfigCallback`.
To do so, set the wanted `SshSessionFactory` on the SSH transport, like:
```java
SshSessionFactory customFactory = ...; // Get it from wherever
FetchCommand fetch = git.fetch()
.setTransportConfigCallback(transport -> {
if (transport instanceof SshTransport) {
((SshTransport) transport).setSshSessionFactory(customFactory);
}
})
...
.call();
```
## Using a different SSH implementation
To use a different SSH implementation:
* Do not include this bundle in your product.
* Include the bundle of the alternate implementation.
* If the service loader finds the alternate implementation, nothing more is needed.
* Otherwise ensure the service declaration from the other bundle is on the Classpath of bundle `org.eclipse.jgit`,
* or set the `SshSessionFactory` for JGit explicitly (see above).
## Using an external SSH executable
JGit has built-in support for not using any Java SSH implementation but an external SSH
executable. To use an external SSH executable, set environment variable **GIT_SSH** to
the path of the executable. JGit will create a sub-process to run the executable and
communicate with this sub-process to perform the git operation.

View File

@ -19,6 +19,7 @@ identityFileNoKey=No keys found in identity {0}
identityFileMultipleKeys=Multiple key pairs found in identity {0}
identityFileNotFound=Skipping identity ''{0}'': file not found
identityFileUnsupportedFormat=Unsupported format in identity {0}
invalidSignatureAlgorithm=Signature algorithm ''{0}'' is not valid for a key of type ''{1}''
kexServerKeyInvalid=Server key did not validate
keyEncryptedMsg=Key ''{0}'' is encrypted. Enter the passphrase to decrypt it.
keyEncryptedPrompt=Passphrase
@ -84,6 +85,10 @@ serverIdTooLong=Server identification is longer than 255 characters (including l
serverIdWithNul=Server identification contains a NUL character: {0}
sessionCloseFailed=Closing the session failed
sessionWithoutUsername=SSH session created without user name; cannot authenticate
sshAgentReplyLengthError=Invalid SSH agent reply message length {0} after command {1}
sshAgentReplyUnexpected=Unexpected reply from ssh-agent: {0}
sshAgentShortReadBuffer=Short read from SSH agent
sshAgentWrongNumberOfKeys=Invalid number of SSH agent keys: {0}
sshClosingDown=Apache MINA sshd session factory is closing down; cannot create new ssh sessions on this factory
sshCommandTimeout={0} timed out after {1} seconds while opening the channel
sshProcessStillRunning={0} is not yet completed, cannot get exit code

View File

@ -12,8 +12,12 @@
import static java.text.MessageFormat.format;
import static org.eclipse.jgit.transport.SshConstants.PUBKEY_ACCEPTED_ALGORITHMS;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import org.apache.sshd.client.auth.pubkey.KeyAgentIdentity;
import org.apache.sshd.client.auth.pubkey.PublicKeyIdentity;
import org.apache.sshd.client.auth.pubkey.UserAuthPublicKey;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.session.ClientSession;
@ -38,7 +42,7 @@ public void init(ClientSession rawSession, String service)
throw new IllegalStateException("Wrong session type: " //$NON-NLS-1$
+ rawSession.getClass().getCanonicalName());
}
JGitClientSession session = ((JGitClientSession) rawSession);
JGitClientSession session = (JGitClientSession) rawSession;
HostConfigEntry hostConfig = session.getHostConfigEntry();
// Set signature algorithms for public key authentication
String pubkeyAlgos = hostConfig.getProperty(PUBKEY_ACCEPTED_ALGORITHMS);
@ -60,5 +64,48 @@ public void init(ClientSession rawSession, String service)
// If we don't set signature factories here, the default ones from the
// session will be used.
super.init(session, service);
// In sshd 2.7.0, we end up now with a key iterator that uses keys
// provided by an ssh-agent even if IdentitiesOnly is true. So if
// needed, filter out any KeyAgentIdentity.
if (hostConfig.isIdentitiesOnly()) {
Iterator<PublicKeyIdentity> original = keys;
// The original iterator will already have gotten the identities
// from the agent. Unfortunately there's nothing we can do about
// that; it'll have to be fixed upstream. (As will, ultimately,
// respecting isIdentitiesOnly().) At least we can simply not
// use the keys the agent provided.
//
// See https://issues.apache.org/jira/browse/SSHD-1218
keys = new Iterator<>() {
private PublicKeyIdentity value;
@Override
public boolean hasNext() {
if (value != null) {
return true;
}
PublicKeyIdentity next = null;
while (original.hasNext()) {
next = original.next();
if (!(next instanceof KeyAgentIdentity)) {
value = next;
return true;
}
}
return false;
}
@Override
public PublicKeyIdentity next() {
if (hasNext()) {
PublicKeyIdentity result = value;
value = null;
return result;
}
throw new NoSuchElementException();
}
};
}
}
}

View File

@ -32,8 +32,10 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.config.hosts.HostConfigEntry;
import org.apache.sshd.client.future.ConnectFuture;
@ -100,6 +102,8 @@ public class JGitSshClient extends SshClient {
private ProxyDataFactory proxyDatabase;
private Supplier<SshAgentFactory> agentFactorySupplier = () -> null;
@Override
protected SessionFactory createSessionFactory() {
// Override the parent's default
@ -368,6 +372,22 @@ public CredentialsProvider getCredentialsProvider() {
return credentialsProvider;
}
@Override
public SshAgentFactory getAgentFactory() {
return agentFactorySupplier.get();
}
@Override
protected void checkConfig() {
// The super class requires channel factories for agent forwarding if a
// factory for an SSH agent is set. We haven't implemented this yet, and
// we don't do SSH agent forwarding for now. Unfortunately, there is no
// way to bypass this check in the super class except making
// getAgentFactory() return null until after the check.
super.checkConfig();
agentFactorySupplier = super::getAgentFactory;
}
/**
* A {@link SessionFactory} to create our own specialized
* {@link JGitClientSession}s.
@ -439,7 +459,7 @@ public boolean hasNext() {
@Override
public KeyPair next() {
if (hasElement == null && !hasNext()
if ((hasElement == null && !hasNext())
|| !hasElement.booleanValue()) {
throw new NoSuchElementException();
}

View File

@ -34,6 +34,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;
@ -138,6 +139,8 @@ public class OpenSshServerKeyDatabase
private final List<HostKeyFile> defaultFiles = new ArrayList<>();
private Random prng;
/**
* Creates a new {@link OpenSshServerKeyDatabase}.
*
@ -680,7 +683,9 @@ private String createHostKeyLine(Collection<SshdSocketAddress> patterns,
// or to Apache MINA sshd.
NamedFactory<Mac> digester = KnownHostDigest.SHA1;
Mac mac = digester.create();
SecureRandom prng = new SecureRandom();
if (prng == null) {
prng = new SecureRandom();
}
byte[] salt = new byte[mac.getDefaultBlockSize()];
for (SshdSocketAddress address : patterns) {
if (result.length() > 0) {

View File

@ -1,3 +1,12 @@
/*
* Copyright (C) 2018, 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.internal.transport.sshd;
import org.eclipse.jgit.nls.NLS;
@ -39,6 +48,7 @@ public static SshdText get() {
/***/ public String identityFileMultipleKeys;
/***/ public String identityFileNotFound;
/***/ public String identityFileUnsupportedFormat;
/***/ public String invalidSignatureAlgorithm;
/***/ public String kexServerKeyInvalid;
/***/ public String keyEncryptedMsg;
/***/ public String keyEncryptedPrompt;
@ -96,6 +106,10 @@ public static SshdText get() {
/***/ public String serverIdWithNul;
/***/ public String sessionCloseFailed;
/***/ public String sessionWithoutUsername;
/***/ public String sshAgentReplyLengthError;
/***/ public String sshAgentReplyUnexpected;
/***/ public String sshAgentShortReadBuffer;
/***/ public String sshAgentWrongNumberOfKeys;
/***/ public String sshClosingDown;
/***/ public String sshCommandTimeout;
/***/ public String sshProcessStillRunning;

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.internal.transport.sshd.agent;
import java.util.Iterator;
import java.util.ServiceLoader;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
/**
* Provides a {@link ConnectorFactory} obtained via the {@link ServiceLoader}.
*/
public final class ConnectorFactoryProvider {
private static volatile ConnectorFactory INSTANCE = loadDefaultFactory();
private static ConnectorFactory loadDefaultFactory() {
ServiceLoader<ConnectorFactory> loader = ServiceLoader
.load(ConnectorFactory.class);
Iterator<ConnectorFactory> iter = loader.iterator();
while (iter.hasNext()) {
ConnectorFactory candidate = iter.next();
if (candidate.isSupported()) {
return candidate;
}
}
return null;
}
/**
* Retrieves the currently set default {@link ConnectorFactory}.
*
* @return the {@link ConnectorFactory}, or {@code null} if none.
*/
public static ConnectorFactory getDefaultFactory() {
return INSTANCE;
}
/**
* Sets the default {@link ConnectorFactory}.
*
* @param factory
* {@link ConnectorFactory} to use, or {@code null} to use the
* factory discovered via the {@link ServiceLoader}.
*/
public static void setDefaultFactory(ConnectorFactory factory) {
INSTANCE = factory == null ? loadDefaultFactory() : factory;
}
private ConnectorFactoryProvider() {
// No instantiation
}
}

View File

@ -0,0 +1,72 @@
/*
* 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.internal.transport.sshd.agent;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import org.apache.sshd.agent.SshAgent;
import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.agent.SshAgentServer;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.channel.ChannelFactory;
import org.apache.sshd.common.session.ConnectionService;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
/**
* A factory for creating {@link SshAgentClient}s.
*/
public class JGitSshAgentFactory implements SshAgentFactory {
private final @NonNull ConnectorFactory factory;
private final File homeDir;
/**
* Creates a new {@link JGitSshAgentFactory}.
*
* @param factory
* {@link JGitSshAgentFactory} to wrap
* @param homeDir
* for obtaining the current local user's home directory
*/
public JGitSshAgentFactory(@NonNull ConnectorFactory factory,
File homeDir) {
this.factory = factory;
this.homeDir = homeDir;
}
@Override
public List<ChannelFactory> getChannelForwardingFactories(
FactoryManager manager) {
// No agent forwarding supported yet.
return Collections.emptyList();
}
@Override
public SshAgent createClient(FactoryManager manager) throws IOException {
// sshd 2.8.0 will pass us the session here. At that point, we can get
// the HostConfigEntry and extract and handle the IdentityAgent setting.
// For now, pass null to let the ConnectorFactory do its default
// behavior (Pageant on Windows, SSH_AUTH_SOCK on Unixes with the
// jgit-builtin factory).
return new SshAgentClient(factory.create(null, homeDir));
}
@Override
public SshAgentServer createServer(ConnectionService service)
throws IOException {
// This should be called in a server only.
return null;
}
}

View File

@ -0,0 +1,246 @@
/*
* 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.internal.transport.sshd.agent;
import java.io.IOException;
import java.security.KeyPair;
import java.security.PublicKey;
import java.text.MessageFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sshd.agent.SshAgent;
import org.apache.sshd.agent.SshAgentConstants;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.BufferException;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
import org.eclipse.jgit.transport.sshd.agent.Connector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A client for an SSH2 agent. This client supports only querying identities and
* signature requests.
*
* @see <a href="https://tools.ietf.org/html/draft-miller-ssh-agent-04">SSH
* Agent Protocol, RFC draft</a>
*/
public class SshAgentClient implements SshAgent {
private static final Logger LOG = LoggerFactory
.getLogger(SshAgentClient.class);
// OpenSSH limit
private static final int MAX_NUMBER_OF_KEYS = 2048;
private final AtomicBoolean closed = new AtomicBoolean();
private final Connector connector;
/**
* Creates a new {@link SshAgentClient} implementing the SSH2 ssh agent
* protocol, using the given {@link Connector} to connect to the SSH agent
* and to exchange messages.
*
* @param connector
* {@link Connector} to use
*/
public SshAgentClient(Connector connector) {
this.connector = connector;
}
private boolean open(boolean debugging) throws IOException {
if (closed.get()) {
if (debugging) {
LOG.debug("SSH agent connection already closed"); //$NON-NLS-1$
}
return false;
}
boolean connected = connector != null && connector.connect();
if (!connected) {
if (debugging) {
LOG.debug("No SSH agent (SSH_AUTH_SOCK not set)"); //$NON-NLS-1$
}
}
return connected;
}
@Override
public void close() throws IOException {
if (!closed.getAndSet(true) && connector != null) {
connector.close();
}
}
@Override
public Iterable<? extends Map.Entry<PublicKey, String>> getIdentities()
throws IOException {
boolean debugging = LOG.isDebugEnabled();
if (!open(debugging)) {
return Collections.emptyList();
}
if (debugging) {
LOG.debug("Requesting identities from SSH agent"); //$NON-NLS-1$
}
try {
Buffer reply = rpc(
SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES);
byte cmd = reply.getByte();
if (cmd != SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER) {
throw new SshException(MessageFormat.format(
SshdText.get().sshAgentReplyUnexpected,
SshAgentConstants.getCommandMessageName(cmd)));
}
int numberOfKeys = reply.getInt();
if (numberOfKeys < 0 || numberOfKeys > MAX_NUMBER_OF_KEYS) {
throw new SshException(MessageFormat.format(
SshdText.get().sshAgentWrongNumberOfKeys,
Integer.toString(numberOfKeys)));
}
if (numberOfKeys == 0) {
if (debugging) {
LOG.debug("SSH agent has no keys"); //$NON-NLS-1$
}
return Collections.emptyList();
}
if (debugging) {
LOG.debug("Got {} key(s) from the SSH agent", //$NON-NLS-1$
Integer.toString(numberOfKeys));
}
boolean tracing = LOG.isTraceEnabled();
List<Map.Entry<PublicKey, String>> keys = new ArrayList<>(
numberOfKeys);
for (int i = 0; i < numberOfKeys; i++) {
PublicKey key = reply.getPublicKey();
String comment = reply.getString();
if (tracing) {
LOG.trace("Got SSH agent {} key: {} {}", //$NON-NLS-1$
KeyUtils.getKeyType(key),
KeyUtils.getFingerPrint(key), comment);
}
keys.add(new AbstractMap.SimpleImmutableEntry<>(key, comment));
}
return keys;
} catch (BufferException e) {
throw new SshException(SshdText.get().sshAgentShortReadBuffer, e);
}
}
@Override
public Map.Entry<String, byte[]> sign(SessionContext session, PublicKey key,
String algorithm, byte[] data) throws IOException {
boolean debugging = LOG.isDebugEnabled();
String keyType = KeyUtils.getKeyType(key);
String signatureAlgorithm;
if (algorithm != null) {
if (!KeyUtils.getCanonicalKeyType(algorithm).equals(keyType)) {
throw new IllegalArgumentException(MessageFormat.format(
SshdText.get().invalidSignatureAlgorithm, algorithm,
keyType));
}
signatureAlgorithm = algorithm;
} else {
signatureAlgorithm = keyType;
}
if (!open(debugging)) {
return null;
}
int flags = 0;
switch (signatureAlgorithm) {
case KeyUtils.RSA_SHA512_KEY_TYPE_ALIAS:
case KeyUtils.RSA_SHA512_CERT_TYPE_ALIAS:
flags = 4;
break;
case KeyUtils.RSA_SHA256_KEY_TYPE_ALIAS:
case KeyUtils.RSA_SHA256_CERT_TYPE_ALIAS:
flags = 2;
break;
default:
break;
}
ByteArrayBuffer msg = new ByteArrayBuffer();
msg.putInt(0);
msg.putByte(SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST);
msg.putPublicKey(key);
msg.putBytes(data);
msg.putInt(flags);
if (debugging) {
LOG.debug(
"sign({}): signing request to SSH agent for {} key, {} signature; flags={}", //$NON-NLS-1$
session, keyType, signatureAlgorithm,
Integer.toString(flags));
}
Buffer reply = rpc(SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST,
msg.getCompactData());
byte cmd = reply.getByte();
if (cmd != SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE) {
throw new SshException(
MessageFormat.format(SshdText.get().sshAgentReplyUnexpected,
SshAgentConstants.getCommandMessageName(cmd)));
}
try {
Buffer signatureReply = new ByteArrayBuffer(reply.getBytes());
String actualAlgorithm = signatureReply.getString();
byte[] signature = signatureReply.getBytes();
if (LOG.isTraceEnabled()) {
LOG.trace(
"sign({}): signature reply from SSH agent for {} key: {} signature={}", //$NON-NLS-1$
session, keyType, actualAlgorithm,
BufferUtils.toHex(':', signature));
} else if (LOG.isDebugEnabled()) {
LOG.debug(
"sign({}): signature reply from SSH agent for {} key, {} signature", //$NON-NLS-1$
session, keyType, actualAlgorithm);
}
return new AbstractMap.SimpleImmutableEntry<>(actualAlgorithm,
signature);
} catch (BufferException e) {
throw new SshException(SshdText.get().sshAgentShortReadBuffer, e);
}
}
private Buffer rpc(byte command, byte[] message) throws IOException {
return new ByteArrayBuffer(connector.rpc(command, message));
}
private Buffer rpc(byte command) throws IOException {
return new ByteArrayBuffer(connector.rpc(command));
}
@Override
public boolean isOpen() {
return !closed.get();
}
@Override
public void addIdentity(KeyPair key, String comment) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void removeIdentity(PublicKey key) throws IOException {
throw new UnsupportedOperationException();
}
@Override
public void removeAllIdentities() throws IOException {
throw new UnsupportedOperationException();
}
}

View File

@ -95,8 +95,8 @@ public final void close() {
@Override
public final void start() throws Exception {
if (user != null && !user.isEmpty()
|| password != null && password.length > 0) {
if ((user != null && !user.isEmpty())
|| (password != null && password.length > 0)) {
return;
}
askCredentials();

View File

@ -31,7 +31,7 @@ public abstract class AbstractClientProxyConnector
.toMillis(30L);
/** Guards {@link #done} and {@link #bufferedCommands}. */
private Object lock = new Object();
private final Object lock = new Object();
private boolean done;

View File

@ -113,8 +113,8 @@ public void sendClientProxyMetadata(ClientSession sshSession)
IoSession session = sshSession.getIoSession();
session.addCloseFutureListener(f -> close());
StringBuilder msg = connect();
if (proxyUser != null && !proxyUser.isEmpty()
|| proxyPassword != null && proxyPassword.length > 0) {
if ((proxyUser != null && !proxyUser.isEmpty())
|| (proxyPassword != null && proxyPassword.length > 0)) {
authenticator = basic;
basic.setParams(null);
basic.start();
@ -232,7 +232,8 @@ private void handleMessage(IoSession session, List<String> reply)
} catch (HttpParser.ParseException e) {
throw new IOException(
format(SshdText.get().proxyHttpUnexpectedReply,
proxyAddress, reply.get(0)));
proxyAddress, reply.get(0)),
e);
}
}

View File

@ -31,6 +31,23 @@ public static class ParseException extends Exception {
private static final long serialVersionUID = -1634090143702048640L;
/**
* Creates a new {@link ParseException} without cause.
*/
public ParseException() {
super();
}
/**
* Creates a new {@link ParseException} with the given {@code cause}.
*
* @param cause
* {@link Throwable} that caused this exception, or
* {@code null} if none
*/
public ParseException(Throwable cause) {
super(cause);
}
}
private HttpParser() {
@ -64,7 +81,7 @@ public static StatusLine parseStatusLine(String line)
resultCode = Integer.parseUnsignedInt(
line.substring(firstBlank + 1, secondBlank));
} catch (NumberFormatException e) {
throw new ParseException();
throw new ParseException(e);
}
// Again, accept even if the reason is missing
String reason = ""; //$NON-NLS-1$

View File

@ -94,7 +94,7 @@ private enum SocksAuthenticationMethod {
// JSON(9),
NONE_ACCEPTABLE(0xFF);
private byte value;
private final byte value;
SocksAuthenticationMethod(int value) {
this.value = (byte) value;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 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
@ -28,7 +28,6 @@
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.regex.Pattern;
@ -44,9 +43,9 @@
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.functors.IOFunction;
import org.apache.sshd.common.util.net.SshdSocketAddress;
import org.apache.sshd.sftp.client.SftpClient;
import org.apache.sshd.sftp.client.SftpClient.CloseableHandle;
import org.apache.sshd.sftp.client.SftpClient.CopyMode;
import org.apache.sshd.sftp.client.SftpClientFactory;
import org.apache.sshd.sftp.common.SftpException;
@ -220,7 +219,8 @@ private List<URIish> determineHops(List<URIish> currentHops,
HostConfigEntry hostConfig, String host) throws IOException {
if (currentHops.isEmpty()) {
String jumpHosts = hostConfig.getProperty(SshConstants.PROXY_JUMP);
if (!StringUtils.isEmptyOrNull(jumpHosts)) {
if (!StringUtils.isEmptyOrNull(jumpHosts)
&& !SshConstants.NONE.equals(jumpHosts)) {
try {
return parseProxyJump(jumpHosts);
} catch (URISyntaxException e) {
@ -416,20 +416,6 @@ public void destroy() {
}
}
/**
* Helper interface like {@link Supplier}, but possibly raising an
* {@link IOException}.
*
* @param <T>
* return type
*/
@FunctionalInterface
private interface FtpOperation<T> {
T call() throws IOException;
}
private class SshdFtpChannel implements FtpChannel {
private SftpClient ftp;
@ -485,9 +471,9 @@ private String absolute(String path) {
return path;
}
private <T> T map(FtpOperation<T> op) throws IOException {
private <T> T map(IOFunction<Void, T> op) throws IOException {
try {
return op.call();
return op.apply(null);
} catch (IOException e) {
if (e instanceof SftpException) {
throw new FtpChannel.FtpException(e.getLocalizedMessage(),
@ -499,7 +485,7 @@ private <T> T map(FtpOperation<T> op) throws IOException {
@Override
public void cd(String path) throws IOException {
cwd = map(() -> ftp.canonicalPath(absolute(path)));
cwd = map(x -> ftp.canonicalPath(absolute(path)));
if (cwd.isEmpty()) {
cwd += '/';
}
@ -512,39 +498,28 @@ public String pwd() throws IOException {
@Override
public Collection<DirEntry> ls(String path) throws IOException {
return map(() -> {
return map(x -> {
List<DirEntry> result = new ArrayList<>();
try (CloseableHandle handle = ftp.openDir(absolute(path))) {
AtomicReference<Boolean> atEnd = new AtomicReference<>(
Boolean.FALSE);
while (!atEnd.get().booleanValue()) {
List<SftpClient.DirEntry> chunk = ftp.readDir(handle,
atEnd);
if (chunk == null) {
break;
for (SftpClient.DirEntry remote : ftp.readDir(absolute(path))) {
result.add(new DirEntry() {
@Override
public String getFilename() {
return remote.getFilename();
}
for (SftpClient.DirEntry remote : chunk) {
result.add(new DirEntry() {
@Override
public String getFilename() {
return remote.getFilename();
}
@Override
public long getModifiedTime() {
return remote.getAttributes()
.getModifyTime().toMillis();
}
@Override
public boolean isDirectory() {
return remote.getAttributes().isDirectory();
}
});
@Override
public long getModifiedTime() {
return remote.getAttributes().getModifyTime()
.toMillis();
}
}
@Override
public boolean isDirectory() {
return remote.getAttributes().isDirectory();
}
});
}
return result;
});
@ -552,7 +527,7 @@ public boolean isDirectory() {
@Override
public void rmdir(String path) throws IOException {
map(() -> {
map(x -> {
ftp.rmdir(absolute(path));
return null;
});
@ -561,7 +536,7 @@ public void rmdir(String path) throws IOException {
@Override
public void mkdir(String path) throws IOException {
map(() -> {
map(x -> {
ftp.mkdir(absolute(path));
return null;
});
@ -569,17 +544,17 @@ public void mkdir(String path) throws IOException {
@Override
public InputStream get(String path) throws IOException {
return map(() -> ftp.read(absolute(path)));
return map(x -> ftp.read(absolute(path)));
}
@Override
public OutputStream put(String path) throws IOException {
return map(() -> ftp.write(absolute(path)));
return map(x -> ftp.write(absolute(path)));
}
@Override
public void rm(String path) throws IOException {
map(() -> {
map(x -> {
ftp.remove(absolute(path));
return null;
});
@ -587,7 +562,7 @@ public void rm(String path) throws IOException {
@Override
public void rename(String from, String to) throws IOException {
map(() -> {
map(x -> {
String src = absolute(from);
String dest = absolute(to);
try {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2018, 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
@ -56,11 +56,14 @@
import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyDatabase;
import org.eclipse.jgit.internal.transport.sshd.PasswordProviderWrapper;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
import org.eclipse.jgit.internal.transport.sshd.agent.JGitSshAgentFactory;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshConfigStore;
import org.eclipse.jgit.transport.SshConstants;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.sshd.agent.Connector;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
import org.eclipse.jgit.util.FS;
/**
@ -102,9 +105,9 @@ public SshdSessionFactory() {
/**
* Creates a new {@link SshdSessionFactory} using the given {@link KeyCache}
* and {@link ProxyDataFactory}. The {@code keyCache} is used for all sessions
* created through this session factory; cached keys are destroyed when the
* session factory is {@link #close() closed}.
* and {@link ProxyDataFactory}. The {@code keyCache} is used for all
* sessions created through this session factory; cached keys are destroyed
* when the session factory is {@link #close() closed}.
* <p>
* Caching ssh keys in memory for an extended period of time is generally
* considered bad practice, but there may be circumstances where using a
@ -114,13 +117,21 @@ public SshdSessionFactory() {
* to use a {@link #createKeyPasswordProvider(CredentialsProvider)
* KeyPasswordProvider} that has access to some secure storage and can save
* and retrieve passwords from there without user interaction. Another
* approach is to use an ssh agent.
* approach is to use an SSH agent.
* </p>
* <p>
* Note that the underlying ssh library (Apache MINA sshd) may or may not
* keep ssh keys in memory for unspecified periods of time irrespective of
* the use of a {@link KeyCache}.
* </p>
* <p>
* By default, the factory uses the {@link java.util.ServiceLoader} to find
* a {@link ConnectorFactory} for creating a {@link Connector} to connect to
* a running SSH agent. If it finds one, the SSH agent is used in publickey
* authentication. If there is none, no SSH agent will ever be contacted.
* Note that one can define {@code IdentitiesOnly yes} for a host entry in
* the {@code ~/.ssh/config} file to bypass the SSH agent in any case.
* </p>
*
* @param keyCache
* {@link KeyCache} to use for caching ssh keys, or {@code null}
@ -216,6 +227,11 @@ public SshdSession getSession(URIish uri,
new JGitUserInteraction(credentialsProvider));
client.setUserAuthFactories(getUserAuthFactories());
client.setKeyIdentityProvider(defaultKeysProvider);
ConnectorFactory connectors = getConnectorFactory();
if (connectors != null) {
client.setAgentFactory(
new JGitSshAgentFactory(connectors, home));
}
// JGit-specific things:
JGitSshClient jgitClient = (JGitSshClient) client;
jgitClient.setKeyCache(getKeyCache());
@ -436,6 +452,20 @@ protected ServerKeyDatabase createServerKeyDatabase(@NonNull File homeDir,
getDefaultKnownHostsFiles(sshDir));
}
/**
* Gets a {@link ConnectorFactory}. If this returns {@code null}, SSH agents
* are not supported.
* <p>
* The default implementation uses {@link ConnectorFactory#getDefault()}
* </p>
*
* @return the factory, or {@code null} if no SSH agent support is desired
* @since 6.0
*/
protected ConnectorFactory getConnectorFactory() {
return ConnectorFactory.getDefault();
}
/**
* Gets the list of default user known hosts files. The default returns
* ~/.ssh/known_hosts and ~/.ssh/known_hosts2. The ssh config

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
* Copyright (C) 2020, 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
@ -20,6 +20,7 @@
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshConfigStore;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
import org.eclipse.jgit.util.StringUtils;
/**
@ -114,7 +115,7 @@ public SshdSessionFactoryBuilder setConfigFile(
}
/**
* A factory interface for creating a @link SshConfigStore}.
* A factory interface for creating a {@link SshConfigStore}.
*/
@FunctionalInterface
public interface ConfigStoreFactory {
@ -232,6 +233,41 @@ public SshdSessionFactoryBuilder setServerKeyDatabase(
return this;
}
/**
* Sets an explicit {@link ConnectorFactory}. If {@code null}, there will be
* no support for SSH agents.
* <p>
* If not set, the created {@link SshdSessionFactory} will use the
* {@link java.util.ServiceLoader} to find an {@link ConnectorFactory}.
* </p>
*
* @param factory
* {@link ConnectorFactory} to use
* @return this {@link SshdSessionFactoryBuilder}
* @since 6.0
*/
public SshdSessionFactoryBuilder setConnectorFactory(
ConnectorFactory factory) {
this.state.connectorFactory = factory;
this.state.connectorFactorySet = true;
return this;
}
/**
* Removes a previously set {@link ConnectorFactory}. The created
* {@link SshdSessionFactory} will use the {@link java.util.ServiceLoader}
* to find an {@link ConnectorFactory}. This is also the default if
* {@link #setConnectorFactory(ConnectorFactory)} isn't called at all.
*
* @return this {@link SshdSessionFactoryBuilder}
* @since 6.0
*/
public SshdSessionFactoryBuilder withDefaultConnectorFactory() {
this.state.connectorFactory = null;
this.state.connectorFactorySet = false;
return this;
}
/**
* Builds a {@link SshdSessionFactory} as configured, using the given
* {@link KeyCache} for caching keys.
@ -277,6 +313,10 @@ private static class State {
BiFunction<File, File, ServerKeyDatabase> serverKeyDatabaseCreator;
ConnectorFactory connectorFactory;
boolean connectorFactorySet;
State copy() {
State c = new State();
c.proxyDataFactory = proxyDataFactory;
@ -290,6 +330,8 @@ State copy() {
c.defaultKeyFileFinder = defaultKeyFileFinder;
c.defaultKeysProvider = defaultKeysProvider;
c.serverKeyDatabaseCreator = serverKeyDatabaseCreator;
c.connectorFactory = connectorFactory;
c.connectorFactorySet = connectorFactorySet;
return c;
}
@ -388,6 +430,15 @@ protected SshConfigStore createSshConfigStore(File homeDir,
return super.createSshConfigStore(homeDir, configFile,
localUserName);
}
@Override
protected ConnectorFactory getConnectorFactory() {
if (connectorFactorySet) {
return connectorFactory;
}
// Use default via ServiceLoader
return super.getConnectorFactory();
}
}
}
}

View File

@ -0,0 +1,116 @@
/*
* 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.transport.sshd.agent;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Objects;
import org.apache.sshd.agent.SshAgentConstants;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
/**
* Provides some utility methods for implementing {@link Connector}s.
*
* @since 6.0
*/
public abstract class AbstractConnector implements Connector {
// A somewhat sane lower bound for the maximum reply length
private static final int MIN_REPLY_LENGTH = 8 * 1024;
/**
* Default maximum reply length. 256kB is the OpenSSH limit.
*/
protected static final int DEFAULT_MAX_REPLY_LENGTH = 256 * 1024;
private final int maxReplyLength;
/**
* Creates a new instance using the {@link #DEFAULT_MAX_REPLY_LENGTH}.
*/
protected AbstractConnector() {
this(DEFAULT_MAX_REPLY_LENGTH);
}
/**
* Creates a new instance.
*
* @param maxReplyLength
* maximum number of payload bytes we're ready to accept
*/
protected AbstractConnector(int maxReplyLength) {
if (maxReplyLength < MIN_REPLY_LENGTH) {
throw new IllegalArgumentException(
"Maximum payload length too small"); //$NON-NLS-1$
}
this.maxReplyLength = maxReplyLength;
}
/**
* Retrieves the maximum message length this {@link AbstractConnector} is
* configured for.
*
* @return the maximum message length
*/
protected int getMaximumMessageLength() {
return this.maxReplyLength;
}
/**
* Prepares a message for sending by inserting the command and message
* length.
*
* @param command
* SSH agent command the request is for
* @param message
* about to be sent, including the 5 spare bytes at the front
* @throws IllegalArgumentException
* if {@code message} has less than 5 bytes
*/
protected void prepareMessage(byte command, byte[] message)
throws IllegalArgumentException {
Objects.requireNonNull(message);
if (message.length < 5) {
// No translation; internal error
throw new IllegalArgumentException("Message buffer for " //$NON-NLS-1$
+ SshAgentConstants.getCommandMessageName(command)
+ " must have at least 5 bytes; have only " //$NON-NLS-1$
+ message.length);
}
BufferUtils.putUInt(message.length - 4, message);
message[4] = command;
}
/**
* Checks the received length of a reply.
*
* @param command
* SSH agent command the reply is for
* @param length
* length as received: number of payload bytes
* @return the length as an {@code int}
* @throws IOException
* if the length is invalid
*/
protected int toLength(byte command, byte[] length)
throws IOException {
long l = BufferUtils.getUInt(length);
if (l <= 0 || l > maxReplyLength - 4) {
throw new SshException(MessageFormat.format(
SshdText.get().sshAgentReplyLengthError,
Long.toString(l),
SshAgentConstants.getCommandMessageName(command)));
}
return (int) l;
}
}

View File

@ -0,0 +1,62 @@
/*
* 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.transport.sshd.agent;
import java.io.Closeable;
import java.io.IOException;
/**
* Simple interface for connecting to something and making RPC-style
* request-reply calls.
*
* @see ConnectorFactory
* @since 6.0
*/
public interface Connector extends Closeable {
/**
* Connects to an SSH agent if there is one running. If called when already
* connected just returns {@code true}.
*
* @return {@code true} if an SSH agent is available and connected,
* {@false} if no SSH agent is available
* @throws IOException
* if connecting to the SSH agent failed
*/
boolean connect() throws IOException;
/**
* Performs a remote call to the SSH agent and returns the result.
*
* @param command
* to send
* @param message
* to send; must have at least 5 bytes, and must have 5 unused
* bytes at the front.
* @return the result received
* @throws IOException
* if an error occurs
*/
byte[] rpc(byte command, byte[] message) throws IOException;
/**
* Performs a remote call sending only a command without any parameters to
* the SSH agent and returns the result.
*
* @param command
* to send
* @return the result received
* @throws IOException
* if an error occurs
*/
default byte[] rpc(byte command) throws IOException {
return rpc(command, new byte[5]);
}
}

View File

@ -0,0 +1,173 @@
/*
* 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.transport.sshd.agent;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.internal.transport.sshd.agent.ConnectorFactoryProvider;
/**
* A factory for creating {@link Connector}s. This is a service provider
* interface; implementations are discovered via the
* {@link java.util.ServiceLoader}, or can be set explicitly on a
* {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
*
* @since 6.0
*/
public interface ConnectorFactory {
/**
* Retrieves the currently set default {@link ConnectorFactory}. This is the
* factory that is used unless overridden by the
* {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
*
* @return the current default factory; may be {@code null} if none is set
* and the {@link java.util.ServiceLoader} cannot find any suitable
* implementation
*/
static ConnectorFactory getDefault() {
return ConnectorFactoryProvider.getDefaultFactory();
}
/**
* Sets a default {@link ConnectorFactory}. This is the factory that is used
* unless overridden by the
* {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
* <p>
* If no default factory is set programmatically, an implementation is
* discovered via the {@link java.util.ServiceLoader}.
* </p>
*
* @param factory
* {@link ConnectorFactory} to set, or {@code null} to revert to
* the default behavior of using the
* {@link java.util.ServiceLoader}.
*/
static void setDefault(ConnectorFactory factory) {
ConnectorFactoryProvider.setDefaultFactory(factory);
}
/**
* Creates a new {@link Connector}.
*
* @param identityAgent
* identifies the wanted agent connection; if {@code null}, the
* factory is free to provide a {@link Connector} to a default
* agent. The value will typically come from the
* {@code IdentityAgent} setting in {@code ~/.ssh/config}.
* @param homeDir
* the current local user's home directory as configured in the
* {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}
* @return a new {@link Connector}
* @throws IOException
* if no connector can be created
*/
@NonNull
Connector create(String identityAgent, File homeDir)
throws IOException;
/**
* Tells whether this {@link ConnectorFactory} is applicable on the
* currently running platform.
*
* @return {@code true} if the factory can be used, {@code false} otherwise
*/
boolean isSupported();
/**
* Retrieves a name for this factory.
*
* @return the name
*/
String getName();
/**
* {@link ConnectorDescriptor}s describe available {@link Connector}s a
* {@link ConnectorFactory} may provide.
* <p>
* A {@link ConnectorFactory} may support connecting to different SSH
* agents. Agents are identified by name; a user can choose a specific agent
* for instance via the {@code IdentityAgent} setting in
* {@code ~/.ssh/config}.
* </p>
* <p>
* OpenSSH knows two built-in names: "none" for not using any agent, and
* "SSH_AUTH_SOCK" for using an agent that communicates over a Unix domain
* socket given by the value of environment variable {@code SSH_AUTH_SOCK}.
* Other agents can be specified in OpenSSH by specifying the socket file
* directly. (The "standard" OpenBSD OpenSSH knows only this communication
* mechanism.) "SSH_AUTH_SOCK" is also the default in OpenBSD OpenSSH if
* nothing is configured.
* </p>
* <p>
* A particular {@link ConnectorFactory} may support more communication
* mechanisms or different agents. For instance, a factory on Windows might
* support Pageant, Win32-OpenSSH, or even git bash ssh-agent, and might
* accept internal names like "pageant", "openssh", "SSH_AUTH_SOCK" in
* {@link ConnectorFactory#create(String, File)} to choose among them.
* </p>
* The {@link ConnectorDescriptor} interface and the
* {@link ConnectorFactory#getSupportedConnectors()} and
* {@link ConnectorFactory#getDefaultConnector()} methods provide a way for
* code using a {@link ConnectorFactory} to learn what the factory supports
* and thus implement some way by which a user can influence the default
* behavior if {@code IdentityAgent} is not set or
* {@link ConnectorFactory#create(String, File)} is called with
* {@code identityAgent == null}.
*/
interface ConnectorDescriptor {
/**
* Retrieves the internal name of a supported {@link Connector}. The
* internal name is the one a user can specify for instance in the
* {@code IdentityAgent} setting in {@code ~/.ssh/config} to select the
* connector.
*
* @return the internal name; not empty
*/
@NonNull
String getIdentityAgent();
/**
* Retrieves a display name for a {@link Connector}, suitable for
* showing in a UI.
*
* @return the display name; properly localized and not empty
*/
@NonNull
String getDisplayName();
}
/**
* Tells which kinds of SSH agents this {@link ConnectorFactory} supports.
* <p>
* An implementation of this method should document the possible values it
* returns.
* </p>
*
* @return an immutable collection of {@link ConnectorDescriptor}s,
* including {@link #getDefaultConnector()} and not including a
* descriptor for internal name "none"
*/
@NonNull
Collection<ConnectorDescriptor> getSupportedConnectors();
/**
* Tells what kind of {@link Connector} this {@link ConnectorFactory}
* creates if {@link ConnectorFactory#create(String, File)} is called with
* {@code identityAgent == null}.
*
* @return a {@link ConnectorDescriptor} for the default connector
*/
ConnectorDescriptor getDefaultConnector();
}

View File

@ -0,0 +1,6 @@
/**
* Service provider interfaces for connecting to an SSH agent. Implementations
* are discovered via the {@link java.util.ServiceLoader}, or can be set
* explicitly on a {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
*/
package org.eclipse.jgit.transport.sshd.agent;

View File

@ -0,0 +1,6 @@
/**
* Provides a JGit {@link org.eclipse.jgit.transport.SshSessionFactory}
* implemented via <a href="https://mina.apache.org/sshd-project/">Apache MINA
* sshd</a>.
*/
package org.eclipse.jgit.transport.sshd;

View File

@ -138,7 +138,7 @@ public void testQuoteParsing() throws Exception {
assertEquals(2222, osc.lookup("unquoted").getPort());
assertEquals(2222, osc.lookup("hosts").getPort());
assertEquals(" spaced\ttld ", osc.lookup("spaced").getHostName());
assertEquals("bad.tld\"", osc.lookup("bad").getHostName());
assertEquals("bad.tld", osc.lookup("bad").getHostName());
}
@Test
@ -229,7 +229,7 @@ public void testAlias_PreferredAuthentications() throws Exception {
@Test
public void testAlias_InheritPreferredAuthentications() throws Exception {
config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+ "\tPreferredAuthentications publickey, hostbased\n");
+ "\tPreferredAuthentications 'publickey, hostbased'\n");
final Host h = osc.lookup("orcz");
assertNotNull(h);
assertEquals("publickey,hostbased", h.getPreferredAuthentications());

View File

@ -0,0 +1,59 @@
# JGit SSH support via JSch
This bundle provides an implementation of git transport over SSH implemented via JSch.
**This bundle should be considered deprecated**. It is essentially unmaintained, and
the JGit project may decide anytime to remove it completely without further ado.
The officially supported SSH transport is in bundle `org.eclipse.jgit.ssh.apache` and is
built upon [Apache MINA sshd](https://mina.apache.org/sshd-project/).
## Service registration
This bundle declares a service for the `java.util.ServiceLoader` for interface
`org.eclipse.jgit.transport.ssh.SshSessionFactory`. The core JGit bundle uses the service
loader to pick up an implementation of that interface. The bundle in an OSGi fragment
to ensure that the service loader works in an OSGi environment without the need to
install a service loader bridge.
Note that JGit simply uses the first `SshSessionFactory` provided by the `ServiceLoader`.
## Using a different SSH implementation
To use a different SSH implementation:
* Do not include this bundle in your product.
* Include the bundle of the alternate implementation.
* If the service loader finds the alternate implementation, nothing more is needed.
* Otherwise ensure the service declaration from the other bundle is on the Classpath of bundle `org.eclipse.jgit`,
* or set the `SshSessionFactory` for JGit explicitly (see below).
## Configuring an SSH implementation for JGit
The simplest way to set an SSH implementation for JGit is to install it globally via
`SshSessionFactory.setInstance()`. This instance will be used by JGit for all SSH
connections by default.
It is also possible to set the SSH implementation individually for any git command
that needs a transport (`TransportCommand`) via a `org.eclipse.jgit.api.TransportConfigCallback`.
To do so, set the wanted `SshSessionFactory` on the SSH transport, like:
```java
SshSessionFactory customFactory = ...; // Get it from wherever
FetchCommand fetch = git.fetch()
.setTransportConfigCallback(transport -> {
if (transport instanceof SshTransport) {
((SshTransport) transport).setSshSessionFactory(customFactory);
}
})
...
.call();
```
## Using an external SSH executable
JGit has built-in support for not using any Java SSH implementation but an external SSH
executable. To use an external SSH executable, set environment variable **GIT_SSH** to
the path of the executable. JGit will create a sub-process to run the executable and
communicate with this sub-process to perform the git operation.

View File

@ -0,0 +1,14 @@
/**
* Provides a JGit {@link org.eclipse.jgit.transport.SshSessionFactory}
* implemented via JSch.
* <p>
* This package should be considered <b>deprecated</b>. It is essentially
* unmaintained and the JGit project may decide to remove it completely without
* further ado at any time.
* </p>
* <p>
* The officially supported Java SSH implementation for JGit is in bundle
* {@code org.eclipse.jgit.ssh.apache} and is built upon
* <a href="https://mina.apache.org/sshd-project/">Apache MINA sshd</a>.
*/
package org.eclipse.jgit.transport.ssh.jsch;

View File

@ -43,6 +43,7 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
org.eclipse.jgit.internal.transport.connectivity;version="[6.0.0,6.1.0)",
org.eclipse.jgit.internal.transport.http;version="[6.0.0,6.1.0)",
org.eclipse.jgit.internal.transport.parser;version="[6.0.0,6.1.0)",
org.eclipse.jgit.internal.transport.ssh;version="[6.0.0,6.1.0)",
org.eclipse.jgit.junit;version="[6.0.0,6.1.0)",
org.eclipse.jgit.junit.time;version="[6.0.0,6.1.0)",
org.eclipse.jgit.lfs;version="[6.0.0,6.1.0)",

View File

@ -81,7 +81,8 @@ public void testCheckoutCRLF() throws Exception {
testCheckout(TEXT_CRLF, AUTO_CRLF, "\n", "\r\n");
testCheckout(TEXT_CRLF, AUTO_CRLF, "\r\n", "\r\n");
testCheckout(TEXT_CRLF, AUTO_CRLF, "\n\r", "\r\n\r");
testCheckout(TEXT_CRLF, null, "\n\r", "\r\n\r");
testCheckout(null, AUTO_CRLF, "\n\r", "\n\r"); // Lone CR
testCheckout(null, AUTO_CRLF, "\n\r\n", "\n\r\n");
testCheckout(TEXT_CRLF, null, "\n\r\n", "\r\n\r\n");
@ -89,7 +90,8 @@ public void testCheckoutCRLF() throws Exception {
testCheckout(TEXT_CRLF, AUTO_CRLF, "a\nb\n", "a\r\nb\r\n");
testCheckout(TEXT_CRLF, AUTO_CRLF, "a\rb\r", "a\rb\r");
testCheckout(TEXT_CRLF, AUTO_CRLF, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
testCheckout(TEXT_CRLF, null, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
testCheckout(null, AUTO_CRLF, "a\n\rb\n\r", "a\n\rb\n\r"); // Lone CR
testCheckout(TEXT_CRLF, AUTO_CRLF, "a\r\nb\r\n", "a\r\nb\r\n");
}
@ -199,7 +201,8 @@ public void testCheckinLF() throws Exception {
testCheckin(TEXT_LF, AUTO_LF, "\n\r", "\n\r");
testCheckin(TEXT_LF, AUTO_LF, "\n\r\n", "\n\n");
testCheckin(TEXT_LF, AUTO_LF, "\r\n\r", "\n\r");
testCheckin(TEXT_LF, null, "\r\n\r", "\n\r");
testCheckin(null, AUTO_LF, "\r\n\r", "\r\n\r"); // Lone CR
testCheckin(TEXT_LF, AUTO_LF, "a\nb\n", "a\nb\n");
testCheckin(TEXT_LF, AUTO_LF, "a\rb\r", "a\rb\r");
@ -214,14 +217,16 @@ public void testCheckinCRLF() throws Exception {
testCheckin(TEXT_CRLF, AUTO_CRLF, "\n", "\r\n");
testCheckin(TEXT_CRLF, AUTO_CRLF, "\r\n", "\r\n");
testCheckin(TEXT_CRLF, AUTO_CRLF, "\n\r", "\r\n\r");
testCheckin(TEXT_CRLF, null, "\n\r", "\r\n\r");
testCheckin(null, AUTO_CRLF, "\n\r", "\n\r"); // Lone CR
testCheckin(TEXT_CRLF, AUTO_CRLF, "\n\r\n", "\r\n\r\n");
testCheckin(TEXT_CRLF, AUTO_CRLF, "\r\n\r", "\r\n\r");
testCheckin(TEXT_CRLF, AUTO_CRLF, "a\nb\n", "a\r\nb\r\n");
testCheckin(TEXT_CRLF, AUTO_CRLF, "a\rb\r", "a\rb\r");
testCheckin(TEXT_CRLF, AUTO_CRLF, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
testCheckin(TEXT_CRLF, null, "a\n\rb\n\r", "a\r\n\rb\r\n\r");
testCheckin(null, AUTO_CRLF, "a\n\rb\n\r", "a\n\rb\n\r"); // Lone CR
testCheckin(TEXT_CRLF, AUTO_CRLF, "a\r\nb\r\n", "a\r\nb\r\n");
}
@ -257,47 +262,55 @@ private void testCheckin(EolStreamType streamTypeText,
byte[] inputBytes = input.getBytes(UTF_8);
byte[] expectedConversionBytes = expectedConversion.getBytes(UTF_8);
// test using input text and assuming it was declared TEXT
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes),
streamTypeText)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
if (streamTypeText != null) {
// test using input text and assuming it was declared TEXT
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes), streamTypeText)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes,
Arrays.copyOf(b, len));
}
}
// test using input text and assuming it was declared AUTO, using binary
// detection
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes),
streamTypeWithBinaryCheck)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
if (streamTypeWithBinaryCheck != null) {
// test using input text and assuming it was declared AUTO, using
// binary detection
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes),
streamTypeWithBinaryCheck)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes,
Arrays.copyOf(b, len));
}
}
// now pollute input text with some binary bytes
inputBytes = extendWithBinaryData(inputBytes);
expectedConversionBytes = extendWithBinaryData(expectedConversionBytes);
// again, test using input text and assuming it was declared TEXT
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes), streamTypeText)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes, Arrays.copyOf(b, len));
if (streamTypeText != null) {
// again, test using input text and assuming it was declared TEXT
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes), streamTypeText)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
assertArrayEquals(expectedConversionBytes,
Arrays.copyOf(b, len));
}
}
// again, test using input text and assuming it was declared AUTO, using
// binary
// detection
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes),
streamTypeWithBinaryCheck)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
// expect no conversion
assertArrayEquals(inputBytes, Arrays.copyOf(b, len));
if (streamTypeWithBinaryCheck != null) {
// again, test using input text and assuming it was declared AUTO,
// using binary detection
try (InputStream in = EolStreamTypeUtil.wrapInputStream(
new ByteArrayInputStream(inputBytes),
streamTypeWithBinaryCheck)) {
byte[] b = new byte[1024];
int len = IO.readFully(in, b, 0);
// expect no conversion
assertArrayEquals(inputBytes, Arrays.copyOf(b, len));
}
}
}

View File

@ -608,7 +608,7 @@ public void testDiffAutoCrlfSmallFile() throws Exception {
public void testDiffAutoCrlfMediumFile() throws Exception {
String content = mediumCrLfString();
String expectedDiff = "diff --git a/test.txt b/test.txt\n"
+ "index 215c502..c10f08c 100644\n" //
+ "index 6d9ffed..50d7b5a 100644\n" //
+ "--- a/test.txt\n" //
+ "+++ b/test.txt\n" //
+ "@@ -1,4 +1,5 @@\n" //
@ -624,7 +624,7 @@ public void testDiffAutoCrlfMediumFile() throws Exception {
public void testDiffAutoCrlfLargeFile() throws Exception {
String content = largeCrLfString();
String expectedDiff = "diff --git a/test.txt b/test.txt\n"
+ "index 7014942..c0487a7 100644\n" //
+ "index d6399a1..de26ce5 100644\n" //
+ "--- a/test.txt\n" //
+ "+++ b/test.txt\n" //
+ "@@ -1,4 +1,5 @@\n"
@ -665,9 +665,9 @@ private void doAutoCrLfTest(String content, String expectedDiff)
private static String largeCrLfString() {
String line = "012345678901234567890123456789012345678901234567\r\n";
StringBuilder builder = new StringBuilder(
2 * RawText.FIRST_FEW_BYTES);
while (builder.length() < 2 * RawText.FIRST_FEW_BYTES) {
int bufferSize = RawText.getBufferSize();
StringBuilder builder = new StringBuilder(2 * bufferSize);
while (builder.length() < 2 * bufferSize) {
builder.append(line);
}
return builder.toString();
@ -677,9 +677,9 @@ private static String mediumCrLfString() {
// Create a CR-LF string longer than RawText.FIRST_FEW_BYTES whose
// canonical representation is shorter than RawText.FIRST_FEW_BYTES.
String line = "01234567\r\n"; // 10 characters
StringBuilder builder = new StringBuilder(
RawText.FIRST_FEW_BYTES + line.length());
while (builder.length() <= RawText.FIRST_FEW_BYTES) {
int bufferSize = RawText.getBufferSize();
StringBuilder builder = new StringBuilder(bufferSize + line.length());
while (builder.length() <= bufferSize) {
builder.append(line);
}
return builder.toString();

View File

@ -0,0 +1,636 @@
/*
* Copyright (C) 2008, 2021 Google Inc. 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.internal.transport.ssh;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.SshConfigStore.HostConfig;
import org.eclipse.jgit.transport.SshConstants;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.eclipse.jgit.util.SystemReader;
import org.junit.Before;
import org.junit.Test;
public class OpenSshConfigFileTest extends RepositoryTestCase {
private File home;
private File configFile;
private OpenSshConfigFile osc;
@Override
@Before
public void setUp() throws Exception {
super.setUp();
home = new File(trash, "home");
FileUtils.mkdir(home);
configFile = new File(new File(home, ".ssh"), Constants.CONFIG);
FileUtils.mkdir(configFile.getParentFile());
mockSystemReader.setProperty(Constants.OS_USER_NAME_KEY, "jex_junit");
mockSystemReader.setProperty("TST_VAR", "TEST");
osc = new OpenSshConfigFile(home, configFile, "jex_junit");
}
private void config(String data) throws IOException {
FS fs = FS.DETECTED;
long resolution = FS.getFileStoreAttributes(configFile.toPath())
.getFsTimestampResolution().toNanos();
Instant lastMtime = fs.lastModifiedInstant(configFile);
do {
try (final OutputStreamWriter fw = new OutputStreamWriter(
new FileOutputStream(configFile), UTF_8)) {
fw.write(data);
TimeUnit.NANOSECONDS.sleep(resolution);
} catch (InterruptedException e) {
Thread.interrupted();
}
} while (lastMtime.equals(fs.lastModifiedInstant(configFile)));
}
private HostConfig lookup(String hostname) {
return osc.lookupDefault(hostname, 0, null);
}
private void assertHost(String expected, HostConfig h) {
assertEquals(expected, h.getValue(SshConstants.HOST_NAME));
}
private void assertUser(String expected, HostConfig h) {
assertEquals(expected, h.getValue(SshConstants.USER));
}
private void assertPort(int expected, HostConfig h) {
assertEquals(expected,
OpenSshConfigFile.positive(h.getValue(SshConstants.PORT)));
}
private void assertIdentity(File expected, HostConfig h) {
String actual = h.getValue(SshConstants.IDENTITY_FILE);
if (expected == null) {
assertNull(actual);
} else {
assertEquals(expected, new File(actual));
}
}
private void assertAttempts(int expected, HostConfig h) {
assertEquals(expected, OpenSshConfigFile
.positive(h.getValue(SshConstants.CONNECTION_ATTEMPTS)));
}
@Test
public void testNoConfig() {
final HostConfig h = lookup("repo.or.cz");
assertNotNull(h);
assertHost("repo.or.cz", h);
assertUser("jex_junit", h);
assertPort(22, h);
assertAttempts(1, h);
assertIdentity(null, h);
}
@Test
public void testSeparatorParsing() throws Exception {
config("Host\tfirst\n" +
"\tHostName\tfirst.tld\n" +
"\n" +
"Host second\n" +
" HostName\tsecond.tld\n" +
"Host=third\n" +
"HostName=third.tld\n\n\n" +
"\t Host = fourth\n\n\n" +
" \t HostName\t=fourth.tld\n" +
"Host\t = last\n" +
"HostName \t last.tld");
assertNotNull(lookup("first"));
assertHost("first.tld", lookup("first"));
assertNotNull(lookup("second"));
assertHost("second.tld", lookup("second"));
assertNotNull(lookup("third"));
assertHost("third.tld", lookup("third"));
assertNotNull(lookup("fourth"));
assertHost("fourth.tld", lookup("fourth"));
assertNotNull(lookup("last"));
assertHost("last.tld", lookup("last"));
}
@Test
public void testQuoteParsing() throws Exception {
config("Host \"good\"\n" +
" HostName=\"good.tld\"\n" +
" Port=\"6007\"\n" +
" User=\"gooduser\"\n" +
"Host multiple unquoted and \"quoted\" \"hosts\"\n" +
" Port=\"2222\"\n" +
"Host \"spaced\"\n" +
"# Bad host name, but testing preservation of spaces\n" +
" HostName=\" spaced\ttld \"\n" +
"# Misbalanced quotes\n" +
"Host \"bad\"\n" +
"# OpenSSH doesn't allow this but ...\n" +
" HostName=bad.tld\"\n");
assertHost("good.tld", lookup("good"));
assertUser("gooduser", lookup("good"));
assertPort(6007, lookup("good"));
assertPort(2222, lookup("multiple"));
assertPort(2222, lookup("quoted"));
assertPort(2222, lookup("and"));
assertPort(2222, lookup("unquoted"));
assertPort(2222, lookup("hosts"));
assertHost(" spaced\ttld ", lookup("spaced"));
assertHost("bad.tld", lookup("bad"));
}
@Test
public void testAdvancedParsing() throws Exception {
// Escaped quotes, and line comments
config("Host foo\n"
+ " HostName=\"foo\\\"d.tld\"\n"
+ " User= someone#foo\n"
+ "Host bar\n"
+ " User ' some one#two' # Comment\n"
+ " GlobalKnownHostsFile '/a folder/with spaces/hosts' '/other/more hosts' # Comment\n"
+ "Host foobar\n"
+ " User a\\ u\\ thor\n"
+ "Host backslash\n"
+ " User some\\one\\\\\\ foo\n"
+ "Host backslash_before_quote\n"
+ " User \\\"someone#\"el#se\" #Comment\n"
+ "Host backslash_in_quote\n"
+ " User 'some\\one\\\\\\ foo'\n");
assertHost("foo\"d.tld", lookup("foo"));
assertUser("someone#foo", lookup("foo"));
HostConfig c = lookup("bar");
assertUser(" some one#two", c);
assertArrayEquals(
new Object[] { "/a folder/with spaces/hosts",
"/other/more hosts" },
c.getValues("GlobalKnownHostsFile").toArray());
assertUser("a u thor", lookup("foobar"));
assertUser("some\\one\\ foo", lookup("backslash"));
assertUser("\"someone#el#se", lookup("backslash_before_quote"));
assertUser("some\\one\\\\ foo", lookup("backslash_in_quote"));
}
@Test
public void testCaseInsensitiveKeyLookup() throws Exception {
config("Host orcz\n" + "Port 29418\n"
+ "\tHostName repo.or.cz\nStrictHostKeyChecking yes\n");
final HostConfig c = lookup("orcz");
String exactCase = c.getValue("StrictHostKeyChecking");
assertEquals("yes", exactCase);
assertEquals(exactCase, c.getValue("stricthostkeychecking"));
assertEquals(exactCase, c.getValue("STRICTHOSTKEYCHECKING"));
assertEquals(exactCase, c.getValue("sTrIcThostKEYcheckING"));
assertNull(c.getValue("sTrIcThostKEYcheckIN"));
}
@Test
public void testAlias_DoesNotMatch() throws Exception {
config("Host orcz\n" + "Port 29418\n"
+ "\tHostName repo.or.cz\n");
final HostConfig h = lookup("repo.or.cz");
assertNotNull(h);
assertHost("repo.or.cz", h);
assertUser("jex_junit", h);
assertPort(22, h);
assertIdentity(null, h);
final HostConfig h2 = lookup("orcz");
assertHost("repo.or.cz", h);
assertUser("jex_junit", h);
assertPort(29418, h2);
assertIdentity(null, h);
}
@Test
public void testAlias_OptionsSet() throws Exception {
config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\tPort 2222\n"
+ "\tUser jex\n" + "\tIdentityFile .ssh/id_jex\n"
+ "\tForwardX11 no\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertHost("repo.or.cz", h);
assertUser("jex", h);
assertPort(2222, h);
assertIdentity(new File(home, ".ssh/id_jex"), h);
}
@Test
public void testAlias_OptionsKeywordCaseInsensitive() throws Exception {
config("hOsT orcz\n" + "\thOsTnAmE repo.or.cz\n" + "\tPORT 2222\n"
+ "\tuser jex\n" + "\tidentityfile .ssh/id_jex\n"
+ "\tForwardX11 no\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertHost("repo.or.cz", h);
assertUser("jex", h);
assertPort(2222, h);
assertIdentity(new File(home, ".ssh/id_jex"), h);
}
@Test
public void testAlias_OptionsInherit() throws Exception {
config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+ "\tHostName not.a.host.example.com\n" + "\tPort 2222\n"
+ "\tUser jex\n" + "\tIdentityFile .ssh/id_jex\n"
+ "\tForwardX11 no\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertHost("repo.or.cz", h);
assertUser("jex", h);
assertPort(2222, h);
assertIdentity(new File(home, ".ssh/id_jex"), h);
}
@Test
public void testAlias_PreferredAuthenticationsDefault() throws Exception {
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertNull(h.getValue(SshConstants.PREFERRED_AUTHENTICATIONS));
}
@Test
public void testAlias_PreferredAuthentications() throws Exception {
config("Host orcz\n" + "\tPreferredAuthentications publickey\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertEquals("publickey",
h.getValue(SshConstants.PREFERRED_AUTHENTICATIONS));
}
@Test
public void testAlias_InheritPreferredAuthentications() throws Exception {
config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+ "\tPreferredAuthentications 'publickey, hostbased'\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertEquals("publickey,hostbased",
h.getValue(SshConstants.PREFERRED_AUTHENTICATIONS));
}
@Test
public void testAlias_BatchModeDefault() throws Exception {
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertNull(h.getValue(SshConstants.BATCH_MODE));
}
@Test
public void testAlias_BatchModeYes() throws Exception {
config("Host orcz\n" + "\tBatchMode yes\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertTrue(OpenSshConfigFile.flag(h.getValue(SshConstants.BATCH_MODE)));
}
@Test
public void testAlias_InheritBatchMode() throws Exception {
config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+ "\tBatchMode yes\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertTrue(OpenSshConfigFile.flag(h.getValue(SshConstants.BATCH_MODE)));
}
@Test
public void testAlias_ConnectionAttemptsDefault() throws Exception {
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(1, h);
}
@Test
public void testAlias_ConnectionAttempts() throws Exception {
config("Host orcz\n" + "\tConnectionAttempts 5\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(5, h);
}
@Test
public void testAlias_invalidConnectionAttempts() throws Exception {
config("Host orcz\n" + "\tConnectionAttempts -1\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(1, h);
}
@Test
public void testAlias_badConnectionAttempts() throws Exception {
config("Host orcz\n" + "\tConnectionAttempts xxx\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(1, h);
}
@Test
public void testDefaultBlock() throws Exception {
config("ConnectionAttempts 5\n\nHost orcz\nConnectionAttempts 3\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(5, h);
}
@Test
public void testHostCaseInsensitive() throws Exception {
config("hOsT orcz\nConnectionAttempts 3\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(3, h);
}
@Test
public void testListValueSingle() throws Exception {
config("Host orcz\nUserKnownHostsFile /foo/bar\n");
final HostConfig c = lookup("orcz");
assertNotNull(c);
assertEquals("/foo/bar", c.getValue("UserKnownHostsFile"));
}
@Test
public void testListValueMultiple() throws Exception {
// Tilde expansion occurs within the parser
config("Host orcz\nUserKnownHostsFile \"~/foo/ba z\" /foo/bar \n");
final HostConfig c = lookup("orcz");
assertNotNull(c);
assertArrayEquals(new Object[] { new File(home, "foo/ba z").getPath(),
"/foo/bar" },
c.getValues("UserKnownHostsFile").toArray());
}
@Test
public void testRepeatedLookupsWithModification() throws Exception {
config("Host orcz\n" + "\tConnectionAttempts -1\n");
final HostConfig h1 = lookup("orcz");
assertNotNull(h1);
assertAttempts(1, h1);
config("Host orcz\n" + "\tConnectionAttempts 5\n");
final HostConfig h2 = lookup("orcz");
assertNotNull(h2);
assertNotSame(h1, h2);
assertAttempts(5, h2);
assertAttempts(1, h1);
assertNotSame(h1, h2);
}
@Test
public void testIdentityFile() throws Exception {
config("Host orcz\nIdentityFile \"~/foo/ba z\"\nIdentityFile /foo/bar");
final HostConfig h = lookup("orcz");
assertNotNull(h);
// Does tilde replacement
assertArrayEquals(new Object[] { new File(home, "foo/ba z").getPath(),
"/foo/bar" },
h.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testMultiIdentityFile() throws Exception {
config("IdentityFile \"~/foo/ba z\"\nHost orcz\nIdentityFile /foo/bar\nHOST *\nIdentityFile /foo/baz");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertArrayEquals(new Object[] { new File(home, "foo/ba z").getPath(),
"/foo/bar", "/foo/baz" },
h.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testNegatedPattern() throws Exception {
config("Host repo.or.cz\nIdentityFile ~/foo/bar\nHOST !*.or.cz\nIdentityFile /foo/baz");
final HostConfig h = lookup("repo.or.cz");
assertNotNull(h);
assertIdentity(new File(home, "foo/bar"), h);
assertArrayEquals(new Object[] { new File(home, "foo/bar").getPath() },
h.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testPattern() throws Exception {
config("Host repo.or.cz\nIdentityFile ~/foo/bar\nHOST *.or.cz\nIdentityFile /foo/baz");
final HostConfig h = lookup("repo.or.cz");
assertNotNull(h);
assertIdentity(new File(home, "foo/bar"), h);
assertArrayEquals(new Object[] { new File(home, "foo/bar").getPath(),
"/foo/baz" },
h.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testMultiHost() throws Exception {
config("Host orcz *.or.cz\nIdentityFile ~/foo/bar\nHOST *.or.cz\nIdentityFile /foo/baz");
final HostConfig h1 = lookup("repo.or.cz");
assertNotNull(h1);
assertIdentity(new File(home, "foo/bar"), h1);
assertArrayEquals(new Object[] { new File(home, "foo/bar").getPath(),
"/foo/baz" },
h1.getValues(SshConstants.IDENTITY_FILE).toArray());
final HostConfig h2 = lookup("orcz");
assertNotNull(h2);
assertIdentity(new File(home, "foo/bar"), h2);
assertArrayEquals(new Object[] { new File(home, "foo/bar").getPath() },
h2.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testEqualsSign() throws Exception {
config("Host=orcz\n\tConnectionAttempts = 5\n\tUser=\t foobar\t\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertAttempts(5, h);
assertUser("foobar", h);
}
@Test
public void testMissingArgument() throws Exception {
config("Host=orcz\n\tSendEnv\nIdentityFile\t\nForwardX11\n\tUser=\t foobar\t\n");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertUser("foobar", h);
assertEquals("[]", h.getValues("SendEnv").toString());
assertIdentity(null, h);
assertNull(h.getValue("ForwardX11"));
}
@Test
public void testHomeDirUserReplacement() throws Exception {
config("Host=orcz\n\tIdentityFile %d/.ssh/%u_id_dsa");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertIdentity(new File(new File(home, ".ssh"), "jex_junit_id_dsa"), h);
}
@Test
public void testHostnameReplacement() throws Exception {
config("Host=orcz\nHost *.*\n\tHostname %h\nHost *\n\tHostname %h.example.org");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertHost("orcz.example.org", h);
}
@Test
public void testRemoteUserReplacement() throws Exception {
config("Host=orcz\n\tUser foo\n" + "Host *.*\n\tHostname %h\n"
+ "Host *\n\tHostname %h.ex%%20ample.org\n\tIdentityFile ~/.ssh/%h_%r_id_dsa");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertIdentity(
new File(new File(home, ".ssh"),
"orcz.ex%20ample.org_foo_id_dsa"),
h);
}
@Test
public void testLocalhostFQDNReplacement() throws Exception {
String localhost = SystemReader.getInstance().getHostname();
config("Host=orcz\n\tIdentityFile ~/.ssh/%l_id_dsa");
final HostConfig h = lookup("orcz");
assertNotNull(h);
assertIdentity(
new File(new File(home, ".ssh"), localhost + "_id_dsa"),
h);
}
@Test
public void testPubKeyAcceptedAlgorithms() throws Exception {
config("Host=orcz\n\tPubkeyAcceptedAlgorithms ^ssh-rsa");
HostConfig h = lookup("orcz");
assertEquals("^ssh-rsa",
h.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS));
assertEquals("^ssh-rsa", h.getValue("PubkeyAcceptedKeyTypes"));
}
@Test
public void testPubKeyAcceptedKeyTypes() throws Exception {
config("Host=orcz\n\tPubkeyAcceptedKeyTypes ^ssh-rsa");
HostConfig h = lookup("orcz");
assertEquals("^ssh-rsa",
h.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS));
assertEquals("^ssh-rsa", h.getValue("PubkeyAcceptedKeyTypes"));
}
@Test
public void testEolComments() throws Exception {
config("#Comment\nHost=orcz #Comment\n\tPubkeyAcceptedAlgorithms ^ssh-rsa # Comment\n#Comment");
HostConfig h = lookup("orcz");
assertNotNull(h);
assertEquals("^ssh-rsa",
h.getValue(SshConstants.PUBKEY_ACCEPTED_ALGORITHMS));
}
@Test
public void testEnVarSubstitution() throws Exception {
config("Host orcz\nIdentityFile /tmp/${TST_VAR}\n"
+ "CertificateFile /tmp/${}/foo\nUser ${TST_VAR}\nIdentityAgent /tmp/${TST_VAR/bar");
HostConfig h = lookup("orcz");
assertNotNull(h);
assertEquals("/tmp/TEST",
h.getValue(SshConstants.IDENTITY_FILE));
// No variable name
assertEquals("/tmp/${}/foo", h.getValue(SshConstants.CERTIFICATE_FILE));
// User doesn't get env var substitution:
assertUser("${TST_VAR}", h);
// Unterminated:
assertEquals("/tmp/${TST_VAR/bar",
h.getValue(SshConstants.IDENTITY_AGENT));
}
@Test
public void testNegativeMatch() throws Exception {
config("Host foo.bar !foobar.baz *.baz\n" + "Port 29418\n");
HostConfig h = lookup("foo.bar");
assertNotNull(h);
assertPort(29418, h);
h = lookup("foobar.baz");
assertNotNull(h);
assertPort(22, h);
h = lookup("foo.baz");
assertNotNull(h);
assertPort(29418, h);
}
@Test
public void testNegativeMatch2() throws Exception {
// Negative match after the positive match.
config("Host foo.bar *.baz !foobar.baz\n" + "Port 29418\n");
HostConfig h = lookup("foo.bar");
assertNotNull(h);
assertPort(29418, h);
h = lookup("foobar.baz");
assertNotNull(h);
assertPort(22, h);
h = lookup("foo.baz");
assertNotNull(h);
assertPort(29418, h);
}
@Test
public void testNoMatch() throws Exception {
config("Host !host1 !host2\n" + "Port 29418\n");
HostConfig h = lookup("host1");
assertNotNull(h);
assertPort(22, h);
h = lookup("host2");
assertNotNull(h);
assertPort(22, h);
h = lookup("host3");
assertNotNull(h);
assertPort(22, h);
}
@Test
public void testMultipleMatch() throws Exception {
config("Host foo.bar\nPort 29418\nIdentityFile /foo\n\n"
+ "Host *.bar\nPort 22\nIdentityFile /bar\n"
+ "Host foo.bar\nPort 47\nIdentityFile /baz\n");
HostConfig h = lookup("foo.bar");
assertNotNull(h);
assertPort(29418, h);
assertArrayEquals(new Object[] { "/foo", "/bar", "/baz" },
h.getValues(SshConstants.IDENTITY_FILE).toArray());
}
@Test
public void testWhitespace() throws Exception {
config("Host foo \tbar baz\nPort 29418\n");
HostConfig h = lookup("foo");
assertNotNull(h);
assertPort(29418, h);
h = lookup("bar");
assertNotNull(h);
assertPort(29418, h);
h = lookup("baz");
assertNotNull(h);
assertPort(29418, h);
h = lookup("\tbar");
assertNotNull(h);
assertPort(22, h);
}
}

View File

@ -33,6 +33,7 @@
import org.eclipse.jgit.api.errors.CheckoutConflictException;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.diff.RawText;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEditor;
import org.eclipse.jgit.dircache.DirCacheEntry;
@ -826,6 +827,8 @@ public void checkContentMergeLargeBinaries(MergeStrategy strategy) throws Except
RevCommit sideCommit = git.commit().setAll(true)
.setMessage("modified file l 1500").call();
int originalBufferSize = RawText.getBufferSize();
int smallBufferSize = RawText.setBufferSize(8000);
try (ObjectInserter ins = db.newObjectInserter()) {
// Check that we don't read the large blobs.
ObjectInserter forbidInserter = new ObjectInserter.Filter() {
@ -836,7 +839,8 @@ protected ObjectInserter delegate() {
@Override
public ObjectReader newReader() {
return new BigReadForbiddenReader(super.newReader(), 8000);
return new BigReadForbiddenReader(super.newReader(),
smallBufferSize);
}
};
@ -844,6 +848,8 @@ public ObjectReader newReader() {
(ResolveMerger) strategy.newMerger(forbidInserter, db.getConfig());
boolean noProblems = merger.merge(masterCommit, sideCommit);
assertFalse(noProblems);
} finally {
RawText.setBufferSize(originalBufferSize);
}
}

View File

@ -12,6 +12,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
@ -70,4 +71,86 @@ public void testReplaceLineBreaks() {
assertEquals("a b c d",
StringUtils.replaceLineBreaksWithSpace("a\r\nb\nc d"));
}
@Test
public void testFormatWithSuffix() {
assertEquals("1023", StringUtils.formatWithSuffix(1023));
assertEquals("1k", StringUtils.formatWithSuffix(1024));
assertEquals("1025", StringUtils.formatWithSuffix(1025));
assertEquals("1048575", StringUtils.formatWithSuffix(1024 * 1024 - 1));
assertEquals("1m", StringUtils.formatWithSuffix(1024 * 1024));
assertEquals("1048577", StringUtils.formatWithSuffix(1024 * 1024 + 1));
assertEquals("1073741823",
StringUtils.formatWithSuffix(1024 * 1024 * 1024 - 1));
assertEquals("1g", StringUtils.formatWithSuffix(1024 * 1024 * 1024));
assertEquals("1073741825",
StringUtils.formatWithSuffix(1024 * 1024 * 1024 + 1));
assertEquals("3k", StringUtils.formatWithSuffix(3 * 1024));
assertEquals("3m", StringUtils.formatWithSuffix(3 * 1024 * 1024));
assertEquals("2050k",
StringUtils.formatWithSuffix(2 * 1024 * 1024 + 2048));
assertEquals("3g",
StringUtils.formatWithSuffix(3L * 1024 * 1024 * 1024));
assertEquals("3000", StringUtils.formatWithSuffix(3000));
assertEquals("3000000", StringUtils.formatWithSuffix(3_000_000));
assertEquals("1953125k", StringUtils.formatWithSuffix(2_000_000_000));
assertEquals("2000000010", StringUtils.formatWithSuffix(2_000_000_010));
assertEquals("3000000000",
StringUtils.formatWithSuffix(3_000_000_000L));
}
@Test
public void testParseWithSuffix() {
assertEquals(1024, StringUtils.parseIntWithSuffix("1k", true));
assertEquals(1024, StringUtils.parseIntWithSuffix("1 k", true));
assertEquals(1024, StringUtils.parseIntWithSuffix("1 k", true));
assertEquals(1024, StringUtils.parseIntWithSuffix(" \t1 k \n", true));
assertEquals(1024, StringUtils.parseIntWithSuffix("1k", false));
assertEquals(1024, StringUtils.parseIntWithSuffix("1K", false));
assertEquals(1024 * 1024, StringUtils.parseIntWithSuffix("1m", false));
assertEquals(1024 * 1024, StringUtils.parseIntWithSuffix("1M", false));
assertEquals(-1024 * 1024,
StringUtils.parseIntWithSuffix("-1M", false));
assertEquals(1_000_000,
StringUtils.parseIntWithSuffix(" 1000000\r\n", false));
assertEquals(1024 * 1024 * 1024,
StringUtils.parseIntWithSuffix("1g", false));
assertEquals(1024 * 1024 * 1024,
StringUtils.parseIntWithSuffix("1G", false));
assertEquals(3L * 1024 * 1024 * 1024,
StringUtils.parseLongWithSuffix("3g", false));
assertEquals(3L * 1024 * 1024 * 1024,
StringUtils.parseLongWithSuffix("3G", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseIntWithSuffix("2G", false));
assertEquals(2L * 1024 * 1024 * 1024,
StringUtils.parseLongWithSuffix("2G", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("-1m", true));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("-1000", true));
assertThrows(StringIndexOutOfBoundsException.class,
() -> StringUtils.parseLongWithSuffix("", false));
assertThrows(StringIndexOutOfBoundsException.class,
() -> StringUtils.parseLongWithSuffix(" \t \n", false));
assertThrows(StringIndexOutOfBoundsException.class,
() -> StringUtils.parseLongWithSuffix("k", false));
assertThrows(StringIndexOutOfBoundsException.class,
() -> StringUtils.parseLongWithSuffix("m", false));
assertThrows(StringIndexOutOfBoundsException.class,
() -> StringUtils.parseLongWithSuffix("g", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("1T", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("1t", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("Nonumber", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("0x001f", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("beef", false));
assertThrows(NumberFormatException.class,
() -> StringUtils.parseLongWithSuffix("8000000000000000000G",
false));
}
}

View File

@ -17,6 +17,7 @@
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.jgit.diff.RawText;
import org.junit.Assert;
import org.junit.Test;
@ -29,16 +30,17 @@ public void test() throws IOException {
assertNoCrLf("\r\n", "\n");
assertNoCrLf("\r\n", "\r\n");
assertNoCrLf("\r\r", "\r\r");
assertNoCrLf("\r\n\r", "\n\r");
assertNoCrLf("\n\r", "\n\r"); // Lone CR
assertNoCrLf("\r\n\r\r", "\r\n\r\r");
assertNoCrLf("\r\n\r\n", "\r\n\r\n");
assertNoCrLf("\r\n\r\n\r", "\n\r\n\r");
assertNoCrLf("\n\r\n\r", "\n\r\n\r"); // Lone CR
assertNoCrLf("\0\n", "\0\n");
}
@Test
public void testBoundary() throws IOException {
for (int i = AutoCRLFInputStream.BUFFER_SIZE - 10; i < AutoCRLFInputStream.BUFFER_SIZE + 10; i++) {
int boundary = RawText.getBufferSize();
for (int i = boundary - 10; i < boundary + 10; i++) {
String s1 = Strings.repeat("a", i);
assertNoCrLf(s1, s1);
String s2 = Strings.repeat("\0", i);

View File

@ -19,6 +19,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import org.eclipse.jgit.diff.RawText;
import org.junit.Assert;
import org.junit.Test;
@ -31,7 +32,7 @@ public void test() throws IOException {
assertNoCrLf("\r\n", "\n");
assertNoCrLf("\r\n", "\r\n");
assertNoCrLf("\r\r", "\r\r");
assertNoCrLf("\r\n\r", "\n\r");
assertNoCrLf("\n\r", "\n\r"); // Lone CR
assertNoCrLf("\r\n\r\r", "\r\n\r\r");
assertNoCrLf("\r\n\r\n", "\r\n\r\n");
assertNoCrLf("\n\r\n\r", "\n\r\n\r");
@ -40,7 +41,8 @@ public void test() throws IOException {
@Test
public void testBoundary() throws IOException {
for (int i = AutoCRLFOutputStream.BUFFER_SIZE - 10; i < AutoCRLFOutputStream.BUFFER_SIZE + 10; i++) {
int bufferSize = RawText.getBufferSize();
for (int i = bufferSize - 10; i < bufferSize + 10; i++) {
String s1 = Strings.repeat("a", i);
assertNoCrLf(s1, s1);
String s2 = Strings.repeat("\0", i);

View File

@ -111,7 +111,8 @@ Export-Package: org.eclipse.jgit.annotations;version="6.0.0",
org.eclipse.jgit.test",
org.eclipse.jgit.internal.transport.ssh;version="6.0.0";
x-friends:="org.eclipse.jgit.ssh.apache,
org.eclipse.jgit.ssh.jsch",
org.eclipse.jgit.ssh.jsch,
org.eclipse.jgit.test",
org.eclipse.jgit.lib;version="6.0.0";
uses:="org.eclipse.jgit.transport,
org.eclipse.jgit.util.sha1,

View File

@ -793,6 +793,7 @@ uriNotFoundWithMessage={0} not found: {1}
URINotSupported=URI not supported: {0}
userConfigInvalid=Git config in the user's home directory {0} is invalid {1}
validatingGitModules=Validating .gitmodules files
valueExceedsRange=Value ''{0}'' exceeds the range of {1}
verifySignatureBad=BAD signature from "{0}"
verifySignatureExpired=Expired signature from "{0}"
verifySignatureGood=Good signature from "{0}"

View File

@ -17,6 +17,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jgit.errors.BinaryBlobException;
import org.eclipse.jgit.errors.LargeObjectException;
@ -38,11 +39,20 @@
* they are converting from "line number" to "element index".
*/
public class RawText extends Sequence {
/** A RawText of length 0 */
public static final RawText EMPTY_TEXT = new RawText(new byte[0]);
/** Number of bytes to check for heuristics in {@link #isBinary(byte[])} */
static final int FIRST_FEW_BYTES = 8000;
/**
* Default and minimum for {@link #BUFFER_SIZE}.
*/
private static final int FIRST_FEW_BYTES = 8 * 1024;
/**
* Number of bytes to check for heuristics in {@link #isBinary(byte[])}.
*/
private static final AtomicInteger BUFFER_SIZE = new AtomicInteger(
FIRST_FEW_BYTES);
/** The file content for this sequence. */
protected final byte[] content;
@ -236,15 +246,30 @@ private int getEnd(int i) {
}
/**
* Determine heuristically whether a byte array represents binary (as
* opposed to text) content.
* Obtains the buffer size to use for analyzing whether certain content is
* text or binary, or what line endings are used if it's text.
*
* @param raw
* the raw file content.
* @return true if raw is likely to be a binary file, false otherwise
* @return the buffer size, by default {@link #FIRST_FEW_BYTES} bytes
* @since 6.0
*/
public static boolean isBinary(byte[] raw) {
return isBinary(raw, raw.length);
public static int getBufferSize() {
return BUFFER_SIZE.get();
}
/**
* Sets the buffer size to use for analyzing whether certain content is text
* or binary, or what line endings are used if it's text. If the given
* {@code bufferSize} is smaller than {@link #FIRST_FEW_BYTES} set the
* buffer size to {@link #FIRST_FEW_BYTES}.
*
* @param bufferSize
* Size to set
* @return the size actually set
* @since 6.0
*/
public static int setBufferSize(int bufferSize) {
int newSize = Math.max(FIRST_FEW_BYTES, bufferSize);
return BUFFER_SIZE.updateAndGet(curr -> newSize);
}
/**
@ -263,7 +288,7 @@ public static boolean isBinary(byte[] raw) {
* if input stream could not be read
*/
public static boolean isBinary(InputStream raw) throws IOException {
final byte[] buffer = new byte[FIRST_FEW_BYTES];
final byte[] buffer = new byte[getBufferSize()];
int cnt = 0;
while (cnt < buffer.length) {
final int n = raw.read(buffer, cnt, buffer.length - cnt);
@ -271,7 +296,19 @@ public static boolean isBinary(InputStream raw) throws IOException {
break;
cnt += n;
}
return isBinary(buffer, cnt);
return isBinary(buffer, cnt, cnt < buffer.length);
}
/**
* Determine heuristically whether a byte array represents binary (as
* opposed to text) content.
*
* @param raw
* the raw file content.
* @return true if raw is likely to be a binary file, false otherwise
*/
public static boolean isBinary(byte[] raw) {
return isBinary(raw, raw.length);
}
/**
@ -287,16 +324,63 @@ public static boolean isBinary(InputStream raw) throws IOException {
* @return true if raw is likely to be a binary file, false otherwise
*/
public static boolean isBinary(byte[] raw, int length) {
// Same heuristic as C Git
if (length > FIRST_FEW_BYTES)
length = FIRST_FEW_BYTES;
for (int ptr = 0; ptr < length; ptr++)
if (raw[ptr] == '\0')
return true;
return isBinary(raw, length, false);
}
/**
* Determine heuristically whether a byte array represents binary (as
* opposed to text) content.
*
* @param raw
* the raw file content.
* @param length
* number of bytes in {@code raw} to evaluate. This should be
* {@code raw.length} unless {@code raw} was over-allocated by
* the caller.
* @param complete
* whether {@code raw} contains the whole data
* @return true if raw is likely to be a binary file, false otherwise
* @since 6.0
*/
public static boolean isBinary(byte[] raw, int length, boolean complete) {
// Similar heuristic as C Git. Differences:
// - limited buffer size; may be only the beginning of a large blob
// - no counting of printable vs. non-printable bytes < 0x20 and 0x7F
int maxLength = getBufferSize();
if (length > maxLength) {
length = maxLength;
}
byte last = 'x'; // Just something inconspicuous.
for (int ptr = 0; ptr < length; ptr++) {
byte curr = raw[ptr];
if (isBinary(curr, last)) {
return true;
}
last = curr;
}
if (complete) {
// Buffer contains everything...
return last == '\r'; // ... so this must be a lone CR
}
return false;
}
/**
* Determines from the last two bytes read from a source if it looks like
* binary content.
*
* @param curr
* the last byte, read after {@code prev}
* @param prev
* the previous byte, read before {@code last}
* @return {@code true} if either byte is NUL, or if prev is CR and curr is
* not LF, {@code false} otherwise
* @since 6.0
*/
public static boolean isBinary(byte curr, byte prev) {
return curr == '\0' || (curr != '\n' && prev == '\r') || prev == '\0';
}
/**
* Determine heuristically whether a byte array represents text content
* using CR-LF as line separator.
@ -329,7 +413,7 @@ public static boolean isCrLfText(byte[] raw) {
* @since 5.3
*/
public static boolean isCrLfText(InputStream raw) throws IOException {
byte[] buffer = new byte[FIRST_FEW_BYTES];
byte[] buffer = new byte[getBufferSize()];
int cnt = 0;
while (cnt < buffer.length) {
int n = raw.read(buffer, cnt, buffer.length - cnt);
@ -354,13 +438,44 @@ public static boolean isCrLfText(InputStream raw) throws IOException {
* @since 5.3
*/
public static boolean isCrLfText(byte[] raw, int length) {
return isCrLfText(raw, length, false);
}
/**
* Determine heuristically whether a byte array represents text content
* using CR-LF as line separator.
*
* @param raw
* the raw file content.
* @param length
* number of bytes in {@code raw} to evaluate.
* @return {@code true} if raw is likely to be CR-LF delimited text,
* {@code false} otherwise
* @param complete
* whether {@code raw} contains the whole data
* @since 6.0
*/
public static boolean isCrLfText(byte[] raw, int length, boolean complete) {
boolean has_crlf = false;
for (int ptr = 0; ptr < length - 1; ptr++) {
if (raw[ptr] == '\0') {
return false; // binary
} else if (raw[ptr] == '\r' && raw[ptr + 1] == '\n') {
byte last = 'x'; // Just something inconspicuous
for (int ptr = 0; ptr < length; ptr++) {
byte curr = raw[ptr];
if (isBinary(curr, last)) {
return false;
}
if (curr == '\n' && last == '\r') {
has_crlf = true;
}
last = curr;
}
if (last == '\r') {
if (complete) {
// Lone CR: it's binary after all.
return false;
}
// Tough call. If the next byte, which we don't have, would be a
// '\n', it'd be a CR-LF text, otherwise it'd be binary. Just decide
// based on what we already scanned; it wasn't binary until now.
}
return has_crlf;
}
@ -409,18 +524,20 @@ public static RawText load(ObjectLoader ldr, int threshold)
throw new BinaryBlobException();
}
if (sz <= FIRST_FEW_BYTES) {
byte[] data = ldr.getCachedBytes(FIRST_FEW_BYTES);
if (isBinary(data)) {
int bufferSize = getBufferSize();
if (sz <= bufferSize) {
byte[] data = ldr.getCachedBytes(bufferSize);
if (isBinary(data, data.length, true)) {
throw new BinaryBlobException();
}
return new RawText(data);
}
byte[] head = new byte[FIRST_FEW_BYTES];
byte[] head = new byte[bufferSize];
try (InputStream stream = ldr.openStream()) {
int off = 0;
int left = head.length;
byte last = 'x'; // Just something inconspicuous
while (left > 0) {
int n = stream.read(head, off, left);
if (n < 0) {
@ -429,9 +546,11 @@ public static RawText load(ObjectLoader ldr, int threshold)
left -= n;
while (n > 0) {
if (head[off] == '\0') {
byte curr = head[off];
if (isBinary(curr, last)) {
throw new BinaryBlobException();
}
last = curr;
off++;
n--;
}

View File

@ -108,7 +108,8 @@ static boolean isBinary(ObjectLoader obj) throws IOException {
return RawText.isBinary(in1);
}
}
return RawText.isBinary(obj.getCachedBytes());
byte[] raw = obj.getCachedBytes();
return RawText.isBinary(raw, raw.length, true);
}
void hash(ObjectLoader obj) throws MissingObjectException, IOException,
@ -132,7 +133,7 @@ private void hashLargeObject(ObjectLoader obj) throws IOException,
}
void hash(byte[] raw, int ptr, int end) throws TableFullException {
final boolean text = !RawText.isBinary(raw);
final boolean text = !RawText.isBinary(raw, raw.length, true);
hashedCnt = 0;
while (ptr < end) {
int hash = 5381;

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