~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs-iroh

iroh transport for atlibs hosts: com.fedfork.exec.iroh.connect in Rust (atlibs-host) and JavaScript

0
0
main
78 lines · 4.3 KB Raw History
import assert from "node:assert/strict";
import { test } from "node:test";

import { readFileSync } from "node:fs";

import { spawnSync } from "node:child_process";

import { irohHost, knownHosts, sshArgs, ticket } from "../js/index.js";
import { atircTicket } from "./iroh.mjs";

const T = "endpointabex5k47heqqkdykv2b27ydg75jjaxeucm2ej74nt34a7up6wqlkyaiaenuhi5dqom5c6l3von3tcljrfzzgk3dbpexg4mbonfzg62bonruw42zof4";

test("ticket strips iroh:// and refuses non-tickets", () => {
	assert.equal(ticket(`iroh://${T}\n`), T);
	assert.equal(ticket(T), T);
	for (const bad of ["", "https://x", "iroh://ABC", "a b", null, "x".repeat(4097)]) assert.throws(() => ticket(bad));
});

test("knownHosts pins lexicon hostKeys and refuses none", () => {
	const keys = [
		{ type: "ssh-ed25519", publicKey: "ssh-ed25519 AAAAC3Nz root@guest", fingerprint: "SHA256:x" },
		{ type: "ssh-ed25519", publicKey: "AAAAC3Bare", fingerprint: "SHA256:y" }, // hat-7 shape
		"ecdsa-sha2-nistp256 AAAAE2 c",
	];
	assert.equal(knownHosts("guest", keys), "guest ssh-ed25519 AAAAC3Nz\nguest ssh-ed25519 AAAAC3Bare\nguest ecdsa-sha2-nistp256 AAAAE2\n");
	assert.throws(() => knownHosts("guest", []));
	assert.throws(() => knownHosts("guest", undefined));
});

test("sshArgs: an option-looking command stays the remote command (ssh -G, no network)", () => {
	const evil = "-oKnownHostsCommand=/nonexistent/pwned";
	const args = sshArgs("/k/key", T, "/k/known_hosts", [evil]);
	assert.deepEqual(args.slice(-3), ["--", "root@guest", evil]);
	const g = spawnSync("ssh", ["-G", ...args], { encoding: "utf8" });
	if (g.error) return; // no ssh binary here
	assert.match(g.stdout, new RegExp(`^proxycommand dumbpipe connect ${T}$`, "m"));
	assert.doesNotMatch(g.stdout, /pwned/);
	// without "--" ssh would take the command as an option: the regression this guards
	const bad = spawnSync("ssh", ["-G", ...args.filter((a) => a !== "--")], { encoding: "utf8" });
	assert.match(bad.stdout, /pwned/);
});

test("atircTicket reads the endpoint claim", () => {
	const jwt = ["e30", Buffer.from(JSON.stringify({ endpoint: T })).toString("base64url"), "sig"].join(".");
	assert.equal(atircTicket(jwt), T);
});

test("irohHost: ssh with pinned host keys, or a raw exchange on a custom ALPN", async () => {
	const ran = [];
	const keys = [{ type: "ssh-ed25519", publicKey: "AAAAC3Bare" }];
	let reply = { stdout: "fc-1\n", stderr: "", code: 0 };
	const iroh = irohHost({ key: "/k/guest_ed25519", run: async (cmd, args, input) => {
		const known = args.find((a) => a.startsWith("UserKnownHostsFile="));
		ran.push({ cmd, args, input, known: known && readFileSync(known.slice("UserKnownHostsFile=".length), "utf8") });
		return reply;
	} });
	assert.deepEqual(await iroh({ ticket: `iroh://${T}`, hostKeys: keys, command: "hostname" }), { output: "fc-1\n", exitCode: 0 });
	assert.equal(ran[0].cmd, "ssh");
	assert.ok(ran[0].args.includes(`ProxyCommand=dumbpipe connect ${T}`) && ran[0].args.includes("StrictHostKeyChecking=yes"));
	assert.deepEqual(ran[0].args.slice(-3), ["--", "root@guest", "hostname"]);
	assert.equal(ran[0].known, "guest ssh-ed25519 AAAAC3Bare\n");
	assert.equal(ran[0].input, "", "nothing on stdin by default");
	// a secret goes over the session's stdin, never into ssh's argv
	await iroh({ ticket: T, hostKeys: keys, command: "IFS= read -r t; echo ok", stdin: "secret-token\n" });
	assert.equal(ran.at(-1).input, "secret-token\n");
	assert.ok(!ran.at(-1).args.some((a) => a.includes("secret-token")));
	await assert.rejects(iroh({ ticket: T, hostKeys: keys, command: "x", stdin: 5 }), /stdin must be a string/);
	await assert.rejects(iroh({ ticket: T, hostKeys: [], command: "x" }), /no host keys/);
	await assert.rejects(iroh({ ticket: T, hostKeys: keys }), /command is required/);
	await assert.rejects(iroh({ ticket: "nope!", hostKeys: keys, command: "x" }), /not an iroh ticket/);
	reply = { stdout: "", stderr: "Host key verification failed.", code: 255 };
	await assert.rejects(iroh({ ticket: T, hostKeys: keys, command: "x" }), /Host key verification failed/);

	reply = { stdout: ":irc 001 me :hi\r\n", stderr: "", code: 0 };
	assert.deepEqual(await iroh({ ticket: T, alpn: "atirc/irc/1", send: "NICK me\r\n" }), { output: ":irc 001 me :hi\r\n" });
	assert.deepEqual(ran.at(-1), { cmd: "dumbpipe", args: ["connect", "--custom-alpn", "utf8:atirc/irc/1", T], input: "NICK me\r\n", known: undefined });
	await assert.rejects(iroh({ ticket: T, alpn: "a b" }), /alpn/);
});