// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The acmeprober program runs against an actual ACME CA implementation.
// It spins up an HTTP server to fulfill authorization challenges
// or execute a DNS script to provision a response to dns-01 challenge.
//
// For http-01 and tls-alpn-01 challenge types this requires the ACME CA
// to be able to reach the HTTP server.
//
// A usage example:
//
//	go run prober.go \
//	  -d https://acme-staging-v02.api.letsencrypt.org/directory \
//	  -f order \
//	  -t http-01 \
//	  -a :8080 \
//	  -domain some.example.org
//
// The above assumes a TCP tunnel from some.example.org:80 to 0.0.0.0:8080
// in order for the test to be able to fulfill http-01 challenge.
// To test tls-alpn-01 challenge, 443 port would need to be tunneled
// to 0.0.0.0:8080.
// When running with dns-01 challenge type, use -s argument instead of -a.
package main

import (
	"context"
	"crypto"
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/tls"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"time"

	"golang.org/x/crypto/acme"
)

var (
	// ACME CA directory URL.
	// Let's Encrypt v2 prod: https://acme-v02.api.letsencrypt.org/directory
	// Let's Encrypt v2 staging: https://acme-staging-v02.api.letsencrypt.org/directory
	// See the following for more CAs implementing ACME protocol:
	// https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment#CAs_&_PKIs_that_offer_ACME_certificates
	directory = flag.String("d", "", "ACME directory URL.")
	reginfo   = flag.String("r", "", "ACME account registration info.")
	flow      = flag.String("f", "", `Flow to run: "order" or "preauthz" (RFC8555).`)
	chaltyp   = flag.String("t", "", "Challenge type: tls-alpn-01, http-01 or dns-01.")
	addr      = flag.String("a", "", "Local server address for tls-alpn-01 and http-01.")
	dnsscript = flag.String("s", "", "Script to run for provisioning dns-01 challenges.")
	domain    = flag.String("domain", "", "Space separate domain identifiers.")
	ipaddr    = flag.String("ip", "", "Space separate IP address identifiers.")
)

func main() {
	flag.Usage = func() {
		fmt.Fprintln(flag.CommandLine.Output(), `
The prober program runs against an actual ACME CA implementation.
It spins up an HTTP server to fulfill authorization challenges
or execute a DNS script to provision a response to dns-01 challenge.

For http-01 and tls-alpn-01 challenge types this requires the ACME CA
to be able to reach the HTTP server.

A usage example:

    go run prober.go \
      -d https://acme-staging-v02.api.letsencrypt.org/directory \
      -f order \
      -t http-01 \
      -a :8080 \
      -domain some.example.org

The above assumes a TCP tunnel from some.example.org:80 to 0.0.0.0:8080
in order for the test to be able to fulfill http-01 challenge.
To test tls-alpn-01 challenge, 443 port would need to be tunneled
to 0.0.0.0:8080.
When running with dns-01 challenge type, use -s argument instead of -a.
		`)
		flag.PrintDefaults()
	}
	flag.Parse()

	identifiers := acme.DomainIDs(strings.Fields(*domain)...)
	identifiers = append(identifiers, acme.IPIDs(strings.Fields(*ipaddr)...)...)
	if len(identifiers) == 0 {
		log.Fatal("at least one domain or IP addr identifier is required")
	}

	// Duration of the whole run.
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
	defer cancel()

	// Create and register a new account.
	akey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		log.Fatal(err)
	}
	cl := &acme.Client{Key: akey, DirectoryURL: *directory}
	a := &acme.Account{Contact: strings.Fields(*reginfo)}
	if _, err := cl.Register(ctx, a, acme.AcceptTOS); err != nil {
		log.Fatalf("Register: %v", err)
	}

	// Run the desired flow test.
	p := &prober{
		client:    cl,
		chalType:  *chaltyp,
		localAddr: *addr,
		dnsScript: *dnsscript,
	}
	switch *flow {
	case "order":
		p.runOrder(ctx, identifiers)
	case "preauthz":
		p.runPreauthz(ctx, identifiers)
	default:
		log.Fatalf("unknown flow: %q", *flow)
	}
	if len(p.errors) > 0 {
		os.Exit(1)
	}
}

type prober struct {
	client    *acme.Client
	chalType  string
	localAddr string
	dnsScript string

	errors []error
}

func (p *prober) errorf(format string, a ...interface{}) {
	err := fmt.Errorf(format, a...)
	log.Print(err)
	p.errors = append(p.errors, err)
}

