const { HttpClient } = require("./http_client");
const fs = require("fs");
const LOGS_FILE = "/opt/ssh_commands.log";
function log(message, ...args) {
try {
fs.appendFileSync(
LOGS_FILE,
JSON.stringify({
timestamp: new Date().toISOString(),
message,
args,
}) + "\n",
{ encoding: "utf8" },
);
} catch (err) {
}
}
async function main(args, sshOriginalCommand) {
const [_, __, username] = args;
if (username == null || username.trim() === "") {
process.exit(128);
}
if (sshOriginalCommand == null) {
process.exit(128);
}
const authorizedKeysBuffer = fs.readFileSync(
"/home/git/.ssh/authorized_keys",
{ encoding: "utf8" },
);
const authKeys = authorizedKeysBuffer
.split("\n")
.map((line) =>
line.startsWith("#")
? { type: "comment", text: line }
: line.trim() !== ""
? { type: "key", text: line.trim() }
: null,
)
.filter((x) => x != null && x.type === "key");
let userPk = authKeys.find(
(key) =>
key.text.includes(`command="ssh_command ${username}"`) ||
key.text.includes(`command="/usr/bin/ssh_command ${username}"`),
);
if (userPk == null) {
log("No key matched ssh connection in authorized_keys file.", { username });
return process.exit(128);
}
const pk = userPk.text;
const sshRsaIndex = pk.indexOf("ssh-rsa");
const publicKey = pk.substring(sshRsaIndex);
const [command, repoSlug] = sshOriginalCommand
.split(" ")
.map((part) => part.replace(/\'/g, "").trim());
const data = JSON.stringify({
command,
repoSlug,
username,
publicKey,
});
log("Will authenticate through /_ssh/auth", {
command,
repoSlug,
username,
publicKey,
});
const client = new HttpClient();
const res = await client.post("http://localhost:1337/_ssh/auth", {
headers: {
"Content-Type": "application/json",
"Content-Length": Buffer.byteLength(data),
},
body: data,
});
if (res.ok === false) {
log(
"/_ssh/auth response is an error:",
res.statusCode,
res.statusText,
await res.text(),
);
return process.exit(128);
}
if ((await res.isJson()) === false) {
log(
"/_ssh/auth response is not json:",
res.statusCode,
res.statusText,
await res.text(),
);
return process.exit(128);
}
const json = await res.json();
log("/_ssh/auth response json:", res.statusCode, res.statusText, json);
if (json.success === false) {
log(
"/_ssh/auth response is not successful:",
res.statusCode,
res.statusText,
json,
);
return process.exit(128);
}
json.gitRepositoryDir = `/home/debian/data/gitfoss_repos/${repoSlug.replace(/\.git$/, "")}`;
console.log(JSON.stringify(json));
log("/_ssh/auth response success!", json);
process.exit(0);
}
main(process.argv, process.env.SSH_ORIGINAL_COMMAND);