/** * Server passport * * One probe per session instead of a scatter of one-off checks like "does * the server have bash / timeout / what to hash with". From then on every * decision is made from the passport, not from separate round trips to the server. * * Two rules, without which the passport would become a source of failures itself: * * 1. The probe runs as `sh -c '…'`. The remote command executes in the * user's login shell, which could be csh or fish with different syntax; * running a program with an argument is valid in any shell. The remote * guard is not applied to the probe — the command language is exactly * what it's finding out. * 2. The response is read by marker: banner, motd, and any stray output are * ignored. No marker — we assume we know nothing and take the cautious * path. The passport speeds things up and refines them, but never grants * permission on its own. */ /** What to hash sha256 with on the server */ export type Sha256Tool = 'sha256sum' | 'openssl' | 'none'; /** Which flavor of base utilities the server has */ type UtilityFlavor = 'coreutils' | 'busybox' | 'unknown'; export interface ServerPassport { /** Whether bash is present — determines the language we send commands in */ bash: boolean; sha256: Sha256Tool; coreutils: UtilityFlavor; rsync: boolean; /** Whether the `timeout` utility is available for the remote guard */ remoteTimeout: boolean; /** * Whether `setsid` is available — used to detach a background task. * * Without it the task stays in the ssh session and can't be killed as a * group: the leader's pid matches its pgid only in its own session. */ setsid: boolean; install: boolean; /** What `uname -s` reported — for diagnostics and error text */ os: string; /** * The user's home directory — the only way to expand `~`. * * The tilde can't be expanded on the server: the path travels inside * single-quoted commands, where `~` stays a literal character, and without * quotes any name with a space or `$` would fall apart. An empty string * means "unknown" — a `~`-path is then rejected, not guessed at. */ home: string; /** Whether the passport could be read at all */ known: boolean; } /** * The most cautious state possible: assume nothing. * * No bash, no remote guard, nothing to hash with. Each of these values leads * to a slower but safe path — and none of them blocks the operation itself. */ export declare const UNKNOWN_PASSPORT: ServerPassport; /** * The probe: one line of output, nothing extra. * * The utility set is told apart by `ls --version`: coreutils has it, * BusyBox doesn't. The same trick can't be used for `sha256sum` — it might * simply be absent, and the machine would be mistakenly classified as BusyBox. * * The home directory is printed last: it can contain spaces, so it has to be * read to the end of the line rather than field by field like the rest. */ export declare const PASSPORT_PROBE_COMMAND: string; /** Parse the probe's output. Unrecognized values are treated as "unknown". */ export declare function parsePassport(stdout: string): ServerPassport; /** A probe that takes the passport: returns the remote command's stdout */ export type PassportProbe = () => Promise; /** * Destination key — the same `user@host:port` used by the transport cache. * * Computed in one place: tools ask for the passport through the executor, * the transport asks for its own, and both must land on the same cache entry. */ export declare function passportKey(config: { username: string; host: string; port?: number; }): string; /** * Passport for a destination. The key is the same `user@host:port` used by * the transport cache: two profiles for the same server under the same user * see one shared passport. */ export declare function getServerPassport(key: string, probe: PassportProbe): Promise; /** * Forget the passport for a destination. * * Needed when the server changed under us: a promised utility turned out to * be missing, credentials changed, packages were reinstalled. */ export declare function invalidatePassport(key: string): void; /** Reset the whole cache (used in tests) */ export declare function resetPassportCache(): void; export {};