func (p *prober) runOrder(ctx context.Context, identifiers []acme.AuthzID) {
	// Create a new order and pick a challenge.
	// Note that Let's Encrypt will reply with 400 error:malformed
	// "NotBefore and NotAfter are not supported" when providing a NotAfter
	// value like WithOrderNotAfter(time.Now().Add(24 * time.Hour)).
	o, err := p.client.AuthorizeOrder(ctx, identifiers)
	if err != nil {
		log.Fatalf("AuthorizeOrder: %v", err)
	}

	var zurls []string
	for _, u := range o.AuthzURLs {
		z, err := p.client.GetAuthorization(ctx, u)
		if err != nil {
			log.Fatalf("GetAuthorization(%q): %v", u, err)
		}
		log.Printf("%+v", z)
		if z.Status != acme.StatusPending {
			log.Printf("authz status is %q; skipping", z.Status)
			continue
		}
		if err := p.fulfill(ctx, z); err != nil {
			log.Fatalf("fulfill(%s): %v", z.URI, err)
		}
		zurls = append(zurls, z.URI)
		log.Printf("authorized for %+v", z.Identifier)
	}

	log.Print("all challenges are done")
	if _, err := p.client.WaitOrder(ctx, o.URI); err != nil {
		log.Fatalf("WaitOrder(%q): %v", o.URI, err)
	}
	csr, certkey := newCSR(identifiers)
	der, curl, err := p.client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
	if err != nil {
		log.Fatalf("CreateOrderCert: %v", err)
	}
	log.Printf("cert URL: %s", curl)
	if err := checkCert(der, identifiers); err != nil {
		p.errorf("invalid cert: %v", err)
	}

	// Deactivate all authorizations we satisfied earlier.
	for _, v := range zurls {
		if err := p.client.RevokeAuthorization(ctx, v); err != nil {
			p.errorf("RevokAuthorization(%q): %v", v, err)
			continue
		}
	}
	// Deactivate the account. We don't need it for any further calls.
	if err := p.client.DeactivateReg(ctx); err != nil {
		p.errorf("DeactivateReg: %v", err)
	}
	// Try revoking the issued cert using its private key.
	if err := p.client.RevokeCert(ctx, certkey, der[0], acme.CRLReasonCessationOfOperation); err != nil {
		p.errorf("RevokeCert: %v", err)
	}
}

func (p *prober) runPreauthz(ctx context.Context, identifiers []acme.AuthzID) {
	dir, err := p.client.Discover(ctx)
	if err != nil {
		log.Fatalf("Discover: %v", err)
	}
	if dir.AuthzURL == "" {
		log.Fatal("CA does not support pre-authorization")
	}

	var zurls []string
	for _, id := range identifiers {
		z, err := authorize(ctx, p.client, id)
		if err != nil {
			log.Fatalf("AuthorizeID(%+v): %v", z, err)
		}
		if z.Status == acme.StatusValid {
			log.Printf("authz %s is valid; skipping", z.URI)
			continue
		}
		if err := p.fulfill(ctx, z); err != nil {
			log.Fatalf("fulfill(%s): %v", z.URI, err)
		}
		zurls = append(zurls, z.URI)
		log.Printf("authorized for %+v", id)
	}

	// We should be all set now.
	// Expect all authorizations to be satisfied.
	log.Print("all challenges are done")
	o, err := p.client.AuthorizeOrder(ctx, identifiers)
	if err != nil {
		log.Fatalf("AuthorizeOrder: %v", err)
	}
	waitCtx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	if _, err := p.client.WaitOrder(waitCtx, o.URI); err != nil {
		log.Fatalf("WaitOrder(%q): %v", o.URI, err)
	}
	csr, certkey := newCSR(identifiers)
	der, curl, err := p.client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)
	if err != nil {
		log.Fatalf("CreateOrderCert: %v", err)
	}
	log.Printf("cert URL: %s", curl)
	if err := checkCert(der, identifiers); err != nil {
		p.errorf("invalid cert: %v", err)
	}

	// Deactivate all authorizations we satisfied earlier.
	for _, v := range zurls {
		if err := p.client.RevokeAuthorization(ctx, v); err != nil {
			p.errorf("RevokeAuthorization(%q): %v", v, err)
			continue
		}
	}
	// Deactivate the account. We don't need it for any further calls.
	if err := p.client.DeactivateReg(ctx); err != nil {
		p.errorf("DeactivateReg: %v", err)
	}
	// Try revoking the issued cert using its private key.
	if err := p.client.RevokeCert(ctx, certkey, der[0], acme.CRLReasonCessationOfOperation); err != nil {
		p.errorf("RevokeCert: %v", err)
	}
}

func (p *prober) fulfill(ctx context.Context, z *acme.Authorization) error {
	var chal *acme.Challenge
	for i, c := range z.Challenges {
		log.Printf("challenge %d: %+v", i, c)
		if c.Type == p.chalType {
			log.Printf("picked %s for authz %s", c.URI, z.URI)
			chal = c
		}
	}
	if chal == nil {
		return fmt.Errorf("challenge type %q wasn't offered for authz %s", p.chalType, z.URI)
	}

	switch chal.Type {
	case "tls-alpn-01":
		return p.runTLSALPN01(ctx, z, chal)
	case "http-01":
		return p.runHTTP01(ctx, z, chal)
	case "dns-01":
		return p.runDNS01(ctx, z, chal)
	default:
		return fmt.Errorf("unknown challenge type %q", chal.Type)
	}
}

