summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Pursehouse <dpursehouse@collab.net>2018-09-26 21:10:59 +0900
committerDavid Pursehouse <dpursehouse@collab.net>2018-11-14 15:52:04 -0800
commit437d7ef616b33e5c22dafe76b51dc700c65853d7 (patch)
treef4820e11e393c910b38e09379f86d232cfd7eaa7
parent48827f691680b52064b050754096afc49443e734 (diff)
Allow to enable git protocol version 2 for upload pack
When receive.enableProtocolV2 is set to true, set the necessary extra parameters on the UploadPack to tell JGit to handle the request with protocol v2. Note that according to JGit's implementation, the git config on the repository on the server must also be configured to use protocol v2. This can be achieved either by setting it globally in the gerrit user's ~/.gitconfig or per repository in the repository's .git/config: [protocol] version = 2 Test plan: - Set protocol.version to 2 in the project's server-side config (or in the gerrit user's ~/.gitconfig) - Clone the project over SSH or HTTP - From the client, run: GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote (one can also configure this permanently on the local project by running `git config protocol.version 2`) - Observe the packet output including: git< version 2 Feature: Issue 9046 Helped-by: David Ostrovsky <david@ostrovsky.org> Helped-by: Jonathan Nieder <jrn@google.com> Change-Id: I30290e8f060c1ee11b170aac2baeed10f213aad1
-rw-r--r--Documentation/config-gerrit.txt14
-rw-r--r--java/com/google/gerrit/httpd/GitOverHttpServlet.java8
-rw-r--r--java/com/google/gerrit/server/git/TransferConfig.java6
-rw-r--r--java/com/google/gerrit/sshd/AbstractGitCommand.java4
-rw-r--r--java/com/google/gerrit/sshd/commands/Upload.java5
5 files changed, 36 insertions, 1 deletions
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 3927b49c0b..0cb2b003b4 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -3806,6 +3806,20 @@ link:https://www.gnupg.org/documentation/manuals/gnupg/OpenPGP-Key-Management.ht
If no keys are specified, web-of-trust checks are disabled. This is the
default behavior.
+[[receive.enableProtocolV2]]receive.enableProtocolV2::
++
+Enable support for git protocol version 2.
++
+When this option is enabled, clients may send upload pack using git
+protocol version 2.
++
+The repository must also be configured on the server side to use protocol
+version 2 by setting `protocol.version = 2` either in the gerrit user's
+`~/.gitconfig` file (which will enable it for all repositories) or on
+a per repository basis by setting the option in the `.git/config` file
+of the repository.
++
+Defaults to false, git protocol version 2 is not enabled.
[[repository]]
=== Section repository
diff --git a/java/com/google/gerrit/httpd/GitOverHttpServlet.java b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
index 08ff8a74f7..e74c4b2bfa 100644
--- a/java/com/google/gerrit/httpd/GitOverHttpServlet.java
+++ b/java/com/google/gerrit/httpd/GitOverHttpServlet.java
@@ -49,6 +49,7 @@ import com.google.inject.TypeLiteral;
import com.google.inject.name.Named;
import java.io.IOException;
import java.time.Duration;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -258,6 +259,13 @@ public class GitOverHttpServlet extends GitServlet {
up.setTimeout(config.getTimeout());
up.setPreUploadHook(PreUploadHookChain.newChain(Lists.newArrayList(preUploadHooks)));
up.setPostUploadHook(PostUploadHookChain.newChain(Lists.newArrayList(postUploadHooks)));
+ if (config.enableProtocolV2()) {
+ String header = req.getHeader("Git-Protocol");
+ if (header != null) {
+ String[] params = header.split(":");
+ up.setExtraParameters(Arrays.asList(params));
+ }
+ }
ProjectState state = (ProjectState) req.getAttribute(ATT_STATE);
for (UploadPackInitializer initializer : uploadPackInitializers) {
initializer.init(state.getNameKey(), up);
diff --git a/java/com/google/gerrit/server/git/TransferConfig.java b/java/com/google/gerrit/server/git/TransferConfig.java
index 55b9448fc9..dde524f681 100644
--- a/java/com/google/gerrit/server/git/TransferConfig.java
+++ b/java/com/google/gerrit/server/git/TransferConfig.java
@@ -29,6 +29,7 @@ public class TransferConfig {
private final long maxObjectSizeLimit;
private final String maxObjectSizeLimitFormatted;
private final boolean inheritProjectMaxObjectSizeLimit;
+ private final boolean enableProtocolV2;
@Inject
TransferConfig(@GerritServerConfig Config cfg) {
@@ -45,6 +46,7 @@ public class TransferConfig {
maxObjectSizeLimitFormatted = cfg.getString("receive", null, "maxObjectSizeLimit");
inheritProjectMaxObjectSizeLimit =
cfg.getBoolean("receive", "inheritProjectMaxObjectSizeLimit", false);
+ enableProtocolV2 = cfg.getBoolean("receive", "enableProtocolV2", false);
packConfig = new PackConfig();
packConfig.setDeltaCompress(false);
@@ -72,4 +74,8 @@ public class TransferConfig {
public boolean inheritProjectMaxObjectSizeLimit() {
return inheritProjectMaxObjectSizeLimit;
}
+
+ public boolean enableProtocolV2() {
+ return enableProtocolV2;
+ }
}
diff --git a/java/com/google/gerrit/sshd/AbstractGitCommand.java b/java/com/google/gerrit/sshd/AbstractGitCommand.java
index c49ae82de2..5370c9e4fc 100644
--- a/java/com/google/gerrit/sshd/AbstractGitCommand.java
+++ b/java/com/google/gerrit/sshd/AbstractGitCommand.java
@@ -29,6 +29,8 @@ import org.eclipse.jgit.lib.Repository;
import org.kohsuke.args4j.Argument;
public abstract class AbstractGitCommand extends BaseCommand {
+ private static final String GIT_PROTOCOL = "GIT_PROTOCOL";
+
@Argument(index = 0, metaVar = "PROJECT.git", required = true, usage = "project name")
protected ProjectState projectState;
@@ -45,9 +47,11 @@ public abstract class AbstractGitCommand extends BaseCommand {
protected Repository repo;
protected Project.NameKey projectName;
protected Project project;
+ protected String gitProtocol;
@Override
public void start(Environment env) {
+ gitProtocol = env.getEnv().get(GIT_PROTOCOL);
Context ctx = context.subContext(newSession(), context.getCommandLine());
final Context old = sshScope.set(ctx);
try {
diff --git a/java/com/google/gerrit/sshd/commands/Upload.java b/java/com/google/gerrit/sshd/commands/Upload.java
index 24a6975867..c5ffc168c8 100644
--- a/java/com/google/gerrit/sshd/commands/Upload.java
+++ b/java/com/google/gerrit/sshd/commands/Upload.java
@@ -14,6 +14,7 @@
package com.google.gerrit.sshd.commands;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.gerrit.extensions.registration.DynamicSet;
import com.google.gerrit.extensions.restapi.AuthException;
@@ -52,7 +53,6 @@ final class Upload extends AbstractGitCommand {
PermissionBackend.ForProject perm =
permissionBackend.user(user).project(projectState.getNameKey());
try {
-
perm.check(ProjectPermission.RUN_UPLOAD_PACK);
} catch (AuthException e) {
throw new Failure(1, "fatal: upload-pack not permitted on this server");
@@ -65,6 +65,9 @@ final class Upload extends AbstractGitCommand {
up.setPackConfig(config.getPackConfig());
up.setTimeout(config.getTimeout());
up.setPostUploadHook(PostUploadHookChain.newChain(Lists.newArrayList(postUploadHooks)));
+ if (config.enableProtocolV2() && gitProtocol != null) {
+ up.setExtraParameters(ImmutableList.of(gitProtocol));
+ }
List<PreUploadHook> allPreUploadHooks = Lists.newArrayList(preUploadHooks);
allPreUploadHooks.add(