From 70bffc73f13d3365c9f5834739c81060d2a35130 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Fri, 11 Dec 2020 14:14:09 +0100 Subject: [PATCH] go-dnsstamps update --- go.mod | 2 +- go.sum | 4 +- .../jedisct1/go-dnsstamps/dnsstamps.go | 201 +++++++++++++----- vendor/modules.txt | 2 +- 4 files changed, 147 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index d99b0e1f..22a459a0 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/hectane/go-acl v0.0.0-20190604041725-da78bae5fc95 github.com/jedisct1/dlog v0.0.0-20201201133931-57e17ecd14f1 github.com/jedisct1/go-clocksmith v0.0.0-20190707124905-73e087c7979c - github.com/jedisct1/go-dnsstamps v0.0.0-20201210214355-8114706e4f2a + github.com/jedisct1/go-dnsstamps v0.0.0-20201211123510-8d2deeae02b9 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/jedisct1/xsecretbox v0.0.0-20200921000858-23f5ec706e6a github.com/k-sone/critbitgo v1.4.0 diff --git a/go.sum b/go.sum index 29f93a46..630c405a 100644 --- a/go.sum +++ b/go.sum @@ -53,8 +53,8 @@ github.com/jedisct1/dlog v0.0.0-20201201133931-57e17ecd14f1 h1:glnf1FFQoM6G8Z9i2 github.com/jedisct1/dlog v0.0.0-20201201133931-57e17ecd14f1/go.mod h1:+vbxop6USWgBLUajqc/ak72bH24IpH+HqVy/jiUndSY= github.com/jedisct1/go-clocksmith v0.0.0-20190707124905-73e087c7979c h1:a/NQUT7AXkEfhaZ+nb7Uzqijo1Qc7C7SZpRrv+6UQDA= github.com/jedisct1/go-clocksmith v0.0.0-20190707124905-73e087c7979c/go.mod h1:SAINchklztk2jcLWJ4bpNF4KnwDUSUTX+cJbspWC2Rw= -github.com/jedisct1/go-dnsstamps v0.0.0-20201210214355-8114706e4f2a h1:XXNdV/wI5aLjCEWiYHZEIArB81lHHDcNpfXndq/52aA= -github.com/jedisct1/go-dnsstamps v0.0.0-20201210214355-8114706e4f2a/go.mod h1:t35n6rsPE3nD3RXbc5hI5Ax1ci/SSYTpx0BdMXh/1aE= +github.com/jedisct1/go-dnsstamps v0.0.0-20201211123510-8d2deeae02b9 h1:jshbyLcOa5t1ACxQuBZM4C/uX+Xp9veK9Ng2FVqXJ4c= +github.com/jedisct1/go-dnsstamps v0.0.0-20201211123510-8d2deeae02b9/go.mod h1:t35n6rsPE3nD3RXbc5hI5Ax1ci/SSYTpx0BdMXh/1aE= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jedisct1/xsecretbox v0.0.0-20200921000858-23f5ec706e6a h1:poHGyVo1+BCg7ngkrgq1h8xr2MDZHBwD6l2uG2GEMDI= diff --git a/vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go b/vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go index d77315f4..9fd69744 100644 --- a/vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go +++ b/vendor/github.com/jedisct1/go-dnsstamps/dnsstamps.go @@ -16,11 +16,9 @@ const DefaultPort = 443 type ServerInformalProperties uint64 const ( - ServerInformalPropertyDNSSEC = ServerInformalProperties(1) << 0 - ServerInformalPropertyNoLog = ServerInformalProperties(1) << 1 - ServerInformalPropertyNoFilter = ServerInformalProperties(1) << 2 - ServerInformalPropertyRelay = ServerInformalProperties(1) << 3 - ServerInformalPropertyODoHTarget = ServerInformalProperties(1) << 4 + ServerInformalPropertyDNSSEC = ServerInformalProperties(1) << 0 + ServerInformalPropertyNoLog = ServerInformalProperties(1) << 1 + ServerInformalPropertyNoFilter = ServerInformalProperties(1) << 2 ) type StampProtoType uint8 @@ -31,8 +29,9 @@ const ( StampProtoTypeDoH = StampProtoType(0x02) StampProtoTypeTLS = StampProtoType(0x03) StampProtoTypeDoQ = StampProtoType(0x04) - StampProtoTypeODoH = StampProtoType(0x05) + StampProtoTypeODoHTarget = StampProtoType(0x05) StampProtoTypeDNSCryptRelay = StampProtoType(0x81) + StampProtoTypeODoHRelay = StampProtoType(0x85) ) func (stampProtoType *StampProtoType) String() string { @@ -47,12 +46,14 @@ func (stampProtoType *StampProtoType) String() string { return "TLS" case StampProtoTypeDoQ: return "QUIC" - case StampProtoTypeODoH: - return "oDoH" + case StampProtoTypeODoHTarget: + return "oDoH target" case StampProtoTypeDNSCryptRelay: - return "Anonymized DNSCrypt" + return "DNSCrypt relay" + case StampProtoTypeODoHRelay: + return "oDoH relay" default: - panic("Unexpected protocol") + return "(unknown)" } } @@ -100,10 +101,12 @@ func NewServerStampFromString(stampStr string) (ServerStamp, error) { return newDNSCryptServerStamp(bin) } else if bin[0] == uint8(StampProtoTypeDoH) { return newDoHServerStamp(bin) - } else if bin[0] == uint8(StampProtoTypeODoH) { - return newODoHServerStamp(bin) + } else if bin[0] == uint8(StampProtoTypeODoHTarget) { + return newODoHTargetStamp(bin) } else if bin[0] == uint8(StampProtoTypeDNSCryptRelay) { return newDNSCryptRelayStamp(bin) + } else if bin[0] == uint8(StampProtoTypeODoHRelay) { + return newODoHRelayStamp(bin) } return ServerStamp{}, errors.New("Unsupported stamp version or protocol") } @@ -251,11 +254,11 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) { return stamp, nil } -// id(u8)=0x05 props addrLen(1) serverAddr hostNameLen(1) hostName pathLen(1) path +// id(u8)=0x05 props hostNameLen(1) hostName pathLen(1) path -func newODoHServerStamp(bin []byte) (ServerStamp, error) { - stamp := ServerStamp{Proto: StampProtoTypeODoH} - if len(bin) < 22 { +func newODoHTargetStamp(bin []byte) (ServerStamp, error) { + stamp := ServerStamp{Proto: StampProtoTypeODoHTarget} + if len(bin) < 12 { return stamp, errors.New("Stamp is too short") } stamp.Props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9])) @@ -267,14 +270,6 @@ func newODoHServerStamp(bin []byte) (ServerStamp, error) { return stamp, errors.New("Invalid stamp") } pos++ - stamp.ServerAddrStr = string(bin[pos : pos+length]) - pos += length - - length = int(bin[pos]) - if 1+length >= binLen-pos { - return stamp, errors.New("Invalid stamp") - } - pos++ stamp.ProviderName = string(bin[pos : pos+length]) pos += length @@ -290,29 +285,6 @@ func newODoHServerStamp(bin []byte) (ServerStamp, error) { return stamp, errors.New("Invalid stamp (garbage after end)") } - if len(stamp.ServerAddrStr) > 0 { - colIndex := strings.LastIndex(stamp.ServerAddrStr, ":") - bracketIndex := strings.LastIndex(stamp.ServerAddrStr, "]") - if colIndex < bracketIndex { - colIndex = -1 - } - if colIndex < 0 { - colIndex = len(stamp.ServerAddrStr) - stamp.ServerAddrStr = fmt.Sprintf("%s:%d", stamp.ServerAddrStr, DefaultPort) - } - if colIndex >= len(stamp.ServerAddrStr)-1 { - return stamp, errors.New("Invalid stamp (empty port)") - } - ipOnly := stamp.ServerAddrStr[:colIndex] - portOnly := stamp.ServerAddrStr[colIndex+1:] - if _, err := strconv.ParseUint(portOnly, 10, 16); err != nil { - return stamp, errors.New("Invalid stamp (port range)") - } - if net.ParseIP(strings.TrimRight(strings.TrimLeft(ipOnly, "["), "]")) == nil { - return stamp, errors.New("Invalid stamp (IP address)") - } - } - return stamp, nil } @@ -359,15 +331,98 @@ func newDNSCryptRelayStamp(bin []byte) (ServerStamp, error) { return stamp, nil } +// id(u8)=0x85 props addrLen(1) serverAddr hashLen(1) hash hostNameLen(1) hostName pathLen(1) path + +func newODoHRelayStamp(bin []byte) (ServerStamp, error) { + stamp := ServerStamp{Proto: StampProtoTypeODoHRelay} + if len(bin) < 13 { + return stamp, errors.New("Stamp is too short") + } + stamp.Props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9])) + binLen := len(bin) + pos := 9 + + length := int(bin[pos]) + if 1+length >= binLen-pos { + return stamp, errors.New("Invalid stamp") + } + pos++ + stamp.ServerAddrStr = string(bin[pos : pos+length]) + pos += length + + for { + vlen := int(bin[pos]) + length = vlen & ^0x80 + if 1+length >= binLen-pos { + return stamp, errors.New("Invalid stamp") + } + pos++ + if length > 0 { + stamp.Hashes = append(stamp.Hashes, bin[pos:pos+length]) + } + pos += length + if vlen&0x80 != 0x80 { + break + } + } + + length = int(bin[pos]) + if 1+length >= binLen-pos { + return stamp, errors.New("Invalid stamp") + } + pos++ + stamp.ProviderName = string(bin[pos : pos+length]) + pos += length + + length = int(bin[pos]) + if length >= binLen-pos { + return stamp, errors.New("Invalid stamp") + } + pos++ + stamp.Path = string(bin[pos : pos+length]) + pos += length + + if pos != binLen { + return stamp, errors.New("Invalid stamp (garbage after end)") + } + + if len(stamp.ServerAddrStr) > 0 { + colIndex := strings.LastIndex(stamp.ServerAddrStr, ":") + bracketIndex := strings.LastIndex(stamp.ServerAddrStr, "]") + if colIndex < bracketIndex { + colIndex = -1 + } + if colIndex < 0 { + colIndex = len(stamp.ServerAddrStr) + stamp.ServerAddrStr = fmt.Sprintf("%s:%d", stamp.ServerAddrStr, DefaultPort) + } + if colIndex >= len(stamp.ServerAddrStr)-1 { + return stamp, errors.New("Invalid stamp (empty port)") + } + ipOnly := stamp.ServerAddrStr[:colIndex] + portOnly := stamp.ServerAddrStr[colIndex+1:] + if _, err := strconv.ParseUint(portOnly, 10, 16); err != nil { + return stamp, errors.New("Invalid stamp (port range)") + } + if net.ParseIP(strings.TrimRight(strings.TrimLeft(ipOnly, "["), "]")) == nil { + return stamp, errors.New("Invalid stamp (IP address)") + } + } + + return stamp, nil +} + func (stamp *ServerStamp) String() string { if stamp.Proto == StampProtoTypeDNSCrypt { return stamp.dnsCryptString() } else if stamp.Proto == StampProtoTypeDoH { return stamp.dohString() - } else if stamp.Proto == StampProtoTypeODoH { - return stamp.oDohString() + } else if stamp.Proto == StampProtoTypeODoHTarget { + return stamp.oDohTargetString() } else if stamp.Proto == StampProtoTypeDNSCryptRelay { return stamp.dnsCryptRelayString() + } else if stamp.Proto == StampProtoTypeODoHRelay { + return stamp.oDohRelayString() } panic("Unsupported protocol") } @@ -432,18 +487,11 @@ func (stamp *ServerStamp) dohString() string { return "sdns://" + str } -func (stamp *ServerStamp) oDohString() string { +func (stamp *ServerStamp) oDohTargetString() string { bin := make([]uint8, 9) - bin[0] = uint8(StampProtoTypeODoH) + bin[0] = uint8(StampProtoTypeODoHTarget) binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.Props)) - serverAddrStr := stamp.ServerAddrStr - if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) { - serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))] - } - bin = append(bin, uint8(len(serverAddrStr))) - bin = append(bin, []uint8(serverAddrStr)...) - bin = append(bin, uint8(len(stamp.ProviderName))) bin = append(bin, []uint8(stamp.ProviderName)...) @@ -470,3 +518,40 @@ func (stamp *ServerStamp) dnsCryptRelayString() string { return "sdns://" + str } + +func (stamp *ServerStamp) oDohRelayString() string { + bin := make([]uint8, 9) + bin[0] = uint8(StampProtoTypeODoHRelay) + binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.Props)) + + serverAddrStr := stamp.ServerAddrStr + if strings.HasSuffix(serverAddrStr, ":"+strconv.Itoa(DefaultPort)) { + serverAddrStr = serverAddrStr[:len(serverAddrStr)-1-len(strconv.Itoa(DefaultPort))] + } + bin = append(bin, uint8(len(serverAddrStr))) + bin = append(bin, []uint8(serverAddrStr)...) + + if len(stamp.Hashes) == 0 { + bin = append(bin, uint8(0)) + } else { + last := len(stamp.Hashes) - 1 + for i, hash := range stamp.Hashes { + vlen := len(hash) + if i < last { + vlen |= 0x80 + } + bin = append(bin, uint8(vlen)) + bin = append(bin, hash...) + } + } + + bin = append(bin, uint8(len(stamp.ProviderName))) + bin = append(bin, []uint8(stamp.ProviderName)...) + + bin = append(bin, uint8(len(stamp.Path))) + bin = append(bin, []uint8(stamp.Path)...) + + str := base64.RawURLEncoding.EncodeToString(bin) + + return "sdns://" + str +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 281bbf97..14c014bc 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,7 +42,7 @@ github.com/jedisct1/dlog # github.com/jedisct1/go-clocksmith v0.0.0-20190707124905-73e087c7979c ## explicit github.com/jedisct1/go-clocksmith -# github.com/jedisct1/go-dnsstamps v0.0.0-20201210214355-8114706e4f2a +# github.com/jedisct1/go-dnsstamps v0.0.0-20201211123510-8d2deeae02b9 ## explicit github.com/jedisct1/go-dnsstamps # github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e