1

When I try to clone an existing remote git repository using JGit api, I get the below error.

Exception:org.eclipse.jgit.api.errors.TransportException: http://admin@localhost:7990/scm/cp/myrepo.git Secure connection to https://admin@localhost:7990/scm/cp/myrepo.git could not be stablished because of SSL problems

In my class I have the below method which I use to clone the repository.

public static void cloneRepoTemp(String cloneRepoUrl, String username, String password)
            throws FileNotFoundException, IOException {

        Git git;
        try {

            git = Git.cloneRepository().setURI(cloneRepoUrl)
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password))
                    .setDirectory(new File("C:/temp/testrepo")).setBranch("integration").call();
            git.close();
        } catch (GitAPIException e) {
            System.out.println("Exception:" + e);
    }

I know I can address this issue by using the below command,

git config --global http.sslVerify false

But, since I am using JGit api I want to enable that via the api itself rather than making the setting explicit on the host machine. Also, I intend to have the library distributed in multiple machines so do not make the change in users' machine to make that change for my code to work.

Is there a way to achieve this in code without adding a entry in git configuration file.

kostix
  • 51,517
  • 14
  • 93
  • 176
surya
  • 21
  • 1
  • 2
  • Possible duplicate of [Set ssl Verification off for JGit clone command](https://stackoverflow.com/questions/33998477/set-ssl-verification-off-for-jgit-clone-command) – Rüdiger Herrmann Dec 13 '17 at 17:02

2 Answers2

1

JGit does have its own internal representation of the repository configuration, which allows you (as mentioned by @eugène-adell) to change the settings. Its available via Repository.getConfig(). The problem is that the cloneRepository command creates the Repository object and invokes the clone sequence (fecth + checkout) atomically (from your point of view) and hence you don't have time to change the Repository settings.

To solve this, I recommend a poor man's clone: init -> configure -> add remote -> pull (https://stackoverflow.com/a/33999922/3837873 suggests an init->configure->fetch->checkout, both work). The (complete) code would look like this:

Repositoryrepo = Git.init().setDirectory(this.tempGitDir.toFile()).call();
repo.getRepository()
        .getConfig()
        .setBoolean("http", "https://selfsigned.server.com", "sslVerify", false);
URIish u = createURIish();
repo.remoteAdd()
        .setName("origin")
        .setUri(u)
        .call();
repo.pull()
        .setCredentialsProvider(new UsernamePasswordCredentialsProvider("token", pat))
        .setRemote("origin")
        .setRemoteBranchName("master")
        .call(); 

Where we first init the repo and then change its sslVerify settings. Note: Always prefer per repo, per server sslVerify ignores; setting the flag globally is a secuirty issue. Replace the url for the specific "base" url of the server you are connecting to.

The createURIish method just creates a new URIish object with the remote URI, I do it in a separate method to reduce complexity (nested trys):

private URIish createURIish() throws InvalidRemoteException {
    URIish u = null;
    try {
        u = new URIish(this.gitUrl);
    } catch (URISyntaxException e) {
        throw new InvalidRemoteException(
                MessageFormat.format(JGitText.get().invalidURL, this.gitUrl), e);
    }
    return u;
}

Then you add the URIish as a new remote and finally invoke the pull command. For this I have used a UsernamePasswordCredentialsProvider so that I can pass the PAT used by the TFS server I am connecting to, but username:pasword as you are using should also work.

Arcanefoam
  • 687
  • 7
  • 20
0

Maybe have a look at the Config class, with Config.setBoolean("branch", "master", "isSslVerify", false)

Eugène Adell
  • 3,089
  • 2
  • 18
  • 34