2012-12-03 14 views
13

Używam JGit, aby uzyskać dostęp do zdalnego repozytorium Git i muszę do niego użyć SSH. JGit używa JSch, aby zapewnić bezpieczny dostęp. Jednak nie jestem pewien, jak ustawić plik klucza i zna plik hosts dla JGit. To, co próbowałem, jest następujące.Używanie kluczy z JGitem do bezpiecznego dostępu do repozytorium Git

utworzono niestandardową konfigurację z SshSessionFactory, stosując przez instacji JSchConfigSessionFactory:

public class CustomJschConfigSessionFactory extends JschConfigSessionFactory { 
    @Override 
    protected void configure(OpenSshConfig.Host host, Session session) { 
     session.setConfig("StrictHostKeyChecking", "yes"); 
    } 
} 

W klasie, która mam dostępu zdalnego Git repo, czy następujące elementy:

CustomJschConfigSessionFactory jschConfigSessionFactory = new CustomJschConfigSessionFactory(); 

JSch jsch = new JSch(); 
try { 
    jsch.addIdentity(".ssh/id_rsa"); 
    jsch.setKnownHosts(".ssh/known_hosts"); 
} catch (JSchException e) { 
    e.printStackTrace(); 
} 
    SshSessionFactory.setInstance(jschConfigSessionFactory); 

nie mogę dowiedzieć się, jak powiązać ten obiekt JSch z JGit, aby mógł on pomyślnie połączyć się ze zdalnym repozytorium. Kiedy próbuję sklonować go JGit, pojawia się następujący wyjątek:

org.eclipse.jgit.api.errors.TransportException: [email protected]:abc.org/test_repo.git: reject HostKey: git.test.com 
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:137) 
at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:178) 
at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:125) 
at GitTest.cloneRepo(GitTest.java:109) 
at GitTest.main(GitTest.java:223) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) 
Caused by: org.eclipse.jgit.errors.TransportException: [email protected]:abc.org/test_repo.git: reject HostKey: git.test.com 
at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:142) 
at org.eclipse.jgit.transport.SshTransport.getSession(SshTransport.java:121) 
at org.eclipse.jgit.transport.TransportGitSsh$SshFetchConnection.<init>(TransportGitSsh.java:248) 
at org.eclipse.jgit.transport.TransportGitSsh.openFetch(TransportGitSsh.java:147) 
at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:136) 
at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:122) 
at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1104) 
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:128) 
... 9 more 
Caused by: com.jcraft.jsch.JSchException: reject HostKey: git.test.com 
at com.jcraft.jsch.Session.checkHost(Session.java:748) 
at com.jcraft.jsch.Session.connect(Session.java:321) 
at org.eclipse.jgit.transport.JschConfigSessionFactory.getSession(JschConfigSessionFactory.java:116) 
... 16 more 

Dodałem wpis git.test.com do moich akt /etc/hosts. Użyłem tego samego kodu, aby uzyskać dostęp do repozytorium git z adresem URL http, więc kod działa poprawnie. To kluczowa część obsługi, która zawodzi. Masz pomysł, jak sobie z tym poradzić?

Odpowiedz

3

Zarządzane, aby znaleźć problem. Klucz publiczny po stronie serwera miał inną nazwę niż zwykły id_rsa.pub, a klucz prywatny po mojej stronie to id_rsa. JSch domyślnie oczekuje, że klucz publiczny będzie miał taką samą nazwę jak klucz prywatny i przyrostek .pub. Używanie pary kluczy o wspólnej nazwie (np .: private = key_1 i public = key_1.pub) rozwiązuje problem.

11

trzeba zastąpić metodę getJSch w niestandardowej klasy fabrycznej:

class CustomConfigSessionFactory extends JschConfigSessionFactory 
{ 
    @Override 
    protected JSch getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException { 
     JSch jsch = super.getJSch(hc, fs); 
     jsch.removeAllIdentity(); 
     jsch.addIdentity("/path/to/private/key"); 
     return jsch; 
    } 
} 

Wywołanie jsch.removeAllIdentity jest ważna; wydaje się, że nie działa bez niego.

Ograniczenie: Napisałem powyższe w Scali, a następnie przetłumaczyłem na Javę, więc może to nie być w porządku. Oryginalny Scala jest następujący:

class CustomConfigSessionFactory extends JschConfigSessionFactory 
{ 
    override protected def getJSch(hc : OpenSshConfig.Host, fs : FS) : JSch = 
    { 
     val jsch = super.getJSch(hc, fs) 
     jsch.removeAllIdentity() 
     jsch.addIdentity("/path/to/private/key") 
     jsch 
    } 
} 
+1

Moim problemem było to, że muszę być w stanie podać hasło do klucza prywatnego, który można albo dodać jako kolejny parametr 'addIdentity' lub tworzenie własnych klasa, która implementuje 'UserInfo', a następnie ustawia parametr' session' na metodę 'configure' w' CustomConfigSessionFactory', aby używać 'UserInfo'. – WhiteKnight

+2

Specjalne podziękowania za podpowiedź 'jsch.removeAllIdentity()'! – Vincent

4

jsch sesems się nie podoba plik known_hosts w hashed format-- muszą być zgodne z formatem produkowanej przez:

ssh-keyscan -t rsa hostname >> ~/.ssh/known_hosts

np

<hostname> ssh-rsa <longstring/longstring> 

nie:

|1|<hashed hostname>= ecdsa-sha2-nistp256 <hashed fingerprint>= 
Powiązane problemy