diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2021-11-02 18:48:25 +0100 |
---|---|---|
committer | Matthias Sohn <matthias.sohn@sap.com> | 2021-11-03 23:46:54 +0100 |
commit | 634302d2da74226cff9f78e121ad5b8216c476e6 (patch) | |
tree | 29b6a8b1fb07f00fd5926ed79bbf06758fa753db | |
parent | 68017a029cb6b8648b29ae695c9e614d1f7a9770 (diff) | |
download | jgit-634302d2da74226cff9f78e121ad5b8216c476e6.tar.gz jgit-634302d2da74226cff9f78e121ad5b8216c476e6.zip |
sshd: add support for ssh-agent
Add a simple SSH agent connector using JNA. Include com.sum.jna and
com.sun.jna.platform in the target platform.
JNA is used to communicate through Unix domain sockets with ssh-agent,
and if on Windows, to communicate via shared memory with Pageant.
The new bundle o.e.j.ssh.apache.agent is an OSGi fragment so that
the java.util.ServiceLoader can find the provided factory without
further ado in OSGi environments.
Adapt both maven and bazel builds to include the new bundle.
Manually tested on OS X, CentOS 7, and Win10 with Pageant 0.76. Tested
by installing JGit built from this change into freshly downloaded
Eclipse 2021-12 M1, and then doing git fetches via SSH with different
~/.ssh/config settings (explicit IdentityFile, without any but a key in
the agent, with no keys and a key in the agent and IdentitiesOnly=yes
(must fail)).
Bug: 541274
Bug: 541275
Change-Id: I34e85467293707dbad1eb44d1f40fc2e70ba3622
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
57 files changed, 2362 insertions, 24 deletions
@@ -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"], @@ -134,6 +134,18 @@ maven_jar( ) 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", sha1 = "3cb1181b2141a7e752f5bdc998b7ef1849f726cf", @@ -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__", ], @@ -94,6 +95,22 @@ java_library( ) 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"], exports = ["@javaewah//jar"], diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml index 8139810390..22e4ebc249 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/pom.xml @@ -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> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml index ca0935a514..a15d0fd76e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml @@ -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> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml index f36717e950..98f264da0d 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml @@ -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> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml index eb0a658e59..dcd1238f9c 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.source.feature/feature.xml @@ -111,6 +111,13 @@ 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" install-size="0" diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml index 46ea77995c..01d2b33e9e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/feature.xml @@ -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> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml index 886b9b3ce7..5e0f05a850 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.ssh.apache.feature/pom.xml @@ -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> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target index ab7f63d983..5356dea1c8 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.17.target @@ -1,7 +1,7 @@ <?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="1635977786"> +<target name="jgit-4.17" sequenceNumber="1635979596"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/> @@ -31,6 +31,10 @@ <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="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.12.v20210622-2206"/> <unit id="javaewah.source" version="1.1.12.v20210622-2206"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target index 611ac5bcf3..cf8d12fdb9 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.18.target @@ -1,7 +1,7 @@ <?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="1635977786"> +<target name="jgit-4.18" sequenceNumber="1635979596"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/> @@ -31,6 +31,10 @@ <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="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.12.v20210622-2206"/> <unit id="javaewah.source" version="1.1.12.v20210622-2206"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target index d852f91782..3e6ee56b8e 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.19.target @@ -1,7 +1,7 @@ <?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="1635977786"> +<target name="jgit-4.19-staging" sequenceNumber="1635979596"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/> @@ -31,6 +31,10 @@ <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="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.12.v20210622-2206"/> <unit id="javaewah.source" version="1.1.12.v20210622-2206"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target index 08fb6ccc3b..ce9d8bca22 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.20.target @@ -1,7 +1,7 @@ <?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="1635977786"> +<target name="jgit-4.20" sequenceNumber="1635979596"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/> @@ -31,6 +31,10 @@ <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="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.12.v20210622-2206"/> <unit id="javaewah.source" version="1.1.12.v20210622-2206"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target index eaf9752588..41954429d4 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.21.target @@ -1,7 +1,7 @@ <?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="1635977845"> +<target name="jgit-4.21" sequenceNumber="1635979596"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.4.43.v20210629"/> @@ -31,6 +31,10 @@ <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="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.12.v20210622-2206"/> <unit id="javaewah.source" version="1.1.12.v20210622-2206"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210825222808-2021-09.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210825222808-2021-09.tpd index 059a5844ab..99f352011b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210825222808-2021-09.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20210825222808-2021-09.tpd @@ -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] diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 7b75c2eb68..4e1fbcb971 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -149,6 +149,12 @@ </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> <version>${project.version}</version> <classifier>sources</classifier> diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index c28da4d7fa..11f3f79637 100644 --- a/org.eclipse.jgit.pgm/pom.xml +++ b/org.eclipse.jgit.pgm/pom.xml @@ -81,6 +81,12 @@ <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> </dependency> diff --git a/org.eclipse.jgit.ssh.apache.agent/.classpath b/org.eclipse.jgit.ssh.apache.agent/.classpath new file mode 100644 index 0000000000..df1b324f7f --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.classpath @@ -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> diff --git a/org.eclipse.jgit.ssh.apache.agent/.fbprefs b/org.eclipse.jgit.ssh.apache.agent/.fbprefs new file mode 100644 index 0000000000..81a0767ff6 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.fbprefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.project b/org.eclipse.jgit.ssh.apache.agent/.project new file mode 100644 index 0000000000..73358f4a6b --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.project @@ -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> diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..66ac15c47c --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +#Mon Aug 11 16:46:12 PDT 2008 +eclipse.preferences.version=1 +encoding/<project>=UTF-8 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.runtime.prefs new file mode 100644 index 0000000000..006e07ede5 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.core.runtime.prefs @@ -0,0 +1,3 @@ +#Mon Mar 24 18:55:50 EDT 2008 +eclipse.preferences.version=1 +line.separator=\n diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..d1f54bbe65 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.core.prefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000000..5cfb8b6ac6 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.jdt.ui.prefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.tasks.ui.prefs new file mode 100644 index 0000000000..823c0f56ae --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.tasks.ui.prefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.team.ui.prefs new file mode 100644 index 0000000000..0cba949fb7 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.mylyn.team.ui.prefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.api.tools.prefs new file mode 100644 index 0000000000..c0030ded71 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.api.tools.prefs @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000000..82793f2d27 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +#Thu Jan 14 14:34:32 CST 2010 +eclipse.preferences.version=1 +resolve.requirebundle=false diff --git a/org.eclipse.jgit.ssh.apache.agent/BUILD b/org.eclipse.jgit.ssh.apache.agent/BUILD new file mode 100644 index 0000000000..0c8cf838d4 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/BUILD @@ -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" + ], +) diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..19b8ee850d --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/MANIFEST.MF @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF new file mode 100644 index 0000000000..afad570846 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/META-INF/SOURCE-MANIFEST.MF @@ -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="." diff --git a/org.eclipse.jgit.ssh.apache.agent/about.html b/org.eclipse.jgit.ssh.apache.agent/about.html new file mode 100644 index 0000000000..f971af18d0 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/about.html @@ -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> diff --git a/org.eclipse.jgit.ssh.apache.agent/build.properties b/org.eclipse.jgit.ssh.apache.agent/build.properties new file mode 100644 index 0000000000..8148271ef3 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/build.properties @@ -0,0 +1,7 @@ +source.. = src/,\ + resources/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.properties,\ + about.html diff --git a/org.eclipse.jgit.ssh.apache.agent/plugin.properties b/org.eclipse.jgit.ssh.apache.agent/plugin.properties new file mode 100644 index 0000000000..86df8f2e72 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/plugin.properties @@ -0,0 +1,2 @@ +Bundle-Name=JGit Unix SSH agent client for Apache MINA sshd +Bundle-Vendor=Eclipse JGit diff --git a/org.eclipse.jgit.ssh.apache.agent/pom.xml b/org.eclipse.jgit.ssh.apache.agent/pom.xml new file mode 100644 index 0000000000..0b5267a402 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/pom.xml @@ -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> diff --git a/org.eclipse.jgit.ssh.apache.agent/resources/META-INF/services/org.eclipse.jgit.transport.sshd.agent.ConnectorFactory b/org.eclipse.jgit.ssh.apache.agent/resources/META-INF/services/org.eclipse.jgit.transport.sshd.agent.ConnectorFactory new file mode 100644 index 0000000000..538888c770 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/resources/META-INF/services/org.eclipse.jgit.transport.sshd.agent.ConnectorFactory @@ -0,0 +1 @@ +org.eclipse.jgit.internal.transport.sshd.agent.connector.Factory diff --git a/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties b/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties new file mode 100644 index 0000000000..f884adc089 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties @@ -0,0 +1,16 @@ +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} + diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java new file mode 100644 index 0000000000..1cbf0e41b6 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java @@ -0,0 +1,44 @@ +/* + * 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 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; + } +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/LibraryHolder.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/LibraryHolder.java new file mode 100644 index 0000000000..b09b55f817 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/LibraryHolder.java @@ -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); + } + +}
\ No newline at end of file diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java new file mode 100644 index 0000000000..59fe2fc246 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +package org.eclipse.jgit.internal.transport.sshd.agent.connector; + +import java.io.IOException; + +import org.eclipse.jgit.transport.sshd.agent.AbstractConnector; + +/** + * A connector using Pageant's shared memory IPC mechanism. + */ +public class PageantConnector extends AbstractConnector { + + 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; + } + } +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantLibrary.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantLibrary.java new file mode 100644 index 0000000000..9a30d804e7 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantLibrary.java @@ -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); + } + } + } + } +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Sockets.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Sockets.java new file mode 100644 index 0000000000..3d95bdb51c --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Sockets.java @@ -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; + } + } +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java new file mode 100644 index 0000000000..6b66261546 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java @@ -0,0 +1,46 @@ +/* + * 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; + +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java new file mode 100644 index 0000000000..4c698d974a --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java @@ -0,0 +1,218 @@ +/* + * 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.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 { + + 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); + } + } +} diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java new file mode 100644 index 0000000000..6f8153d000 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixSockets.java @@ -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; +} diff --git a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF index b9a7ba9dc9..e5a66f1ee1 100644 --- a/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ssh.apache.test/META-INF/MANIFEST.MF @@ -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)", diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java index 0ad96b9acf..eef0402b07 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshProtocol2Test.java @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java index c1f5fef3cd..85626d8ee3 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java @@ -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 diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java index 9d64adc95e..fd51e0cf47 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java @@ -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() { diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java index 7b6e508c31..04c1c605d8 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java @@ -33,6 +33,7 @@ import org.eclipse.jgit.junit.ssh.SshTestHarness; 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; @@ -81,6 +82,12 @@ public class NoFilesSshTest extends SshTestHarness { } @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: // return Collections.singletonList(testUserKey); diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java index 08da18f5aa..c082a9a963 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java @@ -12,8 +12,12 @@ package org.eclipse.jgit.internal.transport.sshd; 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 class JGitPublicKeyAuthentication extends UserAuthPublicKey { 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 class JGitPublicKeyAuthentication extends UserAuthPublicKey { // 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(); + } + }; + } } } diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java index da99f56cb8..3364180099 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java @@ -63,6 +63,7 @@ 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; @@ -105,9 +106,9 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { /** * 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 @@ -117,13 +118,21 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable { * 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} diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java index b6da0866a0..d8dfbfc94d 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/Connector.java @@ -16,6 +16,7 @@ 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 { diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java index fa725ab858..b351d89ef5 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java @@ -15,7 +15,10 @@ import java.io.IOException; import org.eclipse.jgit.annotations.NonNull; /** - * A factory for creating {@link Connector}s. + * 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 */ diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/package-info.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/package-info.java new file mode 100644 index 0000000000..71ca43f3d5 --- /dev/null +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/package-info.java @@ -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; @@ -925,6 +925,7 @@ <module>org.eclipse.jgit.http.apache</module> <module>org.eclipse.jgit.http.server</module> <module>org.eclipse.jgit.ssh.apache</module> + <module>org.eclipse.jgit.ssh.apache.agent</module> <module>org.eclipse.jgit.ssh.jsch</module> <module>org.eclipse.jgit.pgm</module> <module>org.eclipse.jgit.lfs</module> diff --git a/tools/BUILD b/tools/BUILD index 4769f4222b..0c6b8ece7c 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -121,6 +121,7 @@ package_group( "//org.eclipse.jgit.pgm.test/...", "//org.eclipse.jgit.pgm/...", "//org.eclipse.jgit.ssh.apache/...", + "//org.eclipse.jgit.ssh.apache.agent/...", "//org.eclipse.jgit.test/...", "//org.eclipse.jgit.ui/...", "//org.eclipse.jgit/...", |