a73x

internal/cli/pin_test.go

Ref:   Size: 1.6 KiB   History

package cli

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"testing"
)

func TestWriteHostCAPin(t *testing.T) {
	// A real (public) ed25519 key line — the pin now refuses unparsable CAs.
	const caLine = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPZ8BFXvSU9tCz3sm5uuXG8UXsRWCkEBHYBJk8OjJgeA eitri-host-ca"
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.URL.Path != "/api/v1/ssh-ca" {
			http.NotFound(w, r)
			return
		}
		json.NewEncoder(w).Encode(map[string]string{"ca": caLine + "\r\n"})
	}))
	defer srv.Close()

	pin := filepath.Join(t.TempDir(), "sub", "eitri_known_hosts")
	// Trailing-slash base URL must work too.
	if err := WriteHostCAPin(context.Background(), srv.URL+"/", pin); err != nil {
		t.Fatal(err)
	}
	got, err := os.ReadFile(pin)
	if err != nil {
		t.Fatal(err)
	}
	want := "@cert-authority * " + caLine + "\n"
	if string(got) != want {
		t.Errorf("pin = %q, want %q", got, want)
	}
	if err := WriteHostCAPin(context.Background(), srv.URL, pin); err != nil {
		t.Fatal(err)
	}
	if b, _ := os.ReadFile(pin); string(b) != want {
		t.Errorf("pin after rewrite = %q", b)
	}
}

func TestWriteHostCAPinRejectsGarbage(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`{"ca":"not a key at all"}`))
	}))
	defer srv.Close()
	pin := filepath.Join(t.TempDir(), "kh")
	if err := WriteHostCAPin(context.Background(), srv.URL, pin); err == nil {
		t.Fatal("want error for unparsable CA")
	}
	if _, err := os.Stat(pin); !os.IsNotExist(err) {
		t.Error("garbage CA must not be written to the pin file")
	}
}