summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.jsch
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.ssh.jsch')
-rw-r--r--org.eclipse.jgit.ssh.jsch/.classpath8
-rw-r--r--org.eclipse.jgit.ssh.jsch/.fbprefs125
-rw-r--r--org.eclipse.jgit.ssh.jsch/.gitignore2
-rw-r--r--org.eclipse.jgit.ssh.jsch/.project34
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.runtime.prefs2
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs399
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.ui.prefs66
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.tasks.ui.prefs3
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.team.ui.prefs2
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.api.tools.prefs104
-rw-r--r--org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.core.prefs2
-rw-r--r--org.eclipse.jgit.ssh.jsch/BUILD20
-rw-r--r--org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF26
-rw-r--r--org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF7
-rw-r--r--org.eclipse.jgit.ssh.jsch/about.html96
-rw-r--r--org.eclipse.jgit.ssh.jsch/build.properties7
-rw-r--r--org.eclipse.jgit.ssh.jsch/plugin.properties2
-rw-r--r--org.eclipse.jgit.ssh.jsch/pom.xml218
-rw-r--r--org.eclipse.jgit.ssh.jsch/resources/META-INF/services/org.eclipse.jgit.transport.SshSessionFactory1
-rw-r--r--org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties4
-rw-r--r--org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/jsch/JSchText.java35
-rw-r--r--org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java133
-rw-r--r--org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java541
-rw-r--r--org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java373
-rw-r--r--org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/OpenSshConfig.java346
26 files changed, 2558 insertions, 0 deletions
diff --git a/org.eclipse.jgit.ssh.jsch/.classpath b/org.eclipse.jgit.ssh.jsch/.classpath
new file mode 100644
index 0000000000..110168ffa1
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="resources"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/org.eclipse.jgit.ssh.jsch/.fbprefs b/org.eclipse.jgit.ssh.jsch/.fbprefs
new file mode 100644
index 0000000000..81a0767ff6
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.fbprefs
@@ -0,0 +1,125 @@
+#FindBugs User Preferences
+#Mon May 04 16:24:13 PDT 2009
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|true
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|false
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+excludefilter0=findBugs/FindBugsExcludeFilter.xml
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+run_at_full_build=true
diff --git a/org.eclipse.jgit.ssh.jsch/.gitignore b/org.eclipse.jgit.ssh.jsch/.gitignore
new file mode 100644
index 0000000000..934e0e06ff
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/target
diff --git a/org.eclipse.jgit.ssh.jsch/.project b/org.eclipse.jgit.ssh.jsch/.project
new file mode 100644
index 0000000000..c29a38cb54
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.jgit.ssh.jsch</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>
+ <buildCommand>
+ <name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.resources.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000000..99f26c0203
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.runtime.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000000..5a0ad22d2a
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000000..15ef2aad5d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,399 @@
+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=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+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.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.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.source=1.8
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+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_assignment=0
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+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_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+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_resources_in_try=80
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=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_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_union_type_in_multicatch=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=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_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_method_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.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.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.insert_new_line_before_root_tags=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=true
+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_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_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=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_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_and_in_type_parameter=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_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_superinterfaces=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_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_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_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_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=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_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_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_superinterfaces=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_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_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_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_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_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_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_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+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_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+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.use_on_off_tags=true
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.ui.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000000..fef3713825
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,66 @@
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_JGit Format
+formatter_settings_version=12
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=java;javax;org;com;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=true
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_missing_override_annotations_interface_methods=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=true
+sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.insert_inferred_type_arguments=false
+sp_cleanup.make_local_variable_final=false
+sp_cleanup.make_parameters_final=false
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=true
+sp_cleanup.remove_unnecessary_nls_tags=true
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.tasks.ui.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.tasks.ui.prefs
new file mode 100644
index 0000000000..3dec4d97c7
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.tasks.ui.prefs
@@ -0,0 +1,3 @@
+eclipse.preferences.version=1
+project.repository.kind=bugzilla
+project.repository.url=https\://bugs.eclipse.org/bugs
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.team.ui.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.team.ui.prefs
new file mode 100644
index 0000000000..ce7a0f0478
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.mylyn.team.ui.prefs
@@ -0,0 +1,2 @@
+commit.comment.template=${task.description} \n\nBug\: ${task.key}
+eclipse.preferences.version=1
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.api.tools.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.api.tools.prefs
new file mode 100644
index 0000000000..c0030ded71
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.api.tools.prefs
@@ -0,0 +1,104 @@
+ANNOTATION_ELEMENT_TYPE_ADDED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_ADDED_METHOD_WITHOUT_DEFAULT_VALUE=Error
+ANNOTATION_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_FIELD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_METHOD=Error
+ANNOTATION_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_API_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_REEXPORTED_TYPE=Error
+API_COMPONENT_ELEMENT_TYPE_REMOVED_TYPE=Error
+API_USE_SCAN_FIELD_SEVERITY=Error
+API_USE_SCAN_METHOD_SEVERITY=Error
+API_USE_SCAN_TYPE_SEVERITY=Error
+CLASS_ELEMENT_TYPE_ADDED_FIELD=Error
+CLASS_ELEMENT_TYPE_ADDED_METHOD=Error
+CLASS_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+CLASS_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CLASS_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+CLASS_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+CLASS_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+CLASS_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+CLASS_ELEMENT_TYPE_REMOVED_CONSTRUCTOR=Error
+CLASS_ELEMENT_TYPE_REMOVED_FIELD=Error
+CLASS_ELEMENT_TYPE_REMOVED_METHOD=Error
+CLASS_ELEMENT_TYPE_REMOVED_SUPERCLASS=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+CLASS_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+CONSTRUCTOR_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+CONSTRUCTOR_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+ENUM_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+ENUM_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+ENUM_ELEMENT_TYPE_REMOVED_ENUM_CONSTANT=Error
+ENUM_ELEMENT_TYPE_REMOVED_FIELD=Error
+ENUM_ELEMENT_TYPE_REMOVED_METHOD=Error
+ENUM_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+FIELD_ELEMENT_TYPE_ADDED_VALUE=Error
+FIELD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+FIELD_ELEMENT_TYPE_CHANGED_FINAL_TO_NON_FINAL_STATIC_CONSTANT=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+FIELD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+FIELD_ELEMENT_TYPE_CHANGED_TYPE=Error
+FIELD_ELEMENT_TYPE_CHANGED_VALUE=Error
+FIELD_ELEMENT_TYPE_REMOVED_TYPE_ARGUMENT=Error
+FIELD_ELEMENT_TYPE_REMOVED_VALUE=Error
+ILLEGAL_EXTEND=Warning
+ILLEGAL_IMPLEMENT=Warning
+ILLEGAL_INSTANTIATE=Warning
+ILLEGAL_OVERRIDE=Warning
+ILLEGAL_REFERENCE=Warning
+INTERFACE_ELEMENT_TYPE_ADDED_DEFAULT_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_SUPER_INTERFACE_WITH_METHODS=Error
+INTERFACE_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_CONTRACTED_SUPERINTERFACES_SET=Error
+INTERFACE_ELEMENT_TYPE_CHANGED_TYPE_CONVERSION=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_FIELD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_METHOD=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_MEMBER=Error
+INTERFACE_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+INVALID_ANNOTATION=Ignore
+INVALID_JAVADOC_TAG=Ignore
+INVALID_REFERENCE_IN_SYSTEM_LIBRARIES=Error
+LEAK_EXTEND=Warning
+LEAK_FIELD_DECL=Warning
+LEAK_IMPLEMENT=Warning
+LEAK_METHOD_PARAM=Warning
+LEAK_METHOD_RETURN_TYPE=Warning
+METHOD_ELEMENT_TYPE_ADDED_RESTRICTIONS=Error
+METHOD_ELEMENT_TYPE_ADDED_TYPE_PARAMETER=Error
+METHOD_ELEMENT_TYPE_CHANGED_DECREASE_ACCESS=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_ABSTRACT_TO_ABSTRACT=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_FINAL_TO_FINAL=Error
+METHOD_ELEMENT_TYPE_CHANGED_NON_STATIC_TO_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_STATIC_TO_NON_STATIC=Error
+METHOD_ELEMENT_TYPE_CHANGED_VARARGS_TO_ARRAY=Error
+METHOD_ELEMENT_TYPE_REMOVED_ANNOTATION_DEFAULT_VALUE=Error
+METHOD_ELEMENT_TYPE_REMOVED_TYPE_PARAMETER=Error
+MISSING_EE_DESCRIPTIONS=Warning
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_ADDED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_CHANGED_INTERFACE_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_CLASS_BOUND=Error
+TYPE_PARAMETER_ELEMENT_TYPE_REMOVED_INTERFACE_BOUND=Error
+UNUSED_PROBLEM_FILTERS=Warning
+automatically_removed_unused_problem_filters=false
+changed_execution_env=Error
+eclipse.preferences.version=1
+incompatible_api_component_version=Error
+incompatible_api_component_version_include_major_without_breaking_change=Disabled
+incompatible_api_component_version_include_minor_without_api_change=Disabled
+incompatible_api_component_version_report_major_without_breaking_change=Warning
+incompatible_api_component_version_report_minor_without_api_change=Ignore
+invalid_since_tag_version=Error
+malformed_since_tag=Error
+missing_since_tag=Error
+report_api_breakage_when_major_version_incremented=Disabled
+report_resolution_errors_api_component=Warning
diff --git a/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.core.prefs b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000000..923c37fb8d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+resolve.requirebundle=false
diff --git a/org.eclipse.jgit.ssh.jsch/BUILD b/org.eclipse.jgit.ssh.jsch/BUILD
new file mode 100644
index 0000000000..4917e28e04
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/BUILD
@@ -0,0 +1,20 @@
+load("@rules_java//java:defs.bzl", "java_library")
+
+package(default_visibility = ["//visibility:public"])
+
+SRCS = glob(["src/**/*.java"])
+
+RESOURCES = glob(["resources/**"])
+
+java_library(
+ name = "ssh-jsch",
+ srcs = SRCS,
+ resource_strip_prefix = "org.eclipse.jgit.ssh.jsch/resources",
+ resources = RESOURCES,
+ deps = [
+ "//lib:jsch",
+ "//lib:jzlib",
+ "//lib:slf4j-api",
+ "//org.eclipse.jgit:jgit",
+ ],
+)
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..5ae5d4b303
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/MANIFEST.MF
@@ -0,0 +1,26 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Automatic-Module-Name: org.eclipse.jgit.ssh.jsch
+Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch;singleton:=true
+Fragment-Host: org.eclipse.jgit;bundle-version="5.8.0.qualifier"
+Bundle-Vendor: %Bundle-Vendor
+Bundle-Localization: plugin
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 5.8.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Export-Package: org.eclipse.jgit.internal.transport.jsch;version="5.8.0";x-friends:="org.eclipse.egit.core",
+ org.eclipse.jgit.transport;version="5.8.0";
+ uses:="org.eclipse.jgit.transport,
+ org.eclipse.jgit.internal.transport.ssh,
+ org.eclipse.jgit.util,
+ com.jcraft.jsch"
+Import-Package: com.jcraft.jsch;version="[0.1.37,0.2.0)",
+ org.eclipse.jgit.errors;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.internal;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.internal.transport.ssh;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.nls;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.transport;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.util;version="[5.8.0,5.9.0)",
+ org.eclipse.jgit.util.io;version="[5.8.0,5.9.0)",
+ org.slf4j;version="[1.7.0,2.0.0)"
diff --git a/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
new file mode 100644
index 0000000000..35b27810c5
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/META-INF/SOURCE-MANIFEST.MF
@@ -0,0 +1,7 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: org.eclipse.jgit.ssh.jsch - Sources
+Bundle-SymbolicName: org.eclipse.jgit.ssh.jsch.source
+Bundle-Vendor: Eclipse.org - JGit
+Bundle-Version: 5.8.0.qualifier
+Eclipse-SourceBundle: org.eclipse.jgit.ssh.jsch;version="5.8.0.qualifier";roots="."
diff --git a/org.eclipse.jgit.ssh.jsch/about.html b/org.eclipse.jgit.ssh.jsch/about.html
new file mode 100644
index 0000000000..f971af18d0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/about.html
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
+<title>Eclipse Distribution License - Version 1.0</title>
+<style type="text/css">
+ body {
+ size: 8.5in 11.0in;
+ margin: 0.25in 0.5in 0.25in 0.5in;
+ tab-interval: 0.5in;
+ }
+ p {
+ margin-left: auto;
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+ }
+ p.list {
+ margin-left: 0.5in;
+ margin-top: 0.05em;
+ margin-bottom: 0.05em;
+ }
+ .ubc-name {
+ margin-left: 0.5in;
+ white-space: pre;
+ }
+ </style>
+
+</head>
+
+<body lang="EN-US">
+
+<p><b>Eclipse Distribution License - v 1.0</b></p>
+
+<p>Copyright (c) 2007, Eclipse Foundation, Inc. and its licensors. </p>
+
+<p>All rights reserved.</p>
+<p>Redistribution and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+<ul><li>Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer. </li>
+<li>Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution. </li>
+<li>Neither the name of the Eclipse Foundation, Inc. nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission. </li></ul>
+</p>
+<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.</p>
+
+<hr>
+<p><b>SHA-1 UbcCheck - MIT</b></p>
+
+<p>Copyright (c) 2017:</p>
+<div class="ubc-name">
+Marc Stevens
+Cryptology Group
+Centrum Wiskunde & Informatica
+P.O. Box 94079, 1090 GB Amsterdam, Netherlands
+marc@marc-stevens.nl
+</div>
+<div class="ubc-name">
+Dan Shumow
+Microsoft Research
+danshu@microsoft.com
+</div>
+<p>Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+</p>
+<ul><li>The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.</li></ul>
+<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.</p>
+
+</body>
+
+</html>
diff --git a/org.eclipse.jgit.ssh.jsch/build.properties b/org.eclipse.jgit.ssh.jsch/build.properties
new file mode 100644
index 0000000000..8148271ef3
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/build.properties
@@ -0,0 +1,7 @@
+source.. = src/,\
+ resources/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.properties,\
+ about.html
diff --git a/org.eclipse.jgit.ssh.jsch/plugin.properties b/org.eclipse.jgit.ssh.jsch/plugin.properties
new file mode 100644
index 0000000000..126709b961
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/plugin.properties
@@ -0,0 +1,2 @@
+Bundle-Name=JGit SSH support based on JSch
+Bundle-Vendor=Eclipse JGit
diff --git a/org.eclipse.jgit.ssh.jsch/pom.xml b/org.eclipse.jgit.ssh.jsch/pom.xml
new file mode 100644
index 0000000000..142ea28b1d
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/pom.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2018, 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>5.8.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.eclipse.jgit.ssh.jsch</artifactId>
+ <name>JGit - JSch-based SSH support</name>
+
+ <description>
+ SSH support for JGit based on JSch
+ </description>
+
+ <properties>
+ <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>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jzlib</artifactId>
+ </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>
+
+ <!-- No previous version to compare to
+ <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>
+
+ <reporting>
+ <plugins>
+ <!-- No previous version to compare to
+ <plugin>
+ <groupId>com.github.siom79.japicmp</groupId>
+ <artifactId>japicmp-maven-plugin</artifactId>
+ <version>${japicmp-version}</version>
+ <reportSets>
+ <reportSet>
+ <reports>
+ <report>cmp-report</report>
+ </reports>
+ </reportSet>
+ </reportSets>
+ <configuration>
+ <oldVersion>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>${project.artifactId}</artifactId>
+ <version>${jgit-last-release-version}</version>
+ </dependency>
+ </oldVersion>
+ <newVersion>
+ <file>
+ <path>${project.build.directory}/${project.artifactId}-${project.version}.jar</path>
+ </file>
+ </newVersion>
+ <parameter>
+ <onlyModified>true</onlyModified>
+ <includes>
+ <include>org.eclipse.jgit.*</include>
+ </includes>
+ <accessModifier>public</accessModifier>
+ <breakBuildOnModifications>false</breakBuildOnModifications>
+ <breakBuildOnBinaryIncompatibleModifications>false</breakBuildOnBinaryIncompatibleModifications>
+ <onlyBinaryIncompatible>false</onlyBinaryIncompatible>
+ <includeSynthetic>false</includeSynthetic>
+ <ignoreMissingClasses>false</ignoreMissingClasses>
+ <skipPomModules>true</skipPomModules>
+ </parameter>
+ <skip>false</skip>
+ </configuration>
+ </plugin>
+ -->
+ </plugins>
+ </reporting>
+</project>
diff --git a/org.eclipse.jgit.ssh.jsch/resources/META-INF/services/org.eclipse.jgit.transport.SshSessionFactory b/org.eclipse.jgit.ssh.jsch/resources/META-INF/services/org.eclipse.jgit.transport.SshSessionFactory
new file mode 100644
index 0000000000..81927466bb
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/resources/META-INF/services/org.eclipse.jgit.transport.SshSessionFactory
@@ -0,0 +1 @@
+org.eclipse.jgit.transport.JschConfigSessionFactory
diff --git a/org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties b/org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties
new file mode 100644
index 0000000000..529e9f488c
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/resources/org/eclipse/jgit/internal/transport/jsch/JSchText.properties
@@ -0,0 +1,4 @@
+connectionFailed=connection failed
+sshUserNameError=Jsch error: failed to set SSH user name correctly to ''{0}''; using ''{1}'' picked up from SSH config file.
+transportSSHRetryInterrupt=Interrupted while waiting for retry
+unknownHost=unknown host
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/jsch/JSchText.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/jsch/JSchText.java
new file mode 100644
index 0000000000..4d4c9cb250
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/internal/transport/jsch/JSchText.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020, Michael Dardis <git@md-5.net> 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.jsch;
+
+import org.eclipse.jgit.nls.NLS;
+import org.eclipse.jgit.nls.TranslationBundle;
+
+/**
+ * Externalized text messages for localization.
+ */
+public final class JSchText extends TranslationBundle {
+
+ /**
+ * Get an instance of this translation bundle.
+ *
+ * @return an instance of this translation bundle
+ */
+ public static JSchText get() {
+ return NLS.getBundleFor(JSchText.class);
+ }
+
+ // @formatter:off
+ /***/ public String connectionFailed;
+ /***/ public String sshUserNameError;
+ /***/ public String transportSSHRetryInterrupt;
+ /***/ public String unknownHost;
+
+}
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
new file mode 100644
index 0000000000..01adcf30b0
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/CredentialsProviderUserInfo.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+//TODO(ms): move to org.eclipse.jgit.ssh.jsch in 6.0
+package org.eclipse.jgit.transport;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UIKeyboardInteractive;
+import com.jcraft.jsch.UserInfo;
+
+/**
+ * A JSch {@link com.jcraft.jsch.UserInfo} adapter for a
+ * {@link org.eclipse.jgit.transport.CredentialsProvider}.
+ */
+public class CredentialsProviderUserInfo implements UserInfo,
+ UIKeyboardInteractive {
+ private final URIish uri;
+
+ private final CredentialsProvider provider;
+
+ private String password;
+
+ private String passphrase;
+
+ /**
+ * Wrap a CredentialsProvider to make it suitable for use with JSch.
+ *
+ * @param session
+ * the JSch session this UserInfo will support authentication on.
+ * @param credentialsProvider
+ * the provider that will perform the authentication.
+ */
+ public CredentialsProviderUserInfo(Session session,
+ CredentialsProvider credentialsProvider) {
+ this.uri = createURI(session);
+ this.provider = credentialsProvider;
+ }
+
+ private static URIish createURI(Session session) {
+ URIish uri = new URIish();
+ uri = uri.setScheme("ssh"); //$NON-NLS-1$
+ uri = uri.setUser(session.getUserName());
+ uri = uri.setHost(session.getHost());
+ uri = uri.setPort(session.getPort());
+ return uri;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String getPassphrase() {
+ return passphrase;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean promptPassphrase(String msg) {
+ CredentialItem.StringType v = newPrompt(msg);
+ if (provider.get(uri, v)) {
+ passphrase = v.getValue();
+ return true;
+ }
+ passphrase = null;
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean promptPassword(String msg) {
+ CredentialItem.Password p = new CredentialItem.Password(msg);
+ if (provider.get(uri, p)) {
+ password = new String(p.getValue());
+ return true;
+ }
+ password = null;
+ return false;
+ }
+
+ private CredentialItem.StringType newPrompt(String msg) {
+ return new CredentialItem.StringType(msg, true);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean promptYesNo(String msg) {
+ CredentialItem.YesNoType v = new CredentialItem.YesNoType(msg);
+ return provider.get(uri, v) && v.getValue();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void showMessage(String msg) {
+ provider.get(uri, new CredentialItem.InformationalMessage(msg));
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String[] promptKeyboardInteractive(String destination, String name,
+ String instruction, String[] prompt, boolean[] echo) {
+ CredentialItem.StringType[] v = new CredentialItem.StringType[prompt.length];
+ for (int i = 0; i < prompt.length; i++)
+ v[i] = new CredentialItem.StringType(prompt[i], !echo[i]);
+
+ List<CredentialItem> items = new ArrayList<>();
+ if (instruction != null && instruction.length() > 0)
+ items.add(new CredentialItem.InformationalMessage(instruction));
+ items.addAll(Arrays.asList(v));
+
+ if (!provider.get(uri, items))
+ return null; // cancel
+
+ String[] result = new String[v.length];
+ for (int i = 0; i < v.length; i++)
+ result[i] = v[i].getValue();
+ return result;
+ }
+}
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
new file mode 100644
index 0000000000..88202dd2d6
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschConfigSessionFactory.java
@@ -0,0 +1,541 @@
+/*
+ * Copyright (C) 2018, Sasa Zivkov <sasa.zivkov@sap.com>
+ * Copyright (C) 2016, Mark Ingram <markdingram@gmail.com>
+ * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
+ * Copyright (C) 2008-2009, Google Inc.
+ * Copyright (C) 2009, Google, Inc.
+ * Copyright (C) 2009, JetBrains s.r.o.
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+//TODO(ms): move to org.eclipse.jgit.ssh.jsch in 6.0
+package org.eclipse.jgit.transport;
+
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.ConnectException;
+import java.net.UnknownHostException;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
+import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.internal.transport.jsch.JSchText;
+import org.eclipse.jgit.util.FS;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.jcraft.jsch.ConfigRepository;
+import com.jcraft.jsch.ConfigRepository.Config;
+import com.jcraft.jsch.HostKey;
+import com.jcraft.jsch.HostKeyRepository;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+
+/**
+ * The base session factory that loads known hosts and private keys from
+ * <code>$HOME/.ssh</code>.
+ * <p>
+ * This is the default implementation used by JGit and provides most of the
+ * compatibility necessary to match OpenSSH, a popular implementation of SSH
+ * used by C Git.
+ * <p>
+ * The factory does not provide UI behavior. Override the method
+ * {@link #configure(org.eclipse.jgit.transport.OpenSshConfig.Host, Session)} to
+ * supply appropriate {@link com.jcraft.jsch.UserInfo} to the session.
+ */
+public class JschConfigSessionFactory extends SshSessionFactory {
+
+ private static final String JSCH = "jsch"; //$NON-NLS-1$
+
+ private static final Logger LOG = LoggerFactory
+ .getLogger(JschConfigSessionFactory.class);
+
+ /**
+ * We use different Jsch instances for hosts that have an IdentityFile
+ * configured in ~/.ssh/config. Jsch by default would cache decrypted keys
+ * only per session, which results in repeated password prompts. Using
+ * different Jsch instances, we can cache the keys on these instances so
+ * that they will be re-used for successive sessions, and thus the user is
+ * prompted for a key password only once while Eclipse runs.
+ */
+ private final Map<String, JSch> byIdentityFile = new HashMap<>();
+
+ private JSch defaultJSch;
+
+ private OpenSshConfig config;
+
+ /** {@inheritDoc} */
+ @Override
+ public synchronized RemoteSession getSession(URIish uri,
+ CredentialsProvider credentialsProvider, FS fs, int tms)
+ throws TransportException {
+
+ String user = uri.getUser();
+ final String pass = uri.getPass();
+ String host = uri.getHost();
+ int port = uri.getPort();
+
+ try {
+ if (config == null)
+ config = OpenSshConfig.get(fs);
+
+ final OpenSshConfig.Host hc = config.lookup(host);
+ if (port <= 0)
+ port = hc.getPort();
+ if (user == null)
+ user = hc.getUser();
+
+ Session session = createSession(credentialsProvider, fs, user,
+ pass, host, port, hc);
+
+ int retries = 0;
+ while (!session.isConnected()) {
+ try {
+ retries++;
+ session.connect(tms);
+ } catch (JSchException e) {
+ session.disconnect();
+ session = null;
+ // Make sure our known_hosts is not outdated
+ knownHosts(getJSch(hc, fs), fs);
+
+ if (isAuthenticationCanceled(e)) {
+ throw e;
+ } else if (isAuthenticationFailed(e)
+ && credentialsProvider != null) {
+ // if authentication failed maybe credentials changed at
+ // the remote end therefore reset credentials and retry
+ if (retries < 3) {
+ credentialsProvider.reset(uri);
+ session = createSession(credentialsProvider, fs,
+ user, pass, host, port, hc);
+ } else
+ throw e;
+ } else if (retries >= hc.getConnectionAttempts()) {
+ throw e;
+ } else {
+ try {
+ Thread.sleep(1000);
+ session = createSession(credentialsProvider, fs,
+ user, pass, host, port, hc);
+ } catch (InterruptedException e1) {
+ throw new TransportException(
+ JSchText.get().transportSSHRetryInterrupt,
+ e1);
+ }
+ }
+ }
+ }
+
+ return new JschSession(session, uri);
+
+ } catch (JSchException je) {
+ final Throwable c = je.getCause();
+ if (c instanceof UnknownHostException) {
+ throw new TransportException(uri,
+ JSchText.get().unknownHost,
+ je);
+ }
+ if (c instanceof ConnectException) {
+ throw new TransportException(uri, c.getMessage(), je);
+ }
+ throw new TransportException(uri, je.getMessage(), je);
+ }
+
+ }
+
+ @Override
+ public String getType() {
+ return JSCH;
+ }
+
+ private static boolean isAuthenticationFailed(JSchException e) {
+ return e.getCause() == null && e.getMessage().equals("Auth fail"); //$NON-NLS-1$
+ }
+
+ private static boolean isAuthenticationCanceled(JSchException e) {
+ return e.getCause() == null && e.getMessage().equals("Auth cancel"); //$NON-NLS-1$
+ }
+
+ // Package visibility for tests
+ Session createSession(CredentialsProvider credentialsProvider,
+ FS fs, String user, final String pass, String host, int port,
+ final OpenSshConfig.Host hc) throws JSchException {
+ final Session session = createSession(hc, user, host, port, fs);
+ // Jsch will have overridden the explicit user by the one from the SSH
+ // config file...
+ setUserName(session, user);
+ // Jsch will also have overridden the port.
+ if (port > 0 && port != session.getPort()) {
+ session.setPort(port);
+ }
+ // We retry already in getSession() method. JSch must not retry
+ // on its own.
+ session.setConfig("MaxAuthTries", "1"); //$NON-NLS-1$ //$NON-NLS-2$
+ if (pass != null)
+ session.setPassword(pass);
+ final String strictHostKeyCheckingPolicy = hc
+ .getStrictHostKeyChecking();
+ if (strictHostKeyCheckingPolicy != null)
+ session.setConfig("StrictHostKeyChecking", //$NON-NLS-1$
+ strictHostKeyCheckingPolicy);
+ final String pauth = hc.getPreferredAuthentications();
+ if (pauth != null)
+ session.setConfig("PreferredAuthentications", pauth); //$NON-NLS-1$
+ if (credentialsProvider != null
+ && (!hc.isBatchMode() || !credentialsProvider.isInteractive())) {
+ session.setUserInfo(new CredentialsProviderUserInfo(session,
+ credentialsProvider));
+ }
+ safeConfig(session, hc.getConfig());
+ if (hc.getConfig().getValue("HostKeyAlgorithms") == null) { //$NON-NLS-1$
+ setPreferredKeyTypesOrder(session);
+ }
+ configure(hc, session);
+ return session;
+ }
+
+ private void safeConfig(Session session, Config cfg) {
+ // Ensure that Jsch checks all configured algorithms, not just its
+ // built-in ones. Otherwise it may propose an algorithm for which it
+ // doesn't have an implementation, and then run into an NPE if that
+ // algorithm ends up being chosen.
+ copyConfigValueToSession(session, cfg, "Ciphers", "CheckCiphers"); //$NON-NLS-1$ //$NON-NLS-2$
+ copyConfigValueToSession(session, cfg, "KexAlgorithms", "CheckKexes"); //$NON-NLS-1$ //$NON-NLS-2$
+ copyConfigValueToSession(session, cfg, "HostKeyAlgorithms", //$NON-NLS-1$
+ "CheckSignatures"); //$NON-NLS-1$
+ }
+
+ private static void setPreferredKeyTypesOrder(Session session) {
+ HostKeyRepository hkr = session.getHostKeyRepository();
+ HostKey[] hostKeys = hkr.getHostKey(hostName(session), null);
+
+ if (hostKeys == null) {
+ return;
+ }
+
+ List<String> known = Stream.of(hostKeys)
+ .map(HostKey::getType)
+ .collect(toList());
+
+ if (!known.isEmpty()) {
+ String serverHostKey = "server_host_key"; //$NON-NLS-1$
+ String current = session.getConfig(serverHostKey);
+ if (current == null) {
+ session.setConfig(serverHostKey, String.join(",", known)); //$NON-NLS-1$
+ return;
+ }
+
+ String knownFirst = Stream.concat(
+ known.stream(),
+ Stream.of(current.split(",")) //$NON-NLS-1$
+ .filter(s -> !known.contains(s)))
+ .collect(joining(",")); //$NON-NLS-1$
+ session.setConfig(serverHostKey, knownFirst);
+ }
+ }
+
+ private static String hostName(Session s) {
+ if (s.getPort() == SshConstants.SSH_DEFAULT_PORT) {
+ return s.getHost();
+ }
+ return String.format("[%s]:%d", s.getHost(), //$NON-NLS-1$
+ Integer.valueOf(s.getPort()));
+ }
+
+ private void copyConfigValueToSession(Session session, Config cfg,
+ String from, String to) {
+ String value = cfg.getValue(from);
+ if (value != null) {
+ session.setConfig(to, value);
+ }
+ }
+
+ private void setUserName(Session session, String userName) {
+ // Jsch 0.1.54 picks up the user name from the ssh config, even if an
+ // explicit user name was given! We must correct that if ~/.ssh/config
+ // has a different user name.
+ if (userName == null || userName.isEmpty()
+ || userName.equals(session.getUserName())) {
+ return;
+ }
+ try {
+ Class<?>[] parameterTypes = { String.class };
+ Method method = Session.class.getDeclaredMethod("setUserName", //$NON-NLS-1$
+ parameterTypes);
+ method.setAccessible(true);
+ method.invoke(session, userName);
+ } catch (NullPointerException | IllegalAccessException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e) {
+ LOG.error(MessageFormat.format(JSchText.get().sshUserNameError,
+ userName, session.getUserName()), e);
+ }
+ }
+
+ /**
+ * Create a new remote session for the requested address.
+ *
+ * @param hc
+ * host configuration
+ * @param user
+ * login to authenticate as.
+ * @param host
+ * server name to connect to.
+ * @param port
+ * port number of the SSH daemon (typically 22).
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
+ * @return new session instance, but otherwise unconfigured.
+ * @throws com.jcraft.jsch.JSchException
+ * the session could not be created.
+ */
+ protected Session createSession(final OpenSshConfig.Host hc,
+ final String user, final String host, final int port, FS fs)
+ throws JSchException {
+ return getJSch(hc, fs).getSession(user, host, port);
+ }
+
+ /**
+ * Provide additional configuration for the JSch instance. This method could
+ * be overridden to supply a preferred
+ * {@link com.jcraft.jsch.IdentityRepository}.
+ *
+ * @param jsch
+ * jsch instance
+ * @since 4.5
+ */
+ protected void configureJSch(JSch jsch) {
+ // No additional configuration required.
+ }
+
+ /**
+ * Provide additional configuration for the session based on the host
+ * information. This method could be used to supply
+ * {@link com.jcraft.jsch.UserInfo}.
+ *
+ * @param hc
+ * host configuration
+ * @param session
+ * session to configure
+ */
+ protected void configure(OpenSshConfig.Host hc, Session session) {
+ // No additional configuration required.
+ }
+
+ /**
+ * Obtain the JSch used to create new sessions.
+ *
+ * @param hc
+ * host configuration
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
+ * @return the JSch instance to use.
+ * @throws com.jcraft.jsch.JSchException
+ * the user configuration could not be created.
+ */
+ protected JSch getJSch(OpenSshConfig.Host hc, FS fs) throws JSchException {
+ if (defaultJSch == null) {
+ defaultJSch = createDefaultJSch(fs);
+ if (defaultJSch.getConfigRepository() == null) {
+ defaultJSch.setConfigRepository(
+ new JschBugFixingConfigRepository(config));
+ }
+ for (Object name : defaultJSch.getIdentityNames())
+ byIdentityFile.put((String) name, defaultJSch);
+ }
+
+ final File identityFile = hc.getIdentityFile();
+ if (identityFile == null)
+ return defaultJSch;
+
+ final String identityKey = identityFile.getAbsolutePath();
+ JSch jsch = byIdentityFile.get(identityKey);
+ if (jsch == null) {
+ jsch = new JSch();
+ configureJSch(jsch);
+ if (jsch.getConfigRepository() == null) {
+ jsch.setConfigRepository(defaultJSch.getConfigRepository());
+ }
+ jsch.setHostKeyRepository(defaultJSch.getHostKeyRepository());
+ jsch.addIdentity(identityKey);
+ byIdentityFile.put(identityKey, jsch);
+ }
+ return jsch;
+ }
+
+ /**
+ * Create default instance of jsch
+ *
+ * @param fs
+ * the file system abstraction which will be necessary to perform
+ * certain file system operations.
+ * @return the new default JSch implementation.
+ * @throws com.jcraft.jsch.JSchException
+ * known host keys cannot be loaded.
+ */
+ protected JSch createDefaultJSch(FS fs) throws JSchException {
+ final JSch jsch = new JSch();
+ JSch.setConfig("ssh-rsa", JSch.getConfig("signature.rsa")); //$NON-NLS-1$ //$NON-NLS-2$
+ JSch.setConfig("ssh-dss", JSch.getConfig("signature.dss")); //$NON-NLS-1$ //$NON-NLS-2$
+ configureJSch(jsch);
+ knownHosts(jsch, fs);
+ identities(jsch, fs);
+ return jsch;
+ }
+
+ private static void knownHosts(JSch sch, FS fs) throws JSchException {
+ final File home = fs.userHome();
+ if (home == null)
+ return;
+ final File known_hosts = new File(new File(home, ".ssh"), "known_hosts"); //$NON-NLS-1$ //$NON-NLS-2$
+ try (FileInputStream in = new FileInputStream(known_hosts)) {
+ sch.setKnownHosts(in);
+ } catch (FileNotFoundException none) {
+ // Oh well. They don't have a known hosts in home.
+ } catch (IOException err) {
+ // Oh well. They don't have a known hosts in home.
+ }
+ }
+
+ private static void identities(JSch sch, FS fs) {
+ final File home = fs.userHome();
+ if (home == null)
+ return;
+ final File sshdir = new File(home, ".ssh"); //$NON-NLS-1$
+ if (sshdir.isDirectory()) {
+ loadIdentity(sch, new File(sshdir, "identity")); //$NON-NLS-1$
+ loadIdentity(sch, new File(sshdir, "id_rsa")); //$NON-NLS-1$
+ loadIdentity(sch, new File(sshdir, "id_dsa")); //$NON-NLS-1$
+ }
+ }
+
+ private static void loadIdentity(JSch sch, File priv) {
+ if (priv.isFile()) {
+ try {
+ sch.addIdentity(priv.getAbsolutePath());
+ } catch (JSchException e) {
+ // Instead, pretend the key doesn't exist.
+ }
+ }
+ }
+
+ private static class JschBugFixingConfigRepository
+ implements ConfigRepository {
+
+ private final ConfigRepository base;
+
+ public JschBugFixingConfigRepository(ConfigRepository base) {
+ this.base = base;
+ }
+
+ @Override
+ public Config getConfig(String host) {
+ return new JschBugFixingConfig(base.getConfig(host));
+ }
+
+ /**
+ * A {@link com.jcraft.jsch.ConfigRepository.Config} that transforms
+ * some values from the config file into the format Jsch 0.1.54 expects.
+ * This is a work-around for bugs in Jsch.
+ * <p>
+ * Additionally, this config hides the IdentityFile config entries from
+ * Jsch; we manage those ourselves. Otherwise Jsch would cache passwords
+ * (or rather, decrypted keys) only for a single session, resulting in
+ * multiple password prompts for user operations that use several Jsch
+ * sessions.
+ */
+ private static class JschBugFixingConfig implements Config {
+
+ private static final String[] NO_IDENTITIES = {};
+
+ private final Config real;
+
+ public JschBugFixingConfig(Config delegate) {
+ real = delegate;
+ }
+
+ @Override
+ public String getHostname() {
+ return real.getHostname();
+ }
+
+ @Override
+ public String getUser() {
+ return real.getUser();
+ }
+
+ @Override
+ public int getPort() {
+ return real.getPort();
+ }
+
+ @Override
+ public String getValue(String key) {
+ String k = key.toUpperCase(Locale.ROOT);
+ if ("IDENTITYFILE".equals(k)) { //$NON-NLS-1$
+ return null;
+ }
+ String result = real.getValue(key);
+ if (result != null) {
+ if ("SERVERALIVEINTERVAL".equals(k) //$NON-NLS-1$
+ || "CONNECTTIMEOUT".equals(k)) { //$NON-NLS-1$
+ // These values are in seconds. Jsch 0.1.54 passes them
+ // on as is to java.net.Socket.setSoTimeout(), which
+ // expects milliseconds. So convert here to
+ // milliseconds.
+ try {
+ int timeout = Integer.parseInt(result);
+ result = Long.toString(
+ TimeUnit.SECONDS.toMillis(timeout));
+ } catch (NumberFormatException e) {
+ // Ignore
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public String[] getValues(String key) {
+ String k = key.toUpperCase(Locale.ROOT);
+ if ("IDENTITYFILE".equals(k)) { //$NON-NLS-1$
+ return NO_IDENTITIES;
+ }
+ return real.getValues(key);
+ }
+ }
+ }
+
+ /**
+ * Set the {@link OpenSshConfig} to use. Intended for use in tests.
+ *
+ * @param config
+ * to use
+ */
+ synchronized void setConfig(OpenSshConfig config) {
+ this.config = config;
+ }
+}
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
new file mode 100644
index 0000000000..300e03d798
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/JschSession.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2009, Constantine Plotnikov <constantine.plotnikov@gmail.com>
+ * Copyright (C) 2008-2009, Google Inc.
+ * Copyright (C) 2009, Google, Inc.
+ * Copyright (C) 2009, JetBrains s.r.o.
+ * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
+ * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+//TODO(ms): move to org.eclipse.jgit.ssh.jsch in 6.0
+package org.eclipse.jgit.transport;
+
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.errors.TransportException;
+import org.eclipse.jgit.internal.transport.jsch.JSchText;
+import org.eclipse.jgit.util.io.IsolatedOutputStream;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.SftpException;
+
+/**
+ * Run remote commands using Jsch.
+ * <p>
+ * This class is the default session implementation using Jsch. Note that
+ * {@link org.eclipse.jgit.transport.JschConfigSessionFactory} is used to create
+ * the actual session passed to the constructor.
+ */
+public class JschSession implements RemoteSession {
+ final Session sock;
+ final URIish uri;
+
+ /**
+ * Create a new session object by passing the real Jsch session and the URI
+ * information.
+ *
+ * @param session
+ * the real Jsch session created elsewhere.
+ * @param uri
+ * the URI information for the remote connection
+ */
+ public JschSession(Session session, URIish uri) {
+ sock = session;
+ this.uri = uri;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Process exec(String command, int timeout) throws IOException {
+ return new JschProcess(command, timeout);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void disconnect() {
+ if (sock.isConnected())
+ sock.disconnect();
+ }
+
+ /**
+ * A kludge to allow {@link org.eclipse.jgit.transport.TransportSftp} to get
+ * an Sftp channel from Jsch. Ideally, this method would be generic, which
+ * would require implementing generic Sftp channel operations in the
+ * RemoteSession class.
+ *
+ * @return a channel suitable for Sftp operations.
+ * @throws com.jcraft.jsch.JSchException
+ * on problems getting the channel.
+ * @deprecated since 5.2; use {@link #getFtpChannel()} instead
+ */
+ @Deprecated
+ public Channel getSftpChannel() throws JSchException {
+ return sock.openChannel("sftp"); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 5.2
+ */
+ @Override
+ public FtpChannel getFtpChannel() {
+ return new JschFtpChannel();
+ }
+
+ /**
+ * Implementation of Process for running a single command using Jsch.
+ * <p>
+ * Uses the Jsch session to do actual command execution and manage the
+ * execution.
+ */
+ private class JschProcess extends Process {
+ private ChannelExec channel;
+
+ final int timeout;
+
+ private InputStream inputStream;
+
+ private OutputStream outputStream;
+
+ private InputStream errStream;
+
+ /**
+ * Opens a channel on the session ("sock") for executing the given
+ * command, opens streams, and starts command execution.
+ *
+ * @param commandName
+ * the command to execute
+ * @param tms
+ * the timeout value, in seconds, for the command.
+ * @throws TransportException
+ * on problems opening a channel or connecting to the remote
+ * host
+ * @throws IOException
+ * on problems opening streams
+ */
+ JschProcess(String commandName, int tms)
+ throws TransportException, IOException {
+ timeout = tms;
+ try {
+ channel = (ChannelExec) sock.openChannel("exec"); //$NON-NLS-1$
+ channel.setCommand(commandName);
+ setupStreams();
+ channel.connect(timeout > 0 ? timeout * 1000 : 0);
+ if (!channel.isConnected()) {
+ closeOutputStream();
+ throw new TransportException(uri,
+ JSchText.get().connectionFailed);
+ }
+ } catch (JSchException e) {
+ closeOutputStream();
+ throw new TransportException(uri, e.getMessage(), e);
+ }
+ }
+
+ private void closeOutputStream() {
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException ioe) {
+ // ignore
+ }
+ }
+ }
+
+ private void setupStreams() throws IOException {
+ inputStream = channel.getInputStream();
+
+ // JSch won't let us interrupt writes when we use our InterruptTimer
+ // to break out of a long-running write operation. To work around
+ // that we spawn a background thread to shuttle data through a pipe,
+ // as we can issue an interrupted write out of that. Its slower, so
+ // we only use this route if there is a timeout.
+ OutputStream out = channel.getOutputStream();
+ if (timeout <= 0) {
+ outputStream = out;
+ } else {
+ IsolatedOutputStream i = new IsolatedOutputStream(out);
+ outputStream = new BufferedOutputStream(i, 16 * 1024);
+ }
+
+ errStream = channel.getErrStream();
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return inputStream;
+ }
+
+ @Override
+ public OutputStream getOutputStream() {
+ return outputStream;
+ }
+
+ @Override
+ public InputStream getErrorStream() {
+ return errStream;
+ }
+
+ @Override
+ public int exitValue() {
+ if (isRunning())
+ throw new IllegalStateException();
+ return channel.getExitStatus();
+ }
+
+ private boolean isRunning() {
+ return channel.getExitStatus() < 0 && channel.isConnected();
+ }
+
+ @Override
+ public void destroy() {
+ if (channel.isConnected())
+ channel.disconnect();
+ closeOutputStream();
+ }
+
+ @Override
+ public int waitFor() throws InterruptedException {
+ while (isRunning())
+ Thread.sleep(100);
+ return exitValue();
+ }
+ }
+
+ private class JschFtpChannel implements FtpChannel {
+
+ private ChannelSftp ftp;
+
+ @Override
+ public void connect(int timeout, TimeUnit unit) throws IOException {
+ try {
+ ftp = (ChannelSftp) sock.openChannel("sftp"); //$NON-NLS-1$
+ ftp.connect((int) unit.toMillis(timeout));
+ } catch (JSchException e) {
+ ftp = null;
+ throw new IOException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Override
+ public void disconnect() {
+ ftp.disconnect();
+ ftp = null;
+ }
+
+ private <T> T map(Callable<T> op) throws IOException {
+ try {
+ return op.call();
+ } catch (Exception e) {
+ if (e instanceof SftpException) {
+ throw new FtpChannel.FtpException(e.getLocalizedMessage(),
+ ((SftpException) e).id, e);
+ }
+ throw new IOException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ @Override
+ public boolean isConnected() {
+ return ftp != null && sock.isConnected();
+ }
+
+ @Override
+ public void cd(String path) throws IOException {
+ map(() -> {
+ ftp.cd(path);
+ return null;
+ });
+ }
+
+ @Override
+ public String pwd() throws IOException {
+ return map(() -> ftp.pwd());
+ }
+
+ @Override
+ public Collection<DirEntry> ls(String path) throws IOException {
+ return map(() -> {
+ List<DirEntry> result = new ArrayList<>();
+ for (Object e : ftp.ls(path)) {
+ ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) e;
+ result.add(new DirEntry() {
+
+ @Override
+ public String getFilename() {
+ return entry.getFilename();
+ }
+
+ @Override
+ public long getModifiedTime() {
+ return entry.getAttrs().getMTime();
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return entry.getAttrs().isDir();
+ }
+ });
+ }
+ return result;
+ });
+ }
+
+ @Override
+ public void rmdir(String path) throws IOException {
+ map(() -> {
+ ftp.rm(path);
+ return null;
+ });
+ }
+
+ @Override
+ public void mkdir(String path) throws IOException {
+ map(() -> {
+ ftp.mkdir(path);
+ return null;
+ });
+ }
+
+ @Override
+ public InputStream get(String path) throws IOException {
+ return map(() -> ftp.get(path));
+ }
+
+ @Override
+ public OutputStream put(String path) throws IOException {
+ return map(() -> ftp.put(path));
+ }
+
+ @Override
+ public void rm(String path) throws IOException {
+ map(() -> {
+ ftp.rm(path);
+ return null;
+ });
+ }
+
+ @Override
+ public void rename(String from, String to) throws IOException {
+ map(() -> {
+ // Plain FTP rename will fail if "to" exists. Jsch knows about
+ // the FTP extension "posix-rename@openssh.com", which will
+ // remove "to" first if it exists.
+ if (hasPosixRename()) {
+ ftp.rename(from, to);
+ } else if (!to.equals(from)) {
+ // Try to remove "to" first. With git, we typically get this
+ // when a lock file is moved over the file locked. Note that
+ // the check for to being equal to from may still fail in
+ // the general case, but for use with JGit's TransportSftp
+ // it should be good enough.
+ delete(to);
+ ftp.rename(from, to);
+ }
+ return null;
+ });
+ }
+
+ /**
+ * Determine whether the server has the posix-rename extension.
+ *
+ * @return {@code true} if it is supported, {@code false} otherwise
+ * @see <a href=
+ * "https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD">OpenSSH
+ * deviations and extensions to the published SSH protocol</a>
+ * @see <a href=
+ * "http://pubs.opengroup.org/onlinepubs/9699919799/functions/rename.html">stdio.h:
+ * rename()</a>
+ */
+ private boolean hasPosixRename() {
+ return "1".equals(ftp.getExtension("posix-rename@openssh.com")); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ }
+}
diff --git a/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/OpenSshConfig.java b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/OpenSshConfig.java
new file mode 100644
index 0000000000..5c6c80c768
--- /dev/null
+++ b/org.eclipse.jgit.ssh.jsch/src/org/eclipse/jgit/transport/OpenSshConfig.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2008, 2018, Google Inc. and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+//TODO(ms): move to org.eclipse.jgit.ssh.jsch in 6.0
+package org.eclipse.jgit.transport;
+
+import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.positive;
+
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile;
+import org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.HostEntry;
+import org.eclipse.jgit.util.FS;
+
+import com.jcraft.jsch.ConfigRepository;
+
+/**
+ * Fairly complete configuration parser for the OpenSSH ~/.ssh/config file.
+ * <p>
+ * JSch does have its own config file parser
+ * {@link com.jcraft.jsch.OpenSSHConfig} since version 0.1.50, but it has a
+ * number of problems:
+ * <ul>
+ * <li>it splits lines of the format "keyword = value" wrongly: you'd end up
+ * with the value "= value".
+ * <li>its "Host" keyword is not case insensitive.
+ * <li>it doesn't handle quoted values.
+ * <li>JSch's OpenSSHConfig doesn't monitor for config file changes.
+ * </ul>
+ * <p>
+ * This parser makes the critical options available to
+ * {@link org.eclipse.jgit.transport.SshSessionFactory} via
+ * {@link org.eclipse.jgit.transport.OpenSshConfig.Host} objects returned
+ * by {@link #lookup(String)}, and implements a fully conforming
+ * {@link com.jcraft.jsch.ConfigRepository} providing
+ * {@link com.jcraft.jsch.ConfigRepository.Config}s via
+ * {@link #getConfig(String)}.
+ * </p>
+ *
+ * @see OpenSshConfigFile
+ */
+public class OpenSshConfig implements ConfigRepository {
+
+ /**
+ * Obtain the user's configuration data.
+ * <p>
+ * The configuration file is always returned to the caller, even if no file
+ * exists in the user's home directory at the time the call was made. Lookup
+ * requests are cached and are automatically updated if the user modifies
+ * the configuration file since the last time it was cached.
+ *
+ * @param fs
+ * the file system abstraction which will be necessary to
+ * perform certain file system operations.
+ * @return a caching reader of the user's configuration file.
+ */
+ public static OpenSshConfig get(FS fs) {
+ File home = fs.userHome();
+ if (home == null)
+ home = new File(".").getAbsoluteFile(); //$NON-NLS-1$
+
+ final File config = new File(new File(home, SshConstants.SSH_DIR),
+ SshConstants.CONFIG);
+ return new OpenSshConfig(home, config);
+ }
+
+ /** The base file. */
+ private OpenSshConfigFile configFile;
+
+ OpenSshConfig(File h, File cfg) {
+ configFile = new OpenSshConfigFile(h, cfg,
+ SshSessionFactory.getLocalUserName());
+ }
+
+ /**
+ * Locate the configuration for a specific host request.
+ *
+ * @param hostName
+ * the name the user has supplied to the SSH tool. This may be a
+ * real host name, or it may just be a "Host" block in the
+ * configuration file.
+ * @return r configuration for the requested name. Never null.
+ */
+ public Host lookup(String hostName) {
+ HostEntry entry = configFile.lookup(hostName, -1, null);
+ return new Host(entry, hostName, configFile.getLocalUserName());
+ }
+
+ /**
+ * Configuration of one "Host" block in the configuration file.
+ * <p>
+ * If returned from {@link OpenSshConfig#lookup(String)} some or all of the
+ * properties may not be populated. The properties which are not populated
+ * should be defaulted by the caller.
+ * <p>
+ * When returned from {@link OpenSshConfig#lookup(String)} any wildcard
+ * entries which appear later in the configuration file will have been
+ * already merged into this block.
+ */
+ public static class Host {
+ String hostName;
+
+ int port;
+
+ File identityFile;
+
+ String user;
+
+ String preferredAuthentications;
+
+ Boolean batchMode;
+
+ String strictHostKeyChecking;
+
+ int connectionAttempts;
+
+ private HostEntry entry;
+
+ private Config config;
+
+ // See com.jcraft.jsch.OpenSSHConfig. Translates some command-line keys
+ // to ssh-config keys.
+ private static final Map<String, String> KEY_MAP = new TreeMap<>(
+ String.CASE_INSENSITIVE_ORDER);
+
+ static {
+ KEY_MAP.put("kex", SshConstants.KEX_ALGORITHMS); //$NON-NLS-1$
+ KEY_MAP.put("server_host_key", SshConstants.HOST_KEY_ALGORITHMS); //$NON-NLS-1$
+ KEY_MAP.put("cipher.c2s", SshConstants.CIPHERS); //$NON-NLS-1$
+ KEY_MAP.put("cipher.s2c", SshConstants.CIPHERS); //$NON-NLS-1$
+ KEY_MAP.put("mac.c2s", SshConstants.MACS); //$NON-NLS-1$
+ KEY_MAP.put("mac.s2c", SshConstants.MACS); //$NON-NLS-1$
+ KEY_MAP.put("compression.s2c", SshConstants.COMPRESSION); //$NON-NLS-1$
+ KEY_MAP.put("compression.c2s", SshConstants.COMPRESSION); //$NON-NLS-1$
+ KEY_MAP.put("compression_level", "CompressionLevel"); //$NON-NLS-1$ //$NON-NLS-2$
+ KEY_MAP.put("MaxAuthTries", //$NON-NLS-1$
+ SshConstants.NUMBER_OF_PASSWORD_PROMPTS);
+ }
+
+ private static String mapKey(String key) {
+ String k = KEY_MAP.get(key);
+ return k != null ? k : key;
+ }
+
+ /**
+ * Creates a new uninitialized {@link Host}.
+ */
+ public Host() {
+ // For API backwards compatibility with pre-4.9 JGit
+ }
+
+ Host(HostEntry entry, String hostName, String localUserName) {
+ this.entry = entry;
+ complete(hostName, localUserName);
+ }
+
+ /**
+ * @return the value StrictHostKeyChecking property, the valid values
+ * are "yes" (unknown hosts are not accepted), "no" (unknown
+ * hosts are always accepted), and "ask" (user should be asked
+ * before accepting the host)
+ */
+ public String getStrictHostKeyChecking() {
+ return strictHostKeyChecking;
+ }
+
+ /**
+ * @return the real IP address or host name to connect to; never null.
+ */
+ public String getHostName() {
+ return hostName;
+ }
+
+ /**
+ * @return the real port number to connect to; never 0.
+ */
+ public int getPort() {
+ return port;
+ }
+
+ /**
+ * @return path of the private key file to use for authentication; null
+ * if the caller should use default authentication strategies.
+ */
+ public File getIdentityFile() {
+ return identityFile;
+ }
+
+ /**
+ * @return the real user name to connect as; never null.
+ */
+ public String getUser() {
+ return user;
+ }
+
+ /**
+ * @return the preferred authentication methods, separated by commas if
+ * more than one authentication method is preferred.
+ */
+ public String getPreferredAuthentications() {
+ return preferredAuthentications;
+ }
+
+ /**
+ * @return true if batch (non-interactive) mode is preferred for this
+ * host connection.
+ */
+ public boolean isBatchMode() {
+ return batchMode != null && batchMode.booleanValue();
+ }
+
+ /**
+ * @return the number of tries (one per second) to connect before
+ * exiting. The argument must be an integer. This may be useful
+ * in scripts if the connection sometimes fails. The default is
+ * 1.
+ * @since 3.4
+ */
+ public int getConnectionAttempts() {
+ return connectionAttempts;
+ }
+
+
+ private void complete(String initialHostName, String localUserName) {
+ // Try to set values from the options.
+ hostName = entry.getValue(SshConstants.HOST_NAME);
+ user = entry.getValue(SshConstants.USER);
+ port = positive(entry.getValue(SshConstants.PORT));
+ connectionAttempts = positive(
+ entry.getValue(SshConstants.CONNECTION_ATTEMPTS));
+ strictHostKeyChecking = entry
+ .getValue(SshConstants.STRICT_HOST_KEY_CHECKING);
+ batchMode = Boolean.valueOf(OpenSshConfigFile
+ .flag(entry.getValue(SshConstants.BATCH_MODE)));
+ preferredAuthentications = entry
+ .getValue(SshConstants.PREFERRED_AUTHENTICATIONS);
+ // Fill in defaults if still not set
+ if (hostName == null || hostName.isEmpty()) {
+ hostName = initialHostName;
+ }
+ if (user == null || user.isEmpty()) {
+ user = localUserName;
+ }
+ if (port <= 0) {
+ port = SshConstants.SSH_DEFAULT_PORT;
+ }
+ if (connectionAttempts <= 0) {
+ connectionAttempts = 1;
+ }
+ List<String> identityFiles = entry
+ .getValues(SshConstants.IDENTITY_FILE);
+ if (identityFiles != null && !identityFiles.isEmpty()) {
+ identityFile = new File(identityFiles.get(0));
+ }
+ }
+
+ Config getConfig() {
+ if (config == null) {
+ config = new Config() {
+
+ @Override
+ public String getHostname() {
+ return Host.this.getHostName();
+ }
+
+ @Override
+ public String getUser() {
+ return Host.this.getUser();
+ }
+
+ @Override
+ public int getPort() {
+ return Host.this.getPort();
+ }
+
+ @Override
+ public String getValue(String key) {
+ // See com.jcraft.jsch.OpenSSHConfig.MyConfig.getValue()
+ // for this special case.
+ if (key.equals("compression.s2c") //$NON-NLS-1$
+ || key.equals("compression.c2s")) { //$NON-NLS-1$
+ if (!OpenSshConfigFile.flag(
+ Host.this.entry.getValue(mapKey(key)))) {
+ return "none,zlib@openssh.com,zlib"; //$NON-NLS-1$
+ }
+ return "zlib@openssh.com,zlib,none"; //$NON-NLS-1$
+ }
+ return Host.this.entry.getValue(mapKey(key));
+ }
+
+ @Override
+ public String[] getValues(String key) {
+ List<String> values = Host.this.entry
+ .getValues(mapKey(key));
+ if (values == null) {
+ return new String[0];
+ }
+ return values.toArray(new String[0]);
+ }
+ };
+ }
+ return config;
+ }
+
+ @Override
+ @SuppressWarnings("nls")
+ public String toString() {
+ return "Host [hostName=" + hostName + ", port=" + port
+ + ", identityFile=" + identityFile + ", user=" + user
+ + ", preferredAuthentications=" + preferredAuthentications
+ + ", batchMode=" + batchMode + ", strictHostKeyChecking="
+ + strictHostKeyChecking + ", connectionAttempts="
+ + connectionAttempts + ", entry=" + entry + "]";
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Retrieves the full {@link com.jcraft.jsch.ConfigRepository.Config Config}
+ * for the given host name. Should be called only by Jsch and tests.
+ *
+ * @since 4.9
+ */
+ @Override
+ public Config getConfig(String hostName) {
+ Host host = lookup(hostName);
+ return host.getConfig();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public String toString() {
+ return "OpenSshConfig [configFile=" + configFile + ']'; //$NON-NLS-1$
+ }
+}