4

I am using JGit in an app. This app has a SecurityManager in place that allows only specific white-listed classes and methods from spawning new processes.

JGit internally is discovering if a native git is installed and tries to read its config in org.eclipse.jgit.util.FS.discoverGitSystemConfig() and even tries to find hooks in org.eclipse.jgit.util.FS_POSIX.findHook() and see if they are executable.

Because of the aforementioned Security Manager in place, JGit cannot function and fails. I tried to find in the documentation if there is a way to suppress this behavior?

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
Yogesh_D
  • 17,656
  • 10
  • 41
  • 55

3 Answers3

2

As of now, the FS detection isn't meant to be extenible in JGit (see FS.DETECTED). It will always reference one of the file systems provided by JGit.

But...

It seems feasible to implement your own FS which avoids calling the restricted APIs.

When creating a Repository through a FileRepositoryBuilder you can specify an FS and thus make the repository use your custom FS. If all JGit code consults the repository for the file system to be used your problem should be solved.

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
2

In recent versions of JGit (3.3+), you can set the environment variable GIT_CONFIG_NOSYSTEM to any value, and this will suppress the reading of the native system-wide Git configuration file. This is defined in the JGit sources via Constants#GIT_CONFIG_NOSYSTEM_KEY.

This simulates having an empty system-level configuration file and it prevents the code from searching around in random file paths and provoking security exceptions, which is what the original question asked. Note that even in this scenario, JGit still tries to use a user-level configuration file (typically in $HOME/.gitconfig).

A more common variant of this question is presumably to use a predefined set of configuration options without worrying about any environmental contamination (system or user level configs), so the above fix does not plug all of the gaps.

The following example shows how to use JGit to use a specific user-based Git configuration file in a defined path, and it supplies an empty system-level Git configuration file, meaning that the entire configuration can be controlled programmatically.

To use this, install your own SystemReader using the code below before running any JGit commands:

File userGitConfig = new File("/my/path/foo.config");
SystemReader.setInstance(new CustomConfigSystemReader(userGitConfig));

And then supply the following new CustomConfigSystemReader class:

import org.eclipse.jgit.lib.Config;
import org.eclipse.jgit.storage.file.FileBasedConfig;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.SystemReader;

import java.io.File;

public class CustomConfigSystemReader extends SystemReader
{
    private static final SystemReader proxy = SystemReader.getInstance();
    private File userGitConfig;

    public CustomConfigSystemReader(File userGitConfig)
    {
        super();
        this.userGitConfig = userGitConfig;
    }

    @Override
    public String getenv(String variable)
    {
        return proxy.getenv(variable);
    }

    @Override
    public String getHostname()
    {
        return proxy.getHostname();
    }

    @Override
    public String getProperty(String key)
    {
        return proxy.getProperty(key);
    }

    @Override
    public long getCurrentTime()
    {
        return proxy.getCurrentTime();
    }

    @Override
    public int getTimezone(long when)
    {
        return proxy.getTimezone(when);
    }

    @Override
    public FileBasedConfig openUserConfig(Config parent, FS fs)
    {
        return new FileBasedConfig(parent, userGitConfig, fs);
    }

    // Return an empty system configuration, based on example in SystemReader.Default#openSystemConfig
    @Override
    public FileBasedConfig openSystemConfig(Config parent, FS fs)
    {
        return new FileBasedConfig(parent, null, fs)
        {
            @Override
            public void load()
            {
            }

            @Override
            public boolean isOutdated()
            {
                return false;
            }
        };
    }
}
aSemy
  • 5,485
  • 2
  • 25
  • 51
Scott Dudley
  • 3,256
  • 1
  • 18
  • 30
0

I ended up using SystemReader.getInstance().userConfig.clear() when initializing my git repository.

Saket
  • 2,945
  • 1
  • 29
  • 31