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>
motiejus-detectSymlinkSupport
Thomas Wolf 2021-11-02 18:48:25 +01:00 committed by Matthias Sohn
parent 68017a029c
commit 634302d2da
57 changed files with 2362 additions and 24 deletions

1
BUILD
View File

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

View File

@ -133,6 +133,18 @@ maven_jar(
sha1 = "0c9eff7145e20b338c1dd6aca36ba93ed7c0147c",
)
maven_jar(
name = "jna",
artifact = "net.java.dev.jna:jna:5.8.0",
sha1 = "3551d8d827e54858214107541d3aff9c615cb615",
)
maven_jar(
name = "jna-platform",
artifact = "net.java.dev.jna:jna-platform:5.8.0",
sha1 = "2f12f6d7f7652270d13624cef1b82d8cd9a5398e",
)
maven_jar(
name = "commons-codec",
artifact = "commons-codec:commons-codec:1.14",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

@ -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"/>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Eclipse Distribution License - Version 1.0</title>
<style type="text/css">
body {
size: 8.5in 11.0in;
margin: 0.25in 0.5in 0.25in 0.5in;
tab-interval: 0.5in;
}
p {
margin-left: auto;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
p.list {
margin-left: 0.5in;
margin-top: 0.05em;
margin-bottom: 0.05em;
}
.ubc-name {
margin-left: 0.5in;
white-space: pre;
}
</style>
</head>
<body lang="EN-US">
<p><b>Eclipse Distribution License - v 1.0</b></p>
<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
<p>All rights reserved.</p>
<p>Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
<ul><li>Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. </li>
<li>Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. </li>
<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission. </li></ul>
</p>
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.</p>
<hr>
<p><b>SHA-1 UbcCheck - MIT</b></p>
<p>Copyright (c) 2017:</p>
<div class="ubc-name">
Marc Stevens
Cryptology Group
Centrum Wiskunde & Informatica
P.O. Box 94079, 1090 GB Amsterdam, Netherlands
marc@marc-stevens.nl
</div>
<div class="ubc-name">
Dan Shumow
Microsoft Research
danshu@microsoft.com
</div>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
</p>
<ul><li>The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.</li></ul>
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</p>
</body>
</html>

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,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}

View File

@ -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;
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.transport.sshd.agent.connector;
import java.text.MessageFormat;
import com.sun.jna.LastErrorException;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Kernel32Util;
import com.sun.jna.platform.win32.User32;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Delay loading the native libraries until needed.
*/
class LibraryHolder {
private static final Logger LOG = LoggerFactory
.getLogger(LibraryHolder.class);
private static LibraryHolder INSTANCE;
private static boolean libraryLoaded = false;
public static synchronized LibraryHolder getLibrary() {
if (!libraryLoaded) {
libraryLoaded = true;
try {
INSTANCE = new LibraryHolder();
} catch (Exception | UnsatisfiedLinkError
| NoClassDefFoundError e) {
LOG.error(Texts.get().logErrorLoadLibrary, e);
}
}
return INSTANCE;
}
User32 user;
Kernel32 kernel;
private LibraryHolder() {
user = User32.INSTANCE;
kernel = Kernel32.INSTANCE;
}
String systemError(String pattern) {
int lastError = kernel.GetLastError();
String msg;
try {
msg = Kernel32Util.formatMessageFromLastErrorCode(lastError);
} catch (Exception e) {
String err = e instanceof LastErrorException
? Integer.toString(((LastErrorException) e).getErrorCode())
: Texts.get().errUnknown;
msg = MessageFormat.format(Texts.get().errLastError,
Integer.toString(lastError), err);
LOG.error(msg, e);
}
return MessageFormat.format(pattern, Integer.toString(lastError), msg);
}
}

View File

@ -0,0 +1,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;
}
}
}

