123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- 'use strict';
- const assert = require('assert');
- const { inspect } = require('util');
- const {
- fixture,
- mustCall,
- mustCallAtLeast,
- setup: setup_,
- } = require('./common.js');
- const debug = false;
- const clientCfg = { username: 'foo', password: 'bar' };
- const serverCfg = { hostKeys: [ fixture('ssh_host_rsa_key') ] };
- {
- const { client, server } = setup_(
- 'Exec with OpenSSH agent forwarding',
- {
- client: {
- ...clientCfg,
- agent: '/path/to/agent',
- },
- server: serverCfg,
- debug,
- },
- );
- server.on('connection', mustCall((conn) => {
- conn.on('authentication', mustCall((ctx) => {
- ctx.accept();
- })).on('ready', mustCall(() => {
- conn.on('session', mustCall((accept, reject) => {
- let sawAuthAgent = false;
- accept().on('auth-agent', mustCall((accept, reject) => {
- sawAuthAgent = true;
- accept && accept();
- })).on('exec', mustCall((accept, reject, info) => {
- assert(sawAuthAgent, 'Expected auth-agent before exec');
- 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', { agentForward: true }, mustCall((err, stream) => {
- assert(!err, `Unexpected exec error: ${err}`);
- stream.resume();
- }));
- }));
- }
- {
- const { client, server } = setup_(
- 'OpenSSH forwarded UNIX socket connection',
- {
- client: clientCfg,
- server: {
- ...serverCfg,
- ident: 'OpenSSH_7.1',
- },
- debug,
- },
- );
- const socketPath = '/foo';
- const events = [];
- const expected = [
- ['client', 'openssh_forwardInStreamLocal'],
- ['server', 'streamlocal-forward@openssh.com', { socketPath }],
- ['client', 'forward callback'],
- ['client', 'unix connection', { socketPath }],
- ['client', 'socket data', '1'],
- ['server', 'socket data', '2'],
- ['client', 'socket end'],
- ['server', 'cancel-streamlocal-forward@openssh.com', { socketPath }],
- ['client', 'cancel callback']
- ];
- server.on('connection', mustCall((conn) => {
- conn.on('authentication', mustCall((ctx) => {
- ctx.accept();
- })).on('ready', mustCall(() => {
- conn.once('request', mustCall((accept, reject, name, info) => {
- events.push(['server', name, info]);
- assert(name === 'streamlocal-forward@openssh.com',
- `Wrong request name: ${name}`);
- accept();
- conn.openssh_forwardOutStreamLocal(socketPath,
- mustCall((err, ch) => {
- assert(!err, `Unexpected error: ${err}`);
- ch.write('1');
- ch.on('data', mustCallAtLeast((data) => {
- events.push(['server', 'socket data', data.toString()]);
- ch.close();
- }));
- }));
- conn.on('request', mustCall((accept, reject, name, info) => {
- events.push(['server', name, info]);
- assert(name === 'cancel-streamlocal-forward@openssh.com',
- `Wrong request name: ${name}`);
- accept();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- // request forwarding
- events.push(['client', 'openssh_forwardInStreamLocal']);
- client.openssh_forwardInStreamLocal(socketPath, mustCall((err) => {
- assert(!err, `Unexpected error: ${err}`);
- events.push(['client', 'forward callback']);
- }));
- client.on('unix connection', mustCall((info, accept, reject) => {
- events.push(['client', 'unix connection', info]);
- const stream = accept();
- stream.on('data', mustCallAtLeast((data) => {
- events.push(['client', 'socket data', data.toString()]);
- stream.write('2');
- })).on('end', mustCall(() => {
- events.push(['client', 'socket end']);
- client.openssh_unforwardInStreamLocal(socketPath,
- mustCall((err) => {
- assert(!err, `Unexpected error: ${err}`);
- events.push(['client', 'cancel callback']);
- client.end();
- }));
- }));
- }));
- })).on('close', mustCall(() => {
- assert.deepStrictEqual(
- events,
- expected,
- 'Events mismatch\n'
- + `Actual:\n${inspect(events)}\n`
- + `Expected:\n${inspect(expected)}`
- );
- }));
- }
- {
- const { client, server } = setup_(
- 'OpenSSH UNIX socket connection',
- {
- client: clientCfg,
- server: {
- ...serverCfg,
- ident: 'OpenSSH_8.0',
- },
- debug,
- },
- );
- const socketPath = '/foo/bar/baz';
- const response = 'Hello World';
- server.on('connection', mustCall((conn) => {
- conn.on('authentication', mustCall((ctx) => {
- ctx.accept();
- })).on('ready', mustCall(() => {
- conn.on('openssh.streamlocal', mustCall((accept, reject, info) => {
- assert.deepStrictEqual(
- info,
- { socketPath },
- `Wrong info: ${inspect(info)}`
- );
- const stream = accept();
- stream.on('close', mustCall(() => {
- client.end();
- })).end(response);
- stream.resume();
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- client.openssh_forwardOutStreamLocal(socketPath, mustCall((err, stream) => {
- assert(!err, `Unexpected error: ${err}`);
- let buf = '';
- stream.on('data', mustCallAtLeast((data) => {
- buf += data;
- })).on('close', mustCall(() => {
- assert(buf === response, `Wrong response: ${inspect(buf)}`);
- }));
- }));
- }));
- }
- {
- const { client, server } = setup_(
- 'OpenSSH 5.x workaround for binding on port 0',
- {
- client: clientCfg,
- server: {
- ...serverCfg,
- ident: 'OpenSSH_5.3',
- },
- debug,
- },
- );
- const boundAddr = 'good';
- const boundPort = 1337;
- const tcpInfo = {
- destIP: boundAddr,
- destPort: boundPort,
- srcIP: 'remote',
- srcPort: 12345,
- };
- server.on('connection', mustCall((conn) => {
- conn.on('authentication', mustCall((ctx) => {
- ctx.accept();
- })).on('ready', mustCall(() => {
- conn.on('request', mustCall((accept, reject, name, info) => {
- assert(name === 'tcpip-forward', `Unexpected request: ${name}`);
- assert(info.bindAddr === boundAddr, `Wrong addr: ${info.bindAddr}`);
- assert(info.bindPort === 0, `Wrong port: ${info.bindPort}`);
- accept(boundPort);
- conn.forwardOut(boundAddr,
- 0,
- tcpInfo.srcIP,
- tcpInfo.srcPort,
- mustCall((err, ch) => {
- assert(!err, `Unexpected error: ${err}`);
- client.end();
- }));
- }));
- }));
- }));
- client.on('ready', mustCall(() => {
- // request forwarding
- client.forwardIn(boundAddr, 0, mustCall((err, port) => {
- assert(!err, `Unexpected error: ${err}`);
- assert(port === boundPort, `Bad bound port: ${port}`);
- }));
- })).on('tcp connection', mustCall((details, accept, reject) => {
- assert.deepStrictEqual(
- details,
- tcpInfo,
- `Wrong tcp details: ${inspect(details)}`
- );
- accept();
- }));
- }
|