关闭JGit克隆命令

时间:2015-11-30 12:16:24

标签: jgit

我正试图通过CloneCommand克隆一个Git Repository。 使用这段代码

`Git.cloneRepository().setDirectory(new File(path)).setURI(url).call();`

远程存储库位于使用自签名证书的GitBlit实例上。 由于这些自签名证书,我在克隆的获取部分执行时得到以下异常:

Caused by: java.security.cert.CertificateException: No name matching <hostName> found
    at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:221)
    at sun.security.util.HostnameChecker.match(HostnameChecker.java:95)

虽然我可以创建新的TrustManager,但请注册虚拟HostnameVerifier并创建并初始化使用此虚拟SSLContext的{​​{1}}。 克隆完成后,还原所有这些。

但是,这意味着在同一时间启动的任何其他SSL连接都会将它们暴露给不安全的连接。

在已经克隆的仓库中,您可以将http.sslVerify设置为false,JGit可以正常工作。

有没有一种更清晰的方法可以告诉JGit将此http.sslVerify设置为false以进行克隆操作,就像我可以为已经克隆的回购做的那样。

3 个答案:

答案 0 :(得分:8)

使用4.9版本,JGit将更优雅地处理SSL验证。如果是SSL 握手不成功,JGit会询问CredentialsProvider是否应该跳过SSL验证。

在此过程中,CredentialsProvider会以文本方式提供InformationalMessage,最多三个YesNoType CredentialItem来决定是否跳过此操作的SSL验证,对于当前存储库,和/或始终。

似乎更改是在考虑交互式UI的情况下进行的,并且可能很难以编程方式回答这些“凭据请求”。

commit message of this change更详细地描述了行为。

对于早期版本的JGit,或者CredentialsProvider模型不符合您的需求,下面介绍了两种解决方法。

要解决此限制,您可以手动执行特定克隆步骤,如以下评论中所示:

  • 使用InitCommand
  • 初始化存储库
  • 将ssl verify设置为false
    StoredConfig config = git.getRepository().getConfig();
    config.setBoolean( "http", null, "sslVerify", false );
    config.save();
  • fetch(请参阅FetchCommand)
  • 结帐(请参阅CheckoutCommand)

解决此问题的另一种方法是提供HttpConnectionFactory ,返回带有虚拟主机名和证书验证程序的HttpConnection。例如:

class InsecureHttpConnectionFactory implements HttpConnectionFactory {

  @Override
  public HttpConnection create( URL url ) throws IOException {
    return create( url, null );
  }

  @Override
  public HttpConnection create( URL url, Proxy proxy ) throws IOException {
    HttpConnection connection = new JDKHttpConnectionFactory().create( url, proxy );
    HttpSupport.disableSslVerify( connection );
    return connection;
  }
}

HttpConnection位于包org.eclipse.jgit.transport.http中,是HTTP连接的JGit抽象。虽然该示例使用默认实现(由JDK http代码支持),但您可以自由使用自己的实现或使用Apache http组件的org.eclipse.jgit.transport.http.apache包提供的实现。

可以使用HttpTransport::setConnectionFactory()更改当前使用的连接工厂:

HttpConnectionFactory preservedConnectionFactory = HttpTransport.getConnectionFactory();
HttpTransport.setConnectionFactory( new InsecureHttpConnectionFactory() );
// clone repository
HttpTransport.setConnectionFactory( preservedConnectionFactory );

不幸的是,连接工厂是一个单例,因此当同时执行JGit命令时,这个技巧需要额外的工作(例如,一个线程局部变量来控制sslVerify是打开还是关闭)。

答案 1 :(得分:4)

另一种解决方法是在调用.gitconfig之前在当前用户的主目录中创建Git.cloneRepository()文件:

File file = new File(System.getProperty("user.home")+"/.gitconfig");
if(!file.exists()) {
    PrintWriter writer = new PrintWriter(file);
    writer.println("[http]");
    writer.println("sslverify = false");
    writer.close();
}

这将使JGit跳过SSL证书验证。

答案 2 :(得分:0)

我从上面的所有答案中推断出以下代码段;

private void disableSSLVerify(URI gitServer) throws Exception {
    if (gitServer.getScheme().equals("https")) {
        FileBasedConfig config = SystemReader.getInstance().openUserConfig(null, FS.DETECTED);
        synchronized (config) {
            config.load();
            config.setBoolean(
                "http",
                "https://" + gitServer.getHost() + ':' + (gitServer.getPort() == -1 ? 443 : gitServer.getPort()),
                "sslVerify", false);
            config.save();
        }
    }
}

此选项较为安全,因为它仅允许gitServer的sslVerify为false。

请查看此链接,该链接与其他options共享。