Skip to content

cli/config/credentials: ConvertToHostname: handle IP-addresses - #5196

Merged
thaJeztah merged 1 commit into
docker:masterfrom
thaJeztah:carry_fix_custom_ports
Jun 26, 2024
Merged

cli/config/credentials: ConvertToHostname: handle IP-addresses#5196
thaJeztah merged 1 commit into
docker:masterfrom
thaJeztah:carry_fix_custom_ports

Conversation

@thaJeztah

@thaJeztahthaJeztah commented Jun 26, 2024

Copy link
Copy Markdown
Member

- What I did

- Description for the changelog

Fix handling of IPv6 addresses with custom ports on docker login

- A picture of a cute animal (not mandatory but encouraged)

@thaJeztahthaJeztah added this to the 28.0.0 milestone Jun 26, 2024
@thaJeztahthaJeztah changed the title re-introduced support for port numbers in docker registry URLcli/config/credentials: ConvertToHostname: handle IP-addressesJun 26, 2024
@codecov-commenter

codecov-commenter commented Jun 26, 2024

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 61.43%. Comparing base (94e9aa6) to head (8b0a7b0).

Additional details and impacted files
@@ Coverage Diff @@## master #5196 +/- ##
=======================================
Coverage 61.43% 61.43% =======================================
Files 298 298 Lines 20799 20799 =======================================
Hits 12777 12777 Misses 7109 7109 Partials 913 913 

@vvoland

Copy link
Copy Markdown
Collaborator

Needs a rebase

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
@thaJeztah

Copy link
Copy Markdown
MemberAuthor

Rebased; I also removed the cherry-pick label for now, as this was not the previous handling of these, so perhaps OK for the next release.

@thaJeztahthaJeztah added kind/enhancement and removed kind/bugfix PR's that fix bugs labels Jun 26, 2024
@vvoland

vvoland commented Jun 26, 2024

Copy link
Copy Markdown
Collaborator

The implementation before #3599 only removed the http(s):// prefix and took everything until / - so it would still preserve the port in the IPv6 address (http://[::1]:1234/) and not add an extra : if no explicit port was given (http://[::1]/).

// ConvertToHostname normalizes a registry URL which has http|https prepended
// to just its hostname. It is used to match credentials, which may be either
// stored as hostname or as hostname including scheme (in legacy configuration
// files).
funcConvertToHostname(urlstring) string {
stripped:=url
ifstrings.HasPrefix(url, "http://") {
stripped=strings.TrimPrefix(url, "http://")
} elseifstrings.HasPrefix(url, "https://") {
stripped=strings.TrimPrefix(url, "https://")
}
returnstrings.SplitN(stripped, "/", 2)[0]
}

So IMO we should still cherrypick this.

@thaJeztah

thaJeztah commented Jun 26, 2024

Copy link
Copy Markdown
MemberAuthor

so it would still preserve the port in the IPv6 address (http://[::1]:1234/) and not add an extra : if no explicit port was given (http://[::1]/).

So this function is to normalise hosts, in order to lookup which credentials to use if they're present in ~/.docker/config.json. It's somewhat fine to pick whatever format for these, but we should make sure that we de-duplicate entries to prevent ::1:5000 being considered different than [::1]:5000.

There's some existing weird behavior where we treat index.docker.io separate, and for that we use the URL for lookup (https://index.docker.ioi/v1/) but for any other registry, we use hostname[:port].

AFAIK, the intent was always to store credentials per hostname, which is why URLs are trimmed (i.e. no separate credentials for hostname.example.com/v2/foo and hostname.example.com/v2/bar), but port is preserved, because different ports may be different registries / services, and credentials should not be sent to unrelated ones.

That, hmmm, also brings up the other topic; ambiguous port numbers, because https://example.com and http://example.com are implicitly different ports (443 vs 80), but because we're trimming the scheme, that information gets lost. This also means that example.com:80 and example.com:443 are now considered separate entries.

And to add to the fun, some credential helpers require a scheme in order to store credentials, and because we want to precent credentials that were stored for a TLS host to be sent to a non-TLS host (with the same name), we use https:// to store the credentials

🫠 🫠 🫠 🫠

TL;DR we need to better define how these must be normalised to prevent ambiguity.

@thaJeztahthaJeztah self-assigned this Jun 26, 2024
@vvoland

Copy link
Copy Markdown
Collaborator

Without this PR, we're still not doing the same thing as before #3599.

Consider https://[::1]:5000 as an input:

Before we would correctly return the [::1]:5000, after #5195 the result would be ::1:5000.

If that host was stored on pre v27 versions, it would be stored as [::1]:5000. IMO, it's better to keep the stored data consistent with previous versions, just in case there is other code that's reading this state (like Docker Desktop?).

@thaJeztah

Copy link
Copy Markdown
MemberAuthor

OH!! Now I get it. Sorry, I'm slow. So yes, the url.Parse -> .HostName() would be stripping the square brackets because it's not part of the hostname (only used for host:port). Gotcha 😄

Yes, in that case we should take this one for 27.0.2 as well

@thaJeztah

Copy link
Copy Markdown
MemberAuthor

Prepared a backport; #5198

@thaJeztah
thaJeztah merged commit 1996259 into docker:masterJun 26, 2024
@thaJeztah
thaJeztah deleted the carry_fix_custom_ports branch June 26, 2024 13:09
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

v26.1.4 -> 27.0.1: "docker login https://myregistry:444/" loses port

3 participants

@thaJeztah@codecov-commenter@vvoland