@cryptotaxi247 / kubo / commits / 28d4d9b32

refactor: add isDomainNameAndNotPeerID

This ensures we exclude valid PeerIDs from code paths that require DNSLink names. Ref. https://github.com/ipfs/go-ipfs/pull/8071#pullrequestreview-639409245

Marcin Rataj committed Apr 21, 2021 at 20:36 UTC 28d4d9b327b83cef407a8a79e7162ab54bcfa63d
2 files changed +36 -5
core/corehttp/hostname.go
+16 -4
@@ -349,15 +349,27 @@ func knownSubdomainDetails(hostname string, knownGateways gatewayHosts) (gw *con
349 return nil, "", "", "", false
350 }
351
352 +// isDomainNameAndNotPeerID returns bool if string looks like a valid DNS name AND is not a PeerID
353 +func isDomainNameAndNotPeerID(hostname string) bool {
354 + if len(hostname) == 0 {
355 + return false
356 + }
357 + if _, err := peer.Decode(hostname); err == nil {
358 + return false
359 + }
360 + _, ok := dns.IsDomainName(hostname)
361 + return ok
362 +}
363 +
364 // isDNSLinkName returns bool if a valid DNS TXT record exist for provided host
365 func isDNSLinkName(ctx context.Context, ipfs iface.CoreAPI, host string) bool {
354 - fqdn := stripPort(host)
366 + dnslinkName := stripPort(host)
367
356 - if _, ok := dns.IsDomainName(fqdn); !ok && len(fqdn) == 0 {
368 + if !isDomainNameAndNotPeerID(dnslinkName) {
369 return false
370 }
371
360 - name := "/ipns/" + fqdn
372 + name := "/ipns/" + dnslinkName
373 // check if DNSLink exists
374 depth := options.Name.ResolveOption(nsopts.Depth(1))
375 _, err := ipfs.Name().Resolve(ctx, name, depth)
@@ -476,7 +488,7 @@ func toSubdomainURL(hostname, path string, r *http.Request, ipfs iface.CoreAPI)
488 }
489
490 // Normalize problematic PeerIDs (eg. ed25519+identity) to CID representation
479 - if _, ok := dns.IsDomainName(rootID); !ok && isPeerIDNamespace(ns) {
491 + if isPeerIDNamespace(ns) && !isDomainNameAndNotPeerID(rootID) {
492 peerID, err := peer.Decode(rootID)
493 // Note: PeerID CIDv1 with protobuf multicodec will fail, but we fix it
494 // in the next block
core/corehttp/hostname_test.go
+20 -1
@@ -55,7 +55,7 @@ func TestToSubdomainURL(t *testing.T) {
55 {httpRequest, "localhost", "/ipns/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "http://k2k4r8n0flx3ra0y5dr8fmyvwbzy3eiztmtq6th694k5a3rznayp3e4o.ipns.localhost/", nil},
56 {httpRequest, "localhost", "/ipns/bafybeickencdqw37dpz3ha36ewrh4undfjt2do52chtcky4rxkj447qhdm", "http://k2k4r8l9ja7hkzynavdqup76ou46tnvuaqegbd04a4o1mpbsey0meucb.ipns.localhost/", nil},
57 // PeerID: ed25519+identity multihash → CIDv1Base36
58 - {httpRequest, "localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5.ipns.localhost/", nil},
58 + {httpRequest, "localhost", "/ipns/12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", "http://k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna.ipns.localhost/", nil},
59 {httpRequest, "sub.localhost", "/ipfs/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n", "http://bafybeif7a7gdklt6hodwdrmwmxnhksctcuav6lfxlcyfz4khzl3qfmvcgu.ipfs.sub.localhost/", nil},
60 // HTTPS requires DNSLink name to fit in a single DNS label – see "Option C" from https://github.com/ipfs/in-web-browsers/issues/169
61 {httpRequest, "dweb.link", "/ipns/dnslink.long-name.example.com", "http://dnslink.long-name.example.com.ipns.dweb.link/", nil},
@@ -144,6 +144,25 @@ func TestHasPrefix(t *testing.T) {
144 }
145 }
146
147 +func TestIsDomainNameAndNotPeerID(t *testing.T) {
148 + for _, test := range []struct {
149 + hostname string
150 + out bool
151 + }{
152 + {"", false},
153 + {"example.com", true},
154 + {"non-icann.something", true},
155 + {"..", false},
156 + {"12D3KooWFB51PRY9BxcXSH6khFXw1BZeszeLDy7C8GciskqCTZn5", false}, // valid peerid
157 + {"k51qzi5uqu5di608geewp3nqkg0bpujoasmka7ftkyxgcm3fh1aroup0gsdrna", false}, // valid peerid
158 + } {
159 + out := isDomainNameAndNotPeerID(test.hostname)
160 + if out != test.out {
161 + t.Errorf("(%s) returned '%t', expected '%t'", test.hostname, out, test.out)
162 + }
163 + }
164 +}
165 +
166 func TestPortStripping(t *testing.T) {
167 for _, test := range []struct {
168 in string