Skip to content

Commit

Permalink
🚑 Custom ConnectionFactory for jgit
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarlett committed May 24, 2023
1 parent 5d0ba3a commit b8d0b85
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package software.tnb.product.git;

import software.tnb.product.integration.builder.AbstractGitIntegrationBuilder;

import software.tnb.common.config.TestConfiguration;
import software.tnb.common.utils.FIPSUtils;
import software.tnb.product.git.support.GitHttpConnectionFactory;
import software.tnb.product.integration.builder.AbstractGitIntegrationBuilder;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.transport.TransportHttp;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
Expand Down Expand Up @@ -49,16 +51,23 @@ private void checkout() {
if (!projectDirectory.exists()) {
LOG.info("Check out {} on branch {}", repositoryUrl, branch);

try {
FileBasedConfig fileBasedConfig = SystemReader.getInstance().openJGitConfig(null, FS.DETECTED);
fileBasedConfig.load();
fileBasedConfig.setBoolean("http", null, "sslVerify", false);
fileBasedConfig.save();
} catch (IOException | ConfigInvalidException e) {
throw new IllegalStateException("Can't update git config", e);
if (!FIPSUtils.isFipsEnabled()) {
try {
FileBasedConfig fileBasedConfig = SystemReader.getInstance().openJGitConfig(null, FS.DETECTED);
fileBasedConfig.load();
fileBasedConfig.setBoolean("http", null, "sslVerify", false);
fileBasedConfig.save();
} catch (IOException | ConfigInvalidException e) {
throw new IllegalStateException("Can't update git config", e);
}
}

try (Git ignored = Git.cloneRepository()
.setTransportConfigCallback(transport -> {
if (transport instanceof TransportHttp) {
((TransportHttp) transport).setHttpConnectionFactory(new GitHttpConnectionFactory());
}
})
.setURI(repositoryUrl)
.setDirectory(projectDirectory)
.setBranch(branch)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package software.tnb.product.git.support;

import software.tnb.common.utils.HTTPUtils;

import org.eclipse.jgit.transport.http.HttpConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.TrustManager;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;
import java.util.Optional;

public class GitHttpConnection implements HttpConnection {
HttpURLConnection delegate;

public GitHttpConnection(URL url) throws IOException {
delegate = (HttpURLConnection) url.openConnection();
}

public GitHttpConnection(URL url, Proxy proxy) throws IOException {
delegate = (HttpURLConnection) url.openConnection(proxy);
}

@Override
public int getResponseCode() throws IOException {
return delegate.getResponseCode();
}

@Override
public URL getURL() {
return delegate.getURL();
}

@Override
public String getResponseMessage() throws IOException {
return delegate.getResponseMessage();
}

@Override
public Map<String, List<String>> getHeaderFields() {
return delegate.getHeaderFields();
}

@Override
public void setRequestProperty(String key, String value) {
delegate.setRequestProperty(key, value);
}

@Override
public void setRequestMethod(String method) throws ProtocolException {
delegate.setRequestMethod(method);
}

@Override
public void setUseCaches(boolean usecaches) {
delegate.setUseCaches(usecaches);
}

@Override
public void setConnectTimeout(int timeout) {
delegate.setConnectTimeout(timeout);
}

@Override
public void setReadTimeout(int timeout) {
delegate.setReadTimeout(timeout);
}

@Override
public String getContentType() {
return delegate.getContentType();
}

@Override
public InputStream getInputStream() throws IOException {
return delegate.getInputStream();
}

@Override
public String getHeaderField(String name) {
return delegate.getHeaderField(name);
}

@Override
public List<String> getHeaderFields(String name) {
return delegate.getHeaderFields().get(name);
}

@Override
public int getContentLength() {
return delegate.getContentLength();
}

@Override
public void setInstanceFollowRedirects(boolean followRedirects) {
delegate.setInstanceFollowRedirects(followRedirects);
}

@Override
public void setDoOutput(boolean dooutput) {
delegate.setDoOutput(dooutput);
}

@Override
public void setFixedLengthStreamingMode(int contentLength) {
delegate.setFixedLengthStreamingMode(contentLength);
}

@Override
public OutputStream getOutputStream() throws IOException {
return delegate.getOutputStream();
}

@Override
public void setChunkedStreamingMode(int chunklen) {
delegate.setChunkedStreamingMode(chunklen);
}

@Override
public String getRequestMethod() {
return delegate.getRequestMethod();
}

@Override
public boolean usingProxy() {
return delegate.usingProxy();
}

@Override
public void connect() throws IOException {
delegate.connect();
}

@Override
public void configure(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
//the configuration is managed by HTTPUtils
Optional.of(delegate)
.filter(d -> d instanceof HttpsURLConnection)
.map(d -> (HttpsURLConnection) d)
.orElseThrow(() -> new RuntimeException("unable to apply ssl context"))
.setSSLSocketFactory(HTTPUtils.getSslContext().getSocketFactory());
}

@Override
public void setHostnameVerifier(HostnameVerifier hostnameverifier) throws NoSuchAlgorithmException, KeyManagementException {
Optional.of(delegate)
.filter(d -> d instanceof HttpsURLConnection)
.map(d -> (HttpsURLConnection) d)
.orElseThrow(() -> new RuntimeException("unable to apply hostname verifier"))
.setHostnameVerifier(hostnameverifier);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package software.tnb.product.git.support;

import org.eclipse.jgit.transport.http.HttpConnection;
import org.eclipse.jgit.transport.http.HttpConnectionFactory2;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;

import java.io.IOException;
import java.net.Proxy;
import java.net.URL;

public class GitHttpConnectionFactory implements HttpConnectionFactory2 {
@Override
public HttpConnection create(URL url) throws IOException {
return new GitHttpConnection(url);
}

@Override
public HttpConnection create(URL url, Proxy proxy)
throws IOException {
return new GitHttpConnection(url, proxy);
}

@Override
public GitSession newSession() {
return new GitHttpConnectionFactory.JdkConnectionSession();
}

private static class JdkConnectionSession implements GitSession {

private SSLContext securityContext;

private SSLSocketFactory socketFactory;

@Override
public GitHttpConnection configure(HttpConnection connection, boolean sslVerify) {
if (!(connection instanceof GitHttpConnection)) {
throw new RuntimeException("connection type is not " + GitHttpConnection.class.getName());
}
return (GitHttpConnection) connection;
}

@Override
public void close() {
securityContext = null;
socketFactory = null;
}
}
}

0 comments on commit b8d0b85

Please sign in to comment.