feature: Adds exec support.
This also lets us prepare for support for ssh-copy-id.
This commit is contained in:
parent
95b79ca364
commit
47b707e8cd
2 changed files with 57 additions and 13 deletions
|
@ -9,6 +9,7 @@ import type {
|
||||||
ParameterReturnedValue,
|
ParameterReturnedValue,
|
||||||
BackendBaseClass,
|
BackendBaseClass,
|
||||||
} from "../base.js";
|
} from "../base.js";
|
||||||
|
|
||||||
import { generateRandomData } from "../../libs/generateRandom.js";
|
import { generateRandomData } from "../../libs/generateRandom.js";
|
||||||
import { requestHandler } from "./socket.js";
|
import { requestHandler } from "./socket.js";
|
||||||
import { route } from "./routes.js";
|
import { route } from "./routes.js";
|
||||||
|
|
|
@ -39,34 +39,77 @@ if (!keyFile) 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: [keyFile],
|
hostKeys: [keyFile],
|
||||||
|
banner: "NextNet-LOM (c) NextNet project et al."
|
||||||
banner: "NextNet-LOM (c) NextNet project et al.",
|
|
||||||
greeting: "NextNet LOM (beta)",
|
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("connection", client => {
|
server.on("connection", client => {
|
||||||
let token: string = "";
|
let token: string = "";
|
||||||
|
|
||||||
|
let username: string = "";
|
||||||
|
let password: string = "";
|
||||||
|
|
||||||
client.on("authentication", async auth => {
|
client.on("authentication", async auth => {
|
||||||
if (auth.method != "password") return auth.reject(["password"]); // We need to know the password to auth with the API
|
if (auth.method == "password") {
|
||||||
|
const response = await axios.post("/api/v1/users/login", {
|
||||||
|
username: auth.username,
|
||||||
|
password: auth.password,
|
||||||
|
});
|
||||||
|
|
||||||
const response = await axios.post("/api/v1/users/login", {
|
if (response.status == 403) {
|
||||||
username: auth.username,
|
return auth.reject(["password"]);
|
||||||
password: auth.password,
|
}
|
||||||
});
|
|
||||||
|
|
||||||
if (response.status == 403) {
|
token = response.data.token;
|
||||||
return auth.reject(["password"]);
|
|
||||||
|
username = auth.username;
|
||||||
|
password = auth.password;
|
||||||
|
|
||||||
|
auth.accept();
|
||||||
|
} else if (auth.method == "publickey") {
|
||||||
|
return auth.reject();
|
||||||
|
// todo
|
||||||
|
} else {
|
||||||
|
return auth.reject(["password", "publickey"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
token = response.data.token;
|
|
||||||
auth.accept();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("ready", () => {
|
client.on("ready", () => {
|
||||||
client.on("session", (accept, reject) => {
|
client.on("session", (accept, reject) => {
|
||||||
const conn = accept();
|
const conn = accept();
|
||||||
|
|
||||||
|
conn.on("exec", async (accept, reject, info) => {
|
||||||
|
const stream = accept();
|
||||||
|
|
||||||
|
// Matches on ; and &&
|
||||||
|
const commandsRecv = info.command.split(/;|&&/).map((i) => i.trim());
|
||||||
|
|
||||||
|
function println(...data: any[]) {
|
||||||
|
stream.write(format(...data).replaceAll("\n", "\r\n"));
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const command of commandsRecv) {
|
||||||
|
const argv = parseArgsStringToArgv(command);
|
||||||
|
|
||||||
|
if (argv[0] == "exit") {
|
||||||
|
stream.close();
|
||||||
|
} else {
|
||||||
|
const command = commands.find(i => i.name == argv[0]);
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
stream.write(
|
||||||
|
`Unknown command ${argv[0]}.\r\n`,
|
||||||
|
);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await command.run(argv, println, axios, token, (disableEcho) => readFromKeyboard(stream, disableEcho));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.close();
|
||||||
|
});
|
||||||
|
|
||||||
// We're dumb. We don't really care.
|
// We're dumb. We don't really care.
|
||||||
conn.on("pty", accept => accept());
|
conn.on("pty", accept => accept());
|
||||||
conn.on("window-change", accept => {
|
conn.on("window-change", accept => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue