Skip to content

Commit

Permalink
Merge branch 'main' into fabian/eng-2740-ssh-use-elapsed-time
Browse files Browse the repository at this point in the history
  • Loading branch information
fabgo committed Oct 3, 2024
2 parents d95ef7c + fe72810 commit 9c4ab9f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@p0security/cli",
"version": "0.11.1",
"version": "0.11.2",
"description": "Execute infra CLI commands with P0 grants",
"main": "index.ts",
"repository": {
Expand Down
41 changes: 36 additions & 5 deletions src/plugins/ssh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,14 @@ const RETRY_DELAY_MS = 5000;
const accessPropagationGuard = (
provider: SshProvider,
child: ChildProcessByStdio<null, null, Readable>,
debug?: boolean
options: SpawnSshNodeOptions
) => {
let isEphemeralAccessDeniedException = false;
let isLoginException = false;

child.stderr.on("data", (chunk) => {
const chunkString: string = chunk.toString("utf-8");

if (debug) print2(chunkString);
parseAndPrintSshOutputToStderr(chunkString, options);

const match = provider.unprovisionedAccessPatterns.find((message) =>
chunkString.match(message.pattern)
Expand All @@ -83,6 +82,36 @@ const accessPropagationGuard = (
};
};

/**
* Parses and prints a chunk of SSH output to stderr.
*
* If debug is enabled, all output is printed. Otherwise, only selected messages are printed.
*
* @param chunkString the chunk to print
* @param options SSH spawn options
*/
const parseAndPrintSshOutputToStderr = (
chunkString: string,
options: SpawnSshNodeOptions
) => {
const lines = chunkString.split("\n");
const isPreTest = options.isAccessPropagationPreTest;

for (const line of lines) {
if (options.debug) {
print2(line);
} else {
if (!isPreTest && line.includes("Authenticated to")) {
// We want to let the user know that they successfully authenticated
print2(line);
} else if (!isPreTest && line.includes("port forwarding failed")) {
// We also want to let the user know if port forwarding failed
print2(line);
}
}
}
};

const spawnChildProcess = (
credential: AwsCredentials | undefined,
command: string,
Expand Down Expand Up @@ -140,7 +169,7 @@ async function spawnSshNode(
const { isAccessPropagated, isLoginException } = accessPropagationGuard(
provider,
child,
options.debug
options
);

const exitListener = child.on("exit", (code) => {
Expand Down Expand Up @@ -256,8 +285,9 @@ const addCommonArgs = (args: CommandArgs, proxyCommand: string[]) => {
sshOptions.push("-o", `ProxyCommand=${proxyCommand.join(" ")}`);
}

// Force verbose output from SSH so we can parse the output
const verboseOptionExists = sshOptions.some((opt) => opt === "-v");
if (!verboseOptionExists && args.debug) {
if (!verboseOptionExists) {
sshOptions.push("-v");
}
};
Expand Down Expand Up @@ -317,6 +347,7 @@ const preTestAccessPropagationIfNeeded = async <
endTime: number
) => {
const testCmdArgs = sshProvider.preTestAccessPropagationArgs(cmdArgs);

// Pre-testing comes at a performance cost because we have to execute another ssh subprocess after
// a successful test. Only do when absolutely necessary.
if (testCmdArgs) {
Expand Down

0 comments on commit 9c4ab9f

Please sign in to comment.