libgit2 / libgit2/pygit2

KeypairFromAgent throws fetch into an infinite loop

Aperta
#953 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Lingua principale
Python
Stelle
1.7k
Fork
408
Merge medio
2g 57m
PR unite (30g)
7

Descrizione

I'm not sure I'm using it right, but the following code throws git_remote_fetch into some sort of infinite loop in case the agent can't find an appropriate key.

import pygit2

class MyCallbacks(pygit2.RemoteCallbacks):
    def credentials(self, url, username_from_url, allowed_types):
        # print('Credentials callback called')
        return pygit2.KeypairFromAgent(username_from_url)

repo = pygit2.Repository('foo')
repo.remotes['origin'].fetch(callbacks=MyCallbacks())
print("OK")

Here's an example:

$ git clone git@<some-ssh-repository> foo
Cloning into 'foo'...
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
$ python3 test.py  # Using my regular ssh agent which has the correct key
OK
$ eval $(ssh-agent)  # Create a new ssh-agent with no key and update env variables
$ python3 test.py  # Never returns...

If I uncomment the print statement in the python snippet above, I can see that my callback is called over and over.

There's one more thing that is odd but might help: when I interrupt the script with ctrl-c, I don't always get the same traceback. In the second case bellow it seems that the "correct" exception (_pygit2.GitError: callback failed to initialize SSH credentials) is raised at some point but just doesn't reach my code:

❯❯❯ python3 test.py
# ^C
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    repo.remotes['origin'].fetch(callbacks=MyCallbacks())
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 406, in fetch
    err = C.git_remote_fetch(self._remote, arr, fetch_opts, to_bytes(message))
KeyboardInterrupt
❯❯❯ python3 test.py
# ^C
From cffi callback <function RemoteCallbacks._credentials_cb at 0x7f5e027700d0>:
Traceback (most recent call last):
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 304, in _credentials_cb
    ccred = get_credentials(credentials, url, username, allowed)
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 515, in get_credentials
    if pubkey is None and privkey is None:
KeyboardInterrupt
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    repo.remotes['origin'].fetch(callbacks=MyCallbacks())
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/remote.py", line 409, in fetch
    check_error(err)
  File "/home/gregoire/.local/lib/python3.7/site-packages/pygit2/errors.py", line 64, in check_error
    raise GitError(message)
_pygit2.GitError: callback failed to initialize SSH credentials

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia dai percorsi di remote.py mostrati nel traceback, in particolare RemoteCallbacks._credentials_cb e get_credentials. Riproduci il fetch con uno ssh-agent che non contiene alcuna chiave, quindi segui il callback e la gestione dell’errore delle credenziali. Il lavoro è completato quando la ricerca delle credenziali fallita smette di essere ritentata e il GitError atteso raggiunge il chiamante.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
git, python
Ambito
tooling
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.