chore: Fixes final changes.

This commit is contained in:
greysoh 2024-05-10 18:28:09 -04:00
parent 19aadc20c0
commit 7fa789691c
No known key found for this signature in database
GPG key ID: FE0F173B8FC01571
2 changed files with 43 additions and 28 deletions

View file

@ -4,8 +4,16 @@ import ssh2 from "ssh2";
import { readFromKeyboard } from "./libs/readFromKeyboard.js"; import { readFromKeyboard } from "./libs/readFromKeyboard.js";
import type { ClientKeys } from "./index.js"; import type { ClientKeys } from "./index.js";
export async function runCopyID(username: string, password: string, keys: ClientKeys, stream: ssh2.ServerChannel) { export async function runCopyID(
stream.write("Hey there! I think you're using ssh-copy-id. If this is an error, you may close this terminal.\n"); username: string,
password: string,
keys: ClientKeys,
stream: ssh2.ServerChannel,
) {
stream.write(
"Hey there! I think you're using ssh-copy-id. If this is an error, you may close this terminal.\n",
);
stream.write("Please wait...\n"); stream.write("Please wait...\n");
const keyData = await readFromKeyboard(stream, true); const keyData = await readFromKeyboard(stream, true);
@ -23,14 +31,16 @@ export async function runCopyID(username: string, password: string, keys: Client
keys.push({ keys.push({
username, username,
password, password,
publicKey: keyData publicKey: keyData,
}); });
try { try {
await writeFile("../keys/clients.json", JSON.stringify(keys, null, 2)); await writeFile("../keys/clients.json", JSON.stringify(keys, null, 2));
} catch (e) { } catch (e) {
console.log(e); console.log(e);
return stream.write("ERROR: Failed to save changes! If you're the administrator, view the console for details.\n"); return stream.write(
"ERROR: Failed to save changes! If you're the administrator, view the console for details.\n",
);
} }
stream.write("Success!\n"); stream.write("Success!\n");

View file

@ -11,16 +11,16 @@ import { commands } from "./commands.js";
import { runCopyID } from "./copyID.js"; import { runCopyID } from "./copyID.js";
export type ClientKeys = { export type ClientKeys = {
publicKey: string, publicKey: string;
username: string, username: string;
password: string, password: string;
}[]; }[];
function checkValue(input: Buffer, allowed: Buffer): boolean { function checkValue(input: Buffer, allowed: Buffer): boolean {
const autoReject = (input.length !== allowed.length); const autoReject = input.length !== allowed.length;
if (autoReject) allowed = input; if (autoReject) allowed = input;
const isMatch = timingSafeEqual(input, allowed); const isMatch = timingSafeEqual(input, allowed);
return (!autoReject && isMatch); return !autoReject && isMatch;
} }
let serverKeyFile: Buffer | string | undefined; let serverKeyFile: Buffer | string | undefined;
@ -43,7 +43,9 @@ try {
try { try {
serverKeyFile = await readFile("../keys/host.key"); serverKeyFile = await readFile("../keys/host.key");
} catch (e) { } catch (e) {
console.log("ERROR: Failed to read the host key file! Creating new keypair..."); console.log(
"ERROR: Failed to read the host key file! Creating new keypair...",
);
await mkdir("../keys").catch(() => null); await mkdir("../keys").catch(() => null);
const keyPair: { private: string; public: string } = await new Promise( const keyPair: { private: string; public: string } = await new Promise(
@ -60,11 +62,9 @@ try {
if (!serverKeyFile) throw new Error("Somehow failed to fetch the key file!"); if (!serverKeyFile) throw new Error("Somehow failed to fetch the key file!");
const server: ssh2.Server = new ssh2.Server({ const server: ssh2.Server = new ssh2.Server({
hostKeys: [ hostKeys: [serverKeyFile],
serverKeyFile
],
banner: "NextNet-LOM (c) NextNet project et al." banner: "NextNet-LOM (c) NextNet project et al.",
}); });
server.on("connection", client => { server.on("connection", client => {
@ -95,7 +95,7 @@ server.on("connection", client => {
} else if (auth.method == "publickey") { } else if (auth.method == "publickey") {
const userData = { const userData = {
username: "", username: "",
password: "" password: "",
}; };
for (const rawKey of clientKeys) { for (const rawKey of clientKeys) {
@ -109,18 +109,20 @@ server.on("connection", client => {
console.log(auth.signature, auth.blob); console.log(auth.signature, auth.blob);
if ( if (
rawKey.username == auth.username && (rawKey.username == auth.username &&
auth.key.algo == key.type && auth.key.algo == key.type &&
auth.key.data == key.getPublicSSH() && checkValue(auth.key.data, key.getPublicSSH())) ||
auth.signature && key.verify(auth.blob as Buffer, auth.signature, auth.key.algo) (auth.signature &&
key.verify(auth.blob as Buffer, auth.signature, auth.key.algo))
) { ) {
console.log(" -- VERIFIED PUBLIC KEY --"); console.log(" -- VERIFIED PUBLIC KEY --");
userData.username = rawKey.username; userData.username = rawKey.username;
userData.password = rawKey.password; userData.password = rawKey.password;
}; }
} }
if (!userData.username || !userData.password) return auth.reject(["password", "publickey"]); if (!userData.username || !userData.password)
return auth.reject(["password", "publickey"]);
const response = await axios.post("/api/v1/users/login", userData); const response = await axios.post("/api/v1/users/login", userData);
@ -146,7 +148,10 @@ server.on("connection", client => {
conn.on("exec", async (accept, reject, info) => { conn.on("exec", async (accept, reject, info) => {
const stream = accept(); const stream = accept();
if (info.command.includes(".ssh/authorized_keys") && info.command.startsWith("exec sh -c")) { if (
info.command.includes(".ssh/authorized_keys") &&
info.command.startsWith("exec sh -c")
) {
return await runCopyID(username, password, clientKeys, stream); return await runCopyID(username, password, clientKeys, stream);
} }