Skip to content

Commit

Permalink
Server: allow injected sockets
Browse files Browse the repository at this point in the history
Fixes: #1027
  • Loading branch information
mscdex committed Aug 8, 2021
1 parent 3e7fcb3 commit f53ad45
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,8 @@ You can find more examples in the `examples` directory of this repository.

* **debug** - _function_ - Set this to a function that receives a single string argument to get detailed (local) debug information. **Default:** (none)

* **injectSocket**(< _DuplexStream_ >socket) - Injects a bidirectional stream as though it were a TCP socket connection. Additionally, `socket` should include `net.Socket`-like properties to ensure the best compatibility (e.g. `socket.remoteAddress`, `socket.remotePort`, `socket.remoteFamily`).

#### Connection events

* **authentication**(< _AuthContext_ >ctx) - The client has requested authentication. `ctx.username` contains the client username, `ctx.method` contains the requested authentication method, and `ctx.accept()` and `ctx.reject([< Array >authMethodsLeft[, < Boolean >isPartialSuccess]])` are used to accept or reject the authentication request respectively. `abort` is emitted if the client aborts the authentication request. Other properties/methods available on `ctx` depends on the `ctx.method` of authentication the client has requested:
Expand Down
4 changes: 4 additions & 0 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,10 @@ class Server extends EventEmitter {
this.maxConnections = Infinity;
}

injectSocket(socket) {
this._srv.emit('connection', socket);
}

listen(...args) {
this._srv.listen(...args);
return this;
Expand Down
32 changes: 31 additions & 1 deletion test/test-misc-client-server.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';

const assert = require('assert');
const { createHash } = require('crypto');
const http = require('http');
const https = require('https');
const { createHash } = require('crypto');
const net = require('net');
const { Transform } = require('stream');
const { inspect } = require('util');

const Client = require('../lib/client.js');
Expand Down Expand Up @@ -1397,3 +1398,32 @@ const setup = setupSimple.bind(undefined, debug);
assert.strictEqual(client._chanMgr._count, 0);
}));
}

{
// Allow injected sockets

const socket = new Transform({
emitClose: true,
autoDestroy: true,
transform: (chunk, encoding, cb) => {
cb();
},
});
socket.remoteAddress = '127.0.0.1';
socket.remotePort = '12345';
socket.remoteFamily = 'IPv4';
socket.push(Buffer.from('SSH-2.0-foo\r\n'));

const server = new Server(serverCfg);
server.on('connection', mustCall((conn, info) => {
assert.strictEqual(info.header.versions.software, 'foo');
assert.strictEqual(info.ip, '127.0.0.1');
assert.strictEqual(info.port, '12345');
assert.strictEqual(info.family, 'IPv4');
conn.on('ready', mustNotCall());
conn.on('close', mustCall());
socket.end();
}));
server.injectSocket(socket);
}

0 comments on commit f53ad45

Please sign in to comment.