// Copyright 2021 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build ignore

package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"os"
	"path"
	"strings"

	"golang.org/x/crypto/cryptobyte"
	"golang.org/x/net/dns/dnsmessage"
)

const (
	httpsType = 65 // RRTYPE for HTTPS records.

	// SvcParamKey codepoints defined in RFC 9460 and RFC 9848.
	httpsKeyMandatory     = 0
	httpsKeyALPN          = 1
	httpsKeyNoDefaultALPN = 2
	httpsKeyPort          = 3
	httpsKeyIPV4Hint      = 4
	httpsKeyECH           = 5
	httpsKeyIPV6Hint      = 6
)

var (
	name   = flag.String("name", "", "The name to look up in DNS. Required.")
	server = flag.String("server", "8.8.8.8:53", "Comma-separated host and UDP port that defines the DNS server to query.")
	outDir = flag.String("out-dir", "", "The directory where ECHConfigList values will be written. If unspecified, bytes are hexdumped to stdout.")
)

type httpsRecord struct {
	priority   uint16
	targetName string

	// SvcParams:
	mandatory     []uint16
	alpn          []string
	noDefaultALPN bool
	hasPort       bool
	port          uint16
	ipv4hint      []net.IP
	ech           []byte
	ipv6hint      []net.IP
	unknownParams map[uint16][]byte
}

// String pretty-prints |h| as a multi-line string with bullet points.
func (h httpsRecord) String() string {
	var b strings.Builder
	fmt.Fprintf(&b, "HTTPS SvcPriority:%d TargetName:%q", h.priority, h.targetName)

	if len(h.mandatory) != 0 {
		fmt.Fprintf(&b, "\n  * mandatory: %v", h.mandatory)
	}
	if len(h.alpn) != 0 {
		fmt.Fprintf(&b, "\n  * alpn: %q", h.alpn)
	}
	if h.noDefaultALPN {
		fmt.Fprint(&b, "\n  * no-default-alpn")
	}
	if h.hasPort {
		fmt.Fprintf(&b, "\n  * port: %d", h.port)
	}
	if len(h.ipv4hint) != 0 {
		fmt.Fprintf(&b, "\n  * ipv4hint:")
		for _, address := range h.ipv4hint {
			fmt.Fprintf(&b, "\n    - %s", address)
		}
	}
	if len(h.ech) != 0 {
		fmt.Fprintf(&b, "\n  * ech: %x", h.ech)
	}
	if len(h.ipv6hint) != 0 {
		fmt.Fprintf(&b, "\n  * ipv6hint:")
		for _, address := range h.ipv6hint {
			fmt.Fprintf(&b, "\n    - %s", address)
		}
	}
	if len(h.unknownParams) != 0 {
		fmt.Fprint(&b, "\n  * unknown SvcParams:")
		for key, value := range h.unknownParams {
			fmt.Fprintf(&b, "\n    - %d: %x", key, value)
		}
	}
	return b.String()
}

