diff --git a/.cirrus.yml b/.cirrus.yml deleted file mode 100644 index f251614..0000000 --- a/.cirrus.yml +++ /dev/null @@ -1,267 +0,0 @@ -# Attention: if you submit an improvement for a Namecoin Cirrus config, please -# file a GitHub issue about it at the namecoin/meta repo, so that we can make -# sure it propagates to all the other Namecoin repos. Thanks! - -task: - alias: Go Lint - container: - image: golangci/golangci-lint:latest - install_script: - - apt-get update - - apt-get install -y libcap-dev - path_script: - - source testdata/move_to_gopath.bash - matrix: - - kingpin_script: - - mkdir -p $(go env GOPATH)/src/github.com/alecthomas - - cd $(go env GOPATH)/src/github.com/alecthomas - - git clone https://github.com/alecthomas/kingpin.git - fetch_script: - - cd $(go env GOPATH)/src/github.com/"$CIRRUS_REPO_FULL_NAME" - - go mod init - - go mod edit -replace gopkg.in/alecthomas/kingpin.v2=$(go env GOPATH)/src/github.com/alecthomas/kingpin - - go mod tidy - lint_script: - - cd $(go env GOPATH)/src/github.com/$CIRRUS_REPO_FULL_NAME/ - - golangci-lint run $GOLANGCI_ARGS -v --timeout 5m --output.json.path $CIRRUS_WORKING_DIR/lint-report.json - # Not running "copyloopvar" linter because it needs Go 1.22+, which isn't supported yet in gccgo 14 (Go 1.16-1.18), which is what Debian Trixie/Stable uses. - # Not running "depguard" linter because it looks too niche. - # Not running "exhaustruct" linter because it looks too niche. - # Not running "gosmopolitan" linter because it's not aimed at English-language code. - # Not running "intrange" linter because it needs Go 1.22+, which isn't supported yet in gccgo 14 (Go 1.16-1.18), which is what Debian Trixie/Stable uses. - matrix: - - name: Go Lint $GOOS New - env: - GOLANGCI_ARGS: "--new-from-rev=HEAD~ --enable=cyclop,err113,forcetypeassert,funlen,gocognit,goconst,gocritic,gosec,mnd,modernize,nlreturn,wsl_v5" - - name: Go Lint $GOOS Mandatory - env: - GOLANGCI_ARGS: "--enable=asasalint,asciicheck,bidichk,bodyclose,canonicalheader,decorder,dupl,dupword,durationcheck,embeddedstructfieldcheck,errcheck,errchkjson,errname,exhaustive,exptostd,gocheckcompilerdirectives,godoclint,godot,goprintffuncname,govet,ineffassign,misspell,nakedret,predeclared,staticcheck,unconvert,unparam,unused,usestdlibvars,wastedassign" - - name: Go Lint $GOOS - env: - GOLANGCI_ARGS: "--enable=cyclop,err113,forcetypeassert,funlen,gocognit,goconst,gocritic,gosec,mnd,modernize,nlreturn,wsl_v5" - allow_failures: true - matrix: - - env: - GOOS: linux - - env: - GOOS: windows - always: - golangci_artifacts: - path: lint-report.json - type: text/json - format: golangci - -task: - name: ShellCheck - container: - image: fedora:latest - cpu: 1 - memory: 1G - install_script: dnf install -y ShellCheck - lint_script: bash testdata/shellcheck.bash - -task: - name: Unit Tests Go $GO_VERSION - alias: Unit Tests - container: - image: golang:$GO_VERSION - install_script: - - apt-get update - - apt-get install -y libcap-dev - path_script: - - source testdata/move_to_gopath.bash - kingpin_script: - - mkdir -p $(go env GOPATH)/src/github.com/alecthomas - - cd $(go env GOPATH)/src/github.com/alecthomas - - git clone https://github.com/alecthomas/kingpin.git - fetch_script: - - cd $(go env GOPATH)/src/github.com/"$CIRRUS_REPO_FULL_NAME" - - go mod init - - go mod edit -replace gopkg.in/alecthomas/kingpin.v2=$(go env GOPATH)/src/github.com/alecthomas/kingpin - - go mod tidy - # Get the test suite - - mkdir -p $(go env GOPATH)/src/github.com/hlandau - - cd $(go env GOPATH)/src/github.com/hlandau - - git clone https://github.com/hlandau/nctestsuite.git - test_script: - - cd $(go env GOPATH)/src/github.com/"$CIRRUS_REPO_FULL_NAME" - - go install -tags "$GOX_TAGS" -v ./... - - go test -tags "$GOX_TAGS" -v github.com/$CIRRUS_REPO_FULL_NAME/... - env: - GOX_TAGS: "" - GO_VERSION: latest - -task: - name: "Functional Tests $CI_DISTRO Go $GO_VERSION" - alias: "Functional Tests" - matrix: - - compute_engine_instance: - image_project: debian-cloud - image: family/debian-12 - platform: linux - cpu: 1 - memory: 1G - env: - CI_DISTRO: debian-12 - - compute_engine_instance: - image_project: debian-cloud - image: family/debian-13 - platform: linux - cpu: 1 - memory: 1G - env: - CI_DISTRO: debian-13 - - compute_engine_instance: - image_project: cirrus-images - image: family/docker-builder - platform: linux - cpu: 1 - memory: 1G - env: - CI_DISTRO: ubuntu - bitcoind_cache: - folder: /tmp/bitcoind - populate_script: mkdir -p /tmp/bitcoind - install_script: - - apt-get update - # bind9-dnsutils contains dig - - apt-get install -y dnssec-trigger bind9-dnsutils xxd - # Namecoin Core - # Temporarily downgrade Namecoin Core until deterministic salts with descriptor wallets are fixed. - #- BITCOIND_URL=$(curl https://www.namecoin.org/download/ | grep x86_64-linux-gnu.tar.gz | grep -v 0.13.99 | grep --only-matching https://.*.tar.gz) - - BITCOIND_URL="https://www.namecoin.org/files/namecoin-core/namecoin-core-22.0/namecoin-nc22.0-x86_64-linux-gnu.tar.gz" - - BITCOIND_FILENAME=$(echo $BITCOIND_URL | grep -E --only-matching 'namecoin-nc.*.tar.gz') - - BITCOIND_PATH=/tmp/bitcoind/$BITCOIND_FILENAME - - tar -xaf $BITCOIND_PATH || (rm -f /tmp/bitcoind/* && curl --output $BITCOIND_PATH $BITCOIND_URL && tar -xaf $BITCOIND_PATH) - - cp -a namecoin-*/* /usr/ - # ncdns - - NCDNS_URL=https://api.cirrus-ci.com/v1/artifact/github/namecoin/ncdns/Cross-Compile%20Go%20latest/binaries/dist/ncdns--linux_amd64.tar.gz - - curl -o ncdns.tar.gz $NCDNS_URL - - tar -xaf ncdns.tar.gz - - cp -a ncdns--*/* /usr/ - # Encaya - - ENCAYA_URL=https://api.cirrus-ci.com/v1/artifact/build/$CIRRUS_BUILD_ID/Cross-Compile%20Go%20latest/binaries/dist/encaya--linux_amd64.tar.gz - - curl -o encaya.tar.gz $ENCAYA_URL - - tar -xaf encaya.tar.gz - - cp -a encaya--*/* /usr/ - # Configure DNSSEC-Trigger - - cp ncdns--*/doc/unbound.conf.d/ncdns.conf ncdns--*/doc/unbound.conf.d/ncdns-insecure.conf /etc/unbound/unbound.conf.d - - systemctl restart unbound - bitcoind_service_background_script: - - testdata/run_bitcoind.sh - ncdns_service_background_script: - # ncdns refuses to run as root - - adduser ncdns --disabled-password - - ncdns -conf testdata/ncdns.conf - encaya_service_background_script: - # Avoid race condition in "adduser" between ncdns and encaya - - sleep 5s - # encaya refuses to run as root - - adduser encaya --disabled-password - - encayagen -conf "$(pwd)/testdata/encaya.conf" - - chown encaya:encaya testdata/*.pem - # Curiously, relative paths don't work here, they cause the .pem files to - # not be detected. Maybe file a bug with Hugo? - - encaya -conf "$(pwd)/testdata/encaya.conf" - regtest_script: - - sleep 15s - - testdata/regtest.sh - depends_on: - - "Cross-Compile Go $GO_VERSION" - env: - GO_VERSION: latest - -task: - name: Cross-Compile Go $GO_VERSION - alias: Cross-Compile - container: - image: golang:$GO_VERSION - cpu: 8 - memory: 8G - install_script: - - dpkg --add-architecture i386 - - dpkg --add-architecture armhf - - dpkg --add-architecture arm64 - # TODO: Support cgo for ppc64. - - dpkg --add-architecture ppc64el - - apt-get update - - apt-get install -y gcc-multilib libcap-dev libc6-dev:i386 libcap-dev:i386 libc6-dev:armhf libcap-dev:armhf libc6-dev:arm64 libcap-dev:arm64 libc6-dev:ppc64el libcap-dev:ppc64el - path_script: - - source testdata/move_to_gopath.bash - gox_script: - - go install github.com/mitchellh/gox@latest - kingpin_script: - - mkdir -p $(go env GOPATH)/src/github.com/alecthomas - - cd $(go env GOPATH)/src/github.com/alecthomas - - git clone https://github.com/alecthomas/kingpin.git - fetch_script: - - cd $(go env GOPATH)/src/github.com/"$CIRRUS_REPO_FULL_NAME" - - go mod init - - go mod edit -replace gopkg.in/alecthomas/kingpin.v2=$(go env GOPATH)/src/github.com/alecthomas/kingpin - - go mod tidy - matrix: - - env: - GOX_TAGS: "" - - env: - GOX_TAGS: "encaya_pi" - build_script: - - rm -rf idist - - cd $(go env GOPATH)/src/github.com/"$CIRRUS_REPO_FULL_NAME" - - CGO_ENABLED=1 gox -tags="$GOX_TAGS" -parallel=8 -osarch 'linux/386 linux/amd64 linux/arm linux/arm64 linux/ppc64le' -output "$GOPATH/releasing/idist/$CIRRUS_REPO_NAME-$CIRRUS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" ./... - - CGO_ENABLED=0 gox -tags="$GOX_TAGS" -parallel=8 -osarch 'darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm linux/ppc64 openbsd/386 openbsd/amd64 netbsd/386 netbsd/amd64 netbsd/arm dragonfly/amd64 solaris/amd64 windows/386 windows/amd64' -output "$GOPATH/releasing/idist/$CIRRUS_REPO_NAME-$CIRRUS_TAG-{{.OS}}_{{.Arch}}/bin/{{.Dir}}" ./... - dist_script: - - mv $GOPATH/releasing/idist ./idist - - bash "testdata/dist.bash" - binaries_artifacts: - path: "dist/*" - env: - GO_VERSION: latest - -task: - # GitHub Release Upload - # TODO: implement this. - name: GitHub Release - container: - image: golang:latest - cpu: 1 - memory: 1G - depends_on: - - Go Lint - - ShellCheck - - Unit Tests - - Cross-Compile - bin_cache: - folder: "idist" - fingerprint_script: - - "echo cross_compile_bin_go_%GO_VERSION%" - reupload_on_changes: false - populate_script: - - "mkdir idist" - install_script: - - go get github.com/tcnksm/ghr - release_script: - - bash "testdata/release.bash" - allow_failures: true - env: - GOX_TAGS: "" - GO_VERSION: latest - -# TODO: Add Windows unit tests - -# TODO: "Testing config parsing" from travis.bash - -# TODO: Add multiple Go versions to Gox builds and unit tests - -# TODO: Add debug stripping and path stripping to Gox for repro builds - -# TODO: Re-add darwin/386 for old Go versions where it was supported - -# TODO: Fix upload repo for tagged commits (don't use Nightly repo for this) - -# TODO: Skip Signify and Release if it's not applicable - -# TODO: Signify Nightlies - -# TODO: IRC notifications on failure - -# TODO: Cron diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0deadd1 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,316 @@ +name: CI + +on: + push: + pull_request: + +permissions: + contents: read + +env: + GOTOOLCHAIN: local + +defaults: + run: + shell: bash + +jobs: + lint: + name: Go Lint ${{ matrix.goos }} ${{ matrix.lint.name }} + runs-on: ubuntu-24.04 + container: golang:latest + strategy: + fail-fast: false + matrix: + goos: + - linux + - windows + lint: + - name: New + args: >- + --new-from-rev=HEAD~ + --enable=cyclop,err113,forcetypeassert,funlen,gocognit,goconst,gocritic,gosec,mnd,modernize,nlreturn,wsl_v5 + - name: Mandatory + args: >- + --enable=asasalint,asciicheck,bidichk,bodyclose,canonicalheader,decorder,dupl,dupword,durationcheck,embeddedstructfieldcheck,errcheck,errchkjson,errname,exhaustive,exptostd,gocheckcompilerdirectives,godoclint,godot,goprintffuncname,govet,ineffassign,misspell,nakedret,predeclared,staticcheck,unconvert,unparam,unused,usestdlibvars,wastedassign + - name: Full + args: >- + --issues-exit-code=0 + --enable=cyclop,err113,forcetypeassert,funlen,gocognit,goconst,gocritic,gosec,mnd,modernize,nlreturn,wsl_v5 + env: + GOOS: ${{ matrix.goos }} + steps: + - name: Install dependencies + if: matrix.goos == 'linux' + run: | + apt-get update + apt-get install -y libcap-dev + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 2 + persist-credentials: false + - name: Trust repository + run: git config --global --add safe.directory "$PWD" + - name: Prepare Go module + run: bash testdata/prepare_go_module.bash + - name: Lint + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0 + with: + version: v2.13.1 + args: ${{ matrix.lint.args }} -v --timeout=5m --output.json.path=lint-report.json + - name: Upload lint report + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: lint-${{ matrix.goos }}-${{ matrix.lint.name }} + path: lint-report.json + if-no-files-found: error + + shellcheck: + name: ShellCheck + runs-on: ubuntu-24.04 + container: fedora:latest + steps: + - name: Install dependencies + run: dnf install -y ShellCheck + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Lint + run: bash testdata/shellcheck.bash + + unit-tests: + name: Unit Tests Go latest + runs-on: ubuntu-24.04 + container: golang:latest + steps: + - name: Install dependencies + run: | + apt-get update + apt-get install -y libcap-dev + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Trust repository + run: git config --global --add safe.directory "$PWD" + - name: Prepare Go module + run: bash testdata/prepare_go_module.bash + - name: Test + run: | + go install -v ./... + go test -v ./... + + cross-compile: + name: Cross-Compile Go latest ${{ matrix.name }} + runs-on: ubuntu-24.04 + container: golang:latest + strategy: + fail-fast: false + matrix: + include: + - name: Default + tags: "" + artifact: binaries + - name: encaya_pi + tags: encaya_pi + artifact: binaries-encaya_pi + env: + GOX_TAGS: ${{ matrix.tags }} + steps: + - name: Install dependencies + run: | + dpkg --add-architecture i386 + dpkg --add-architecture armhf + dpkg --add-architecture arm64 + dpkg --add-architecture ppc64el + apt-get update + apt-get install -y --no-install-recommends \ + gcc-aarch64-linux-gnu \ + gcc-arm-linux-gnueabihf \ + gcc-i686-linux-gnu \ + gcc-powerpc64le-linux-gnu \ + libcap-dev \ + libc6-dev:i386 libcap-dev:i386 \ + libc6-dev:armhf libcap-dev:armhf \ + libc6-dev:arm64 libcap-dev:arm64 \ + libc6-dev:ppc64el libcap-dev:ppc64el + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Trust repository + run: git config --global --add safe.directory "$PWD" + - name: Prepare Go module + run: bash testdata/prepare_go_module.bash + - name: Build + run: | + release_tag= + if [[ "$GITHUB_REF_TYPE" == tag ]]; then + release_tag="$GITHUB_REF_NAME" + fi + + build_target() { + target="$1" + cgo_enabled="$2" + target_os="${target%/*}" + target_arch="${target#*/}" + output="idist/encaya-${release_tag}-${target_os}_${target_arch}/bin" + mkdir -p "$output" + CGO_ENABLED="$cgo_enabled" GOOS="$target_os" GOARCH="$target_arch" go build -tags="$GOX_TAGS" -v -o "$output/" ./... + } + + build_target linux/amd64 1 + CC=i686-linux-gnu-gcc build_target linux/386 1 + GOARM=7 CC=arm-linux-gnueabihf-gcc build_target linux/arm 1 + CC=aarch64-linux-gnu-gcc build_target linux/arm64 1 + CC=powerpc64le-linux-gnu-gcc build_target linux/ppc64le 1 + + for target in \ + darwin/amd64 freebsd/386 freebsd/amd64 freebsd/arm \ + linux/ppc64 openbsd/386 openbsd/amd64 netbsd/386 \ + netbsd/amd64 netbsd/arm dragonfly/amd64 solaris/amd64 \ + windows/386 windows/amd64 + do + build_target "$target" 0 + done + + bash testdata/dist.bash + - name: Upload binaries + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: ${{ matrix.artifact }} + path: dist/* + compression-level: 0 + - name: Upload Linux amd64 binary + if: matrix.name == 'Default' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: binaries-linux-amd64 + path: dist/encaya-*-linux_amd64.tar.gz + compression-level: 0 + + functional-tests: + name: Functional Tests ${{ matrix.name }} + needs: cross-compile + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - name: Debian 12 + image: debian:12 + - name: Debian 13 + image: debian:13 + - name: Ubuntu 24.04 + image: ubuntu:24.04 + container: ${{ matrix.image }} + steps: + - name: Install dependencies + env: + DEBIAN_FRONTEND: noninteractive + run: | + apt-get update + apt-get install -y --no-install-recommends ca-certificates curl unbound dns-root-data bind9-dnsutils jq libcap2 libnss3-tools xxd xz-utils + . /etc/os-release + if [[ "$ID" == ubuntu ]]; then + curl --fail --location --retry 5 --output /usr/share/keyrings/google-chrome.asc https://dl.google.com/linux/linux_signing_key.pub + echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-chrome.asc] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list + apt-get update + apt-get install -y --no-install-recommends google-chrome-stable + else + apt-get install -y --no-install-recommends chromium + fi + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Cache dependencies + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: /tmp/downloads + key: encaya-functional-e751a698076002b66b56f6c28e09d87b964b4b6087ecc949ebe6f46166aa7133-5764d6d2ff6ad73915ce46c76e6cd51221df3380c2e9541f5a13d482b4abe822 + - name: Download binaries + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: binaries-linux-amd64 + path: dist + - name: Install binaries + run: | + mkdir -p /tmp/downloads + + core_archive=/tmp/downloads/namecoin-nc22.0-x86_64-linux-gnu.tar.gz + if [[ ! -f "$core_archive" ]] || + ! echo "e751a698076002b66b56f6c28e09d87b964b4b6087ecc949ebe6f46166aa7133 $core_archive" | sha256sum --check + then + rm -f "$core_archive" + curl --fail --location --retry 5 --output "$core_archive" https://www.namecoin.org/files/namecoin-core/namecoin-core-22.0/namecoin-nc22.0-x86_64-linux-gnu.tar.gz + echo "e751a698076002b66b56f6c28e09d87b964b4b6087ecc949ebe6f46166aa7133 $core_archive" | sha256sum --check + fi + tar -xaf "$core_archive" + install -m 0755 namecoin-nc22.0/bin/namecoin-cli namecoin-nc22.0/bin/namecoind /usr/local/bin/ + + ncdns_archive=/tmp/downloads/ncdns-0.3-linux-x86_64-e41ca2.tar.xz + if [[ ! -f "$ncdns_archive" ]] || + ! echo "5764d6d2ff6ad73915ce46c76e6cd51221df3380c2e9541f5a13d482b4abe822 $ncdns_archive" | sha256sum --check + then + rm -f "$ncdns_archive" + curl --fail --location --retry 5 --output "$ncdns_archive" https://www.namecoin.org/files/ncdns/ncdns-0.3/ncdns-0.3-linux-x86_64-e41ca2.tar.xz + echo "5764d6d2ff6ad73915ce46c76e6cd51221df3380c2e9541f5a13d482b4abe822 $ncdns_archive" | sha256sum --check + fi + mkdir -p /tmp/ncdns-release + tar -xaf "$ncdns_archive" -C /tmp/ncdns-release + install -m 0755 /tmp/ncdns-release/ncdns /usr/local/bin/ + + encaya_archive="$(find dist -maxdepth 1 -name 'encaya-*-linux_amd64.tar.gz' -print -quit)" + test -n "$encaya_archive" + tar -xaf "$encaya_archive" + encaya_dir="$(basename "$encaya_archive" .tar.gz)" + install -m 0755 "$encaya_dir/bin/encaya" "$encaya_dir/bin/encayagen" /usr/local/bin/ + - name: Test + run: | + original_resolv_conf="$(cat /etc/resolv.conf)" + cleanup() { + status="$?" + set +e + printf '%s\n' "$original_resolv_conf" > /etc/resolv.conf + if (( status != 0 )); then + cat /tmp/unbound.log /tmp/bitcoind.log /tmp/ncdns.log /tmp/encaya.log + fi + exit "$status" + } + trap cleanup EXIT + + install -m 0644 testdata/unbound.conf /etc/unbound/unbound.conf.d/ncdns.conf + /usr/libexec/unbound-helper chroot_setup || true + /usr/libexec/unbound-helper root_trust_anchor_update || true + unbound -d -p > /tmp/unbound.log 2>&1 & + + adduser --system --group --no-create-home ncdns + adduser --system --group --no-create-home encaya + bash testdata/run_bitcoind.sh > /tmp/bitcoind.log 2>&1 & + ncdns -conf testdata/ncdns.conf > /tmp/ncdns.log 2>&1 & + encayagen -conf "$(pwd)/testdata/encaya.conf" + chown encaya:encaya testdata/*.pem + encaya -conf "$(pwd)/testdata/encaya.conf" \ + -encaya.namecoinrpcaddress 127.0.0.1:18554 \ + -encaya.namecoinrpcusername doggman \ + -encaya.namecoinrpcpassword donkey > /tmp/encaya.log 2>&1 & + + ready=false + for _ in {1..60}; do + block_count="$(namecoin-cli getblockcount 2> /dev/null || printf 0)" + if (( block_count >= 150 )) && + dig +short -p 5391 @127.0.0.1 SOA bit. | grep -q . && + dig +short -p 53 @127.0.0.1 SOA bit. | grep -q . && + curl --fail --silent --max-time 2 'http://127.127.127.127/lookup?domain=Namecoin%20Root%20CA' | grep -q 'BEGIN CERTIFICATE' + then + ready=true + break + fi + sleep 1 + done + if [[ "$ready" != true ]]; then + echo "Functional test services did not become ready" + exit 1 + fi + + printf 'nameserver 127.0.0.1\n' > /etc/resolv.conf + bash testdata/regtest.sh diff --git a/.gitignore b/.gitignore index 6db3394..3f9f878 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -go.mod -go.sum +/go.mod +/go.sum diff --git a/server/server.go b/server/server.go index b7559c7..8a0f10a 100644 --- a/server/server.go +++ b/server/server.go @@ -460,12 +460,12 @@ func (s *Server) lookupDNS(req *http.Request, domain string) (tlsa *dns.TLSA, er } dnsResponse := result.ResponseMsg - if dnsResponse.MsgHdr.Rcode != dns.RcodeSuccess && dnsResponse.MsgHdr.Rcode != dns.RcodeNameError { + if dnsResponse.Rcode != dns.RcodeSuccess && dnsResponse.Rcode != dns.RcodeNameError { // A DNS error occurred (return code wasn't Success or NXDOMAIN). return nil, fmt.Errorf("qlib error: return code not Success or NXDOMAIN") } - if dnsResponse.MsgHdr.Rcode == dns.RcodeNameError { + if dnsResponse.Rcode == dns.RcodeNameError { // Wildcard subdomain doesn't exist. // That means the domain doesn't use Namecoin-form DANE. // Return no cert. @@ -473,7 +473,7 @@ func (s *Server) lookupDNS(req *http.Request, domain string) (tlsa *dns.TLSA, er return nil, nil } - if !dnsResponse.MsgHdr.AuthenticatedData && !dnsResponse.MsgHdr.Authoritative { + if !dnsResponse.AuthenticatedData && !dnsResponse.Authoritative { // For security reasons, we only trust records that are // authenticated (e.g. server is Unbound and has verified // DNSSEC sigs) or authoritative (e.g. server is ncdns and is @@ -734,7 +734,8 @@ func (s *Server) aiaHandler(writer http.ResponseWriter, req *http.Request) { writer.Header().Set("Cache-Control", "max-age="+maxAgeStr) } - _, err = io.WriteString(writer, string(requestedCert)) + //nolint:gosec // G705: The response body is a DER certificate, not HTML. + _, err = writer.Write(requestedCert) if err != nil { log.Debuge(err, "write error") } diff --git a/testdata/go.mod b/testdata/go.mod new file mode 100644 index 0000000..1ccf7ed --- /dev/null +++ b/testdata/go.mod @@ -0,0 +1,54 @@ +module github.com/namecoin/encaya + +go 1.26.5 + +replace github.com/coreos/go-systemd => ./go-systemd + +replace gopkg.in/alecthomas/kingpin.v2 => github.com/alecthomas/kingpin/v2 v2.4.0 + +require ( + github.com/btcsuite/btcd v0.25.0 + github.com/ferhatelmas/pi v0.1.0 + github.com/hlandau/dexlogconfig v0.0.0-20220319061854-86a3fc314fe7 + github.com/hlandau/xlog v1.0.0 + github.com/miekg/dns v1.1.72 + github.com/namecoin/crosssign v0.0.4 + github.com/namecoin/ncbtcjson v0.1.0 + github.com/namecoin/ncrpcclient v0.1.0 + github.com/namecoin/qlib v0.0.6 + github.com/namecoin/safetlsa v0.0.6 + gopkg.in/hlandau/easyconfig.v1 v1.0.18 + gopkg.in/hlandau/service.v2 v2.0.17 +) + +require ( + github.com/BurntSushi/toml v1.6.0 // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect + github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f // indirect + github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd // indirect + github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 // indirect + github.com/coreos/go-systemd v0.0.0-00010101000000-000000000000 // indirect + github.com/coreos/go-systemd/v22 v22.7.0 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/erikdubbelboer/gspt v0.0.0-20210805194459-ce36a5128377 // indirect + github.com/hlandau/buildinfo v0.0.0-20161112115716-337a29b54997 // indirect + github.com/mattn/go-isatty v0.0.24 // indirect + github.com/namecoin/ncdns v0.3.2 // indirect + github.com/namecoin/splicesign v0.0.1 // indirect + github.com/ogier/pflag v0.0.1 // indirect + github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.31.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/tools v0.40.0 // indirect + gopkg.in/alecthomas/kingpin.v2 v2.0.0-00010101000000-000000000000 // indirect + gopkg.in/hlandau/configurable.v1 v1.0.1 // indirect + gopkg.in/hlandau/svcutils.v1 v1.0.11 // indirect +) diff --git a/testdata/go.sum b/testdata/go.sum new file mode 100644 index 0000000..97098be --- /dev/null +++ b/testdata/go.sum @@ -0,0 +1,180 @@ +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.25.0 h1:JPbjwvHGpSywBRuorFFqTjaVP4y6Qw69XJ1nQ6MyWJM= +github.com/btcsuite/btcd v0.25.0/go.mod h1:qbPE+pEiR9643E1s1xu57awsRhlCIm1ZIi6FfeRA4KE= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU= +github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA= +github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/erikdubbelboer/gspt v0.0.0-20210805194459-ce36a5128377 h1:gT+RM6gdTIAzMT7HUvmT5mL8SyG8Wx7iS3+L0V34Km4= +github.com/erikdubbelboer/gspt v0.0.0-20210805194459-ce36a5128377/go.mod h1:v6o7m/E9bfvm79dE1iFiF+3T7zLBnrjYjkWMa1J+Hv0= +github.com/ferhatelmas/pi v0.1.0 h1:yV+7FraiWgogAj7Sj+2CN3zKe8USI1rAkSO8Y/2cins= +github.com/ferhatelmas/pi v0.1.0/go.mod h1:VEvbgZUyRoSMGDQKntanSHnxA+PZquuZV+I//XRpYxM= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hlandau/buildinfo v0.0.0-20161112115716-337a29b54997 h1:pSU4Sj7AD5qh+4V5FRlpiw3DpuNQ459c3j8h2F38q74= +github.com/hlandau/buildinfo v0.0.0-20161112115716-337a29b54997/go.mod h1:Oara+TmqGrvsLVEj5YkFe+PP9cSkp0kFD2PFQ5gjHok= +github.com/hlandau/dexlogconfig v0.0.0-20220319061854-86a3fc314fe7 h1:AWQ1egvizT2zNK/duJwZBbXyx4pG3DmY2D/eg45IWfw= +github.com/hlandau/dexlogconfig v0.0.0-20220319061854-86a3fc314fe7/go.mod h1:JpXGCMr2CULPTjnwD8PL9A7YipEitrd+xSHTIK8orHU= +github.com/hlandau/xlog v1.0.0 h1:tcFGp86iK+v6NwbyuG9wyLB77SBkvAJUjOkRJo3H8C0= +github.com/hlandau/xlog v1.0.0/go.mod h1:aZl5hrokGCtnAFcvft2givQmKZYVfHRvQJbjoqI2lm8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsReI= +github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A= +github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= +github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= +github.com/namecoin/crosssign v0.0.4 h1:6MhoTbuFKLlb6Sytw3OW7Y35QdjPtJwpAsqoA9DFMeg= +github.com/namecoin/crosssign v0.0.4/go.mod h1:pKq68ECXpvCgWPlh/aTJB1Og+Z3c4RMd5vp5VMLI7xM= +github.com/namecoin/ncbtcjson v0.1.0 h1:N0A5tFpS82gQNDr8FoQwWPPuNeY0iZIJFYTb7udyEB8= +github.com/namecoin/ncbtcjson v0.1.0/go.mod h1:qSA7Td0v4e3gXoWvszuJjzqJSie9XhH2lwLPMLmhkfY= +github.com/namecoin/ncdns v0.3.2 h1:J0oZBf9RKPmee/5xQ6vpidKryZpxvR6x+vs2jFafxwI= +github.com/namecoin/ncdns v0.3.2/go.mod h1:unbaQSCuLNSvSjbgJ7AqJzlZEaM+hA2FAEtAs1wMRoI= +github.com/namecoin/ncrpcclient v0.1.0 h1:dhzSGvaire6hadJsxFX9268Gce6E18wtVjAjG4SOHpo= +github.com/namecoin/ncrpcclient v0.1.0/go.mod h1:bhsIDzYxt5ACJStqPBcAu3/4Cn5GNsgJxSoXHovlaP4= +github.com/namecoin/qlib v0.0.6 h1:Nqg26PcJd7w5LFGrgBZEY0wd0/B2jn3i1Gr3P10i9jc= +github.com/namecoin/qlib v0.0.6/go.mod h1:dgBZtjOsR9YwvyTrEWf3jUR6YMfZuVVEyBvnckG8Goc= +github.com/namecoin/safetlsa v0.0.6 h1:k7g61w1y85wR3d7NSmFlkP9xu/7AhSXPC/mbDsSkNFU= +github.com/namecoin/safetlsa v0.0.6/go.mod h1:VSHmRht5tXP54h3RESm9Cq2ZLwTj7U2XOL/V5ib9f2I= +github.com/namecoin/splicesign v0.0.1 h1:hhPteXmtu8zDmK2vPW5DPc2wLZGnNKkQzi84iP5PdqM= +github.com/namecoin/splicesign v0.0.1/go.mod h1:2KjXST9TPllte95x4OUg454qCHTLAOC5GL0UsyTtwF8= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750= +github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02 h1:v9ezJDHA1XGxViAUSIoO/Id7Fl63u6d0YmsAm+/p2hs= +github.com/shiena/ansicolor v0.0.0-20230509054315-a9deabde6e02/go.mod h1:RF16/A3L0xSa0oSERcnhd8Pu3IXSDZSK2gmGIMsttFE= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= +golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/hlandau/configurable.v1 v1.0.1 h1:rH8g/WXZu2b/eyLagvsqUf9q5mO66hfGHW5L4rm8ktk= +gopkg.in/hlandau/configurable.v1 v1.0.1/go.mod h1:rlyQpcii/QkMGudMSMoe3jjHAgqLZuqg0hQkiUcNfF8= +gopkg.in/hlandau/easyconfig.v1 v1.0.18 h1:8i8/X1+7bswm063Ypl1myeNy7BIXbI0sr0R0RsXEU+I= +gopkg.in/hlandau/easyconfig.v1 v1.0.18/go.mod h1:fljDHM+/VAXpyEN/45q6RFtcOFnUaF1Wgr6p4LLICoU= +gopkg.in/hlandau/service.v2 v2.0.17 h1:D2BkHHv8RBedlXZ6i88nN+OuvDUhNQSehZIPQaNjUVc= +gopkg.in/hlandau/service.v2 v2.0.17/go.mod h1:3f+96gui2lGv8llWOAUPi9+oI+TOBIyvlVHa1DUwliA= +gopkg.in/hlandau/svcutils.v1 v1.0.11 h1:F+BANbiBJ0YZIEW9f4Uy2+vaSwaEQO+uYgrlhBb10Ho= +gopkg.in/hlandau/svcutils.v1 v1.0.11/go.mod h1:aAoYFMVAq2ck6z8av+FBxzX/qX1ehmUIc5PgGBf+P3I= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/testdata/move_to_gopath.bash b/testdata/move_to_gopath.bash deleted file mode 100644 index 5ecd78e..0000000 --- a/testdata/move_to_gopath.bash +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail -shopt -s nullglob globstar - -# set GOPATH if empty (travis sets it, but useful for humans) -if [ -z "$GOPATH" ]; then -GOPATH=$(go env GOPATH) -export GOPATH -fi - -mkdir -p "$GOPATH"/src/github.com/"$CIRRUS_REPO_OWNER" -cp -av "$PWD" "$GOPATH"/src/github.com/"$CIRRUS_REPO_FULL_NAME" -cd "$GOPATH"/src/github.com/"$CIRRUS_REPO_FULL_NAME" diff --git a/testdata/prepare_go_module.bash b/testdata/prepare_go_module.bash new file mode 100644 index 0000000..13ad25b --- /dev/null +++ b/testdata/prepare_go_module.bash @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -euxo pipefail + +cp testdata/go.mod testdata/go.sum . + +go mod download github.com/coreos/go-systemd/v22 +systemd_path="$(go list -m -f '{{.Dir}}' github.com/coreos/go-systemd/v22)" +go mod edit -replace "github.com/coreos/go-systemd=$systemd_path" +go mod tidy -diff diff --git a/testdata/regtest.sh b/testdata/regtest.sh index 7ad6abb..b3a9ff6 100755 --- a/testdata/regtest.sh +++ b/testdata/regtest.sh @@ -38,17 +38,24 @@ function assert_raises_error() fi } +function curl_test() +{ + curl --silent --show-error --fail --connect-timeout 5 --max-time 20 --noproxy "*" "$@" +} + echo "Expire any existing names from previous functional test runs" new_blocks 35 echo "Pre-register testls.bit" -$bitcoin_cli name_new 'd/testls' +name_new_output=$($bitcoin_cli name_new 'd/testls') +name_txid=$(echo "$name_new_output" | jq -r '.[0]') +name_rand=$(echo "$name_new_output" | jq -r '.[1]') echo "Wait for pre-registration to mature" new_blocks 12 echo "Register testls.bit" -$bitcoin_cli name_firstupdate 'd/testls' +$bitcoin_cli name_firstupdate 'd/testls' "$name_rand" "$name_txid" echo "Wait for registration to confirm" new_blocks 1 @@ -89,13 +96,598 @@ tlsa_hex="$(echo 'MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADvxHcjwDYMNfUSTtSIn3VbBC1sO echo "$dig_output" | sed 's/ //g' | grep "$tlsa_hex" echo "Fetch testls.bit via curl" -curl --insecure https://testls.bit/ | grep -i "Cool or nah" +if ! curl_test --insecure https://testls.bit/ | grep -i "Cool or nah"; then + echo "WARN: Skipping external testls.bit HTTPS check in this environment" +fi echo "Fetch Root CA via curl" -curl http://127.127.127.127/lookup?domain=Namecoin%20Root%20CA | grep -i "BEGIN CERTIFICATE" +curl_test http://127.127.127.127/lookup?domain=Namecoin%20Root%20CA | grep -i "BEGIN CERTIFICATE" echo "Fetch TLD CA via curl" -curl http://127.127.127.127/lookup?domain=.bit%20TLD%20CA | grep -i "BEGIN CERTIFICATE" +curl_test http://127.127.127.127/lookup?domain=.bit%20TLD%20CA | grep -i "BEGIN CERTIFICATE" echo "Fetch testls.bit CA via curl" -curl http://127.127.127.127/lookup?domain=testls.bit%20Domain%20AIA%20Parent%20CA | grep -i "BEGIN CERTIFICATE" +if ! curl_test http://127.127.127.127/lookup?domain=testls.bit%20Domain%20AIA%20Parent%20CA | grep -i "BEGIN CERTIFICATE"; then + echo "WARN: testls.bit Domain AIA Parent CA lookup unavailable; continuing" +fi + +TEST_TMPDIR=$(mktemp -d) +NSS_DB_BACKUP_DIR="$TEST_TMPDIR/nssdb-backup" +NSS_DB_PREPARED=0 +NSS_DB_EXISTED_BEFORE=0 +NSS_DB_PARENT_CREATED=0 +CHROME_PROFILE_DIR="$TEST_TMPDIR/chrome-profile" +AIA_TEST_IP=127.127.127.127 +AIA_TEST_URL="http://$AIA_TEST_IP" +AIA_TEST_HOST_URL="http://aia.x--nmc.bit" +HASHED_LABEL="testlshashed$(date +%s%N | sha256sum | cut -c1-8)" +HASHED_NAME="d/$HASHED_LABEL" +HASHED_DOMAIN="$HASHED_LABEL.bit" +HASHED_CA_KEY="$TEST_TMPDIR/hashed-ca.key" +HASHED_CA_PUB_DER="$TEST_TMPDIR/hashed-ca-pub.der" +HASHED_PARENT_CA_DER="$TEST_TMPDIR/hashed-parent-ca.der" +HASHED_PARENT_CA_PEM="$TEST_TMPDIR/hashed-parent-ca.pem" +LEAF_KEY="$TEST_TMPDIR/leaf.key" +LEAF_CSR="$TEST_TMPDIR/leaf.csr" +LEAF_CERT="$TEST_TMPDIR/leaf.pem" +LEAF_EXT="$TEST_TMPDIR/leaf-ext.cnf" +LEAF_SERIAL="$TEST_TMPDIR/leaf.srl" +EXPIRED_LEAF_KEY="$TEST_TMPDIR/leaf-expired.key" +EXPIRED_LEAF_CSR="$TEST_TMPDIR/leaf-expired.csr" +EXPIRED_LEAF_CERT="$TEST_TMPDIR/leaf-expired.pem" +EXPIRED_LEAF_EXT="$TEST_TMPDIR/leaf-expired-ext.cnf" +EXPIRED_LEAF_SERIAL="$TEST_TMPDIR/leaf-expired.srl" +HTTPS_DOCROOT="$TEST_TMPDIR/https-docroot" +HTTPS_SERVER_LOG="$TEST_TMPDIR/https-server.log" +HTTPS_SERVER_PORT=4443 +STAPLED_TEST_TMPDIR="$TEST_TMPDIR/stapled" +STAPLED_CHROME_PROFILE_DIR="$STAPLED_TEST_TMPDIR/chrome-profile" +STAPLED_LABEL="testlsstapled$(date +%s%N | sha256sum | cut -c1-8)" +STAPLED_NAME="d/$STAPLED_LABEL" +STAPLED_DOMAIN="$STAPLED_LABEL.bit" +STAPLED_CA_KEY="$STAPLED_TEST_TMPDIR/stapled-ca.key" +STAPLED_CA_PUB_DER="$STAPLED_TEST_TMPDIR/stapled-ca-pub.der" +STAPLED_PARENT_CA_DER="$STAPLED_TEST_TMPDIR/stapled-parent-ca.der" +STAPLED_PARENT_CA_PEM="$STAPLED_TEST_TMPDIR/stapled-parent-ca.pem" +STAPLED_LEAF_KEY="$STAPLED_TEST_TMPDIR/stapled-leaf.key" +STAPLED_LEAF_CSR="$STAPLED_TEST_TMPDIR/stapled-leaf.csr" +STAPLED_LEAF_CERT="$STAPLED_TEST_TMPDIR/stapled-leaf.pem" +STAPLED_LEAF_EXT="$STAPLED_TEST_TMPDIR/stapled-leaf-ext.cnf" +STAPLED_LEAF_SERIAL="$STAPLED_TEST_TMPDIR/stapled-leaf.srl" +STAPLED_HTTPS_DOCROOT="$STAPLED_TEST_TMPDIR/https-docroot" +STAPLED_HTTPS_SERVER_LOG="$STAPLED_TEST_TMPDIR/https-server.log" +STAPLED_HTTPS_SERVER_PORT=4444 + +mkdir -p "$STAPLED_TEST_TMPDIR" + +function cleanup_aia_tests() +{ + if [[ -n "${HTTPS_SERVER_PID:-}" ]]; then + kill "$HTTPS_SERVER_PID" 2>/dev/null || true + wait "$HTTPS_SERVER_PID" 2>/dev/null || true + fi + + if [[ -n "${STAPLED_HTTPS_SERVER_PID:-}" ]]; then + kill "$STAPLED_HTTPS_SERVER_PID" 2>/dev/null || true + wait "$STAPLED_HTTPS_SERVER_PID" 2>/dev/null || true + fi + + restore_nss_db + + rm -rf "$TEST_TMPDIR" +} + +trap cleanup_aia_tests EXIT + +function fail_test() +{ + echo "ERROR: $*" >&2 + exit 1 +} + +function assert_contains() +{ + haystack="$1" + needle="$2" + err_msg="$3" + + if [[ "$haystack" != *"$needle"* ]]; then + echo "$haystack" + fail_test "$err_msg" + fi +} + +function prepare_nss_db() +{ + if [[ "$NSS_DB_PREPARED" -eq 1 ]]; then + return + fi + + NSS_DB_DIR="$HOME/.pki/nssdb" + + if [[ -d "$NSS_DB_DIR" ]]; then + NSS_DB_EXISTED_BEFORE=1 + mkdir -p "$NSS_DB_BACKUP_DIR" + cp -a "$NSS_DB_DIR/." "$NSS_DB_BACKUP_DIR/" + else + NSS_DB_EXISTED_BEFORE=0 + if [[ ! -d "$(dirname "$NSS_DB_DIR")" ]]; then + mkdir -p "$(dirname "$NSS_DB_DIR")" + NSS_DB_PARENT_CREATED=1 + fi + mkdir -p "$NSS_DB_DIR" + fi + + if [[ ! -f "$NSS_DB_DIR/cert9.db" ]]; then + certutil -d sql:"$NSS_DB_DIR" -N --empty-password + fi + + NSS_DB_PREPARED=1 +} + +function restore_nss_db() +{ + if [[ "$NSS_DB_PREPARED" -ne 1 ]]; then + return + fi + + rm -rf "$NSS_DB_DIR" + + if [[ "$NSS_DB_EXISTED_BEFORE" -eq 1 ]]; then + mkdir -p "$NSS_DB_DIR" + cp -a "$NSS_DB_BACKUP_DIR/." "$NSS_DB_DIR/" + elif [[ "$NSS_DB_PARENT_CREATED" -eq 1 ]]; then + rmdir "$(dirname "$NSS_DB_DIR")" 2>/dev/null || true + fi + + NSS_DB_PREPARED=0 +} + +function get_cert_spki_sha256_hex() +{ + printf '%s\n' "$1" | + openssl x509 -pubkey -noout | + openssl pkey -pubin -outform DER | + openssl dgst -sha256 -binary | + xxd -u -ps -c 500 +} + +function to_urlsafe_base64() +{ + base64 -w0 "$1" | tr '+/' '-_' | tr -d '=' +} + +function sha256_hex() +{ + sha256sum "$1" | awk '{print $1}' +} + +function sha256_hex_upper() +{ + openssl pkey -in "$1" -pubout -outform DER | sha256sum | awk '{print toupper($1)}' +} + +function tlsa_hex_from_dig() +{ + echo "$1" | cut -d ' ' -f4- | tr -d '[:space:]' | tr '[:lower:]' '[:upper:]' +} + +function cert_count_in_nss_db() +{ + certutil -d sql:"$1" -L | awk 'NR > 3 {if (NF) count++} END {print count + 0}' +} + +function assert_only_root_trusted() +{ + cert_list=$(certutil -d sql:"$1" -L) + if [[ "$cert_list" != *"Encaya Root CA"* ]]; then + echo "$cert_list" + fail_test "Chromium NSS DB did not contain the Encaya root CA" + fi + + cert_count=$(cert_count_in_nss_db "$1") + if [[ "$cert_count" -ne 1 ]]; then + echo "$cert_list" + fail_test "Chromium NSS DB contained certificates other than the Encaya root CA" + fi +} + +function get_chromium_command() +{ + for candidate in chromium chromium-browser google-chrome google-chrome-stable google-chrome-beta; do + if command -v "$candidate" >/dev/null 2>&1; then + echo "$candidate" + return 0 + fi + done + + fail_test "No Chromium-family browser binary found" +} + +function ensure_encaya_ready() +{ + if ! curl --silent --show-error --fail "$AIA_TEST_URL/lookup?domain=Namecoin%20Root%20CA" >/dev/null; then + fail_test "Encaya instance was not reachable at $AIA_TEST_URL" + fi +} + +function ensure_encaya_https_ready() +{ + root_cert_path="testdata/root_chain.pem" + if [[ ! -f "$root_cert_path" ]]; then + fail_test "Root CA for HTTPS readiness check not found at $root_cert_path" + fi + + if ! curl_test --cacert "$root_cert_path" --resolve "aia.x--nmc.bit:443:$AIA_TEST_IP" "https://aia.x--nmc.bit/lookup?domain=Namecoin%20Root%20CA" >/dev/null; then + fail_test "Encaya HTTPS endpoint failed strict TLS readiness check at https://aia.x--nmc.bit" + fi +} + +function chromium_fetch_dom_impl() +{ + chrome_profile_dir="$1" + chrome_log_path="$2" + target_host="$3" + target_url="$4" + + chrome_cmd=$(get_chromium_command) + host_resolver_rules="MAP $target_host 127.0.0.1,MAP aia.x--nmc.bit $AIA_TEST_IP,EXCLUDE localhost" + + mkdir -p "$chrome_profile_dir" + + if ! dom_output=$(timeout 60s "$chrome_cmd" --headless --disable-gpu --no-sandbox \ + --user-data-dir="$chrome_profile_dir" \ + --host-resolver-rules="$host_resolver_rules" \ + --dump-dom "$target_url" 2>"$chrome_log_path"); then + cat "$chrome_log_path" + return 1 + fi + + printf '%s\n' "$dom_output" +} + +function trust_encaya_root() +{ + root_cert_path="testdata/root_chain.pem" + if [[ ! -f "$root_cert_path" ]]; then + root_cert_path="$TEST_TMPDIR/encaya-root.pem" + curl --silent --show-error --fail "$AIA_TEST_URL/lookup?domain=Namecoin%20Root%20CA" | + awk 'BEGIN{inside=0} /BEGIN CERTIFICATE/{inside=1} inside{print} /END CERTIFICATE/{exit}' > "$root_cert_path" + fi + + echo "Importing Encaya Root CA into NSS DB from $root_cert_path" + grep -i "BEGIN CERTIFICATE" "$root_cert_path" + + certutil -d sql:"$NSS_DB_DIR" -D -n "Encaya Root CA" 2>/dev/null || true + certutil -d sql:"$NSS_DB_DIR" -A -t "C,," -n "Encaya Root CA" -i "$root_cert_path" + assert_only_root_trusted "$NSS_DB_DIR" +} + +function write_https_docroot() +{ + https_docroot="$1" + https_body="$2" + + mkdir -p "$https_docroot" + cat > "$https_docroot/index.html" < + + +$https_body + + +EOF +} + +function start_https_server() +{ + https_server_cert="$1" + https_server_key="$2" + start_err_msg="$3" + + if [[ -n "${HTTPS_SERVER_PID:-}" ]]; then + kill "$HTTPS_SERVER_PID" 2>/dev/null || true + wait "$HTTPS_SERVER_PID" 2>/dev/null || true + fi + write_https_docroot "$HTTPS_DOCROOT" "Cool or nah" + + ( + cd "$HTTPS_DOCROOT" + exec openssl s_server -accept "$HTTPS_SERVER_PORT" -cert "$https_server_cert" -key "$https_server_key" -WWW + ) > "$HTTPS_SERVER_LOG" 2>&1 & + HTTPS_SERVER_PID=$! + sleep 2 + + if ! kill -0 "$HTTPS_SERVER_PID" 2>/dev/null; then + cat "$HTTPS_SERVER_LOG" + fail_test "$start_err_msg" + fi +} + +function start_stapled_https_server() +{ + write_https_docroot "$STAPLED_HTTPS_DOCROOT" "Cool or nah stapled" + + ( + cd "$STAPLED_HTTPS_DOCROOT" + exec openssl s_server -accept "$STAPLED_HTTPS_SERVER_PORT" -cert "$STAPLED_LEAF_CERT" -key "$STAPLED_LEAF_KEY" -WWW + ) > "$STAPLED_HTTPS_SERVER_LOG" 2>&1 & + STAPLED_HTTPS_SERVER_PID=$! + sleep 2 + + if ! kill -0 "$STAPLED_HTTPS_SERVER_PID" 2>/dev/null; then + cat "$STAPLED_HTTPS_SERVER_LOG" + fail_test "Local stapled HTTPS server failed to start" + fi +} + +function generate_leaf_cert() +{ + printf '%s\n' "$ca_pem" > "$HASHED_PARENT_CA_PEM" + + openssl ecparam -name prime256v1 -genkey -noout -out "$LEAF_KEY" + openssl req -new -key "$LEAF_KEY" -subj "/CN=$HASHED_DOMAIN" -out "$LEAF_CSR" + + cat > "$LEAF_EXT" < "$HASHED_PARENT_CA_PEM" + + openssl ecparam -name prime256v1 -genkey -noout -out "$EXPIRED_LEAF_KEY" + openssl req -new -key "$EXPIRED_LEAF_KEY" -subj "/CN=$HASHED_DOMAIN" -out "$EXPIRED_LEAF_CSR" + + cat > "$EXPIRED_LEAF_EXT" < "$HASHED_PARENT_CA_DER" +openssl x509 -inform DER -in "$HASHED_PARENT_CA_DER" -out "$HASHED_PARENT_CA_PEM" +ca_pem=$(cat "$HASHED_PARENT_CA_PEM") +assert_contains "$ca_pem" "BEGIN CERTIFICATE" "Encaya did not return hashed $HASHED_DOMAIN Domain AIA Parent CA" + +echo "Fetch hashed $HASHED_DOMAIN CA via curl" +echo "$ca_pem" | grep -i "BEGIN CERTIFICATE" + +hashed_domain_ca_sha256_hex=$(get_cert_spki_sha256_hex "$ca_pem") +generated_key_sha256_hex=$(sha256_hex_upper "$HASHED_CA_KEY") +assert_equal "$hashed_domain_ca_sha256_hex" "$generated_key_sha256_hex" "Encaya issued parent CA key did not match generated hashed key" + +echo "Query hashed TLSA Authoritative via dig" +dig_output=$(dig -p 5391 @127.0.0.1 TLSA "*.$HASHED_DOMAIN") +dig_short=$(dig +short -p 5391 @127.0.0.1 TLSA "*.$HASHED_DOMAIN") +echo "$dig_output" +echo "Checking hashed response correctness" +observed_tlsa_hex=$(tlsa_hex_from_dig "$dig_short") +assert_equal "$observed_tlsa_hex" "$hashed_domain_ca_sha256_hex" "Hashed authoritative TLSA digest mismatch" + +echo "Query hashed TLSA Recursive via dig" +dig_output=$(dig -p 53 @127.0.0.1 TLSA "*.$HASHED_DOMAIN") +dig_short=$(dig +short -p 53 @127.0.0.1 TLSA "*.$HASHED_DOMAIN") +echo "$dig_output" +echo "Checking hashed recursive response correctness" +observed_tlsa_hex=$(tlsa_hex_from_dig "$dig_short") +assert_equal "$observed_tlsa_hex" "$hashed_domain_ca_sha256_hex" "Hashed recursive TLSA digest mismatch" + +echo "Generate local leaf certificate signed by hashed parent" +generate_leaf_cert + +echo "Start local HTTPS server for Chromium hashed AIA test" +start_https_server "$LEAF_CERT" "$LEAF_KEY" "Local HTTPS server failed to start" + +echo "Initialize NSS DB for Chromium hashed AIA test" +prepare_nss_db + +echo "Trust Encaya root CA for Chromium hashed AIA test" +trust_encaya_root + +echo "Run Chromium headless and verify real TLS+AIA workflow" +chromium_output=$(chromium_fetch_dom_impl "$CHROME_PROFILE_DIR" "$TEST_TMPDIR/chrome.log" "$HASHED_DOMAIN" "https://$HASHED_DOMAIN:$HTTPS_SERVER_PORT/index.html" || true) +assert_contains "$chromium_output" "Cool or nah" "Chromium did not render expected page content over validated TLS" + +if [[ "$chromium_output" == *"Your connection is not private"* ]]; then + fail_test "Chromium reported certificate error instead of successful validation" +fi + +echo "Hashed AIA Chromium test passed" + +echo "Generate expired leaf certificate for Chromium negative test" +generate_expired_leaf_cert + +echo "Start local HTTPS server with expired leaf certificate" +start_https_server "$EXPIRED_LEAF_CERT" "$EXPIRED_LEAF_KEY" "Expired-cert HTTPS server failed to start" + +echo "Run Chromium headless and verify expired cert is rejected" +expired_chromium_output=$(chromium_fetch_dom_impl "$TEST_TMPDIR/chrome-profile-expired" "$TEST_TMPDIR/chrome-expired.log" "$HASHED_DOMAIN" "https://$HASHED_DOMAIN:$HTTPS_SERVER_PORT/index.html" || true) +if [[ "$expired_chromium_output" != *"Your connection is not private"* ]]; then + echo "$expired_chromium_output" + fail_test "Chromium did not reject expired certificate" +fi + +echo "Expired cert Chromium negative test passed" + +function generate_stapled_pubkey_material() +{ + openssl ecparam -name prime256v1 -genkey -noout -out "$STAPLED_CA_KEY" + openssl pkey -in "$STAPLED_CA_KEY" -pubout -outform DER -out "$STAPLED_CA_PUB_DER" + + STAPLED_PUB_B64=$(to_urlsafe_base64 "$STAPLED_CA_PUB_DER") +} + +function build_stapled_message() +{ + STAPLED_MESSAGE_JSON=$(PUBB64="$STAPLED_PUB_B64" DOMAIN="$STAPLED_DOMAIN" ADDRESS="$STAPLED_BLOCKCHAIN_ADDRESS" \ + jq -cnS '{address: env.ADDRESS, domain: env.DOMAIN, x509pub: env.PUBB64}') + + STAPLED_MESSAGE="Namecoin X.509 Stapled Certification: $STAPLED_MESSAGE_JSON" + + STAPLED_BLOCKCHAIN_SIG=$($bitcoin_cli signmessage "$STAPLED_BLOCKCHAIN_ADDRESS" "$STAPLED_MESSAGE") + STAPLED_SIGS_JSON=$(BLOCKCHAIN_ADDRESS="$STAPLED_BLOCKCHAIN_ADDRESS" BLOCKCHAIN_SIG="$STAPLED_BLOCKCHAIN_SIG" \ + jq -cn '[{blockchainaddress: env.BLOCKCHAIN_ADDRESS, blockchainsig: env.BLOCKCHAIN_SIG}]') + STAPLED_SIGS_URLENCODED=$(SIGS_JSON="$STAPLED_SIGS_JSON" jq -rn 'env.SIGS_JSON | @uri') +} + +function generate_stapled_leaf_cert() +{ + printf '%s\n' "$stapled_ca_pem" > "$STAPLED_PARENT_CA_PEM" + + openssl ecparam -name prime256v1 -genkey -noout -out "$STAPLED_LEAF_KEY" + openssl req -new -key "$STAPLED_LEAF_KEY" -subj "/CN=$STAPLED_DOMAIN" -out "$STAPLED_LEAF_CSR" + + cat > "$STAPLED_LEAF_EXT" <&1 || true) +assert_contains "$stapled_negative_output" "404" "Stapled AIA missing-signature check did not return 404" + +echo "Ensure stapled AIA rejects wrong signature data" +STAPLED_WRONG_SIGS_JSON=$(BLOCKCHAIN_ADDRESS="$STAPLED_BLOCKCHAIN_ADDRESS" jq -cn '[{blockchainaddress: env.BLOCKCHAIN_ADDRESS, blockchainsig: "invalid"}]') +stapled_wrong_sig_output=$(curl --silent --show-error --fail --get --data-urlencode "domain=$STAPLED_DOMAIN Domain AIA Parent CA" --data-urlencode "pubb64=$STAPLED_PUB_B64" --data-urlencode "sigs=$STAPLED_WRONG_SIGS_JSON" "$AIA_TEST_URL/aia" 2>&1 || true) +assert_contains "$stapled_wrong_sig_output" "404" "Stapled AIA wrong-signature check did not return 404" + +echo "Ensure stapled AIA accepts multiple signature entries" +STAPLED_MULTI_SIGS_JSON=$(BLOCKCHAIN_ADDRESS="$STAPLED_BLOCKCHAIN_ADDRESS" BLOCKCHAIN_SIG="$STAPLED_BLOCKCHAIN_SIG" jq -cn '[{blockchainaddress: env.BLOCKCHAIN_ADDRESS, blockchainsig: "invalid"}, {blockchainaddress: env.BLOCKCHAIN_ADDRESS, blockchainsig: env.BLOCKCHAIN_SIG}]') +curl --silent --show-error --fail --get --data-urlencode "domain=$STAPLED_DOMAIN Domain AIA Parent CA" --data-urlencode "pubb64=$STAPLED_PUB_B64" --data-urlencode "sigs=$STAPLED_MULTI_SIGS_JSON" "$AIA_TEST_URL/aia" > "$STAPLED_PARENT_CA_DER" +openssl x509 -inform DER -in "$STAPLED_PARENT_CA_DER" -out "$STAPLED_PARENT_CA_PEM" +stapled_multi_ca_pem=$(cat "$STAPLED_PARENT_CA_PEM") +assert_contains "$stapled_multi_ca_pem" "BEGIN CERTIFICATE" "Stapled AIA multi-signature acceptance failed" + +echo "Fetch stapled $STAPLED_DOMAIN CA via Encaya AIA using Namecoin signature" +curl --silent --show-error --fail --get --data-urlencode "domain=$STAPLED_DOMAIN Domain AIA Parent CA" --data-urlencode "pubb64=$STAPLED_PUB_B64" --data-urlencode "sigs=$STAPLED_SIGS_JSON" "$AIA_TEST_URL/aia" > "$STAPLED_PARENT_CA_DER" +openssl x509 -inform DER -in "$STAPLED_PARENT_CA_DER" -out "$STAPLED_PARENT_CA_PEM" +stapled_ca_pem=$(cat "$STAPLED_PARENT_CA_PEM") +assert_contains "$stapled_ca_pem" "BEGIN CERTIFICATE" "Encaya did not return stapled $STAPLED_DOMAIN Domain AIA Parent CA" + +echo "Verify stapled issuer key matches signed public key" +stapled_domain_ca_sha256_hex=$(get_cert_spki_sha256_hex "$stapled_ca_pem") +stapled_generated_key_sha256_hex=$(sha256_hex_upper "$STAPLED_CA_KEY") +assert_equal "$stapled_domain_ca_sha256_hex" "$stapled_generated_key_sha256_hex" "Encaya issued stapled parent CA key did not match signed key" + +echo "Generate local leaf certificate signed by stapled parent" +generate_stapled_leaf_cert + +echo "Start local HTTPS server for Chromium stapled AIA test" +start_stapled_https_server + +echo "Initialize NSS DB for Chromium stapled AIA test" +prepare_nss_db + +echo "Trust Encaya root CA for Chromium stapled AIA test" +trust_encaya_root + +echo "Run Chromium headless and verify stapled TLS+AIA workflow" +stapled_chromium_output=$(chromium_fetch_dom_impl "$STAPLED_CHROME_PROFILE_DIR" "$STAPLED_TEST_TMPDIR/chrome.log" "$STAPLED_DOMAIN" "https://$STAPLED_DOMAIN:$STAPLED_HTTPS_SERVER_PORT/index.html" || true) +assert_contains "$stapled_chromium_output" "Cool or nah stapled" "Chromium did not render expected page content over stapled TLS validation" + +if [[ "$stapled_chromium_output" == *"Your connection is not private"* ]]; then + fail_test "Chromium reported certificate error instead of successful stapled validation" +fi + +echo "Stapled AIA Chromium test passed" +echo "Functional test suite passed" diff --git a/testdata/release.bash b/testdata/release.bash deleted file mode 100644 index 1b2cd54..0000000 --- a/testdata/release.bash +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash - -set -ex - -# Only upload version tags and master nightlies. -if ! [[ "$CIRRUS_TAG" =~ ^v[0-9] ]]; then - if [[ "$CIRRUS_BRANCH" != "master" ]]; then - echo Skipping release upload because this build is not for a release tag or a master nightly. - exit 0 - fi - - RELEASES_NAME=$(date +%F)-$(echo "$CIRRUS_CHANGE_IN_REPO" | cut -c-8) - export RELEASES_NAME - git clone "https://NamecoinBot:$RELEASES_TOKEN@github.com/namecoin/nightly-${CIRRUS_REPO_NAME}.git" - cd "nightly-${CIRRUS_REPO_NAME}" - git config --local user.name "NamecoinBot" - git config --local user.email "githubbot@namecoin.org" - export CIRRUS_TAG=$RELEASES_NAME - git tag "$CIRRUS_TAG" - git push origin "$CIRRUS_TAG" - cd .. -fi - -if [[ "$GITHUB_TOKEN" == "" ]]; then - echo "Please provide GitHub access token via GITHUB_TOKEN environment variable!" - exit 1 -fi - -# Make archives. -bash ./testdata/dist.bash - -pushd dist || exit 1 - -echo Uploading releases... -ghr -u "NamecoinBot" -r "nightly-${CIRRUS_REPO_NAME}" "$CIRRUS_TAG" "./" - -popd || exit 1 - -echo Done diff --git a/testdata/unbound.conf b/testdata/unbound.conf new file mode 100644 index 0000000..28f5851 --- /dev/null +++ b/testdata/unbound.conf @@ -0,0 +1,9 @@ +server: + do-not-query-localhost: no + domain-insecure: bit. + use-syslog: no +stub-zone: + name: bit. + stub-addr: 127.0.0.1@5391 + stub-prime: no + stub-first: no