10000 Fix ssh-agent use by libgit2 by Keno · Pull Request #17459 · JuliaLang/julia · GitHub
[go: up one dir, main page]

Skip to content

Fix ssh-agent use by libgit2 #17459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 21, 2016
Merged

Fix ssh-agent use by libgit2 #17459

merged 2 commits into from
Jul 21, 2016

Conversation

Keno
Copy link
Member
@Keno Keno commented Jul 16, 2016

cc @wildart. Works for me, but I'm not convinced this is the right solution.

@tkelman tkelman added the libgit2 The libgit2 library or the LibGit2 stdlib module label Jul 16, 2016
@@ -82,7 +82,8 @@ function credentials_callback(cred::Ptr{Ptr{Void}}, url_ptr::Cstring,
end

# first try ssh-agent if credentials support its usage
if creds[:usesshagent, credid] == "Y"
if creds[:usesshagent, credid] === nothing ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this have just happened a few lines up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought, but if creds is EmpyCredentials, it ignores that setindex.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that sounds like a bug maybe?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, it looks to be by design, but I'm not sure, @wildart should take a look.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, EmpyCredentials is a useless class. But this fix will work.

Copy link
Contributor
@tkelman tkelman Jul 17, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it getting used or passed around then? if it doesn't store anything, then all the logic is going to be wrong for it and this is not going to be the only bug

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, having a setindex that is later not retrievable by setindex with the same index violates expectations. It would be good to redesign that API

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right. don't need to do so right this minute unless that turns out to be the best fix to the blocker bugs we're seeing, but it's going to be error prone until we do

@wildart
Copy link
Member
wildart commented Jul 17, 2016

You better disable ssh-agent usage on windows.

@tkelman
Copy link
Contributor
tkelman commented Jul 17, 2016

how should windows users use ssh without it? cc @davidanthoff

@wildart
Copy link
Member
wildart commented Jul 17, 2016

Not all git builds on windows come with ssh-agent. I believe recent windows build of Git integrates with Windows Credential Store. I'm not sure whether it is used for ssh.

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

I don't understand what the harm is. If the agent can't be found, it should fall back to alternative methods.

@davidanthoff
Copy link
Contributor

Here is my understanding of the landscape. I might well be off. Current git versions for windows bring ssh-agent along, i.e. ssh-agent.exe is in the usr\bin folder in the folder where you install git. posh-git (the powershell plugin that most people seem to use if the use powershell and git), automatically starts ssh-agent when you start a new powershell prompt. So when I start julia from a powershell prompt, ssh-agent is running. Once ssh-agent is started, you have to manually kill it in task manager, or log out, to end that process. So at least for me, ssh-agent is running 99% of the time.

If I'm in a window session and had never started powershell (with posh-git) and had not somehow manually started ssh-agent, it would probably not be running. If I then started julia from the startmenu shortcut, I guess ssh-agent would not be running.

This has more info that might be relevant. And this. Then there is also the Git credential manager for Windows.

So, my sense is that a lot of Windows users will have a ssh-agent running. I think if it is running, julia should just use it, and not prompt for anything, right?

@tkelman
Copy link
Contributor
tkelman commented Jul 17, 2016

if you check ssh-agent.exe in dependency walker though, it should be linking to msys-2.0.dll, or cygwin1.dll for cygwin's ssh-agent, so it's a posix executable rather than a win32 native one. we no longer bundle a posix layer with the windows julia install (now that cygwin is lgpl we could consider it), so any ssh-agent (or pageant) would have to be a bring your own deal. very few windows users know anything about powershell based tools in my experience, so you might be overestimating how common this will be.

@davidanthoff
Copy link
Contributor

I think the following would be perfectly fine: if julia sees an ssh-agent running, use it, if not, don't. That is probably how it works on Linux and Mac already, right? On Windows that would essentially mean that those people that have git installed (which ships ssh-agent) and got the agent started somehow would see julia using it. Git itself seems the most prevalent vehicle for users to get the ssh-agent binaries on their machines, and then there are lots of ways on how it might be started: the github help tells you how to start it, posh-git starts it, if you install git via something like the github desktop (or whatever the name is), it will run automatically etc.

@tkelman
Copy link
Contributor
tkelman commented Jul 17, 2016

I need to check the code again for how it actually uses ssh-agent, but there's a difference between checking if an ssh-agent is running vs if the ssh-agent executable is on the path. It almost always will be on the path on osx and linux, and often won't be on windows. I think most pieces of software should be much more cautious about modifying users' path settings.

looks like it happens inside libgit2, and is probably up to libssh2 to figure out how to find and talk to an ssh-agent?

@wildart
Copy link
Member
wildart commented Jul 17, 2016

Libgit2 gives very little leeway in terms of managing user credentials. So, either we provide some sort of setup procedure for using SSH protocol, or presume some default parameters (e.g. location of the key), or let user set it up through environmental variables. One should not expect same level of UX functionality from libgit2 comparing to git.

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

@wildart Do you see this as the correct fix or is there something else we should do?

@wildart
Copy link
Member
wildart commented Jul 17, 2016

The logic behind of credentials callback if following: I wanted to connect to ssh-agent firstly before falling back on manually specified ssh key. This PR would always request ssh-agent authentication in usesshaagent field is not provided in Credentials object, and would not provide any alternative authentication mechanism. By default, CachedCredentials is used in the Pkg.update which supports ssh-agent authentication. The rest of LibGit2 network calls do not use any credentials, which is bad for repos that use ssh protocol.

Currently, we avoid authentication issue by forcefully changing protocol to all installed package on https. However, cloned packages could still use ssh protocol, which is a problem cause no credentials will be provided and EmptyCredentials object will be used that does not support ssh-agent.

I think it would be better to provide support of ssh-agent authentication for EmptyCredentials by adding usesshaagent field to it.

N.B. Failing to connect to ssh-agent should not be treaded as error. It only means that some setup is required before using SSH protocol in the package manager.

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

Yes, if the ssh-agent doesn't work, it should fall back to something else. If this is not the correct fix, please suggest an appropriate one.

@wildart
Copy link
Member
wildart commented Jul 17, 2016

There is one caveat: If ssh-agent authentication fails with error, whole operation is aborted. There is no way to fallback on other provider after that.

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

What counts as an error?

@wildart
Copy link
Member
wildart commented Jul 17, 2016

#17391 (comment)

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

That's pretty stupid. Can we patch libgit2 to avoid this?

@wildart
Copy link
Member
wildart commented Jul 17, 2016

Sure, given some time, we can do anything. Just for ref: libgit2/libgit2#3761

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

It just seems ridiculous to me that there's no way to retry a request if the ssh agent can't be found.

@wildart
Copy link
Member
wildart commented Jul 17, 2016

A bit of topic, I looked at libssh2 code and found that this error #17391 (comment) related to Pageant. It looks like ssh-agent is not used for windows in libssh2, pageant on other hand is.

@wildart
Copy link
Member
wildart commented Jul 17, 2016

The proper solution would be to return a authentication error to callback and not fail until callback will specify so.

@Keno
Copy link
Member Author
Keno commented Jul 17, 2016

Maybe re-open the issue with an explanation of the use case we have and why the alternate behavior would be desirable?

@wildart
Copy link
Member
wildart commented Jul 17, 2016

I reopend libgit2/libgit2#3761.

@Keno
Copy link
Member Author
Keno commented Jul 19, 2016

Let's just temporarily patch this loop to retry if there was an error with the agent.

end
function Base.setindex!(p::AbstractCredentials, val, key, _=nothing)
ks = Symbol(key)
@assert isdefined(p, ks)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better error here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's an internal error, an assert is fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it ever happens, would want to be able to see what the inputs were

Also make setindex! fail if requested on a credential type that does
not have the given field.
@Keno
Copy link
Member Author
Keno commented Jul 19, 2016

I've pushed an update to this, removing EmptyCredentials entirely. I'll test on windows to see what we can do about failure to connect to ssh agent.

@@ -7,7 +7,7 @@ $(eval $(call git-external,libgit2,LIBGIT2,CMakeLists.txt,build/libgit2.$(SHLIB_
LIBGIT2_OBJ_SOURCE := $(BUILDDIR)/$(LIBGIT2_SRC_DIR)/libgit2.$(SHLIB_EXT)
LIBGIT2_OBJ_TARGET := $(build_shlibdir)/libgit2.$(SHLIB_EXT)

LIBGIT2_OPTS := $(CMAKE_COMMON) -DCMAKE_BUILD_TYPE=Release -DTHREADSAFE=ON
LIBGIT2_OPTS := $(CMAKE_COMMON) -DCMAKE_BUILD_TYPE=Debug -DTHREADSAFE=ON
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temporary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, left over from debugging, sorry.

@Keno
Copy link
Member Author
Keno commented Jul 21, 2016

Ok, now with 100% fewer fatal failures due to ssh-agent.

@tkelman tkelman added this to the 0.5.0 milestone Jul 21, 2016
@Keno Keno merged commit 555f526 into master Jul 21, 2016
@tkelman tkelman deleted the kf/sshagent branch July 21, 2016 19:06
@tkelman
Copy link
Contributor
tkelman commented Jun 29, 2017

@Keno did this patch ever get upstreamed? If not, any reason it didn't?

@Keno
Copy link
Member Author
Keno commented Jun 29, 2017

IIRC there was an issue opened (libgit2/libgit2#3866), but this was more of a workaround than a real fix.

@tkelman
Copy link
Contributor
tkelman commented Jun 29, 2017

Oh right, thanks, I even bumped it a few months later. Maybe I'll ping them on their slack to see if I can get an opinion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libgit2 The libgit2 library or the LibGit2 stdlib module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0