Skip to content

Instantly share code, notes, and snippets.

@thotypous
Created June 17, 2010 15:52
Show Gist options
  • Select an option

  • Save thotypous/442300 to your computer and use it in GitHub Desktop.

Select an option

Save thotypous/442300 to your computer and use it in GitHub Desktop.
//
// SSH & SSL muxer - mux those restrictive proxies
//
// mux_interval
// |
// |\ |
// | \|
// ssl_port -----| \
// | |
// | |---- mux_port
// | |
// ssh_port -----| /
// | /
// |/
//
// Copyright (c) 2010 Paulo Matias
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
//
// SSL clients always send data just after connection.
// SSH clients don't send data until the server begins the handshake.
// We mux from SSL to SSH if no data is received after mux_interval.
//
var mux_interval = 7000; // interval to switch from ssl to ssh, in ms
var ssl_port = 443;
var ssh_port = 22;
var mux_port = 44322;
var sys = require('sys');
var net = require('net');
process.addListener('uncaughtException', function(err) {
sys.log('Uncaught exception:');
sys.puts(sys.inspect(err));
});
var server = net.createServer(function(stream) {
var muxIn = null;
stream.setTimeout(20 * 60 * 1000);
function setInPort(port) {
muxIn = net.createConnection(port);
muxIn.setTimeout(20 * 60 * 1000);
muxIn.addListener('data', function(data) {
if(!stream.write(data))
muxIn.pause();
});
muxIn.addListener('drain', function() {
stream.resume();
});
muxIn.addListener('end', function() {
try {
stream.end();
}
catch(e) {
}
muxIn.end();
});
muxIn.addListener('error', function(err) {
muxIn.emit('end');
});
}
stream.addListener('connect', function() {
setTimeout(function() {
if(!muxIn)
setInPort(ssh_port);
}, mux_interval);
});
stream.addListener('data', function(data) {
if(!muxIn)
setInPort(ssl_port);
if(muxIn.readyState == 'opening')
muxIn.addListener('connect', function() {
muxIn.write(data);
});
else if(!muxIn.write(data))
stream.pause();
});
stream.addListener('drain', function() {
if(muxIn)
muxIn.resume();
});
stream.addListener('end', function() {
try {
muxIn.end();
}
catch(e) {
}
stream.end();
});
stream.addListener('error', function(err) {
stream.emit('end');
});
});
server.listen(mux_port);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment