You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ol...@apache.org on 2018/12/14 04:12:37 UTC
[maven-scm] branch master updated: [SCM-832]
maven-scm-provider-jgit should support SSH public key auth (#50)
This is an automated email from the ASF dual-hosted git repository.
olamy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-scm.git
The following commit(s) were added to refs/heads/master by this push:
new 9a3daee [SCM-832] maven-scm-provider-jgit should support SSH public key auth (#50)
9a3daee is described below
commit 9a3daeeac48a4bf24df73627bc56c45071629834
Author: Martin Kutter <ma...@fen-net.de>
AuthorDate: Fri Dec 14 05:12:32 2018 +0100
[SCM-832] maven-scm-provider-jgit should support SSH public key auth (#50)
* Support public key auth for SSH #SCM-832
Adds a TransportConfigCallback to all remote commands, which adds a public/private key based identity for repositories with ssh URLs if configured.
* Updated documentation for #SCM-832
* [SCM-832] Updated documentation
* [SCM-832] Added debug logging
maven-scm-provider-jgit now outputs the private key used when run as mvn -X
---
.../jgit/command/JGitTransportConfigCallback.java | 106 +++++++++++++++++++++
.../scm/provider/git/jgit/command/JGitUtils.java | 11 ++-
.../jgit/command/checkout/JGitCheckOutCommand.java | 21 +++-
.../git/jgit/command/list/JGitListCommand.java | 6 +-
.../command/remoteinfo/JGitRemoteInfoCommand.java | 4 +-
.../src/site/markdown/index.md.vm | 17 +++-
6 files changed, 153 insertions(+), 12 deletions(-)
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitTransportConfigCallback.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitTransportConfigCallback.java
new file mode 100644
index 0000000..7b13af5
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitTransportConfigCallback.java
@@ -0,0 +1,106 @@
+package org.apache.maven.scm.provider.git.jgit.command;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import org.apache.maven.scm.log.ScmLogger;
+import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
+import org.eclipse.jgit.api.TransportConfigCallback;
+import org.eclipse.jgit.transport.*;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.StringUtils;
+
+/**
+ * Implementation of {@link TransportConfigCallback} which adds
+ * a public/private key identity to ssh URLs if configured.
+ */
+public class JGitTransportConfigCallback implements TransportConfigCallback {
+ private SshSessionFactory sshSessionFactory = null;
+
+ public JGitTransportConfigCallback(GitScmProviderRepository repo, ScmLogger logger) {
+ if (repo.getFetchInfo().getProtocol().equals("ssh")) {
+ if (!StringUtils.isEmptyOrNull(repo.getPrivateKey()) && repo.getPassphrase() == null) {
+ logger.debug("using private key with passphrase: " + repo.getPrivateKey());
+ sshSessionFactory = new UnprotectedPrivateKeySessionFactory(repo);
+ } else if (!StringUtils.isEmptyOrNull(repo.getPrivateKey()) && repo.getPassphrase() != null) {
+ logger.debug("using private key: " + repo.getPrivateKey());
+ sshSessionFactory = new ProtectedPrivateKeyFileSessionFactory(repo);
+ } else {
+ sshSessionFactory = new SimpleSessionFactory();
+ }
+ }
+ }
+
+ @Override
+ public void configure(Transport transport) {
+ if (transport instanceof SshTransport) {
+ SshTransport sshTransport = (SshTransport) transport;
+ sshTransport.setSshSessionFactory(sshSessionFactory);
+ }
+ }
+
+ static private class SimpleSessionFactory extends JschConfigSessionFactory {
+ @Override
+ protected void configure(OpenSshConfig.Host host, Session session) {
+ }
+ }
+
+ static private abstract class PrivateKeySessionFactory extends SimpleSessionFactory {
+ private final GitScmProviderRepository repo;
+
+ public GitScmProviderRepository getRepo() {
+ return repo;
+ }
+
+ public PrivateKeySessionFactory(GitScmProviderRepository repo) {
+ this.repo = repo;
+ }
+ }
+
+ static private class UnprotectedPrivateKeySessionFactory extends PrivateKeySessionFactory {
+
+ public UnprotectedPrivateKeySessionFactory(GitScmProviderRepository repo) {
+ super(repo);
+ }
+
+ @Override
+ protected JSch createDefaultJSch(FS fs) throws JSchException {
+ JSch defaultJSch = super.createDefaultJSch(fs);
+ defaultJSch.addIdentity(getRepo().getPrivateKey());
+ return defaultJSch;
+ }
+ }
+
+ static private class ProtectedPrivateKeyFileSessionFactory extends PrivateKeySessionFactory {
+
+ public ProtectedPrivateKeyFileSessionFactory(GitScmProviderRepository repo) {
+ super(repo);
+ }
+
+ @Override
+ protected JSch createDefaultJSch(FS fs) throws JSchException {
+ JSch defaultJSch = super.createDefaultJSch(fs);
+ defaultJSch.addIdentity(getRepo().getPrivateKey(), getRepo().getPassphrase());
+ return defaultJSch;
+ }
+ }
+}
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
index b6900b4..3e3a4f4 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
@@ -28,6 +28,7 @@ import org.apache.maven.scm.util.FilenameUtils;
import org.codehaus.plexus.util.StringUtils;
import org.eclipse.jgit.api.AddCommand;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.PushCommand;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
@@ -83,7 +84,7 @@ import java.util.Set;
*/
public class JGitUtils
{
-
+
private JGitUtils()
{
// no op
@@ -178,6 +179,8 @@ public class JGitUtils
return new UsernamePasswordCredentialsProvider( repository.getUser().trim(),
repository.getPassword().trim() );
}
+
+
return null;
}
@@ -185,8 +188,10 @@ public class JGitUtils
throws GitAPIException, InvalidRemoteException, TransportException
{
CredentialsProvider credentials = JGitUtils.prepareSession( logger, git, repo );
- Iterable<PushResult> pushResultList =
- git.push().setCredentialsProvider( credentials ).setRefSpecs( refSpec ).call();
+ PushCommand command = git.push().setRefSpecs(refSpec).setCredentialsProvider(credentials)
+ .setTransportConfigCallback(new JGitTransportConfigCallback(repo, logger));
+
+ Iterable<PushResult> pushResultList = command.call();
for ( PushResult pushResult : pushResultList )
{
Collection<RemoteRefUpdate> ru = pushResult.getRemoteUpdates();
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkout/JGitCheckOutCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkout/JGitCheckOutCommand.java
index b89299a..ea1f1dd 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkout/JGitCheckOutCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkout/JGitCheckOutCommand.java
@@ -30,13 +30,13 @@ import org.apache.maven.scm.command.checkout.CheckOutScmResult;
import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.git.command.GitCommand;
+import org.apache.maven.scm.provider.git.jgit.command.JGitTransportConfigCallback;
import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
import org.apache.maven.scm.provider.git.jgit.command.branch.JGitBranchCommand;
import org.apache.maven.scm.provider.git.jgit.command.remoteinfo.JGitRemoteInfoCommand;
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
import org.codehaus.plexus.util.StringUtils;
-import org.eclipse.jgit.api.CloneCommand;
-import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.*;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ProgressMonitor;
import org.eclipse.jgit.revwalk.RevCommit;
@@ -109,7 +109,13 @@ public class JGitCheckOutCommand
CredentialsProvider credentials = JGitUtils.getCredentials( (GitScmProviderRepository) repo );
getLogger().info( "cloning [" + branch + "] to " + fileSet.getBasedir() );
CloneCommand command = Git.cloneRepository().setURI( repository.getFetchUrl() );
+
command.setCredentialsProvider( credentials ).setBranch( branch ).setDirectory( fileSet.getBasedir() );
+
+ TransportConfigCallback transportConfigCallback = new JGitTransportConfigCallback(
+ (GitScmProviderRepository) repo, getLogger());
+ command.setTransportConfigCallback(transportConfigCallback);
+
command.setProgressMonitor( monitor );
git = command.call();
}
@@ -129,6 +135,8 @@ public class JGitCheckOutCommand
{
// git repo exists, so we must git-pull the changes
CredentialsProvider credentials = JGitUtils.prepareSession( getLogger(), git, repository );
+ TransportConfigCallback transportConfigCallback = new JGitTransportConfigCallback(
+ (GitScmProviderRepository) repo, getLogger());
if ( version != null && StringUtils.isNotEmpty( version.getName() ) && ( version instanceof ScmTag ) )
{
@@ -138,12 +146,17 @@ public class JGitCheckOutCommand
// In fact, a tag in git may be in multiple branches. This occurs if
// you create a branch after the tag has been created
getLogger().debug( "fetch..." );
- git.fetch().setCredentialsProvider( credentials ).setProgressMonitor( monitor ).call();
+ FetchCommand command = git.fetch().setCredentialsProvider(credentials).setProgressMonitor(monitor);
+ command.setTransportConfigCallback(transportConfigCallback);
+ command.call();
+
}
else
{
getLogger().debug( "pull..." );
- git.pull().setCredentialsProvider( credentials ).setProgressMonitor( monitor ).call();
+ PullCommand command = git.pull().setCredentialsProvider(credentials).setProgressMonitor(monitor);
+ command.setTransportConfigCallback(transportConfigCallback);
+ command.call();
}
}
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/list/JGitListCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/list/JGitListCommand.java
index ef86c09..937fa1d 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/list/JGitListCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/list/JGitListCommand.java
@@ -28,6 +28,7 @@ import org.apache.maven.scm.command.list.AbstractListCommand;
import org.apache.maven.scm.command.list.ListScmResult;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.git.command.GitCommand;
+import org.apache.maven.scm.provider.git.jgit.command.JGitTransportConfigCallback;
import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
import org.eclipse.jgit.api.Git;
@@ -61,7 +62,10 @@ public class JGitListCommand
JGitUtils.prepareSession( getLogger(), git, (GitScmProviderRepository) repo );
List<ScmFile> list = new ArrayList<ScmFile>();
- Collection<Ref> lsResult = git.lsRemote().setCredentialsProvider( credentials ).call();
+ Collection<Ref> lsResult = git.lsRemote().setCredentialsProvider( credentials )
+ .setTransportConfigCallback(
+ new JGitTransportConfigCallback((GitScmProviderRepository) repo, getLogger()))
+ .call();
for ( Ref ref : lsResult )
{
getLogger().debug( ref.getObjectId().getName() + " " + ref.getTarget().getName() );
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommand.java
index b521b0b..451be02 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommand.java
@@ -26,6 +26,7 @@ import org.apache.maven.scm.command.remoteinfo.AbstractRemoteInfoCommand;
import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.provider.git.command.GitCommand;
+import org.apache.maven.scm.provider.git.jgit.command.JGitTransportConfigCallback;
import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
import org.eclipse.jgit.api.Git;
@@ -61,7 +62,8 @@ public class JGitRemoteInfoCommand
CredentialsProvider credentials = JGitUtils.getCredentials( repo );
LsRemoteCommand lsCommand =
- git.lsRemote().setRemote( repo.getPushUrl() ).setCredentialsProvider( credentials );
+ git.lsRemote().setRemote( repo.getPushUrl() ).setCredentialsProvider( credentials )
+ .setTransportConfigCallback(new JGitTransportConfigCallback(repo, getLogger()));
Map<String, String> tag = new HashMap<String, String>();
Collection<Ref> allTags = lsCommand.setHeads( false ).setTags( true ).call();
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/site/markdown/index.md.vm b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/site/markdown/index.md.vm
index d95a1a6..b64b7af 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/site/markdown/index.md.vm
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/site/markdown/index.md.vm
@@ -20,8 +20,9 @@ under the License.
maven-scm-provider-jgit
===
-This scm provider implementation allows the usage of git with the release and scm plugin without having to install a nativ git client.
-This implementation uses username and password instead of a public/private keys to authenticate the requests to a remote repository like GitHub.
+This scm provider implementation allows the usage of git with the release and scm plugin without having to install a native git client.
+This implementation can use both username and password, or public/private keys to authenticate the requests to a remote
+repository like GitHub. At the moment, public/private keys are only supported for SSH access.
Configuration
---
@@ -65,7 +66,17 @@ Usage with the `maven-scm-plugin`
</dependency>
</dependencies>
</plugin>
-
+
+Public/private key configuration in settings.xml - for use with ssh URLs like ssh://git@github.com/apache/maven-scm
+
+ <servers>
+ <server>
+ <id>git@github.com</id>
+ <privateKey>path/to/private/key</privateKey>
+ <passphrase>private key passphrase</passphrase>
+ </server>
+ <server>
+
Examples
____