2
0
mirror of https://github.com/namecoin/ncdns synced 2024-11-16 00:13:01 +00:00

Add no_namecoin_tls build tag

This commit is contained in:
JeremyRand 2019-10-04 03:10:40 +00:00
parent d2db4756d6
commit 0e6369824f
No known key found for this signature in database
GPG Key ID: B3F2D165786D6570
17 changed files with 316 additions and 189 deletions

View File

@ -24,7 +24,9 @@ addons:
sudo: false
install:
- go get -d -v -t ./...
- if [[ "${NO_NAMECOIN_TLS}" = 1 ]]; then TAGS="no_namecoin_tls"; fi
- if [[ "${NO_NAMECOIN_TLS}" = 0 ]]; then TAGS=""; fi
- go get -tags "$TAGS" -d -v -t ./...
- X509_BRANCH=master
- if [[ "$(go version)" =~ go1.[5678] ]]; then X509_BRANCH=go1.6; fi
- if [[ "$(go version)" =~ go1.9 ]]; then X509_BRANCH=go1.9; fi
@ -33,8 +35,8 @@ install:
- if [[ "$(go version)" =~ go1.12 ]]; then X509_BRANCH=go1.12; fi
- pushd $(go env GOPATH)/src/github.com/namecoin/x509-signature-splice; git checkout $X509_BRANCH; popd
- go generate -v github.com/namecoin/x509-signature-splice/...
- go get -v -t ./...
- env GOOS=windows GOARCH=amd64 go get -d -v -t ./...
- go get -tags "$TAGS" -v -t ./...
- env GOOS=windows GOARCH=amd64 go get -tags "$TAGS" -d -v -t ./...
script:
- source ./.travis/script
after_success:
@ -46,3 +48,6 @@ env:
- secure: "at1oJs7ib7glx3W+zk+OkT041LdknVXirIhN403CIihVUrlOhODY7yCTgvF4Rk0jYBJiT35Q2qxpgfWF2qGnsNsQmjG3ydDWQDCepDc/CgXfLyoiSTJK5vTK72dYWTVsBTycXbj1CbSy2X2ah/KWjc4RcgZ67ER7mDpRU5nFeow="
# Set this to the Go version to use for releases (must appear in version list above).
- RELEASE_GO_VERSION="1.12.5"
matrix:
- NO_NAMECOIN_TLS=1
- NO_NAMECOIN_TLS=0

View File

@ -6,6 +6,11 @@ if ! [[ "$TRAVIS_TAG" =~ ^v[0-9] ]]; then
return 0
fi
if [ "${NO_NAMECOIN_TLS}" != "0" ]; then
echo "Skipping release upload because TLS is disabled."
return 0
fi
if [ -z "$GITHUB_TOKEN" ]; then
echo "Don't appear to have GitHub token, cannot continue."
return 0

View File