// dnsQueryForHTTPS queries the DNS server over UDP for any HTTPS records
// associated with |domain|. It scans the response's answers and returns all the
// HTTPS records it finds. It returns an error if any connection steps fail.
func dnsQueryForHTTPS(domain string) ([][]byte, error) {
	udpAddr, err := net.ResolveUDPAddr("udp", *server)
	if err != nil {
		return nil, err
	}
	conn, err := net.DialUDP("udp", nil, udpAddr)
	if err != nil {
		return nil, fmt.Errorf("failed to dial: %s", err)
	}
	defer conn.Close()

	// Domain name must be canonical or message packing will fail.
	if domain[len(domain)-1] != '.' {
		domain += "."
	}
	dnsName, err := dnsmessage.NewName(domain)
	if err != nil {
		return nil, fmt.Errorf("failed to create DNS name from %q: %s", domain, err)
	}
	question := dnsmessage.Question{
		Name:  dnsName,
		Type:  httpsType,
		Class: dnsmessage.ClassINET,
	}
	msg := dnsmessage.Message{
		Header: dnsmessage.Header{
			RecursionDesired: true,
		},
		Questions: []dnsmessage.Question{question},
	}
	packedMsg, err := msg.Pack()
	if err != nil {
		return nil, fmt.Errorf("failed to pack msg: %s", err)
	}

	if _, err = conn.Write(packedMsg); err != nil {
		return nil, fmt.Errorf("failed to send the DNS query: %s", err)
	}

	for {
		response := make([]byte, 512)
		n, err := conn.Read(response)
		if err != nil {
			return nil, fmt.Errorf("failed to read the DNS response: %s", err)
		}
		response = response[:n]

		var p dnsmessage.Parser
		header, err := p.Start(response)
		if err != nil {
			return nil, err
		}
		if !header.Response {
			return nil, errors.New("received DNS message is not a response")
		}
		if header.RCode != dnsmessage.RCodeSuccess {
			return nil, fmt.Errorf("response from DNS has non-success RCode: %s", header.RCode.String())
		}
		if header.ID != 0 {
			return nil, errors.New("received a DNS response with the wrong ID")
		}
		if !header.RecursionAvailable {
			return nil, errors.New("server does not support recursion")
		}
		// Verify that this response answers the question that we asked in the
		// query. If the resolver encountered any CNAMEs, it's not guaranteed
		// that the response will contain a question with the same QNAME as our
		// query. However, RFC 8499 Section 4 indicates that in general use, the
		// response's QNAME should match the query, so we will make that
		// assumption.
		q, err := p.Question()
		if err != nil {
			return nil, err
		}
		if q != question {
			return nil, fmt.Errorf("response answers the wrong question: %v", q)
		}
		if q, err = p.Question(); err != dnsmessage.ErrSectionDone {
			return nil, fmt.Errorf("response contains an unexpected question: %v", q)
		}

		var httpsRecords [][]byte
		for {
			h, err := p.AnswerHeader()
			if err == dnsmessage.ErrSectionDone {
				break
			}
			if err != nil {
				return nil, err
			}

			switch h.Type {
			case httpsType:
				// This should continue to work when golang.org/x/net/dns/dnsmessage
				// adds support for HTTPS records.
				r, err := p.UnknownResource()
				if err != nil {
					return nil, err
				}
				httpsRecords = append(httpsRecords, r.Data)
			default:
				if _, err := p.UnknownResource(); err != nil {
					return nil, err
				}
			}
		}
		return httpsRecords, nil
	}
}

