Skip to content

Commit

Permalink
[SCM-945] Update to JGit 5.13.1 leveraging Apache Mina SSHD
Browse files Browse the repository at this point in the history
This supports OpenSSH private keys and drops usage of unmaintained JSch
  • Loading branch information
kwin committed Jul 8, 2022
1 parent b04525f commit ee650d9
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.5.4.201711221230-r</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
<version>5.13.1.202206130422-r</version><!-- since version 6 requires Java 11 -->
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>5.13.1.202206130422-r</version><!-- since version 6 requires Java 11 -->
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,22 @@
* under the License.
*/

import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;

import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshTransport;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.sshd.IdentityPasswordProvider;
import org.eclipse.jgit.transport.sshd.KeyPasswordProvider;
import org.eclipse.jgit.transport.sshd.SshdSessionFactory;
import org.eclipse.jgit.util.StringUtils;
import org.slf4j.Logger;

Expand All @@ -39,26 +44,13 @@
*/
public class JGitTransportConfigCallback implements TransportConfigCallback
{
private SshSessionFactory sshSessionFactory = null;
private SshdSessionFactory sshSessionFactory = null;

public JGitTransportConfigCallback( GitScmProviderRepository repo, Logger logger )
{
if ( repo.getFetchInfo().getProtocol().equals( "ssh" ) )
{
if ( !StringUtils.isEmptyOrNull( repo.getPrivateKey() ) && repo.getPassphrase() == null )
{
logger.debug( "using private key: " + repo.getPrivateKey() );
sshSessionFactory = new UnprotectedPrivateKeySessionFactory( repo );
}
else if ( !StringUtils.isEmptyOrNull( repo.getPrivateKey() ) && repo.getPassphrase() != null )
{
logger.debug( "using private key with passphrase: " + repo.getPrivateKey() );
sshSessionFactory = new ProtectedPrivateKeyFileSessionFactory( repo );
}
else
{
sshSessionFactory = new SimpleSessionFactory();
}
sshSessionFactory = new ScmProviderAwareSshdSessionFactory( repo, logger );
}
}

Expand All @@ -72,60 +64,56 @@ public void configure( Transport transport )
}
}

private static class SimpleSessionFactory extends JschConfigSessionFactory
{
@Override
protected void configure( OpenSshConfig.Host host, Session session )
{
}
}

private abstract static class PrivateKeySessionFactory extends SimpleSessionFactory
private static final class ScmProviderAwareSshdSessionFactory extends SshdSessionFactory
{
private final GitScmProviderRepository repo;
private final Logger logger;

GitScmProviderRepository getRepo()
{
return repo;
}

PrivateKeySessionFactory( GitScmProviderRepository repo )
ScmProviderAwareSshdSessionFactory( GitScmProviderRepository repo, Logger logger )
{
this.repo = repo;
}
}

private static class UnprotectedPrivateKeySessionFactory extends PrivateKeySessionFactory
{

UnprotectedPrivateKeySessionFactory( GitScmProviderRepository repo )
{
super( repo );
this.logger = logger;
}

@Override
protected JSch createDefaultJSch( FS fs ) throws JSchException
{
JSch defaultJSch = super.createDefaultJSch( fs );
defaultJSch.addIdentity( getRepo().getPrivateKey() );
return defaultJSch;
}
}

private static class ProtectedPrivateKeyFileSessionFactory extends PrivateKeySessionFactory
{

ProtectedPrivateKeyFileSessionFactory( GitScmProviderRepository repo )
protected List<Path> getDefaultIdentities( File sshDir )
{
super( repo );
if ( !StringUtils.isEmptyOrNull( repo.getPrivateKey() ) )
{
logger.debug( "using private key: {}", repo.getPrivateKey() );
return Collections.singletonList( Paths.get( repo.getPrivateKey() ) );
}
else
{
return super.getDefaultIdentities( sshDir );
}
}

@Override
protected JSch createDefaultJSch( FS fs ) throws JSchException
protected KeyPasswordProvider createKeyPasswordProvider( CredentialsProvider provider )
{
JSch defaultJSch = super.createDefaultJSch( fs );
defaultJSch.addIdentity( getRepo().getPrivateKey(), getRepo().getPassphrase() );
return defaultJSch;
if ( repo.getPassphrase() != null )
{
return new IdentityPasswordProvider( provider )
{
@Override
public char[] getPassphrase( URIish uri, int attempt ) throws IOException
{
if ( attempt > 0 )
{
throw new IOException( "Passphrase was not correct in first attempt, "
+ "cancel further attempts!" );
}
logger.debug( "using stored passphrase" );
return repo.getPassphrase().toCharArray();
}
};
}
else
{
return super.createKeyPasswordProvider( provider );
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,12 @@ public int getTimezone( long when )
{
return reader.getTimezone( when );
}

@Override
public FileBasedConfig openJGitConfig( Config config, FS fs )
{
return reader.openJGitConfig( config, fs );
}
}

}

0 comments on commit ee650d9

Please sign in to comment.