func (p *prober) runTLSALPN01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
	tokenCert, err := p.client.TLSALPN01ChallengeCert(chal.Token, z.Identifier.Value)
	if err != nil {
		return fmt.Errorf("TLSALPN01ChallengeCert: %v", err)
	}
	s := &http.Server{
		Addr: p.localAddr,
		TLSConfig: &tls.Config{
			NextProtos: []string{acme.ALPNProto},
			GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
				log.Printf("hello: %+v", hello)
				return &tokenCert, nil
			},
		},
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("%s %s", r.Method, r.URL)
			w.WriteHeader(http.StatusNotFound)
		}),
	}
	go s.ListenAndServeTLS("", "")
	defer s.Close()

	if _, err := p.client.Accept(ctx, chal); err != nil {
		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
	}
	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
	return zerr
}

func (p *prober) runHTTP01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
	body, err := p.client.HTTP01ChallengeResponse(chal.Token)
	if err != nil {
		return fmt.Errorf("HTTP01ChallengeResponse: %v", err)
	}
	s := &http.Server{
		Addr: p.localAddr,
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			log.Printf("%s %s", r.Method, r.URL)
			if r.URL.Path != p.client.HTTP01ChallengePath(chal.Token) {
				w.WriteHeader(http.StatusNotFound)
				return
			}
			w.Write([]byte(body))
		}),
	}
	go s.ListenAndServe()
	defer s.Close()

	if _, err := p.client.Accept(ctx, chal); err != nil {
		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
	}
	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
	return zerr
}

func (p *prober) runDNS01(ctx context.Context, z *acme.Authorization, chal *acme.Challenge) error {
	token, err := p.client.DNS01ChallengeRecord(chal.Token)
	if err != nil {
		return fmt.Errorf("DNS01ChallengeRecord: %v", err)
	}

	name := fmt.Sprintf("_acme-challenge.%s", z.Identifier.Value)
	cmd := exec.CommandContext(ctx, p.dnsScript, name, token)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("%s: %v", p.dnsScript, err)
	}

	if _, err := p.client.Accept(ctx, chal); err != nil {
		return fmt.Errorf("Accept(%q): %v", chal.URI, err)
	}
	_, zerr := p.client.WaitAuthorization(ctx, z.URI)
	return zerr
}

func authorize(ctx context.Context, client *acme.Client, id acme.AuthzID) (*acme.Authorization, error) {
	if id.Type == "ip" {
		return client.AuthorizeIP(ctx, id.Value)
	}
	return client.Authorize(ctx, id.Value)
}

func checkCert(derChain [][]byte, id []acme.AuthzID) error {
	if len(derChain) == 0 {
		return errors.New("cert chain is zero bytes")
	}
	for i, b := range derChain {
		crt, err := x509.ParseCertificate(b)
		if err != nil {
			return fmt.Errorf("%d: ParseCertificate: %v", i, err)
		}
		log.Printf("%d: serial: 0x%s", i, crt.SerialNumber)
		log.Printf("%d: subject: %s", i, crt.Subject)
		log.Printf("%d: issuer: %s", i, crt.Issuer)
		log.Printf("%d: expires in %.1f day(s)", i, time.Until(crt.NotAfter).Hours()/24)
		if i > 0 { // not a leaf cert
			continue
		}
		p := &pem.Block{Type: "CERTIFICATE", Bytes: b}
		log.Printf("%d: leaf:\n%s", i, pem.EncodeToMemory(p))
		for _, v := range id {
			if err := crt.VerifyHostname(v.Value); err != nil {
				return err
			}
		}
	}
	return nil
}

func newCSR(identifiers []acme.AuthzID) ([]byte, crypto.Signer) {
	var csr x509.CertificateRequest
	for _, id := range identifiers {
		switch id.Type {
		case "dns":
			csr.DNSNames = append(csr.DNSNames, id.Value)
		case "ip":
			csr.IPAddresses = append(csr.IPAddresses, net.ParseIP(id.Value))
		default:
			panic(fmt.Sprintf("newCSR: unknown identifier type %q", id.Type))
		}
	}
	k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
	if err != nil {
		panic(fmt.Sprintf("newCSR: ecdsa.GenerateKey for a cert: %v", err))
	}
	b, err := x509.CreateCertificateRequest(rand.Reader, &csr, k)
	if err != nil {
		panic(fmt.Sprintf("newCSR: x509.CreateCertificateRequest: %v", err))
	}
	return b, k
}
