New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tunnel-ssh

Package Overview
Dependencies
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tunnel-ssh - npm Package Compare versions

Comparing version 4.1.6 to 5.0.0

140

index.js

@@ -1,112 +0,62 @@

var net = require('net');
var debug = require('debug')('tunnel-ssh');
var Connection = require('ssh2').Client;
var createConfig = require('./lib/config');
var events = require('events');
var noop = function () {
};
const net = require('net');
const { Client } = require('ssh2');
function bindSSHConnection(config, netConnection) {
var sshConnection = new Connection();
netConnection.on('close', sshConnection.end.bind(sshConnection));
sshConnection.on('ready', function () {
debug('sshConnection:ready');
netConnection.emit('sshConnection', sshConnection, netConnection);
sshConnection.forwardOut(config.srcHost, config.srcPort, config.dstHost, config.dstPort, function (err, sshStream) {
if (err) {
// Bubble up the error => netConnection => server
netConnection.emit('error', err);
debug('Destination port:', err);
return;
function autoClose(server){
let interval = setInterval(()=>{
server.getConnections((error, count)=>{
if(count === 0){
server.close();
clearInterval(interval);
}
});
}, 1000);
}
debug('sshStream:create');
netConnection.emit('sshStream', sshStream);
netConnection.pipe(sshStream).pipe(netConnection);
});
async function createServer(options){
return new Promise(function(resolve, reject){
let server = net.createServer();
server.listen(options);
server.on('listening', ()=> resolve(server));
server.on('error', reject);
});
return sshConnection;
}
function omit(obj, keys) {
return keys.reduce(function (copyObj, key) {
delete copyObj[key];
return copyObj;
}, Object.assign({}, obj));
async function createClient(config){
return new Promise(function(resolve, reject){
let conn = new Client();
conn.on('ready', () => resolve(conn));
conn.on('error', reject);
conn.connect(config);
});
}
function createServer(config) {
var server;
var connections = [];
var connectionCount = 0;
async function createTunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions){
server = net.createServer(function (netConnection) {
var sshConnection;
connectionCount++;
netConnection.on('error', server.emit.bind(server, 'error'));
netConnection.on('close', function () {
connectionCount--;
if (connectionCount === 0) {
if (!config.keepAlive) {
setTimeout(function () {
if (connectionCount === 0) {
server.close();
}
}, 2);
}
}
});
let isVirginConnection = true;
server.emit('netConnection', netConnection, server);
sshConnection = bindSSHConnection(config, netConnection);
sshConnection.on('error', server.emit.bind(server, 'error'));
return new Promise(function(resolve, reject){
createServer(serverOptions).then(function(server, reject){
createClient(sshOptions).then(function(conn){
server.on('connection',(connection)=>{
if(isVirginConnection && tunnelOptions.autoClose){
isVirginConnection = false;
autoClose(server);
}
netConnection.on('sshStream', function (sshStream) {
sshStream.on('error', function () {
server.close();
conn.forwardOut(
forwardOptions.srcAddr,
forwardOptions.srcPort,
forwardOptions.dstAddr,
forwardOptions.dstPort, (err, stream) => {
connection.pipe(stream).pipe(connection);
});
});
server.on('close',()=> conn.end());
resolve([server, conn]);
});
});
connections.push(sshConnection, netConnection);
try {
sshConnection.connect(omit(config, ['localPort', 'localHost']));
} catch (error) {
server.emit('error', error);
}
});
server.on('close', function () {
connections.forEach(function (connection) {
connection.end();
});
});
return server;
}
function tunnel(configArgs, callback) {
var server;
var config;
if (!callback) {
callback = noop;
}
try {
config = createConfig(configArgs);
server = createServer(config);
server.listen(config.localPort, config.localHost, function (error) {
callback(error, server);
});
} catch (e) {
server = new events.EventEmitter();
setImmediate(function () {
callback(e);
server.emit('error', e);
});
}
return server;
}
module.exports = tunnel;
exports.createTunnel = createTunnel;
{
"name": "tunnel-ssh",
"version": "4.1.6",
"version": "5.0.0",
"description": "Easy extendable SSH tunnel",
"main": "index.js",
"scripts": {
"test": "mocha && eslint ."
"publishConfig":{
"registry":"https://registry.npmjs.org"
},
"scripts": {},
"repository": {

@@ -18,3 +19,5 @@ "type": "git",

"develop",
"net"
"net",
"ssh-tunnel",
"network"
],

@@ -27,24 +30,4 @@ "author": {

"dependencies": {
"debug": "2.6.9",
"lodash.defaults": "^4.1.0",
"ssh2": "1.4.0"
},
"devDependencies": {
"chai": "3.5.0",
"eslint": "^3.2.2",
"eslint-config-xo": "^0.17.0",
"mocha": "^3.5.3"
},
"eslintConfig": {
"extends": "xo",
"env": {
"mocha": true
},
"rules": {
"indent": [
"error",
4
]
}
"ssh2": "^1.11.0"
}
}

@@ -11,17 +11,31 @@ Tunnel-SSH

### Latest Relese 4.1.3
### Latest Relese 5.0.0
## Release notes
* Closing sshconnections correctly thx @actionshrimp
* Improved readme
* Updated modules
### Breaking change in 5.0.0
Please note that release 5.0.0 uses a complete different approch for configuration and is not compatible to prio versions.
Special thanks to
@vweevers and @dickeyxxx
## Concept
Tunnel-ssh v5 is designed to be very extendable and does not provide as much sematic sugar as prio versions.
The design goal was to use the original settings for each part used in the project to be able to use all possible
binding features from client and server.
The configuration is separated in the following parts:
### Related projects
* [If you don't want to wrap a tunnel around your code: inject-tunnel-ssh](https://github.com/agebrock/inject-tunnel-ssh)
* [If you need it the other way around: reverse-tunnel-ssh](https://github.com/agebrock/reverse-tunnel-ssh)
* Tunnel server
* TCP Server
* SSH Client
* SSH Forwarding
### Tunnel Server Settings
This configuration controls be behaviour of the tunnel server.
Currently there is only one option available.
```
const tunnelOptions = {
autoClose:true
}
```
### Integration

@@ -28,0 +42,0 @@ By default tunnel-ssh will close the tunnel after a client disconnects, so your cli tools should work in the same way, they do if you connect directly.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc