Skip to content

Commit

Permalink
downloader: Migrate from JSch to MINA as the SSH backend for JGit
Browse files Browse the repository at this point in the history
The used `org.eclipse.jgit.ssh.apache.agent` artifact has build-in
ssh-agent support.

Resolves #6029.

Signed-off-by: Sebastian Schuberth <[email protected]>
  • Loading branch information
sschuberth committed Nov 2, 2022
1 parent 5788347 commit ca40652
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 43 deletions.
10 changes: 1 addition & 9 deletions downloader/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,8 @@ dependencies {

implementation(project(":utils:ort-utils"))

// Force the generated Maven POM to use the same version of "jsch" Gradle resolves the version conflict to.
implementation("com.jcraft:jsch") {
version {
strictly("0.1.55")
}
}

implementation(libs.jgit)
implementation(libs.jgitJsch)
implementation(libs.jschAgentProxy)
implementation(libs.jgitSshApacheAgent)
implementation(libs.svnkit)

testImplementation(libs.mockk)
Expand Down
56 changes: 25 additions & 31 deletions downloader/src/main/kotlin/vcs/Git.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@

package org.ossreviewtoolkit.downloader.vcs

import com.jcraft.jsch.JSch
import com.jcraft.jsch.agentproxy.AgentProxyException
import com.jcraft.jsch.agentproxy.RemoteIdentityRepository
import com.jcraft.jsch.agentproxy.connector.SSHAgentConnector
import com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory

import com.vdurmont.semver4j.Requirement

import java.io.File
import java.io.IOException
import java.net.Authenticator
import java.net.InetSocketAddress
import java.security.PublicKey
import java.util.regex.Pattern

import org.apache.logging.log4j.kotlin.Logging
Expand All @@ -45,7 +41,10 @@ import org.eclipse.jgit.transport.CredentialsProvider
import org.eclipse.jgit.transport.SshSessionFactory
import org.eclipse.jgit.transport.TagOpt
import org.eclipse.jgit.transport.URIish
import org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory
import org.eclipse.jgit.transport.sshd.DefaultProxyDataFactory
import org.eclipse.jgit.transport.sshd.JGitKeyCache
import org.eclipse.jgit.transport.sshd.ServerKeyDatabase
import org.eclipse.jgit.transport.sshd.SshdSessionFactory

import org.ossreviewtoolkit.downloader.VersionControlSystem
import org.ossreviewtoolkit.downloader.WorkingTree
Expand Down Expand Up @@ -73,30 +72,25 @@ class Git : VersionControlSystem(), CommandLineTool {
// discrepancies in the way .netrc files are interpreted between JGit's and ORT's implementation.
CredentialsProvider.setDefault(AuthenticatorCredentialsProvider)

val sessionFactory = object : JschConfigSessionFactory() {
override fun configureJSch(jsch: JSch) {
// Accept unknown hosts.
JSch.setConfig("StrictHostKeyChecking", "no")

// Limit to "publickey" to avoid "keyboard-interactive" prompts.
JSch.setConfig("PreferredAuthentications", "publickey")

try {
// By default, JGit configures JSch to use identity files (named "identity", "id_rsa" or
// "id_dsa") from the current user's ".ssh" directory only, also see
// https://www.codeaffine.com/2014/12/09/jgit-authentication/. Additionally configure JSch to
// connect to an SSH-Agent if available.
if (SSHAgentConnector.isConnectorAvailable()) {
val socketFactory = JNAUSocketFactory()
val connector = SSHAgentConnector(socketFactory)
jsch.identityRepository = RemoteIdentityRepository(connector)
}
} catch (e: AgentProxyException) {
e.showStackTrace()

logger.error { "Could not create SSH Agent connector: ${e.collectMessages()}" }
}
}
// Create a dummy key database that accepts any key from any (unknown) host.
val dummyKeyDatabase = object : ServerKeyDatabase {
override fun lookup(
connectAddress: String,
remoteAddress: InetSocketAddress,
config: ServerKeyDatabase.Configuration
) = emptyList<PublicKey>()

override fun accept(
connectAddress: String,
remoteAddress: InetSocketAddress,
serverKey: PublicKey,
config: ServerKeyDatabase.Configuration,
provider: CredentialsProvider?
) = true
}

val sessionFactory = object : SshdSessionFactory(JGitKeyCache(), DefaultProxyDataFactory()) {
override fun getServerKeyDatabase(homeDir: File, sshDir: File) = dummyKeyDatabase
}

SshSessionFactory.setInstance(sessionFactory)
Expand Down
4 changes: 1 addition & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jackson = "2.13.4"
jgit = "6.3.0.202209071007-r"
jiraRestClient = "5.2.4"
jruby = "9.3.9.0"
jschAgentProxy = "0.0.9"
jslt = "0.1.13"
jsonSchemaValidator = "1.0.73"
kotest = "5.5.3"
Expand Down Expand Up @@ -111,11 +110,10 @@ jacksonDatatypeJsr310 = { module = "com.fasterxml.jackson.datatype:jackson-datat
jacksonModuleJaxbAnnotations = { module = "com.fasterxml.jackson.module:jackson-module-jaxb-annotations", version.ref = "jackson" }
jacksonModuleKotlin = { module = "com.fasterxml.jackson.module:jackson-module-kotlin", version.ref = "jackson" }
jgit = { module = "org.eclipse.jgit:org.eclipse.jgit", version.ref = "jgit" }
jgitJsch = { module = "org.eclipse.jgit:org.eclipse.jgit.ssh.jsch", version.ref = "jgit" }
jgitSshApacheAgent = { module = "org.eclipse.jgit:org.eclipse.jgit.ssh.apache.agent", version.ref = "jgit" }
jiraRestClientApi = { module = "com.atlassian.jira:jira-rest-java-client-api", version.ref = "jiraRestClient" }
jiraRestClientApp = { module = "com.atlassian.jira:jira-rest-java-client-app", version.ref = "jiraRestClient" }
jruby = { module = "org.jruby:jruby-complete", version.ref = "jruby" }
jschAgentProxy = { module = "com.jcraft:jsch.agentproxy.jsch", version.ref = "jschAgentProxy" }
jslt = { module = "com.schibsted.spt.data:jslt", version.ref = "jslt" }
jsonSchemaValidator = { module = "com.networknt:json-schema-validator", version.ref = "jsonSchemaValidator" }
kotestAssertionsCore = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
Expand Down

0 comments on commit ca40652

Please sign in to comment.