1 | var net = require('net');
|
2 | var debug = require('debug')('tunnel-ssh');
|
3 | var Connection = require('ssh2');
|
4 | var createConfig = require('./lib/config');
|
5 |
|
6 | function bindSSHConnection(config, netConnection) {
|
7 | var sshConnection = new Connection();
|
8 |
|
9 | sshConnection.on('ready', function() {
|
10 | debug('sshConnection:ready');
|
11 | netConnection.emit('sshConnection', sshConnection, netConnection);
|
12 |
|
13 | sshConnection.forwardOut(
|
14 | config.srcHost,
|
15 | config.srcPort,
|
16 | config.dstHost,
|
17 | config.dstPort, function(err, sshStream) {
|
18 | if (err) {
|
19 | if (!config.keepAlive) {
|
20 | server.close();
|
21 | }
|
22 |
|
23 | netConnection.emit('error', err);
|
24 | debug('Destination port:', err);
|
25 | return;
|
26 | }
|
27 | sshStream.once('close', function() {
|
28 | debug('sshStream:close');
|
29 | if (config.keepAlive) {
|
30 | sshConnection.end();
|
31 | }
|
32 | });
|
33 | debug('sshStream:create');
|
34 | netConnection.pipe(sshStream).pipe(netConnection);
|
35 | netConnection.emit('sshStream', sshStream);
|
36 | });
|
37 | });
|
38 | return sshConnection;
|
39 | }
|
40 |
|
41 | function createServer(config) {
|
42 | var server,
|
43 | sshConnection,
|
44 | connections = [];
|
45 |
|
46 | server = net.createServer(function(netConnection) {
|
47 | netConnection.on('error', server.emit.bind(server, 'error'));
|
48 | server.emit('netConnection', netConnection, server);
|
49 | sshConnection = bindSSHConnection(config, netConnection);
|
50 | netConnection.on('sshStream', function(sshStream) {
|
51 | sshStream.once('close', function() {
|
52 | debug('sshStream:close');
|
53 | if (!config.keepAlive) {
|
54 | server.close();
|
55 | }
|
56 | });
|
57 | });
|
58 | connections.push(sshConnection, netConnection);
|
59 | sshConnection.connect(config);
|
60 | });
|
61 |
|
62 | server.on('close', function() {
|
63 | connections.forEach(function(connection) {
|
64 | connection.end();
|
65 | });
|
66 | });
|
67 |
|
68 | return server;
|
69 | }
|
70 |
|
71 | function tunnel(configArgs, callback) {
|
72 |
|
73 | try {
|
74 | var config = createConfig(configArgs);
|
75 | } catch (e) {
|
76 | callback(null, e);
|
77 | }
|
78 |
|
79 | return createServer(config).listen(config.localPort, config.localHost, callback);
|
80 | }
|
81 | tunnel.reverse = require('./lib/reverse');
|
82 | module.exports = tunnel;
|