fix(striker-ui-api): manage vnc with higher permissions

main
Tsu-ba-me 2 years ago
parent 9b13c77752
commit 73e567b0dc
  1. 52
      striker-ui-api/src/lib/accessModule.ts
  2. 53
      striker-ui-api/src/lib/request_handlers/command/manageVncSshTunnel.ts
  3. 3
      striker-ui-api/src/lib/shell.ts

@ -131,17 +131,21 @@ class Access extends EventEmitter {
}
const access = new Access();
const rootAccess = new Access({ spawnOptions: { gid: 0, uid: 0 } });
const subroutine = async <T extends unknown[]>(
subroutine: string,
{
params = [],
pre = ['Database'],
root,
}: {
params?: unknown[];
pre?: string[];
root?: boolean;
} = {},
) => {
const selectedAccess = root ? rootAccess : access;
const chain = `${pre.join('->')}->${subroutine}`;
const subParams: string[] = params.map<string>((p) => {
@ -156,11 +160,9 @@ const subroutine = async <T extends unknown[]>(
return `"${result.replaceAll('"', '\\"')}"`;
});
const { sub_results: results } = await access.interact<{ sub_results: T }>(
'x',
chain,
...subParams,
);
const { sub_results: results } = await selectedAccess.interact<{
sub_results: T;
}>('x', chain, ...subParams);
shvar(results, `${chain} results: `);
@ -382,6 +384,45 @@ const getUpsSpec = async () => {
return getData<AnvilDataUPSHash>('ups_data');
};
const vncpipe = async (serverUuid: string, open?: boolean) => {
const [output, rReturnCode]: [string, string] = await subroutine('call', {
params: [
{
shell_call: `${
SERVER_PATHS.usr.sbin['striker-manage-vnc-pipes'].self
} -vv --server-uuid ${serverUuid} --component st${
open ? ' --open' : ''
}`,
},
],
pre: ['System'],
root: true,
});
const rcode = Number.parseInt(rReturnCode);
if (rcode !== 0) {
throw new Error(`VNC pipe call failed with code ${rcode}`);
}
const lines = output.split('\n');
const lastLine = lines[lines.length - 1];
const rVncPipeProps = lastLine
.split(',')
.reduce<Record<string, string>>((previous, pair) => {
const [key, value] = pair.trim().split(/\s*:\s*/, 2);
previous[key] = value;
return previous;
}, {});
const forwardPort = Number.parseInt(rVncPipeProps.forward_port);
const protocol = rVncPipeProps.protocol;
return { forwardPort, protocol };
};
export {
insertOrUpdateJob as job,
insertOrUpdateUser,
@ -401,5 +442,6 @@ export {
getUpsSpec,
query,
subroutine as sub,
vncpipe,
write,
};

@ -3,14 +3,15 @@ import { RequestHandler } from 'express';
import { REP_UUID } from '../../consts';
import { vncpipe } from '../../accessModule';
import { sanitize } from '../../sanitize';
import { stderr, vncpipe } from '../../shell';
import { stderr, stdoutVar } from '../../shell';
export const manageVncSshTunnel: RequestHandler<
unknown,
{ forwardPort: number; protocol: string },
{ open: boolean; serverUuid: string }
> = (request, response) => {
> = async (request, response) => {
const { body: { open: rOpen, serverUuid: rServerUuid } = {} } = request;
const isOpen = sanitize(rOpen, 'boolean');
@ -27,53 +28,25 @@ export const manageVncSshTunnel: RequestHandler<
return response.status(400).send();
}
let cstdout = '';
stdoutVar({ isOpen, serverUuid }, 'Manage VNC SSH tunnel params: ');
try {
cstdout = vncpipe(
'--server-uuid',
serverUuid,
'--component',
'st',
isOpen ? '--open' : '',
);
} catch (error) {
stderr(
`Failed to ${
isOpen ? 'open' : 'close'
} VNC SSH tunnel to server ${serverUuid}; CAUSE: ${error}`,
);
let operation = 'close';
return response.status(500).send();
if (isOpen) {
operation = 'open';
}
const coutput = cstdout
.split(/\s*,\s*/)
.reduce<Record<string, string>>((previous, pair: string) => {
const [key, value] = pair.split(/\s*:\s*/, 2);
previous[key] = value;
return previous;
}, {});
let forwardPort: number;
let protocol: string;
let rsbody: { forwardPort: number; protocol: string };
try {
assert('forwardPort' in coutput, 'Missing forward port in command output');
assert('protocol' in coutput, 'Missing protocol in command output');
forwardPort = Number.parseInt(coutput.forwardPort);
protocol = coutput.protocol;
rsbody = await vncpipe(serverUuid, isOpen);
} catch (error) {
stderr(`Failed to get VNC SSH tunnel connect info; CAUSE: ${error}`);
stderr(
`Failed to ${operation} VNC SSH tunnel to server ${serverUuid}; CAUSE: ${error}`,
);
return response.status(500).send();
}
return response.json({
forwardPort,
protocol,
});
return response.json(rsbody);
};

@ -47,9 +47,6 @@ export const rm = (...args: string[]) =>
export const uuidgen = (...args: string[]) =>
systemCall(SERVER_PATHS.usr.bin.uuidgen.self, args);
export const vncpipe = (...args: string[]) =>
systemCall(SERVER_PATHS.usr.sbin['striker-manage-vnc-pipes'].self, args);
export const resolveId = (id: number | string, database: string) =>
Number.parseInt(getent(database, String(id)).split(':', 3)[2]);

Loading…
Cancel
Save