This is an automated email from the ASF dual-hosted git repository.
lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
The following commit(s) were added to refs/heads/master by this push:
new f5c63a87d [GH-429] Support GIT protocol-v2
f5c63a87d is described below
commit f5c63a87d46ca5820e17af00b4e65a43288b58c7
Author: =?UTF-8?q?Pavel=20Fla=C5=A1ka?= <[email protected]>
AuthorDate: Mon Dec 11 18:58:20 2023 +0200
[GH-429] Support GIT protocol-v2
---
CHANGES.md | 10 +++++-----
.../java/org/apache/sshd/git/GitModuleProperties.java | 7 +++++++
.../java/org/apache/sshd/git/pack/GitPackCommand.java | 15 ++++++++++++++-
.../org/apache/sshd/git/transport/GitSshdSession.java | 16 +++++++++++++++-
.../org/apache/sshd/git/pack/GitPackCommandTest.java | 13 +++++++++++++
5 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index 97f72b924..800246c46 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -32,9 +32,11 @@
## New Features
-# Behavioral changes and enhancements
+* [GH-429](https://github.com/apache/mina-sshd/issues/429) Support GIT
protocol-v2
-## New `ScpTransferEventListener` callback method
+## Behavioral changes and enhancements
+
+### New `ScpTransferEventListener` callback method
Following [GH-428/GH-392](https://github.com/apache/mina-sshd/issues/428) a
new `handleReceiveCommandAckInfo` method has been added to enable users to
inspect
acknowledgements of a `receive` related command. The user is free to inspect
the command that was attempted as well as the response code and decide how
@@ -43,7 +45,5 @@ an exception if so.
## Potential compatibility issues
-### Server-side SFTP file handle encoding
-
-### Major Code Re-factoring
+## Major Code Re-factoring
diff --git
a/sshd-git/src/main/java/org/apache/sshd/git/GitModuleProperties.java
b/sshd-git/src/main/java/org/apache/sshd/git/GitModuleProperties.java
index e3339a3c1..7ede9b42a 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/GitModuleProperties.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/GitModuleProperties.java
@@ -50,6 +50,13 @@ public final class GitModuleProperties {
public static final Property<Duration> CHANNEL_OPEN_TIMEOUT
= Property.duration("git-ssh-channel-open-timeout",
Duration.ofSeconds(7L));
+ /**
+ * Property used to configure the SSHD {@link
org.apache.sshd.common.FactoryManager} with the {@code GIT_PROTOCOL}
+ * environment variable. The default is not specified and therefore
original (v0) protocol is used.
+ */
+ public static final Property<String> GIT_PROTOCOL_VERSION
+ = Property.string("git-ssh-protocol-version");
+
private GitModuleProperties() {
// private
}
diff --git
a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
index bd102014b..ef77012d7 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
@@ -20,15 +20,20 @@ package org.apache.sshd.git.pack;
import java.io.IOException;
import java.nio.file.Path;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.MapEntryUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.threads.CloseableExecutorService;
import org.apache.sshd.git.AbstractGitCommand;
import org.apache.sshd.git.GitLocationResolver;
+import org.apache.sshd.server.Environment;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
+import org.eclipse.jgit.transport.GitProtocolConstants;
import org.eclipse.jgit.transport.ReceivePack;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.UploadPack;
@@ -77,7 +82,15 @@ public class GitPackCommand extends AbstractGitCommand {
Repository db = key.open(true /* must exist */);
String subCommand = args[0];
if (RemoteConfig.DEFAULT_UPLOAD_PACK.equals(subCommand)) {
- new UploadPack(db).upload(getInputStream(), getOutputStream(),
getErrorStream());
+ UploadPack uploadPack = new UploadPack(db);
+ Environment environment = getEnvironment();
+ Map<String, String> envVars = environment.getEnv();
+ String protocol = MapEntryUtils.isEmpty(envVars)
+ ? null :
envVars.get(GitProtocolConstants.PROTOCOL_ENVIRONMENT_VARIABLE);
+ if (GenericUtils.isNotBlank(protocol)) {
+
uploadPack.setExtraParameters(Collections.singleton(protocol));
+ }
+ uploadPack.upload(getInputStream(), getOutputStream(),
getErrorStream());
} else if (RemoteConfig.DEFAULT_RECEIVE_PACK.equals(subCommand)) {
new ReceivePack(db).receive(getInputStream(),
getOutputStream(), getErrorStream());
} else {
diff --git
a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
index 091c434ae..639f12e52 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSession.java
@@ -19,6 +19,9 @@
package org.apache.sshd.git.transport;
import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.channel.ChannelExec;
@@ -28,6 +31,7 @@ import
org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.git.GitModuleProperties;
import org.eclipse.jgit.transport.CredentialItem;
import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.GitProtocolConstants;
import org.eclipse.jgit.transport.RemoteSession;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.util.FS;
@@ -128,7 +132,17 @@ public class GitSshdSession extends AbstractLoggingBean
implements RemoteSession
log.trace("exec({}) session={}, timeout={} sec.", commandName,
session, timeout);
}
- ChannelExec channel = session.createExecChannel(commandName);
+ ChannelExec channel;
+ Optional<String> protocolVer =
GitModuleProperties.GIT_PROTOCOL_VERSION.get(session);
+ String protocol = protocolVer.orElse(null);
+ if (GenericUtils.isNotBlank(protocol)) {
+ Map<String, String> env = Collections.singletonMap(
+ GitProtocolConstants.PROTOCOL_ENVIRONMENT_VARIABLE,
protocol);
+ channel = session.createExecChannel(commandName, null, env);
+ } else {
+ channel = session.createExecChannel(commandName);
+ }
+
if (traceEnabled) {
log.trace("exec({}) session={} - open channel", commandName,
session);
}
diff --git
a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
index bfee4a395..ea6f00879 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
@@ -24,8 +24,11 @@ import java.util.Collections;
import com.jcraft.jsch.JSch;
import org.apache.sshd.client.SshClient;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.git.GitLocationResolver;
+import org.apache.sshd.git.GitModuleProperties;
import org.apache.sshd.git.transport.GitSshdSessionFactory;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.password.AcceptAllPasswordAuthenticator;
@@ -36,6 +39,7 @@ import org.apache.sshd.util.test.JSchLogger;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.GitProtocolConstants;
import org.eclipse.jgit.transport.SshSessionFactory;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.junit.Assume;
@@ -108,6 +112,15 @@ public class GitPackCommandTest extends BaseTestSupport {
git.pull().setRebase(true).call();
assertTrue("Client not started after rebase",
client.isStarted());
+
+ PropertyResolver useProtocolV2 = PropertyResolverUtils
+ .toPropertyResolver(
+
Collections.singletonMap(GitModuleProperties.GIT_PROTOCOL_VERSION.getName(),
+
GitProtocolConstants.VERSION_2_REQUEST));
+ client.setParentPropertyResolver(useProtocolV2);
+ git.fetch().call();
+ assertTrue("Client not started after fetch using
GIT_PROTOCOL='version=2' env. variable",
+ client.isStarted());
} finally {
client.stop();
}