@ -4,7 +4,12 @@
#travis_retry go get github.com/tcnksm/ghr github.com/mitchellh/gox gopkg.in/alecthomas/gometalinter.v2 github.com/miekg/exdns/q github.com/namecoin/dns-prop279
travis_retry go get github.com/tcnksm/ghr github.com/mitchellh/gox gopkg.in/alecthomas/gometalinter.v2
go test -v ./...
GOX_TAGS=""
if [ "${NO_NAMECOIN_TLS}" = "1" ]; then
GOX_TAGS="no_namecoin_tls"
fi
go test -tags "${GOX_TAGS}" -v ./...
RESULT=$?
echo Done tests with exit code $RESULT
@ -12,6 +17,9 @@ if [ "$RESULT" != "0" ]; then
return $RESULT
fi
# Static analysis for TLS mode will cover non-TLS mode as well.
if [ "${NO_NAMECOIN_TLS}" != "1" ]; then
# Static analysis
gometalinter.v2 --install
@ -63,6 +71,8 @@ gometalinter.v2 --enable-all \
./...
STATICRESULT2=$?
fi
# Test cross-compilation. The binaries produced are also used for release
# upload in after_success if this is a release tag.
@ -76,17 +86,19 @@ GOX_PARA=3
REPOS="github.com/$TRAVIS_REPO_SLUG/..."
# cgo crosscompile
gox -parallel=$GOX_PARA -cgo -osarch 'linux/386 linux/amd64' -output "$GOPATH/releasing/idist/ncdns-$TRAVIS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" $REPOS
gox -tags="$GOX_TAGS" -parallel=$GOX_PARA -cgo -osarch 'linux/386 linux/amd64' -output "$GOPATH/releasing/idist/ncdns-$TRAVIS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" $REPOS
RESULT1=$?
# non-cgo crosscompile
gox -parallel=$GOX_PARA -osarch 'darwin/386 darwin/amd64 linux/arm linux/arm64 linux/ppc64 linux/ppc64le freebsd/386 freebsd/amd64 freebsd/arm openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 netbsd/arm dragonfly/amd64 solaris/amd64 windows/386 windows/amd64' -output "$GOPATH/releasing/idist/ncdns-$TRAVIS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" $REPOS
gox -tags="$GOX_TAGS" -parallel=$GOX_PARA -osarch 'darwin/386 darwin/amd64 linux/arm linux/arm64 linux/ppc64 linux/ppc64le freebsd/386 freebsd/amd64 freebsd/arm openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 netbsd/arm dragonfly/amd64 solaris/amd64 windows/386 windows/amd64' -output "$GOPATH/releasing/idist/ncdns-$TRAVIS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" $REPOS
RESULT2=$?
echo cgo crosscompile exited with code $RESULT1
echo non-cgo crosscompile exited with code $RESULT2
if [ "${NO_NAMECOIN_TLS}" != "1" ]; then
echo critical gometalinter exited with code $STATICRESULT1
echo non-critical gometalinter exited with code $STATICRESULT2
fi
if [ "$RESULT1" != "0" ]; then
return $RESULT1
@ -94,6 +106,8 @@ fi
if [ "$RESULT2" != "0" ]; then
return $RESULT2
fi
if [ "${NO_NAMECOIN_TLS}" != "1" ]; then
if [ "$STATICRESULT1" != "0" ]; then
return $STATICRESULT1
fi
fi

View File

