Skip to content

Modernize to Jenkins 2.479 and Jakarta EE 9 #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ mvn.out*
.settings/
.repository/
.settings.xml
.idea/
41 changes: 21 additions & 20 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.86</version>
<relativePath/>
<version>5.6</version>
<relativePath />
</parent>

<artifactId>git-server</artifactId>
Expand All @@ -15,21 +16,6 @@
<name>Jenkins Git server Plugin</name>
<url>https://github.com/jenkinsci/${project.artifactId}-plugin</url>

<properties>
<changelist>999999-SNAPSHOT</changelist>
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
<jenkins.baseline>2.440</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.3</jenkins.version>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
</properties>

<scm>
<connection>scm:git:https://github.com/${gitHubRepo}.git</connection>
<developerConnection>scm:git:[email protected]:${gitHubRepo}.git</developerConnection>
<url>https://github.com/${gitHubRepo}</url>
<tag>${scmTag}</tag>
</scm>

<licenses>
<license>
<name>The MIT license</name>
Expand All @@ -38,14 +24,29 @@
</license>
</licenses>

<scm>
<connection>scm:git:https://github.com/${gitHubRepo}.git</connection>
<developerConnection>scm:git:[email protected]:${gitHubRepo}.git</developerConnection>
<tag>${scmTag}</tag>
<url>https://github.com/${gitHubRepo}</url>
</scm>

<properties>
<changelist>999999-SNAPSHOT</changelist>
<!-- https://www.jenkins.io/doc/developer/plugin-development/choosing-jenkins-baseline/ -->
<jenkins.baseline>2.479</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
</properties>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>3234.v5ca_5154341ef</version>
<scope>import</scope>
<version>4023.va_eeb_b_4e45f07</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Expand All @@ -67,7 +68,7 @@
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>6.9.0.202403050737-r</version>
<version>7.0.0.202409031743-r</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@

import hudson.Extension;
import hudson.security.csrf.CrumbExclusion;

import javax.servlet.FilterChain;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

