libgit2 / buster

Testing ssh backend:

libssh2 in buster has a problem with (RSA) public key authentifaction. [1] Details about this can be found in [2] and [3], yielding the error message “Unable to send userauth-publickey request” when e.g trying to clone a git repo over ssh for testing purposes.

Workaround is to have the key in PEM format, e.g create it with

ssh-keygen -p -m PEM -f ~/.ssh/id_rsa

For testing, pygit2 or the examples in libgit2/examples can be used. I’ve installed gitolite3 as something to connect too…

Note, when the server is in known_host, the host key type needs also to be either rsa or dss… libssh won’t understand others and validation will fail. I’ve put into my test VM’s .ssh/config:

Host localhost
    HostKeyAlgorithms ssh-dss,ssh-rsa

to hint ssh to use only supported keys and ssh’ed to localhost to populate known_hosts.

testing with the libgit2 examples:

The build system is broken (it triee to link network/common.o two times, I’ve just manually linked it…) and network/common.c, function cred_acquire_cb() needs to be adapted to utilize ssh auth, e.g:

--- a/examples/network/common.c
+++ b/examples/network/common.c
@@ -55,13 +55,16 @@ error:

 int cred_acquire_cb(git_cred **out,
                const char * UNUSED(url),
-               const char * UNUSED(username_from_url),
+               const char * username_from_url,
                unsigned int UNUSED(allowed_types),
                void * UNUSED(payload))
 {
        char *username = NULL, *password = NULL;
        int error;

+        error = git_cred_ssh_key_new(out, username_from_url, "/home/tobi/.ssh/id_rsa.pub", "/home/tobi/.ssh/id_rsa", "");
+        return error;
+
        printf("Username: ");
        if (readline(&username) < 0) {
                fprintf(stderr, "Unable to read username: %s", strerror(errno));

pygit2

simple test.py:

import pygit2

class MyCallbacks(pygit2.RemoteCallbacks):

    def credentials(self, url, username_from_url, allowed_types):
            return pygit2.Keypair("gitolite3", "/home/tobi/.ssh/id_rsa.pub", "/home/tobi/.ssh/id_rsa", "")

print("Cloning pygit2 over ssh with the username in the URL")
pygit2.clone_repository("ssh://gitolite3@localhost/gitolite-admin.git", "gitolite-admin.git",
                        callbacks=MyCallbacks())

[1] /usr/include/libssh2.h indicates it only supports RSA and DSS… I did not try DSS. [2] https://www.libssh2.org/mail/libssh2-devel-archive-2019-03/0013.shtml [3] https://github.com/libgit2/pygit2/issues/836

Copyright (C) 2023 Tobias Frost