Skip to content

Instantly share code, notes, and snippets.

@quidryan
Last active February 14, 2024 22:22
Show Gist options
  • Save quidryan/5449155 to your computer and use it in GitHub Desktop.
Save quidryan/5449155 to your computer and use it in GitHub Desktop.
Code to use ssh-agent when using JGit. Running in Gradle with the gradle-git plugin.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.ajoberstar:gradle-git:0.5.0' // not used in this example, but it's what brings in JGit
classpath 'com.jcraft:jsch.agentproxy.jsch:0.0.5'
classpath 'com.jcraft:jsch.agentproxy.usocket-jna:0.0.5'
classpath 'com.jcraft:jsch.agentproxy.sshagent:0.0.5'
}
}
import com.jcraft.jsch.*;
import com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory;
import com.jcraft.jsch.agentproxy.connector.SSHAgentConnector;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.util.FS;
import java.io.FileInputStream;
def sessionFactory = new JschConfigSessionFactory() {
@Override
protected void configure(OpenSshConfig.Host host, Session session) {
// This can be removed, but the overriden method is required since JschConfigSessionFactory is abstract
session.setConfig("StrictHostKeyChecking", "false");
}
@Override
protected JSch createDefaultJSch(FS fs) throws JSchException {
Connector con = null;
try {
if(SSHAgentConnector.isConnectorAvailable()){
//USocketFactory usf = new JUnixDomainSocketFactory();
USocketFactory usf = new JNAUSocketFactory();
con = new SSHAgentConnector(usf);
}
} catch(AgentProxyException e){
System.out.println(e);
}
if (con == null) {
return super.createDefaultJSch(fs)
} else {
final JSch jsch = new JSch();
jsch.setConfig("PreferredAuthentications", "publickey");
IdentityRepository irepo = new RemoteIdentityRepository(con);
jsch.setIdentityRepository(irepo);
knownHosts(jsch, fs) // private method from parent class, yeah for Groovy!
return jsch
}
}
}
SshSessionFactory.setInstance(sessionFactory)
@realdadfish
Copy link

realdadfish commented Feb 14, 2024

In case anybody stumbles upon this, jsch is kind of abandonware, the Eclipse Bugtracker says they want to move away to Apache MINA, but recent jgit versions today still use jsch with the aforementioned IdentityFile issue. I fiddled around with different settings in my .ssh/config, but other than commenting out the respective IdentityFile entries nothing helped.

Here is the code in org.eclipse.jgit.transport.ssh.jsch.JschConfigSessionFactory that creates the issue:

    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);
                        // ^^^ the identities coming from the agent are identified by their name (comment)
		}

		final File identityFile = hc.getIdentityFile();
                 // ^^^ here the identity file from .ssh/config is returned
		if (identityFile == null)
			return defaultJSch;
                         // ^^^ no identity file, no problem, our JSch instance with the remote identity repository is used

		final String identityKey = identityFile.getAbsolutePath();
		JSch jsch = byIdentityFile.get(identityKey);
                 // ^^^ now that can never succeed, because the comment of the identity is of course unequal to the path of it's file
		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;
	}

Reported upstream as eclipse-jgit/jgit#23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment