Skip to content

Commit

Permalink
feat(endo): Support exec shell environment
Browse files Browse the repository at this point in the history
  • Loading branch information
kriskowal committed Aug 24, 2020
1 parent 3985e72 commit de0ea45
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 9 deletions.
9 changes: 5 additions & 4 deletions packages/endo/bin/endo.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node
import fs from "fs";
import { main } from "../src/cli.js";

main(process, { fs: fs.promises });
(async () => {
const fs = await import("fs");
const { main } = await import("../src/cli.js");
main(process, { fs: fs.promises });
})();
1 change: 1 addition & 0 deletions packages/endo/mitm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node
3 changes: 2 additions & 1 deletion packages/endo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
"browser": "./dist/endo.umd.js"
},
"bin": {
"endo": "./bin/endo"
"endo": "./bin/endo.js"
},
"scripts": {
"build": "rollup --config rollup.config.js",
"clean": "rm -rf dist",
"depcheck": "depcheck",
"lint": "eslint '**/*.js'",
"lint-fix": "eslint --fix '**/*.js'",
"postinstall": "node src/postinstall.js",
"prepublish": "yarn clean && yarn build",
"test": "yarn build && tap --no-esm --no-coverage --reporter spec 'test/**/*.test.js'"
},
Expand Down
20 changes: 16 additions & 4 deletions packages/endo/src/cli.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
/* eslint no-shadow: [0] */
import "./lockdown.js";
import subprocess from "child_process";
import { writeArchive } from "./main.js";
import { search } from "./search.js";
import { compartmentMapForNodeModules } from "./compartmap.js";

const mitmPath = new URL("../mitm", import.meta.url).pathname;

function usage(message) {
console.error(message);
return 1;
Expand Down Expand Up @@ -36,7 +39,7 @@ async function parameter(args, handle, usage) {
return handle(arg, rest);
}

async function run(args, { cwd, read, write, stdout }) {
async function run(args, { cwd, read, write, stdout, env }) {
async function compartmap(args) {
async function handleEntry(applicationPath, args) {
if (args.length) {
Expand Down Expand Up @@ -72,12 +75,20 @@ async function run(args, { cwd, read, write, stdout }) {
return parameter(args, handleArchive, noArchiveUsage);
}

return subcommand(args, { compartmap, archive });
async function exec([arg, ...args]) {
const child = subprocess.spawn(arg, args, {
env: { ...env, PATH: `${mitmPath}:${env.PATH}` },
stdio: "inherit"
});
return new Promise(resolve => child.on("exit", resolve));
}

return subcommand(args, { compartmap, archive, exec });
}

export async function main(process, modules) {
const { fs } = modules;
const { cwd, stdout } = process;
const { cwd, stdout, env } = process;

// Filesystem errors often don't have stacks:

Expand All @@ -102,7 +113,8 @@ export async function main(process, modules) {
read,
write,
cwd,
stdout
stdout,
env
});
} catch (error) {
process.exitCode = usage(error.stack || error.message);
Expand Down
17 changes: 17 additions & 0 deletions packages/endo/src/lockdown.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* global lockdown */

// This is a CommonJS module, to be used like `node -r endo/src/lockdown.cjs`.
// The `endo exec` command stages a man-in-the-middle `node` shell script that
// in turn injects this SES lockdown parameter in all Node.js commands in the
// resulting shell environment.
// The taming behavior may be overridden with environment variables
// like `ERROR_TAMING=unsafe endo exec node ...`

require("ses");
lockdown({
dateTaming: process.env.ENDO_DATE_TAMING || 'safe',
errorTaming: process.env.ENDO_ERROR_TAMING || 'safe',
mathTaming: process.env.ENDO_MATH_TAMING || 'safe',
regExpTaming: process.env.ENDO_REGEXP_TAMING || 'safe',
localeTaming: process.env.ENDO_LOCAlE_TAMING || 'safe',
});
2 changes: 2 additions & 0 deletions packages/endo/src/lockdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* global lockdown */
import "ses";

// This is used by Endo to lockdown its own start compartment.

lockdown({
errorTaming: "unsafe"
});
17 changes: 17 additions & 0 deletions packages/endo/src/postinstall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This postinstall hook creates mitm/node.
// This in turn interposes SES lockdown for all descendent processes, provided
// that the mitm directory is appears before Node.js's bin directory on the
// environment PATH.

import fs from "fs";

const node = process.argv[0];
const lockdown = new URL("../src/lockdown.cjs", import.meta.url).pathname;
const mitm = new URL("../mitm/node", import.meta.url).pathname;

const script = `#!/bin/bash
set -ueo pipefail
${node} -r ${lockdown} "$@"`;

fs.writeFileSync(mitm, script, "utf-8");
fs.chmodSync(mitm, 0o755);

0 comments on commit de0ea45

Please sign in to comment.