package main import ( "context" "crypto/sha256" "encoding/base64" "encoding/hex" "encoding/json" "fmt" "strings" "sync" "testing" ) // secretAcceptWants makes the test binary, run as a command line, read a secret as `secret accept` reads it and // say whether it is the value whose SHA-256 the variable names (TestMain). const secretAcceptWants = "MESH_TEST_SECRET_ACCEPT_WANTS" // readAsSecretAccept is that process: `secret accept [--from -]`, the value read by // valueFor, compared by digest, and only the verdict printed. func readAsSecretAccept(want string, argv []string) int { if len(argv) < 5 || argv[0] != "secret" || argv[1] != "accept" { fmt.Printf("not a secret accept line: %q\n", argv) return 2 } from := "" if len(argv) == 7 && argv[5] == "--from" { from = argv[6] } value, err := valueFor(argv[2], argv[3], argv[4], from) if err != nil { fmt.Printf("secret accept read nothing: %v\n", err) return 1 } sum := sha256.Sum256([]byte(asSupplied(value))) if hex.EncodeToString(sum[:]) != want { fmt.Printf("secret accept read something else (%d bytes)\n", len(value)) return 1 } fmt.Println("secret accept read the value it was given") return 0 } // novox/hq ADR 0259 §10, ADR 0272: what mesh-cli's standard input held reaches `secret accept` on a line that runs // as the controller's terminal, and appears nowhere else — not in the answer, not in the journal, not in the calls // record; an ordinary line carrying it is refused and nothing runs. func TestStandardInputReachesSecretAcceptAtTheTerminalAndNowhereElse(t *testing.T) { token := "123456789:AAEhBOweik6ad9r_QxGivenAtTheTerminal" sum := sha256.Sum256([]byte(token)) t.Setenv(secretAcceptWants, hex.EncodeToString(sum[:])) var journal []string var mu sync.Mutex was := cliJournal cliJournal = func(line string) { mu.Lock(); journal = append(journal, line); mu.Unlock() } t.Cleanup(func() { cliJournal = was }) ctx := context.Background() for _, line := range [][]string{ {"secret", "accept", "anchor", "telegram", "telegram-token", "--from", "-"}, {"secret", "accept", "anchor", "telegram", "telegram-token"}, // the prompt's path, a line on standard input } { asked := cliAsked("operator", 1000, line...) asked.Stdin = []byte(token + "\n") a := runForMeshCLI(ctx, "control", asked, cliVerdict{terminal: true, why: "the terminal"}) if a.Exit != 0 || !strings.Contains(string(a.Stdout), "read the value it was given") { t.Fatalf("%q: secret accept did not read what mesh-cli carried: %+v (%s)", line, a, a.Stdout) } if body, _ := json.Marshal(a); strings.Contains(string(body), "AAEh") || strings.Contains(string(body), base64.StdEncoding.EncodeToString([]byte(token))) { t.Fatalf("the answer carries the secret: %s", body) } } // Without standard input, the line reads nothing, as before. a := runForMeshCLI(ctx, "control", cliAsked("operator", 1000, "secret", "accept", "anchor", "telegram", "telegram-token", "--from", "-"), cliVerdict{terminal: true, why: "the terminal"}) if a.Exit == 0 { t.Fatalf("a line with no standard input read a value: %+v", a) } // An ordinary call is never handed it: refused, and nothing ran. asked := cliAsked("operator", 1000, "status") asked.Stdin = []byte(token) a = runForMeshCLI(ctx, "laptop", asked, cliVerdict{why: "not the terminal"}) if a.Exit == 0 || !strings.Contains(a.Refused, "terminal alone") || len(a.Stdout) != 0 { t.Fatalf("an ordinary line was given standard input: %+v", a) } mu.Lock() defer mu.Unlock() for _, l := range journal { if strings.Contains(l, "AAEh") { t.Fatalf("the journal says the secret: %s", l) } } if len(journal) == 0 { t.Fatal("the lines were not said in the journal at all") } }