// parseHTTPSRecord parses an HTTPS record (RFC 9460, Section 2.2) from |raw|.
// If there are syntax errors, it returns an error.
func parseHTTPSRecord(raw []byte) (httpsRecord, error) {
	reader := cryptobyte.String(raw)

	var priority uint16
	if !reader.ReadUint16(&priority) {
		return httpsRecord{}, errors.New("failed to parse HTTPS record priority")
	}

	// Read the TargetName.
	var dottedDomain string
	for {
		var label cryptobyte.String
		if !reader.ReadUint8LengthPrefixed(&label) {
			return httpsRecord{}, errors.New("failed to parse HTTPS record TargetName")
		}
		if label.Empty() {
			break
		}
		dottedDomain += string(label) + "."
	}

	if priority == 0 {
		// TODO(dmcardle) Recursively follow AliasForm records.
		return httpsRecord{}, fmt.Errorf("received an AliasForm HTTPS record with TargetName=%q", dottedDomain)
	}

	record := httpsRecord{
		priority:      priority,
		targetName:    dottedDomain,
		unknownParams: make(map[uint16][]byte),
	}

	// Read the SvcParams.
	var lastSvcParamKey uint16
	for svcParamCount := 0; !reader.Empty(); svcParamCount++ {
		var svcParamKey uint16
		var svcParamValue cryptobyte.String
		if !reader.ReadUint16(&svcParamKey) ||
			!reader.ReadUint16LengthPrefixed(&svcParamValue) {
			return httpsRecord{}, errors.New("failed to parse HTTPS record SvcParam")
		}
		if svcParamCount > 0 && svcParamKey <= lastSvcParamKey {
			return httpsRecord{}, errors.New("malformed HTTPS record contains out-of-order SvcParamKey")
		}
		lastSvcParamKey = svcParamKey

		switch svcParamKey {
		case httpsKeyMandatory:
			if svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed mandatory SvcParamValue")
			}
			var lastKey uint16
			for !svcParamValue.Empty() {
				// |httpsKeyMandatory| may not appear in the mandatory list.
				// |httpsKeyMandatory| is zero, so checking against the initial
				// value of |lastKey| handles ordering and the invalid code point.
				var key uint16
				if !svcParamValue.ReadUint16(&key) ||
					key <= lastKey {
					return httpsRecord{}, errors.New("malformed mandatory SvcParamValue")
				}
				lastKey = key
				record.mandatory = append(record.mandatory, key)
			}
		case httpsKeyALPN:
			if svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed alpn SvcParamValue")
			}
			for !svcParamValue.Empty() {
				var alpn cryptobyte.String
				if !svcParamValue.ReadUint8LengthPrefixed(&alpn) || alpn.Empty() {
					return httpsRecord{}, errors.New("malformed alpn SvcParamValue")
				}
				record.alpn = append(record.alpn, string(alpn))
			}
		case httpsKeyNoDefaultALPN:
			if !svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed no-default-alpn SvcParamValue")
			}
			record.noDefaultALPN = true
		case httpsKeyPort:
			if !svcParamValue.ReadUint16(&record.port) ||
				!svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed port SvcParamValue")
			}
			record.hasPort = true
		case httpsKeyIPV4Hint:
			if svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed ipv4hint SvcParamValue")
			}
			for !svcParamValue.Empty() {
				var address []byte
				if !svcParamValue.ReadBytes(&address, 4) {
					return httpsRecord{}, errors.New("malformed ipv4hint SvcParamValue")
				}
				record.ipv4hint = append(record.ipv4hint, address)
			}
		case httpsKeyECH:
			if svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed ech SvcParamValue")
			}
			record.ech = svcParamValue
		case httpsKeyIPV6Hint:
			if svcParamValue.Empty() {
				return httpsRecord{}, errors.New("malformed ipv6hint SvcParamValue")
			}
			for !svcParamValue.Empty() {
				var address []byte
				if !svcParamValue.ReadBytes(&address, 16) {
					return httpsRecord{}, errors.New("malformed ipv6hint SvcParamValue")
				}
				record.ipv6hint = append(record.ipv6hint, address)
			}
		default:
			record.unknownParams[svcParamKey] = svcParamValue
		}
	}
	return record, nil
}

func main() {
	flag.Parse()
	log.SetFlags(log.Lshortfile | log.LstdFlags)

	if len(*name) == 0 {
		flag.Usage()
		os.Exit(1)
	}

	httpsRecords, err := dnsQueryForHTTPS(*name)
	if err != nil {
		log.Printf("Error querying %q: %s\n", *name, err)
		os.Exit(1)
	}
	if len(httpsRecords) == 0 {
		log.Println("No HTTPS records found in DNS response.")
		os.Exit(1)
	}

	if len(*outDir) > 0 {
		if err = os.Mkdir(*outDir, 0755); err != nil && !os.IsExist(err) {
			log.Printf("Failed to create out directory %q: %s\n", *outDir, err)
			os.Exit(1)
		}
	}

	var echConfigListCount int
	for _, httpsRecord := range httpsRecords {
		record, err := parseHTTPSRecord(httpsRecord)
		if err != nil {
			log.Printf("Failed to parse HTTPS record: %s", err)
			os.Exit(1)
		}
		fmt.Printf("%s\n", record)
		if len(*outDir) == 0 {
			continue
		}

		outFile := path.Join(*outDir, fmt.Sprintf("ech-config-list-%d", echConfigListCount))
		if err = os.WriteFile(outFile, record.ech, 0644); err != nil {
			log.Printf("Failed to write file: %s\n", err)
			os.Exit(1)
		}
		fmt.Printf("Wrote ECHConfigList to %q\n", outFile)
		echConfigListCount++
	}
}