@ -7,7 +7,6 @@ import "github.com/namecoin/ncdns/namecoin"
import "github.com/namecoin/ncdns/util"
import "github.com/namecoin/ncdns/ncdomain"
import "github.com/namecoin/ncdns/tlshook"
import "github.com/namecoin/tlsrestrictnss/tlsrestrictnsssync"
import "github.com/hlandau/xlog"
import "sync"
import "fmt"
@ -111,8 +110,8 @@ func convertEmail(email string) (string, error) {
// Do low-level queries against an abstract zone file. This is the per-query
// entrypoint from madns.
func (b *Backend) Lookup(qname string) (rrs []dns.RR, err error) {
if !tlsrestrictnsssync.IsReady() {
err = fmt.Errorf("tlsrestrictnss not ready")
err = lookupReadyError()
if err != nil {
return
}

7
backend/backend_notls.go Normal file
View File

@ -0,0 +1,7 @@
// +build no_namecoin_tls
package backend
func lookupReadyError() error {
return nil
}

14
backend/backend_tls.go Normal file
View File

@ -0,0 +1,14 @@
// +build !no_namecoin_tls
package backend
import "github.com/namecoin/tlsrestrictnss/tlsrestrictnsssync"
import "fmt"
func lookupReadyError() error {
if !tlsrestrictnsssync.IsReady() {
return fmt.Errorf("tlsrestrictnss not ready")
}
return nil
}

View File

@ -10,9 +10,6 @@ import "github.com/namecoin/ncdns/util"
import "strings"
import "strconv"
import "github.com/namecoin/ncdns/certdehydrate"
import "github.com/namecoin/x509-signature-splice/x509"
const depthLimit = 16
const mergeDepthLimit = 4
const defaultTTL = 600
@ -30,22 +27,21 @@ const defaultTTL = 600
// in some cases, namely for Alias and Translate, the empty string is represented as "=".
// Therefore when qualifying names in a Value yourself you must check if the
// input string is "=" and if so, replace it with "" first.
type Value struct {
IP []net.IP
IP6 []net.IP
NS []string
Alias string
HasAlias bool // True if Alias was specified. Necessary as "" is a valid relative alias.
Translate string
HasTranslate bool // True if Translate was specified. Necessary as "" is a valid relative value for Translate.
DS []*dns.DS
TXT [][]string
SRV []*dns.SRV
Hostmaster string // "hostmaster@example.com"
MX []*dns.MX // header name is left blank
TLSA []*dns.TLSA
TLSAGenerated []x509.Certificate // Certs can be dehydrated in the blockchain, they will be put here without SAN values. SAN must be filled in before use.
Map map[string]*Value // may contain and "*", will not contain ""
type valueWithoutTLSA struct {
IP []net.IP
IP6 []net.IP
NS []string
Alias string
HasAlias bool // True if Alias was specified. Necessary as "" is a valid relative alias.
Translate string
HasTranslate bool // True if Translate was specified. Necessary as "" is a valid relative value for Translate.
DS []*dns.DS
TXT [][]string
SRV []*dns.SRV
Hostmaster string // "hostmaster@example.com"
MX []*dns.MX // header name is left blank
TLSA []*dns.TLSA
Map map[string]*Value // may contain and "*", will not contain ""
// set if the value is at the top level (alas necessary for relname interpretation)
IsTopLevel bool
@ -249,45 +245,6 @@ func (v *Value) appendSRVs(out []dns.RR, suffix, apexSuffix string) ([]dns.RR, e
return out, nil
}
func (v *Value) appendTLSA(out []dns.RR, suffix, apexSuffix string) ([]dns.RR, error) {
for _, tlsa := range v.TLSA {
out = append(out, tlsa)
}
for _, cert := range v.TLSAGenerated {
template := cert
_, nameNoPort := util.SplitDomainTail(suffix)
_, nameNoPortOrProtocol := util.SplitDomainTail(nameNoPort)
if !strings.HasSuffix(nameNoPortOrProtocol, ".") {
continue
}
nameNoPortOrProtocol = strings.TrimSuffix(nameNoPortOrProtocol, ".")
derBytes, err := certdehydrate.FillRehydratedCertTemplate(template, nameNoPortOrProtocol)
if err != nil {
// TODO: add debug output here
continue
}
derBytesHex := hex.EncodeToString(derBytes)
out = append(out, &dns.TLSA{
Hdr: dns.RR_Header{Name: "", Rrtype: dns.TypeTLSA, Class: dns.ClassINET,
Ttl: defaultTTL},
Usage: uint8(3),
Selector: uint8(0),
MatchingType: uint8(0),
Certificate: strings.ToUpper(derBytesHex),
})
}
return out, nil
}
func (v *Value) appendAlias(out []dns.RR, suffix, apexSuffix string) ([]dns.RR, error) {
if v.HasAlias {
qn, ok := v.qualify(v.Alias, suffix, apexSuffix)
@ -852,115 +809,6 @@ func parseDS(rv map[string]interface{}, v *Value, errFunc ErrorFunc) {
errFunc.add(fmt.Errorf("malformed DS field format"))
}
func parseTLSADehydrated(tlsa1dehydrated interface{}, v *Value) error {
dehydrated, err := certdehydrate.ParseDehydratedCert(tlsa1dehydrated)
if err != nil {
return fmt.Errorf("Error parsing dehydrated certificate: %s", err)
}
template, err := certdehydrate.RehydrateCert(dehydrated)
if err != nil {
return fmt.Errorf("Error rehydrating certificate: %s", err)
}
v.TLSAGenerated = append(v.TLSAGenerated, *template)
return nil
}
func parseTLSADANE(tlsa1dane interface{}, v *Value) error {
if tlsa, ok := tlsa1dane.([]interface{}); ok {
// Format: ["443", "tcp", 1, 2, 3, "base64 certificate data"]
if len(tlsa) < 4 {
return fmt.Errorf("TLSA item must have six items")
}
a1, ok := tlsa[0].(float64)
if !ok {
return fmt.Errorf("Third item in TLSA value must be an integer (usage)")
}
a2, ok := tlsa[1].(float64)
if !ok {
return fmt.Errorf("Fourth item in TLSA value must be an integer (selector)")
}
a3, ok := tlsa[2].(float64)
if !ok {
return fmt.Errorf("Fifth item in TLSA value must be an integer (match type)")
}
a4, ok := tlsa[3].(string)
if !ok {
return fmt.Errorf("Sixth item in TLSA value must be a string (certificate)")
}
a4b, err := base64.StdEncoding.DecodeString(a4)
if err != nil {
return fmt.Errorf("Fourth item in DS value must be valid base64: %v", err)
}
a4h := hex.EncodeToString(a4b)
v.TLSA = append(v.TLSA, &dns.TLSA{
Hdr: dns.RR_Header{Name: "", Rrtype: dns.TypeTLSA, Class: dns.ClassINET,
Ttl: defaultTTL},
Usage: uint8(a1),
Selector: uint8(a2),
MatchingType: uint8(a3),
Certificate: strings.ToUpper(a4h),
})
return nil
} else {
return fmt.Errorf("TLSA item must be an array")
}
}
func parseTLSA(rv map[string]interface{}, v *Value, errFunc ErrorFunc) {
tlsa, ok := rv["tls"]
if !ok || tlsa == nil {
return
}
v.TLSA = nil
if tlsaa, ok := tlsa.([]interface{}); ok {
for _, tlsa1 := range tlsaa {
var tlsa1m map[string]interface{}
if _, ok := tlsa1.([]interface{}); ok {
tlsa1m = map[string]interface{}{
"dane": tlsa1,
}
} else {
tlsa1m = tlsa1.(map[string]interface{})
}
if tlsa1dehydrated, ok := tlsa1m["d8"]; ok {
err := parseTLSADehydrated(tlsa1dehydrated, v)
if err == nil {
continue
}
errFunc.add(err)
}
if tlsa1dane, ok := tlsa1m["dane"]; ok {
err := parseTLSADANE(tlsa1dane, v)
if err == nil {
continue
}
errFunc.add(err)
}
errFunc.add(fmt.Errorf("Unknown TLSA item format"))
}
return
}
errFunc.add(fmt.Errorf("Malformed TLSA field format"))
}
func parseTXT(rv map[string]interface{}, v *Value, errFunc ErrorFunc) {
rtxt, ok := rv["txt"]
if !ok || rtxt == nil {

19
ncdomain/convert_notls.go Normal file
View File

@ -0,0 +1,19 @@
// +build no_namecoin_tls
package ncdomain
import (
"github.com/miekg/dns"
)
type Value struct {
valueWithoutTLSA
}
func (v *Value) appendTLSA(out []dns.RR, suffix, apexSuffix string) ([]dns.RR, error) {
return out, nil
}
func parseTLSA(rv map[string]interface{}, v *Value, errFunc ErrorFunc) {
v.TLSA = nil
}

View File

@ -0,0 +1,5 @@
// +build no_namecoin_tls
package ncdomain_test
const tlsaDisabled = true

View File

@ -11,6 +11,11 @@ import "sort"
func TestSuite(t *testing.T) {
items := testutil.SuiteReader(t)
for ti := range items {
// Don't test TLSA records if TLSA is disabled via build tag.
if tlsaDisabled && strings.HasPrefix(ti.ID, "tlsa") {
continue
}
resolve := func(name string) (string, error) {
v, ok := ti.Names[name]
if !ok {

169
ncdomain/convert_tls.go Normal file
View File

@ -0,0 +1,169 @@
// +build !no_namecoin_tls
package ncdomain
import (
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
"github.com/miekg/dns"
"github.com/namecoin/ncdns/certdehydrate"
"github.com/namecoin/ncdns/util"
"github.com/namecoin/x509-signature-splice/x509"
)
type Value struct {
valueWithoutTLSA
TLSAGenerated []x509.Certificate // Certs can be dehydrated in the blockchain, they will be put here without SAN values. SAN must be filled in before use.
}
func (v *Value) appendTLSA(out []dns.RR, suffix, apexSuffix string) ([]dns.RR, error) {
for _, tlsa := range v.TLSA {
out = append(out, tlsa)
}
for _, cert := range v.TLSAGenerated {
template := cert
_, nameNoPort := util.SplitDomainTail(suffix)
_, nameNoPortOrProtocol := util.SplitDomainTail(nameNoPort)
if !strings.HasSuffix(nameNoPortOrProtocol, ".") {
continue
}
nameNoPortOrProtocol = strings.TrimSuffix(nameNoPortOrProtocol, ".")
derBytes, err := certdehydrate.FillRehydratedCertTemplate(template, nameNoPortOrProtocol)
if err != nil {
// TODO: add debug output here
continue
}
derBytesHex := hex.EncodeToString(derBytes)
out = append(out, &dns.TLSA{
Hdr: dns.RR_Header{Name: "", Rrtype: dns.TypeTLSA, Class: dns.ClassINET,
Ttl: defaultTTL},
Usage: uint8(3),
Selector: uint8(0),
MatchingType: uint8(0),
Certificate: strings.ToUpper(derBytesHex),
})
}
return out, nil
}
func parseTLSADehydrated(tlsa1dehydrated interface{}, v *Value) error {
dehydrated, err := certdehydrate.ParseDehydratedCert(tlsa1dehydrated)
if err != nil {
return fmt.Errorf("Error parsing dehydrated certificate: %s", err)
}
template, err := certdehydrate.RehydrateCert(dehydrated)
if err != nil {
return fmt.Errorf("Error rehydrating certificate: %s", err)
}
v.TLSAGenerated = append(v.TLSAGenerated, *template)
return nil
}
func parseTLSADANE(tlsa1dane interface{}, v *Value) error {
if tlsa, ok := tlsa1dane.([]interface{}); ok {
// Format: ["443", "tcp", 1, 2, 3, "base64 certificate data"]
if len(tlsa) < 4 {
return fmt.Errorf("TLSA item must have six items")
}
a1, ok := tlsa[0].(float64)
if !ok {
return fmt.Errorf("Third item in TLSA value must be an integer (usage)")
}
a2, ok := tlsa[1].(float64)
if !ok {
return fmt.Errorf("Fourth item in TLSA value must be an integer (selector)")
}
a3, ok := tlsa[2].(float64)
if !ok {
return fmt.Errorf("Fifth item in TLSA value must be an integer (match type)")
}
a4, ok := tlsa[3].(string)
if !ok {
return fmt.Errorf("Sixth item in TLSA value must be a string (certificate)")
}
a4b, err := base64.StdEncoding.DecodeString(a4)
if err != nil {
return fmt.Errorf("Fourth item in DS value must be valid base64: %v", err)
}
a4h := hex.EncodeToString(a4b)
v.TLSA = append(v.TLSA, &dns.TLSA{
Hdr: dns.RR_Header{Name: "", Rrtype: dns.TypeTLSA, Class: dns.ClassINET,
Ttl: defaultTTL},
Usage: uint8(a1),
Selector: uint8(a2),
MatchingType: uint8(a3),
Certificate: strings.ToUpper(a4h),
})
return nil
} else {
return fmt.Errorf("TLSA item must be an array")
}
}
func parseTLSA(rv map[string]interface{}, v *Value, errFunc ErrorFunc) {
tlsa, ok := rv["tls"]
if !ok || tlsa == nil {
return
}
v.TLSA = nil
if tlsaa, ok := tlsa.([]interface{}); ok {
for _, tlsa1 := range tlsaa {
var tlsa1m map[string]interface{}
if _, ok := tlsa1.([]interface{}); ok {
tlsa1m = map[string]interface{}{
"dane": tlsa1,
}
} else {
tlsa1m = tlsa1.(map[string]interface{})
}
if tlsa1dehydrated, ok := tlsa1m["d8"]; ok {
err := parseTLSADehydrated(tlsa1dehydrated, v)
if err == nil {
continue
}
errFunc.add(err)
}
if tlsa1dane, ok := tlsa1m["dane"]; ok {
err := parseTLSADANE(tlsa1dane, v)
if err == nil {
continue
}
errFunc.add(err)
}
errFunc.add(fmt.Errorf("Unknown TLSA item format"))
}
return
}
errFunc.add(fmt.Errorf("Malformed TLSA field format"))
}

View File

@ -0,0 +1,5 @@
// +build !no_namecoin_tls
package ncdomain_test
const tlsaDisabled = false

View File

@ -14,8 +14,6 @@ import (
"github.com/miekg/dns"
"github.com/namecoin/ncdns/backend"
"github.com/namecoin/ncdns/namecoin"
"github.com/namecoin/ncdns/tlsoverridefirefox/tlsoverridefirefoxsync"
"github.com/namecoin/tlsrestrictnss/tlsrestrictnsssync"
"gopkg.in/hlandau/madns.v1"
)
@ -218,17 +216,7 @@ func (s *Server) Start() error {
s.wgStart.Wait()
log.Info("Listeners started")
err := tlsoverridefirefoxsync.Start(s.namecoinConn, s.cfg.CanonicalSuffix)
if err != nil {
return fmt.Errorf("Couldn't start Firefox override sync: %s", err)
}
err = tlsrestrictnsssync.Start()
if err != nil {
return fmt.Errorf("Couldn't start tlsrestrictnss sync: %s", err)
}
return nil
return s.StartBackgroundTasks()
}
func (s *Server) doRunListener(ds *dns.Server) {

7
server/server_notls.go Normal file
View File

@ -0,0 +1,7 @@
// +build no_namecoin_tls
package server
func (s *Server) StartBackgroundTasks() error {
return nil
}

24
server/server_tls.go Normal file
View File

@ -0,0 +1,24 @@
// +build !no_namecoin_tls
package server
import (
"fmt"
"github.com/namecoin/ncdns/tlsoverridefirefox/tlsoverridefirefoxsync"
"github.com/namecoin/tlsrestrictnss/tlsrestrictnsssync"
)
func (s *Server) StartBackgroundTasks() error {
err := tlsoverridefirefoxsync.Start(s.namecoinConn, s.cfg.CanonicalSuffix)
if err != nil {
return fmt.Errorf("Couldn't start Firefox override sync: %s", err)
}
err = tlsrestrictnsssync.Start()
if err != nil {
return fmt.Errorf("Couldn't start tlsrestrictnss sync: %s", err)
}
return nil
}

View File

@ -1,3 +1,5 @@
// +build !no_namecoin_tls
package tlshook
import (

11
tlshook/tlshook_notls.go Normal file
View File

@ -0,0 +1,11 @@
// +build no_namecoin_tls
package tlshook
import (
"github.com/namecoin/ncdns/ncdomain"
)
func DomainValueHookTLS(qname string, ncv *ncdomain.Value) error {
return nil
}