123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578 |
- 'use strict';
- const assert = require('assert');
- const { inspect } = require('util');
- const {
- mustCall,
- mustCallAtLeast,
- setupSimple,
- } = require('./common.js');
- const DEBUG = false;
- const setup = setupSimple.bind(undefined, DEBUG);
- {
- const { client, server } = setup('Simple exec()');
- const COMMAND = 'foo --bar';
- const STDOUT_DATA = 'stdout data!\n';
- const STDERR_DATA = 'stderr data!\n';
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- accept().on('exec', mustCall((accept, reject, info) => {
- assert(info.command === COMMAND,
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.stderr.write(STDERR_DATA);
- stream.write(STDOUT_DATA);
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- let out = '';
- let outErr = '';
- const events = [];
- const EXPECTED_EVENTS = [ 'exit', 'close' ];
- const EXPECTED_EXIT_CLOSE_ARGS = [ 100 ];
- client.on('close', mustCall(() => {
- assert(out === STDOUT_DATA, `Wrong stdout data: ${inspect(out)}`);
- assert(outErr === STDERR_DATA, `Wrong stderr data: ${inspect(outErr)}`);
- assert.deepStrictEqual(
- events,
- EXPECTED_EVENTS,
- `Wrong command event order: ${events}`
- );
- })).exec(COMMAND, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.on('data', mustCallAtLeast((d) => {
- out += d;
- })).on('exit', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong exit args: ${inspect(args)}`);
- events.push('exit');
- })).on('close', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong close args: ${inspect(args)}`);
- events.push('close');
- })).stderr.on('data', mustCallAtLeast((d) => {
- outErr += d;
- }));
- }));
- }));
- }
- {
- const { client, server } = setup('Simple exec() (exit signal)');
- const COMMAND = 'foo --bar';
- const STDOUT_DATA = 'stdout data!\n';
- const STDERR_DATA = 'stderr data!\n';
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- accept().on('exec', mustCall((accept, reject, info) => {
- assert(info.command === COMMAND,
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.stderr.write(STDERR_DATA);
- stream.write(STDOUT_DATA);
- assert.throws(() => stream.exit('SIGFAKE'));
- stream.exit('SIGKILL');
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- let out = '';
- let outErr = '';
- const events = [];
- const EXPECTED_EVENTS = [ 'exit', 'close' ];
- const EXPECTED_EXIT_CLOSE_ARGS = [ null, 'SIGKILL', false, '' ];
- client.on('close', mustCall(() => {
- assert(out === STDOUT_DATA, `Wrong stdout data: ${inspect(out)}`);
- assert(outErr === STDERR_DATA, `Wrong stderr data: ${inspect(outErr)}`);
- assert.deepStrictEqual(
- events,
- EXPECTED_EVENTS,
- `Wrong command event order: ${events}`
- );
- })).exec(COMMAND, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.on('data', mustCallAtLeast((d) => {
- out += d;
- })).on('exit', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong exit args: ${inspect(args)}`);
- events.push('exit');
- })).on('close', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong close args: ${inspect(args)}`);
- events.push('close');
- })).stderr.on('data', mustCallAtLeast((d) => {
- outErr += d;
- }));
- }));
- }));
- }
- {
- const { client, server } = setup('Simple exec() (exit signal -- no "SIG")');
- const COMMAND = 'foo --bar';
- const STDOUT_DATA = 'stdout data!\n';
- const STDERR_DATA = 'stderr data!\n';
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- accept().on('exec', mustCall((accept, reject, info) => {
- assert(info.command === COMMAND,
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.stderr.write(STDERR_DATA);
- stream.write(STDOUT_DATA);
- assert.throws(() => stream.exit('FAKE'));
- stream.exit('KILL');
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- let out = '';
- let outErr = '';
- const events = [];
- const EXPECTED_EVENTS = [ 'exit', 'close' ];
- const EXPECTED_EXIT_CLOSE_ARGS = [ null, 'SIGKILL', false, '' ];
- client.on('close', mustCall(() => {
- assert(out === STDOUT_DATA, `Wrong stdout data: ${inspect(out)}`);
- assert(outErr === STDERR_DATA, `Wrong stderr data: ${inspect(outErr)}`);
- assert.deepStrictEqual(
- events,
- EXPECTED_EVENTS,
- `Wrong command event order: ${events}`
- );
- })).exec(COMMAND, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.on('data', mustCallAtLeast((d) => {
- out += d;
- })).on('exit', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong exit args: ${inspect(args)}`);
- events.push('exit');
- })).on('close', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong close args: ${inspect(args)}`);
- events.push('close');
- })).stderr.on('data', mustCallAtLeast((d) => {
- outErr += d;
- }));
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with signal()');
- const COMMAND = 'foo --bar';
- const STDOUT_DATA = 'stdout data!\n';
- const STDERR_DATA = 'stderr data!\n';
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let stream;
- accept().on('exec', mustCall((accept, reject, info) => {
- assert(info.command === COMMAND,
- `Wrong exec command: ${info.command}`);
- stream = accept();
- stream.stderr.write(STDERR_DATA);
- stream.write(STDOUT_DATA);
- })).on('signal', mustCall((accept, reject, info) => {
- assert(info.name === 'INT', `Wrong client signal name: ${info.name}`);
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- let out = '';
- let outErr = '';
- const events = [];
- const EXPECTED_EVENTS = [ 'exit', 'close' ];
- const EXPECTED_EXIT_CLOSE_ARGS = [ 100 ];
- client.on('close', mustCall(() => {
- assert(out === STDOUT_DATA, `Wrong stdout data: ${inspect(out)}`);
- assert(outErr === STDERR_DATA, `Wrong stderr data: ${inspect(outErr)}`);
- assert.deepStrictEqual(
- events,
- EXPECTED_EVENTS,
- `Wrong command event order: ${events}`
- );
- })).exec(COMMAND, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- const sendSignal = (() => {
- let sent = false;
- return () => {
- if (sent)
- return;
- sent = true;
- assert.throws(() => stream.signal('FAKE'));
- assert.throws(() => stream.signal('SIGFAKE'));
- stream.signal('SIGINT');
- };
- })();
- stream.on('data', mustCallAtLeast((d) => {
- out += d;
- sendSignal();
- })).on('exit', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong exit args: ${inspect(args)}`);
- events.push('exit');
- })).on('close', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong close args: ${inspect(args)}`);
- events.push('close');
- })).stderr.on('data', mustCallAtLeast((d) => {
- outErr += d;
- }));
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with signal() -- no "SIG"');
- const COMMAND = 'foo --bar';
- const STDOUT_DATA = 'stdout data!\n';
- const STDERR_DATA = 'stderr data!\n';
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let stream;
- accept().on('exec', mustCall((accept, reject, info) => {
- assert(info.command === COMMAND,
- `Wrong exec command: ${info.command}`);
- stream = accept();
- stream.stderr.write(STDERR_DATA);
- stream.write(STDOUT_DATA);
- })).on('signal', mustCall((accept, reject, info) => {
- assert(info.name === 'INT', `Wrong client signal name: ${info.name}`);
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- let out = '';
- let outErr = '';
- const events = [];
- const EXPECTED_EVENTS = [ 'exit', 'close' ];
- const EXPECTED_EXIT_CLOSE_ARGS = [ 100 ];
- client.on('close', mustCall(() => {
- assert(out === STDOUT_DATA, `Wrong stdout data: ${inspect(out)}`);
- assert(outErr === STDERR_DATA, `Wrong stderr data: ${inspect(outErr)}`);
- assert.deepStrictEqual(
- events,
- EXPECTED_EVENTS,
- `Wrong command event order: ${events}`
- );
- })).exec(COMMAND, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- const sendSignal = (() => {
- let sent = false;
- return () => {
- if (sent)
- return;
- sent = true;
- stream.signal('INT');
- };
- })();
- stream.on('data', mustCallAtLeast((d) => {
- out += d;
- sendSignal();
- })).on('exit', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong exit args: ${inspect(args)}`);
- events.push('exit');
- })).on('close', mustCall((...args) => {
- assert.deepStrictEqual(args,
- EXPECTED_EXIT_CLOSE_ARGS,
- `Wrong close args: ${inspect(args)}`);
- events.push('close');
- })).stderr.on('data', mustCallAtLeast((d) => {
- outErr += d;
- }));
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with environment set');
- const env = { SSH2NODETEST: 'foo' };
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- accept().on('env', mustCall((accept, reject, info) => {
- accept && accept();
- assert(info.key === Object.keys(env)[0],
- 'Wrong env key');
- assert(info.val === Object.values(env)[0],
- 'Wrong env value');
- })).on('exec', mustCall((accept, reject, info) => {
- assert(info.command === 'foo --bar',
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.exec('foo --bar', { env }, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.resume();
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with setWindow()');
- const dimensions = {
- rows: 60,
- cols: 115,
- height: 480,
- width: 640,
- };
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- accept().on('window-change', mustCall((accept, reject, info) => {
- accept && accept();
- assert.deepStrictEqual(info, dimensions, 'Wrong dimensions');
- })).on('exec', mustCall((accept, reject, info) => {
- assert(info.command === 'foo --bar',
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.exec('foo --bar', mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.setWindow(...Object.values(dimensions));
- stream.resume();
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with pty set');
- const pty = {
- rows: 2,
- cols: 4,
- width: 0,
- height: 0,
- term: 'vt220',
- modes: {},
- };
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let sawPty = false;
- accept().on('pty', mustCall((accept, reject, info) => {
- assert.deepStrictEqual(info, pty, 'Wrong pty info');
- sawPty = true;
- accept && accept();
- })).on('exec', mustCall((accept, reject, info) => {
- assert(sawPty, 'Expected pty to be set up');
- assert(info.command === 'foo --bar',
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- stream.exit(100);
- stream.end();
- conn.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.exec('foo --bar', { pty }, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.resume();
- }));
- }));
- }
- {
- const { client, server } = setup('Exec with X11 forwarding');
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let sawX11 = false;
- accept().on('x11', mustCall((accept, reject, info) => {
- assert.strictEqual(info.single,
- false,
- `Wrong x11 single: ${info.single}`);
- assert.strictEqual(info.screen,
- 0,
- `Wrong x11 screen: ${info.screen}`);
- assert.strictEqual(info.protocol,
- 'MIT-MAGIC-COOKIE-1',
- `Wrong x11 protocol: ${info.protocol}`);
- assert(Buffer.isBuffer(info.cookie), 'Expected cookie Buffer');
- assert.strictEqual(
- info.cookie.length,
- 32,
- `Invalid x11 cookie length: ${info.cookie.length}`
- );
- sawX11 = true;
- accept && accept();
- })).on('exec', mustCall((accept, reject, info) => {
- assert(sawX11, 'Expected x11 before exec');
- assert(info.command === 'foo --bar',
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- conn.x11('127.0.0.1', 4321, mustCall((err, xstream) => {
- assert(!err, `Unexpected x11() error: ${err}`);
- xstream.resume();
- xstream.on('end', mustCall(() => {
- stream.exit(100);
- stream.end();
- conn.end();
- })).end();
- }));
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.on('x11', mustCall((info, accept, reject) => {
- assert.strictEqual(info.srcIP,
- '127.0.0.1',
- `Invalid x11 srcIP: ${info.srcIP}`);
- assert.strictEqual(info.srcPort,
- 4321,
- `Invalid x11 srcPort: ${info.srcPort}`);
- accept();
- })).exec('foo --bar', { x11: true }, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.resume();
- }));
- }));
- }
- {
- const { client, server } = setup(
- 'Exec with X11 forwarding (custom X11 settings)'
- );
- const x11 = {
- single: true,
- screen: 1234,
- protocol: 'YUMMY-MAGIC-COOKIE-1',
- cookie: '00112233445566778899001122334455',
- };
- server.on('connection', mustCall((conn) => {
- conn.on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let sawX11 = false;
- accept().on('x11', mustCall((accept, reject, info) => {
- assert.strictEqual(info.single,
- x11.single,
- `Wrong x11 single: ${info.single}`);
- assert.strictEqual(info.screen,
- x11.screen,
- `Wrong x11 screen: ${info.screen}`);
- assert.strictEqual(info.protocol,
- x11.protocol,
- `Wrong x11 protocol: ${info.protocol}`);
- assert(Buffer.isBuffer(info.cookie), 'Expected cookie Buffer');
- assert.strictEqual(info.cookie.toString(),
- x11.cookie,
- `Wrong x11 cookie: ${info.cookie}`);
- sawX11 = true;
- accept && accept();
- })).on('exec', mustCall((accept, reject, info) => {
- assert(sawX11, 'Expected x11 before exec');
- assert(info.command === 'foo --bar',
- `Wrong exec command: ${info.command}`);
- const stream = accept();
- conn.x11('127.0.0.1', 4321, mustCall((err, xstream) => {
- assert(!err, `Unexpected x11() error: ${err}`);
- xstream.resume();
- xstream.on('end', mustCall(() => {
- stream.exit(100);
- stream.end();
- conn.end();
- })).end();
- }));
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.on('x11', mustCall((info, accept, reject) => {
- assert.strictEqual(info.srcIP,
- '127.0.0.1',
- `Invalid x11 srcIP: ${info.srcIP}`);
- assert.strictEqual(info.srcPort,
- 4321,
- `Invalid x11 srcPort: ${info.srcPort}`);
- accept();
- })).exec('foo --bar', { x11 }, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.resume();
- }));
- }));
- }
|