Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
coffinsfcompute committed Sep 21, 2024
1 parent e0e0bdf commit c94d3d6
Showing 1 changed file with 57 additions and 8 deletions.
65 changes: 57 additions & 8 deletions src/lib/ssh.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { expect } from "bun:test";
import os from "node:os";
import path from "node:path";
import util from "node:util";
import type { SpawnOptions } from "bun";
import type { Command } from "commander";
import { apiClient } from "../apiClient";
import { isLoggedIn } from "../helpers/config";
Expand All @@ -10,15 +12,49 @@ import {
unreachable,
} from "../helpers/errors";

// biome-ignore lint/suspicious/noExplicitAny: better than using as
type Constructor<T> = new (...args: any[]) => T;

// openssh-client doesn't check $HOME while homedir() does. This function is to
// make it easy to fix if it causes issues.
function ssh_homedir(): string {
return os.homedir();
}

// Bun 1.1.29 does not handle empty arguments properly, for now us an `sh`
// wrapper.
function spawn_wrapper<Opts extends SpawnOptions.OptionsObject>(
cmds: string[],
options?: Opts,
): SpawnOptions.OptionsToSubprocess<Opts> {
let sh_cmd = "";
for (const cmd of cmds) {
if (sh_cmd.length > 0) {
sh_cmd += " ";
}
sh_cmd += '"';

// utf-16 code points are fine as we will ignore surrogates, and we don't
// care about anything other than characters that don't require surrogates.
for (const c of cmd) {
switch (c) {
case "$":
case "\\":
case "`":
// @ts-ignore
// biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional fallthrough
case '"': {
sh_cmd += "\\";
// fallthrough
}
default: {
sh_cmd += c;
break;
}
}
}
sh_cmd += '"';
}
return Bun.spawn(["sh", "-c", sh_cmd], options);
}

// Returns an absolute path (symbolic links, ".", and ".." are left
// unnormalized).
function normalize_ssh_config_path(ssh_path: string): string {
Expand Down Expand Up @@ -93,7 +129,7 @@ async function find_default_key(): Promise<string> {
];

{
const proc = Bun.spawn(["ssh", "-V"], {
const proc = spawn_wrapper(["ssh", "-V"], {
stdin: null,
stdout: null,
stderr: null,
Expand All @@ -115,7 +151,7 @@ async function find_default_key(): Promise<string> {
let key_supported_ed25519 = false;
let key_supported_rsa = false;

const proc = Bun.spawn(["ssh", "-G", ""], {
const proc = spawn_wrapper(["ssh", "-G", ""], {
stdin: null,
stdout: "pipe",
stderr: null,
Expand All @@ -134,8 +170,21 @@ async function find_default_key(): Promise<string> {
for (const line of stdout_str.split("\n")) {
const prefix = "identityfile ";
if (line.startsWith(prefix)) {
const line_suffix = line.slice(prefix.length);
if (
line_suffix === "~/.ssh/id_ed25519" ||
line_suffix === path.join(ssh_homedir(), ".ssh/id_ed25519")
) {
key_supported_ed25519 = true;
}
if (
line_suffix === "~/.ssh/id_rsa" ||
line_suffix === path.join(ssh_homedir(), ".ssh/id_rsa")
) {
key_supported_rsa = true;
}
const potential_identity_file = normalize_ssh_config_path(
line.slice(prefix.length) + ".pub",
line_suffix + ".pub",
);
ssh_g_parsed_success = true;
if (await Bun.file(potential_identity_file).exists()) {
Expand Down Expand Up @@ -183,7 +232,7 @@ async function find_default_key(): Promise<string> {
);
}

const proc = Bun.spawn(
const proc = spawn_wrapper(
["ssh-keygen", "-N", "", "-q", "-f", priv_ssh_key_path].concat(
extra_ssh_options,
),
Expand All @@ -199,7 +248,7 @@ async function find_default_key(): Promise<string> {
"The ssh-keygen command is not installed, please install it before trying again.",
);
}

console.log(util.format("Generated key %s", priv_ssh_key_path));
identity_file = priv_ssh_key_path + ".pub";
}

Expand Down

0 comments on commit c94d3d6

Please sign in to comment.