View File

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

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.transport.sshd.agent.connector;
import java.nio.charset.Charset;
import com.sun.jna.Structure;
import com.sun.jna.Structure.FieldOrder;
/**
* Common things for socket communication.
*/
public final class Sockets {
private Sockets() {
// No instantiation
}
/**
* Default SSH agent socket environment variable name.
*/
public static final String ENV_SSH_AUTH_SOCK = "SSH_AUTH_SOCK"; //$NON-NLS-1$
/**
* Domain for Unix domain sockets.
*/
public static final int AF_UNIX = 1;
/**
* Socket type for duplex sockets.
*/
public static final int SOCK_STREAM = 1;
/**
* Default protocol selector.
*/
public static final int DEFAULT_PROTOCOL = 0;
/**
* Very simple representation of the C SockAddr type.
*/
@FieldOrder(value = { "sa_family", "sa_data" })
public static class SockAddr extends Structure {
// This is a "variable length struct" in C.
// Why 108 is apparently lost in time. But the file path for a Unix
// domain socket cannot be longer (including the terminating NUL).
private static final int MAX_DATA_LENGTH = 108;
/** Socket family */
public short sa_family = AF_UNIX;
/** Unix domain socket path. */
public byte[] sa_data = new byte[MAX_DATA_LENGTH];
/**
* Creates a new {@link SockAddr} for the given {@code path}.
*
* @param path
* for the Socket
* @param encoding
* to use to decode the {@code path} to a byte sequence
*/
public SockAddr(String path, Charset encoding) {
byte[] bytes = path.getBytes(encoding);
int toCopy = Math.min(sa_data.length - 1, bytes.length);
System.arraycopy(bytes, 0, sa_data, 0, toCopy);
sa_data[toCopy] = 0;
}
}
}

View File

@ -0,0 +1,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;
}

View File

@ -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);
}
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2021, Thomas Wolf <thomas.wolf@paranor.ch> and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
* https://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
package org.eclipse.jgit.internal.transport.sshd.agent.connector;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Structure;
import com.sun.jna.platform.unix.LibCAPI;
/**
* Low-level Unix/Linux JNA socket API.
*/
interface UnixSockets extends LibCAPI, Library {
/**
* Library to load. These functions live in libc.
*/
String LIBRARY_NAME = "c"; //$NON-NLS-1$
/**
* Command to set the close-on-exec flag on a file descriptor via
* {@link #fcntl(int, int, int)}.
*/
int F_SETFD = 2;
/**
* Specifies that a file descriptor shall not be inherited by child
* processes.
*/
int FD_CLOEXEC = 1;
/**
* Creates a socket and returns a file descriptor for it.
*
* @param domain
* socket domain; use {@link Sockets#AF_UNIX}
* @param type
* socket type; use {@link Sockets#SOCK_STREAM}
* @param protocol
* socket communication protocol; use
* {@link Sockets#DEFAULT_PROTOCOL}.
* @return file descriptor for the socket; should be closed eventually, or
* -1 on error.
* @throws LastErrorException
* on errors
* @see LibCAPI#close(int)
*/
int socket(int domain, int type, int protocol) throws LastErrorException;
/**
* Simple binding to fcntl; used to set the FD_CLOEXEC flag. On OS X, we
* cannot include SOCK_CLOEXEC in the socket() call.
*
* @param fd
* file descriptor to operate on
* @param command
* set to {@link #F_SETFD}
* @param flag
* zero to clear the close-on-exec flag, {@link #FD_CLOEXEC} to
* set it
* @return -1 on error, otherwise a value >= 0
* @throws LastErrorException
*/
int fcntl(int fd, int command, int flag) throws LastErrorException;
/**
* Connects a file descriptor, which must refer to a socket, to a
* {@link Sockets.SockAddr}.
*
* @param fd
* file descriptor of the socket, as returned by
* {@link #socket(int, int, int)}
* @param addr
* address to connect to
* @param addrLen
* Length of {@code addr}, use {@link Structure#size()}
* @return 0 on success; -1 otherwise
* @throws LastErrorException
* on errors
*/
int connect(int fd, Sockets.SockAddr addr, int addrLen)
throws LastErrorException;
/**
* Read data from a file descriptor.
*
* @param fd
* file descriptor to read from
* @param buf
* buffer to read into
* @param bufLen
* maximum number of bytes to read; at most length of {@code buf}
* @return number of bytes actually read; zero for EOF, -1 on error
* @throws LastErrorException
* on errors
*/
LibCAPI.ssize_t read(int fd, byte[] buf, LibCAPI.size_t bufLen)
throws LastErrorException;
/**
* Write data to a file descriptor.
*
* @param fd
* file descriptor to write to
* @param data
* data to write
* @param dataLen
* number of bytes to write
* @return number of bytes actually written; -1 on error
* @throws LastErrorException
* on errors
*/
LibCAPI.ssize_t write(int fd, byte[] data, LibCAPI.size_t dataLen)
throws LastErrorException;
}

View File

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

View File

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

View File

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

View File

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

View File

@ -33,6 +33,7 @@ import org.eclipse.jgit.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;
@ -80,6 +81,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:

View File

@ -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();
}
};
}
}
}

View File

@ -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}

View File

@ -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 {

View File

@ -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
*/

View File

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

View File

@ -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>

View File

@ -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/...",