Skip to content
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

SSH_FXP_REALPATH and symlinks #512

Closed
drakkan opened this issue Jun 26, 2022 · 10 comments · Fixed by #516
Closed

SSH_FXP_REALPATH and symlinks #512

drakkan opened this issue Jun 26, 2022 · 10 comments · Fixed by #516

Comments

@drakkan
Copy link
Collaborator

drakkan commented Jun 26, 2022

Hi,

OpenSSH resolves symlinks for SSH_FXP_REALPATH calls (without failing if the symlink is broken), see here.

We simply return a cleaned path without resolving any symbolic links. This is what the v3 specs literally say (v6 has more details):

The SSH_FXP_REALPATH request can be used to have the server
canonicalize any given path name to an absolute path. This is useful
for converting path names containing ".." components or relative
pathnames without a leading slash into absolute paths

If we want to behave like OpenSSH I think we can use os.Lstat and os.Readlink for our server implementation.

For request-server it is more tricky, we would have to generate Lstat and Readlink calls ourself. Maybe we can just document our realpath behaviour and remove the depracation notice from RealPathFileLister. Request server users can implement RealPathFileLister if they want to resolve symlinks. What do you think about? Thanks

@puellanivis
Copy link
Collaborator

Sounds probably good.

@drakkan
Copy link
Collaborator Author

drakkan commented Jul 14, 2022

uhm ... the problem here is that we should also return an error so we cannot reuse the current interface.

@puellanivis
Copy link
Collaborator

😐 Yeah, looking back at it now, it should have always retuned an error.

@drakkan
Copy link
Collaborator Author

drakkan commented Jul 14, 2022

If we cannot change the RealPath interface, I think I have to wait for a v2 to fix this issue.

I don't want to maintain a custom branch, I think this is a minor issue, we don't violate the specs.
Do you have other (non-ugly) ideas?

The current code base never returns an error because it does not resolve symbolic links, so no errors can occur

@puellanivis
Copy link
Collaborator

Well right now, the interface isn’t used for anything right? And we’re supposed to just be using it as an extension interface anyways, right?

So, switching the interface shouldn’t actually break anything? 🤔

@drakkan
Copy link
Collaborator Author

drakkan commented Jul 15, 2022

Well right now, the interface isn’t used for anything right? And we’re supposed to just be using it as an extension interface anyways, right?

So, switching the interface shouldn’t actually break anything? thinking

If we could change the RealPathFileLister like this

type RealPathFileLister interface {
	FileLister
	RealPath(string) (string, error)
}

would be perfect. I think it is unlikely that anyone is using this interface as it was added for the start directory feature but it basically doesn't work.

Another solution is to add a new extension interface but this way we have to check for 2 interfaces here. This doesn't seem ideal

@puellanivis
Copy link
Collaborator

A type switch at that point wouldn’t be the worst thing ever, and I don’t see that it would be any particularly performance critical path either.

So, I kind of see two different options:

  • two interfaces: RealPathWithErrorFileLister and leave the RealPathFileLister interface alone, this requires a type switch where mentioned
  • redefine RealPathFileLister to return an error, which has a small chance that someone might possibly be using it explicitly, and which might break things silently if we don’t also define a [Ll]egacyRealPathFileListener (not exporting it would be more ideal), that would catch the previous interface and account for it. The later would still require a type switch exactly the same as the first, just with different type names.

@puellanivis
Copy link
Collaborator

puellanivis commented Jul 15, 2022

Forgot to mention: I did a search on Github for RealPathFileLister and the only results that come up are our code and vendoring of our code.

But then the worry is always that you might break closed source, right? The one you cannot account for ahead of time.

@drakkan
Copy link
Collaborator Author

drakkan commented Jul 15, 2022

Ok, do you have any preference? Maybe the second option will avoid a backward incompatible change in the future

@puellanivis
Copy link
Collaborator

Yeah, I’m partial to the second option. There’s a higher possibility of source-code-level breakage, but that risk was always going to be fairly low, and the fix is relatively easy as well, just add an error return and return a nil.

It would make sense though to also document that the legacy form is still supported, even though it might not be exported. Just being clear about what kind of behavior exists there (since for anyone coming in new, it might seem astonishing), and why it exists.

drakkan added a commit to drakkan/sftp that referenced this issue Jul 15, 2022
added legacyRealPathFileLister for backward compatibility

Fixes pkg#512
drakkan added a commit to drakkan/sftp that referenced this issue Jul 16, 2022
added legacyRealPathFileLister for backward compatibility

Fixes pkg#512
capnspacehook pushed a commit to gravitational/sftp that referenced this issue Sep 27, 2022
added legacyRealPathFileLister for backward compatibility

Fixes pkg#512
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants