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

Fix mishandling of SSH port numbers in llb.Git #4069

Closed
wants to merge 1 commit into from

Conversation

aaronlehmann
Copy link
Collaborator

In creating a host argument to pass into sshutil.SSHKeyScan, the current code loses the port number and will hang if packets to port 22 are blocked. A port number separated by a : should be preserved.

Copy link
Member

@tonistiigi tonistiigi left a comment

Choose a reason for hiding this comment

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

Do I get it correctly that when the custom port is set then the only valid format is ssh://git@github.com:port/user/repo.git ?

Could we get a test that covers this case to avoid regressions. Unit test just for parsing should be fine.

// don't do this transformation if the text after the : looks
// like a port number.
if len(parts) == 2 &&
(len(parts[1]) == 0 || parts[1][0] < '0' || parts[1][0] > '9') {
Copy link
Member

Choose a reason for hiding this comment

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

Would it be safer to do strconv.ParseInt in here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why would it be safer? I don't think it's quite the same thing, for example it would parse +22 as an int.

Copy link
Member

Choose a reason for hiding this comment

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

iiuc this currently checks the range for first letter after :. Why can't a regular repo name start with a number?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It could, but how would we know it's supposed to be a repo name and not a port number?

Copy link
Member

Choose a reason for hiding this comment

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

I don't know how to know it precisely, but I thought it would at least be safer to check all the letters than just the first one. I didn't consider that ParseInt also accepts the sign.

@aaronlehmann
Copy link
Collaborator Author

Do I get it correctly that when the custom port is set then the only valid format is ssh://git@github.com:port/user/repo.git ?

I'm not sure I understand your question precisely, but I don't think that's correct. We parse the protocol out before this with gitutil.ParseProtocol, so the protocol prefix is still optional. This is just addressing the case where : is used a separator between the host and the path. That is now disallowed if there is a port number provided.

I could try to handle URIs like git@github.com:22:moby/buildkit.git - not sure if that's valid, though.

@tonistiigi
Copy link
Member

I could try to handle URIs like git@github.com:22:moby/buildkit.git - not sure if that's valid, though.

That's what I was wondering as well.

@aaronlehmann
Copy link
Collaborator Author

Added a test. Also made this work for URIs like ssh://github.com:22:moby/buildkit.git, though I'm not sure that's a valid format.

@aaronlehmann aaronlehmann force-pushed the ssh-port-numbers branch 2 times, most recently from 3d99e08 to d7afafc Compare July 31, 2023 16:47
@jedevc
Copy link
Member

jedevc commented Jul 31, 2023

Also made this work for URIs like ssh://github.com:22:moby/buildkit.git, though I'm not sure that's a valid format.

$ git clone git@github.com:22:moby/buildkit.git
Cloning into 'buildkit'...
fatal: remote error: 
  is not a valid repository name
Visit https://support.github.com/ for help

I think we should defer to the git cli compatibility here if we can.

We might want to split out the protocol in gitutil.ParseProtocol to return different values for a ssh:// URL vs a scp-like URL, git seems to have different paths for both of these.

@aaronlehmann
Copy link
Collaborator Author

I think we should defer to the git cli compatibility here if we can.

Great, this makes things simpler. I've updated the PR to drop support for both a port number and a colon-delimited path at the same time.

// check for a possible port number after the host
if !isNumeric(hostParts[1]) {
sshHost = hostParts[0]
pathPrefix := strings.Join(hostParts[1:], "/")
Copy link
Member

Choose a reason for hiding this comment

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

This seems to be no-op as hostParts[1:] always only has one item because of the SplitN

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was left over from when it handled multiple :s. Removed.

In creating a host argument to pass into sshutil.SSHKeyScan, the current
code loses the port number and will hang if packets to port 22 are
blocked. A port number separated by a : should be preserved.

Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
@aaronlehmann
Copy link
Collaborator Author

@tonistiigi: Does this look good now?

@jedevc jedevc self-requested a review August 11, 2023 14:27
{
remote: "ssh://github.com:22:moby/buildkit.git",
expectedProtocol: gitutil.SSHProtocol,
expectedSSHHost: "github.com",
Copy link
Member

Choose a reason for hiding this comment

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

Expected host here should be github.com:22:moby if we want to follow the same behavior as git:

$ git clone ssh://git@github.com:moby:22/buildkit.git
Cloning into 'buildkit'...
ssh: Could not resolve hostname github.com:moby:22: Name or service not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

@jedevc
Copy link
Member

jedevc commented Aug 11, 2023

@aaronlehmann @tonistiigi what do you think of the approach in master...jedevc:buildkit:wip-gitutil? I had a bit of a play around.

Essentially a lot of this issue seems to be that ParseProtocol and callers confuse between the git@ scp-style URLs and the ssh://-style. Port numbers are only valid in ssh:// style, so the logic to do the exact host and path splitting should be pushed down into ParseProtocol where we actually determine if it's an scp-style URL.

(I think this solves the original issue?)

@aaronlehmann
Copy link
Collaborator Author

@jedevc: I really like that approach. Using url.Parse when possible makes a lot of sense. Happy to close this PR in favor of an alternative solution.

@aaronlehmann
Copy link
Collaborator Author

Closing in favor of #4142

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 this pull request may close these issues.

3 participants