jj icon indicating copy to clipboard operation
jj copied to clipboard

git: SSH config not respected

Open uhthomas opened this issue 2 years ago • 28 comments

Expected Behaviour

jj git clone should respect the SSH config (~/.ssh/config).

Actual Behaviour

The SSH config is not respected, which may be problematic in some cases. In this case, ProxyCommand is to communicate with a private Git server.

Steps to Reproduce the Problem

  1. Use an SSH environment which requires additional configuration via ~/.ssh/config to work.
  2. Observe jj git clone hang.

Specifications

  • Version: 0.2.0.r917.2916cb2-1
  • Platform: Linux x86_64

uhthomas avatar Feb 20 '22 17:02 uhthomas

Thanks for your report. I'll be away from my computer for about a week from now. If anyone feels like looking into this while I'm away, I think the right place to start is here.

martinvonz avatar Feb 20 '22 17:02 martinvonz

libgit2 uses libssh2, not OpenSSH, so of course it doesn't use OpenSSH's configuration. And unfortunately there is no support for proxying at all. See https://github.com/libgit2/libgit2/issues/4872 (one linked PR does something in that direction)

the right place to start is here

Hopefully the hardcoded id_rsa won't remain the only supported key path for non-agent operation there for long… :)

valpackett avatar Feb 20 '22 17:02 valpackett

By the way, Git has its "credential helpers", which may be what we should use. I don't know enough about it yet.

martinvonz avatar Apr 13 '22 16:04 martinvonz

Is it possible to use OpenSSH instead of libssh2?

bergkvist avatar Aug 01 '23 13:08 bergkvist

Is it possible to use OpenSSH instead of libssh2?

I was going to say that I think we'd have to ask for such support from libgit2 (or switch to gitoxide or something) but I see you've already asked there (thanks). I have no idea how feasible it is.

martinvonz avatar Aug 01 '23 17:08 martinvonz

@bergkvist One alternative is what I do: I never use jj git and simply use git for all clone/fetch/push operations, and use jj's colocated repo mode to use jj with the Git repository by running jj init --git-repo .. I had to do this at a previous job where they used a custom version of Git. (I'm assuming that your installation of Git uses OpenSSH instead of libssh2 in whatever way you require.)

arxanas avatar Aug 01 '23 18:08 arxanas

@arxanas Do you have to rerun jj init --git-repo . every time you do a git pull? Or does it "keep in sync" after you do it once?

bergkvist avatar Aug 01 '23 22:08 bergkvist

jj init --git-repo . is needed only once.

jj git fetch is basically the same as git fetch --prune && jj git import, and for "colocated" repo created by --git-repo ., jj git import runs implicitly every time you do jj <subcommand>.

yuja avatar Aug 01 '23 23:08 yuja

@martinvonz: See https://github.com/libgit2/libgit2/pull/6617

bergkvist avatar Aug 03 '23 16:08 bergkvist

@martinvonz: See libgit2/libgit2#6617

Wow, that's great news! Thanks for the update. Will you get a chance to try it?

martinvonz avatar Aug 03 '23 16:08 martinvonz

I tested it out now, but I'm getting a segfault when using a git remote like [email protected]:bergkvist/jj. (Building https://github.com/bergkvist/jj will in theory also allow you to reproduce the segfault).

$ git clone [email protected]:bergkvist/jj && cd jj
$ cargo install --path=.
$ ~/.cargo/bin/jj init --git-repo=.
$ ~/.cargo/bin/jj git fetch
Segmentation fault

bergkvist avatar Aug 03 '23 19:08 bergkvist

The above segfault has been fixed. Also, I had to enable SSH exec support in git2-rs (https://github.com/bergkvist/git2-rs/commit/9a4d232bdebb98c650ffbf7dacf0a307fa5e6591).

You can test out installing my patched version like this:

git clone [email protected]:bergkvist/jj && cd jj
git checkout 4327e7ed1283329689efc31a5d244ec5cb707e16
cargo install --path=.

For jj, I guess this will be a matter of upgrading git2-rs once the change has propagated there - possibly with a feature flag specifying ssh exec instead of libssh2.

bergkvist avatar Aug 09 '23 01:08 bergkvist

jj git clone is hanging for me, but I don't have anything weird in my ssh config:

$ jj git clone [email protected]:willhbr/dotfiles.git dotfiles
Fetching into new repo in "/home/will/Projects/dotfiles"
Error: remote rejected authentication: Failed getting response; class=Ssh (23); code=Auth (-16)
Hint: Jujutsu uses libssh2, which doesn't respect ~/.ssh/config. Does `ssh -F /dev/null` to the host work?
$ ssh -F /dev/null [email protected]
PTY allocation request failed on channel 0
Hi willhbr! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.

I do use an ed25519 key normally, but created ~/.id_rsa with the assumption that libgit2 would look for that. ssh -F /dev/null -i ~/.ssh/id_rsa [email protected] also works.

$ jj --version
jj 0.8.0-8149ec6df6490ac596f92fdf584d2d666e8c0b6b
$ uname -a
Linux brett 6.2.0-26-generic #26-Ubuntu SMP PREEMPT_DYNAMIC Mon Jul 10 23:39:54 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

willhbr avatar Aug 28 '23 12:08 willhbr

jj 0.8.0-8149ec6df6490ac596f92fdf584d2d666e8c0b6b

I think it's #1970, and should be fixed in the next release. For now, you can try installing jj from the git repo, or ssh-add the key to register to ssh agent.

yuja avatar Aug 28 '23 12:08 yuja

Confirmed that ssh-add worked:

$ eval `ssh-agent -s`
Agent pid 1721601
$ ssh-add
Identity added: /home/will/.ssh/id_rsa (will@brett)
Identity added: /home/will/.ssh/id_ed25519 (will@brett)
$ jj git clone [email protected]:willhbr/dotfiles.git
Fetching into new repo in "/home/will/Projects/dotfiles"
Working copy now at: b (no description set)
Parent commit      : f Add proper JJ config
Added 34 files, modified 0 files, removed 0 files

willhbr avatar Aug 30 '23 11:08 willhbr

https://github.com/libgit2/libgit2/pull/6617 was just merged :tada:

So now it has to get released, git2-rs updated to enable the feature flag with a cargo feature flag, and then we can update git2-rs and enable the feature flag and it should just work, as @bergkvist showed

necauqua avatar Aug 31 '23 19:08 necauqua

I am now running into this issue as well. I am using the 1Password IdentityAgent (so my ssh keys are not directly present in ssh-add -l. My config looks as follows:

Host *
	IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"

Is this configuration simply not supported or is there some workaround I can do to get this to work?

julienvincent avatar Feb 05 '24 10:02 julienvincent

I've made a PR which attempts to upstream https://github.com/libgit2/libgit2/pull/6617 into git2-rs: https://github.com/rust-lang/git2-rs/pull/1031. However, libgit2 still has not made an official release with the OpenSSH changes, so it might take a while for the changes to propagate.

I've tried building a version of jj with a prerelease version of git2-rs, and things are looking somewhat promising: jj git clone and jj git fetch is able to work with a custom ssh-agent (https://github.com/maxgoedjen/secretive), declared only via SSH_AUTH_SOCK, which it previously wasn't detecting. However, jj git push causes a segfault 😢. If I have some time I'll try to debug and see what's going on (might have messed something up in the upstream repo).

(My changes are at https://github.com/bnjmnt4n/jj/tree/ssh-openssh if anyone is interested in trying it out.)

bnjmnt4n avatar Mar 01 '24 17:03 bnjmnt4n

~~I've tested the git2-rs with OpenSSH on a WSL machine and it is able to fetch and push changes fine, so might just be an issue on my M2 Macbook. I guess I need to figure out how to use lldb 😬~~ Update: fixed!

For now, if anyone's interested in testing:

git clone [email protected]:bnjmnt4n/jj && cd jj
git checkout ssh-openssh
cargo install --path=.

bnjmnt4n avatar Mar 02 '24 09:03 bnjmnt4n

Nice work @bnjmnt4n! I gave it a try locally and get the same result as you: jj fetch works just fine (and uses my custom IdentityAgent) but jj push segfaults. I am also running on an M2 though :)

julienvincent avatar Mar 02 '24 12:03 julienvincent

jj git push worked for me. I am on M1 but linux.

maan2003 avatar Mar 02 '24 12:03 maan2003

I realized the issue, there have been changes to the libgit2 functions which have not been reflected in git2-rs FFI 🤦 I'll try to look at what's changed and see if I can update my fork of git2-rs just to get this working, but I'm not very familiar with libgit2 so I'm not sure how far I'll get. No matter what, it will probably be a bit of time before this even lands: we will have to wait for the next version of libgit2 to release, then update git2-rs FFI before this can land.

For now, I think you can treat the above repo as slightly suspect, even if it appears to work.

bnjmnt4n avatar Mar 02 '24 13:03 bnjmnt4n

finding ffi changes should be easy, just diff include/ from last released version in libgit2

maan2003 avatar Mar 02 '24 13:03 maan2003

looks like git_push_options struct changed in libgit2, that explains the segfault

maan2003 avatar Mar 02 '24 13:03 maan2003

Yeah, I've updated the my git2-rs PR and tried building jj locally, it seems to work fine now! Will take a closer look at the other changes.

bnjmnt4n avatar Mar 02 '24 13:03 bnjmnt4n

I've updated my fork to include the a now fully functional copy of jj. I will probably maintain it until the upstream PR is merged, so if anyone is interested, please do try and test it out and report bugs!

bnjmnt4n avatar Mar 02 '24 14:03 bnjmnt4n

I've updated my fork to include the a now fully functional copy of jj. I will probably maintain it until the upstream PR is merged, so if anyone is interested, please do try and test it out and report bugs!

Thanks for the fork! First few experiments work well with my 1Password-based SSH setup.

FWIW It would also be good to update this error message since libssh2 would no longer be in use.

bromanko avatar Mar 03 '24 21:03 bromanko

Seems to work! Will be using this thanks for doing this @bnjmnt4n

julienvincent avatar Mar 04 '24 16:03 julienvincent

FYI: it was pointed out on Discord that the SSH_AUTH_SOCK is supported by libssh2, so if you're just looking to use a different SSH agent and don't have any other SSH configuration, you can just export SSH_AUTH_SOCK and use the latest Jujutsu. Eg. for 1Password.

bnjmnt4n avatar Apr 17 '24 15:04 bnjmnt4n

@bnjmnt4n That does indeed work. The issue I'm having is I have multiple ssh keys managed by 1Password. It does successfully access the 1Password ssh agent, but it just picks the first key alphabetically. For stock git I have ~/.ssh/config configured for picking the ssh key. Since libssh2 does not use that config file what would be the equivalent? Or do we need to wait until OpenSSH is supported in libssh2?

MikeJCusack avatar May 01 '24 10:05 MikeJCusack