/**
* CSRF exclusion for git-upload-pack.
*
*
* <p>
* We do some basic checks to significantly limit the scope of exclusion, but
* because of the dynamic nature of the URL structure, this doesn't guarantee
* that we have no leak.
*
* <p>
* So to further protect Jenkins, we pass through a fake {@link HttpServletRequest}
* that masks the values of the submission.
*
*
* <p>
* If the fake request is routed to {@link HttpGitRepository}, which is
* the only legitimate destination of the request, we'll unwrap this fake request
Expand All @@ -35,53 +35,51 @@
* <p>
* In this way, even if an attacker manages to route the request to elsewhere in Jenkins,
* that request will not be interpreted as a POST request.
*
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class CSRFExclusionImpl extends CrumbExclusion {
private static final String BOGUS = "bogus";

public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (!"application/x-git-receive-pack-request".equals(request.getHeader("Content-Type")))
return false;

// String path = request.getPathInfo();
// if(!path.contains("/repo.git/") || !path.endsWith("/git-receive-pack"))
// return false;
@Override
public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (!"application/x-git-receive-pack-request".equals(request.getHeader("Content-Type"))) return false;

HttpServletRequestWrapper w = new HttpServletRequestWrapper(request) {
@Override
public String getQueryString() {
return "bogus";
return BOGUS;
}

@Override
public String getParameter(String name) {
return "bogus";
return BOGUS;
}

@Override
public Map getParameterMap() {
public Map<String, String[]> getParameterMap() {
return Collections.emptyMap();
}

@Override
public Enumeration getParameterNames() {
return new Vector().elements();
public Enumeration<String> getParameterNames() {
return Collections.emptyEnumeration();
}

@Override
public String[] getParameterValues(String name) {
return new String[]{"bogus"};
return new String[] {BOGUS};
}

@Override
public String getMethod() {
return "BOGUS";
return BOGUS.toUpperCase(Locale.ROOT);

Check warning on line 78 in src/main/java/org/jenkinsci/plugins/gitserver/CSRFExclusionImpl.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 48-78 are not covered by tests
}

@Override
public ServletInputStream getInputStream() throws IOException {
public ServletInputStream getInputStream() {
return new ServletInputStream() {
@Override
public boolean isFinished() {
Expand All @@ -94,7 +92,7 @@
}

@Override
public int read() throws IOException {
public int read() {
return -1;
}

Expand All @@ -105,13 +103,13 @@
};
}
};
w.setAttribute(ORIGINAL_REQUEST,request);
chain.doFilter(w,response);
w.setAttribute(ORIGINAL_REQUEST, request);

chain.doFilter(w, response);
return true;
}

static final String ORIGINAL_REQUEST = CSRFExclusionImpl.class.getName()+".originalRequest";
static final String ORIGINAL_REQUEST = CSRFExclusionImpl.class.getName() + ".originalRequest";

public static HttpServletRequest unwrapRequest(HttpServletRequest req) {
return (HttpServletRequest) req.getAttribute(CSRFExclusionImpl.ORIGINAL_REQUEST);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package org.jenkinsci.plugins.gitserver;

import hudson.FilePath;
import hudson.FilePath.FileCallable;
import hudson.remoting.Pipe;
import hudson.remoting.VirtualChannel;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import jenkins.MasterToSlaveFileCallable;
import org.apache.commons.io.IOUtils;
import org.eclipse.jgit.errors.NotSupportedException;
Expand All @@ -20,12 +24,6 @@
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UploadPack;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;

/**
* {@link Transport} implementation across pipes.
*
Expand All @@ -34,103 +32,104 @@
public class ChannelTransport extends Transport implements PackTransport {
private final FilePath remoteRepository;

public static Transport open(Repository local, FilePath remoteRepository) throws NotSupportedException, URISyntaxException, TransportException {
if (remoteRepository.isRemote())
return new ChannelTransport(local,remoteRepository);
else
return Transport.open(local,remoteRepository.getRemote());
public static Transport open(Repository local, FilePath remoteRepository)
throws NotSupportedException, URISyntaxException, TransportException {
if (remoteRepository.isRemote()) return new ChannelTransport(local, remoteRepository);
else return Transport.open(local, remoteRepository.getRemote());
}

public ChannelTransport(Repository local, FilePath remoteRepository) throws URISyntaxException {
super(local, new URIish("channel:"+remoteRepository.getRemote()));
super(local, new URIish("channel:" + remoteRepository.getRemote()));
this.remoteRepository = remoteRepository;
}

@Override
public FetchConnection openFetch() throws NotSupportedException, TransportException {
final Pipe l2r = Pipe.createLocalToRemote();
final Pipe r2l = Pipe.createRemoteToLocal();

try {
remoteRepository.actAsync(new GitFetchTask(l2r, r2l));
} catch (IOException e) {
throw new TransportException("Failed to open a fetch connection",e);
throw new TransportException("Failed to open a fetch connection", e);
} catch (InterruptedException e) {
throw new TransportException("Failed to open a fetch connection",e);
Thread.currentThread().interrupt();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not appear to be related to the stated PR goal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was flagged by the SonarQube for IDE in my IntelliJ IDEA (rule java:S1242). I've been fixing a bunch of other issues like this and so wanted to fix it here too. However, if you'd prefer it to be dropped, I can do so. I'm not stuck on getting that in.

throw new TransportException("Failed to open a fetch connection", e);
}

return new BasePackFetchConnection(this) {{
init(new BufferedInputStream(r2l.getIn()), new BufferedOutputStream(l2r.getOut()));
readAdvertisedRefs();
}};
return new BasePackFetchConnection(this) {
{
init(new BufferedInputStream(r2l.getIn()), new BufferedOutputStream(l2r.getOut()));
readAdvertisedRefs();
}
};
}

@Override
public PushConnection openPush() throws NotSupportedException, TransportException {
final Pipe l2r = Pipe.createLocalToRemote();
final Pipe r2l = Pipe.createRemoteToLocal();

try {
remoteRepository.actAsync(new GitPushTask(l2r, r2l));
} catch (IOException e) {
throw new TransportException("Failed to open a fetch connection",e);
throw new TransportException("Failed to open a fetch connection", e);
} catch (InterruptedException e) {
throw new TransportException("Failed to open a fetch connection",e);
Thread.currentThread().interrupt();
throw new TransportException("Failed to open a fetch connection", e);
}

return new BasePackPushConnection(this) {{
init(new BufferedInputStream(r2l.getIn()), new BufferedOutputStream(l2r.getOut()));
readAdvertisedRefs();
}};
return new BasePackPushConnection(this) {
{
init(new BufferedInputStream(r2l.getIn()), new BufferedOutputStream(l2r.getOut()));
readAdvertisedRefs();
}
};
}

@Override
public void close() {
// no-op
}

private static class GitFetchTask extends MasterToSlaveFileCallable<Void> {
private final Pipe l2r;
private final Pipe r2l;

public GitFetchTask(Pipe l2r, Pipe r2l) {
this.l2r = l2r;
this.r2l = r2l;
}

public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
Repository repo = new FileRepositoryBuilder().setWorkTree(f).build();
try {
try (Repository repo = new FileRepositoryBuilder().setWorkTree(f).build()) {
final UploadPack rp = new UploadPack(repo);
rp.upload(new BufferedInputStream(l2r.getIn()), new BufferedOutputStream(r2l.getOut()), null);
return null;
} finally {
IOUtils.closeQuietly(l2r.getIn());
IOUtils.closeQuietly(r2l.getOut());
repo.close();
}
}
}

private static class GitPushTask extends MasterToSlaveFileCallable<Void> {
private final Pipe l2r;
private final Pipe r2l;

public GitPushTask(Pipe l2r, Pipe r2l) {
this.l2r = l2r;
this.r2l = r2l;
}

public Void invoke(File f, VirtualChannel channel) throws IOException, InterruptedException {
Repository repo = new FileRepositoryBuilder().setWorkTree(f).build();
try {
try (Repository repo = new FileRepositoryBuilder().setWorkTree(f).build()) {

Check warning on line 126 in src/main/java/org/jenkinsci/plugins/gitserver/ChannelTransport.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 37-126 are not covered by tests
final ReceivePack rp = new ReceivePack(repo);
rp.receive(new BufferedInputStream(l2r.getIn()), new BufferedOutputStream(r2l.getOut()), null);
return null;
} finally {
IOUtils.closeQuietly(l2r.getIn());
IOUtils.closeQuietly(r2l.getOut());
repo.close();
}
}
}
Expand Down
Loading
Loading