NGIT/JGIT/Git# SSH Session with private key to Clone GiT repository

1.2k views Asked by At

The session part connections with the private key, no problem. However when I do a git Clone, it gives the error 'Auth Fail'. How do I wrap, bind or make the connected session work with git clone. I'm using NGIT under .NET 4.0, but don't think this matters as JGIT is pretty much the same.

Any ideas ?

Thanks Gavin

        JSch jsch = new JSch();
        Session session = jsch.GetSession(gUser, gHost, 22);
        jsch.AddIdentity(PrivateKeyFile); // If I leave this line out, the session fails to Auth. therefore it works.
        Hashtable table = new Hashtable();
        table["StrictHostKeyChecking"] = "no"; // this works
        session.SetConfig(table);
        session.Connect(); // the session connects.



        URIish u = new URIish();
        u.SetPort(22);
        u.SetHost(gHost);
        u.SetUser(gUser);            
        NGit.Transport.JschSession jschSession = new JschSession(session,u );

        if (session.IsConnected())
        {
            try
            {
                CloneCommand clone = Git.CloneRepository()
                    .SetURI(gitAddress)
                    .SetDirectory(folderToSave);                                        
                clone.Call();                  

             //   MessageBox.Show(Status, gitAddress, MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                // AUth Fail..... ????

            }
        }
        else
        {
            session.Disconnect();

        }
        session.Disconnect();
1

There are 1 answers

1
Mark Hildreth On

The problem here is the session object is not actually associated with the CloneCommand at any time. Therefore, all the work you've done to set up the session doesn't really do anything, as the CloneCommand is going to create its own session (with the default session items) itself.

The clone commands will get the session it will actually use from the SSHSessionFactory. First, you need to create a class that implements the SSHSessionFactory abstract class, like I've done below:

public class MySSHSessionFactory : SshSessionFactory
{
    private readonly JSch j;

    public MySSHSessionFactory()
    {
        this.j = new JSch();
    }

    public void Initialize()
    {
        this.j.SetKnownHosts(@"C:/known_hosts");
        this.j.AddIdentity(@"C:\id_rsa");
    }

    public override RemoteSession GetSession(URIish uri, CredentialsProvider credentialsProvider, NGit.Util.FS fs, int tms)
    {
        var session = this.j.GetSession(uri.GetUser(), uri.GetHost());
        session.SetUserInfo(new MyUserInfo());
        session.Connect();

        return new JschSession(session, uri);
    }
}

Then you can set all new Git commands to use this factory for when they want to use a session:

var sessionFactory = new MySSHSessionFactory();
sessionFactory.Initialize();
SshSessionFactory.SetInstance(sessionFactory);

// Now you can do a clone command.

Note that I'm still figuring this library out, so I might have not written MySSHSessionFactory in an optimal way (does it handle fault tolerance for sessions that close, for example?). But this at least a start.