Skip to content

Commit

Permalink
[GH-429] Support GIT protocol-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
=?UTF-8?q?Pavel=20Fla=C5=A1ka?= authored and Lyor Goldstein committed Dec 11, 2023
1 parent f25d800 commit f5c63a8
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 7 deletions.
10 changes: 5 additions & 5 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,20 @@

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;
Expand Down Expand Up @@ -77,7 +82,15 @@ public void run() {
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,6 +31,7 @@
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;
Expand Down Expand Up @@ -128,7 +132,17 @@ public Process exec(String commandName, int timeout) throws IOException {
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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@

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;
Expand All @@ -36,6 +39,7 @@
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;
Expand Down Expand Up @@ -108,6 +112,15 @@ public void testGitPack() throws Exception {

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();
}
Expand Down

0 comments on commit f5c63a8

Please sign in to comment.