bastion 0.53.2
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s

This commit is contained in:
Privatae
2026-10-20 04:42:14 +00:00
commit e4c9b69b46
471 changed files with 159794 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
package main
// The pairing token on standard input.
//
// A token passed as an argument sits in /proc/<pid>/cmdline for as long as
// `pair` runs, where any account on the machine can read it, and in the shell's
// history afterwards. The token is single-use and short-lived, but until it is
// redeemed it is a whole enrolment. So `pair` also takes it on standard input,
// asked for with `-` in place of the token. Only `-` reads standard input:
// `pair` with no token is the usage error it always was, whatever standard
// input is, because some terminals (Git Bash's mintty, `ssh host cmd` without
// -t) do not register as one, and reading there would leave a person who
// forgot the token waiting with nothing said.
//
// No error here repeats what was read. A refusal names what was wrong with the
// input, never its content, so a log of a failed install does not hold the
// token either.
import (
"bufio"
"errors"
"fmt"
"io"
"strings"
)
// pairStdinArg in place of the token says it comes on standard input.
const pairStdinArg = "-"
// pairTokenMax bounds the first line read. A token is a few dozen bytes; this
// is only so a wrong file piped in is refused rather than read whole.
const pairTokenMax = 4096
// pairToken returns the token `pair` redeems. arg is the token parsePairArgs
// found, pairStdinArg, or "" for none. stdinConsole says whether standard
// input is a terminal; when it is and `-` was given, a prompt goes to prompt.
func pairToken(arg string, stdin io.Reader, stdinConsole bool, prompt io.Writer) (string, error) {
switch {
case arg == "":
return "", errors.New(pairUsage)
case arg != "" && arg != pairStdinArg:
return arg, nil
}
if stdinConsole {
fmt.Fprint(prompt, "Paste the pairing token and press Enter: ")
}
return readPairToken(stdin)
}
// readPairToken reads the token as the first line of r: one word, surrounding
// spaces and the line ending dropped.
func readPairToken(r io.Reader) (string, error) {
line, err := bufio.NewReader(io.LimitReader(r, pairTokenMax+1)).ReadString('\n')
if err != nil && !errors.Is(err, io.EOF) {
return "", fmt.Errorf("could not read the pairing token from standard input (%v); nothing was paired", err)
}
if len(line) > pairTokenMax {
return "", fmt.Errorf("the first line of standard input is longer than %d bytes, far longer than a pairing token; nothing was paired", pairTokenMax)
}
words := strings.Fields(line)
switch len(words) {
case 0:
return "", errors.New("standard input held no pairing token: give it as the first line, or as the argument; nothing was paired")
case 1:
return words[0], nil
}
return "", fmt.Errorf("the first line of standard input holds %d words, and a pairing token is one; nothing was paired", len(words))
}