| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | var os = require('os'); | 
					
						
							|  |  |  | var path = require('path'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  | module.exports.print = function (config) { | 
					
						
							|  |  |  |   var services = { https: {}, http: {}, tcp: {} }; | 
					
						
							|  |  |  |   // Note: the remote needs to know:
 | 
					
						
							|  |  |  |   //   what servernames to forward
 | 
					
						
							|  |  |  |   //   what ports to forward
 | 
					
						
							|  |  |  |   //   what udp ports to forward
 | 
					
						
							|  |  |  |   //   redirect http to https automatically
 | 
					
						
							|  |  |  |   //   redirect www to nowww automatically
 | 
					
						
							|  |  |  |   if (config.http) { | 
					
						
							|  |  |  |     Object.keys(config.http).forEach(function (hostname) { | 
					
						
							|  |  |  |       if ('*' === hostname) { | 
					
						
							|  |  |  |         config.servernames.forEach(function (servername) { | 
					
						
							|  |  |  |           services.https[servername] = config.http[hostname]; | 
					
						
							|  |  |  |           services.http[servername] = 'redirect-https'; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       services.https[hostname] = config.http[hostname]; | 
					
						
							|  |  |  |       services.http[hostname] = 'redirect-https'; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   /* | 
					
						
							|  |  |  |   Object.keys(config.localPorts).forEach(function (port) { | 
					
						
							|  |  |  |     var proto = config.localPorts[port]; | 
					
						
							|  |  |  |     if (!proto) { return; } | 
					
						
							|  |  |  |     if ('http' === proto) { | 
					
						
							|  |  |  |       config.servernames.forEach(function (servername) { | 
					
						
							|  |  |  |         services.http[servername] = port; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if ('https' === proto) { | 
					
						
							|  |  |  |       config.servernames.forEach(function (servername) { | 
					
						
							|  |  |  |         services.https[servername] = port; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (true === proto) { proto = 'tcp'; } | 
					
						
							|  |  |  |     if ('tcp' !== proto) { throw new Error("unsupported protocol '" + proto + "'"); } | 
					
						
							|  |  |  |   //services[proxy.protocol]['*'] = proxy.port;
 | 
					
						
							|  |  |  |   //services[proxy.protocol][proxy.hostname] = proxy.port;
 | 
					
						
							|  |  |  |     services[proto]['*'] = port; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Object.keys(services).forEach(function (protocol) { | 
					
						
							|  |  |  |     var subServices = services[protocol]; | 
					
						
							|  |  |  |     Object.keys(subServices).forEach(function (hostname) { | 
					
						
							|  |  |  |       console.info('[local proxy]', protocol + '://' + hostname + ' => ' + subServices[hostname]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   console.info(''); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 00:19:53 -06:00
										 |  |  | module.exports.assign = function (state, tun, cb) { | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  |   console.log('first message from', tun); | 
					
						
							| 
									
										
										
										
											2018-05-31 00:19:53 -06:00
										 |  |  |   var net = state.net || require('net'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |   function trySsh(tun, cb) { | 
					
						
							|  |  |  |     // https://security.stackexchange.com/questions/43231/plausibly-deniable-ssh-does-it-make-sense?rq=1
 | 
					
						
							|  |  |  |     // https://tools.ietf.org/html/rfc4253#section-4.2
 | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  |     var sshPort; | 
					
						
							|  |  |  |     if (-1 !== ['true', 'enable', 'auto', 'on'].indexOf(state.config.sshAuto)) { | 
					
						
							|  |  |  |       sshPort = 22; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       sshPort = parseInt(state.config.sshAuto, 10); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!sshPort || 'SSH-2.0-' !== tun.data.slice(0, 8).toString()) { | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |       cb(null, false); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  |     cb(null, getNetConn(sshPort)); | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |   var handlers = {}; | 
					
						
							|  |  |  |   handlers.http = function (socket) { | 
					
						
							|  |  |  |     if (!state.greenlock) { | 
					
						
							|  |  |  |       state.greenlock = require('greenlock').create(state.greenlockConfig); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!state.httpRedirectServer) { | 
					
						
							|  |  |  |       state.redirectHttps = require('redirect-https')(); | 
					
						
							|  |  |  |       state.httpRedirectServer = require('http').createServer(state.greenlock.middleware(state.redirectHttps)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     state.httpRedirectServer.emit('connection', socket); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   handlers.https = function (tlsSocket) { | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |     console.log('Encrypted', tlsSocket.encrypted, tlsSocket.remoteAddress, tlsSocket.remotePort); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |     if (!state.defaultHttpServer) { | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       state._finalHandler = require('finalhandler'); | 
					
						
							|  |  |  |       state._serveStatic = require('serve-static'); | 
					
						
							|  |  |  |       state._defaultServe = state._serveStatic(path.join(__dirname, 'html')); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       state.defaultHttpServer = require('http').createServer(function (req, res) { | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |         state._defaultServe(req, res, state._finalHandler(req, res)); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     state.defaultHttpServer.emit('connection', tlsSocket); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |   function getNetConn(port) { | 
					
						
							|  |  |  |     var netOpts = { | 
					
						
							|  |  |  |       port: port | 
					
						
							|  |  |  |     , host: '127.0.0.1' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     , servername: tun.name | 
					
						
							|  |  |  |     , name: tun.name | 
					
						
							|  |  |  |     , serviceport: tun.serviceport | 
					
						
							|  |  |  |     , data: tun.data | 
					
						
							|  |  |  |     , remoteFamily: tun.family | 
					
						
							|  |  |  |     , remoteAddress: tun.address | 
					
						
							|  |  |  |     , remotePort: tun.port | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     var conn = net.createConnection(netOpts, function () { | 
					
						
							|  |  |  |       // this will happen before 'data' or 'readable' is triggered
 | 
					
						
							|  |  |  |       // We use the data from the netOpts object so that the createConnection function has
 | 
					
						
							|  |  |  |       // the oppurtunity of removing/changing it if it wants/needs to handle it differently.
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     return conn; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |   function redirectHttp(cb) { | 
					
						
							|  |  |  |     var socketPair = require('socket-pair'); | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |     var conn = socketPair.create(function (err, other) { | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       if (err) { cb(err); return; } | 
					
						
							|  |  |  |       handlers.http(other); | 
					
						
							|  |  |  |       cb(null, conn); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     //if (tun.data) { conn.write(tun.data); }
 | 
					
						
							|  |  |  |     return conn; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 03:50:27 -06:00
										 |  |  |   function echoTcp(cb) { | 
					
						
							|  |  |  |     var socketPair = require('socket-pair'); | 
					
						
							|  |  |  |     var conn = socketPair.create(function (err, other) { | 
					
						
							|  |  |  |       if (err) { cb(err); return; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       other.on('data', function (chunk) { | 
					
						
							|  |  |  |         other.write(chunk); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       other.on('end', function () { | 
					
						
							|  |  |  |         other.end(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cb(null, conn); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |       other.write("\n" + | 
					
						
							|  |  |  |       [ "[Telebit Echo Server] v1.0" | 
					
						
							|  |  |  |       , "To configure tcp run the following:" | 
					
						
							|  |  |  |       , "\ttelebit tcp <port number or module name>" | 
					
						
							|  |  |  |       , "\tex: telebit tcp 5050" | 
					
						
							|  |  |  |       , "\tex: telebit tcp /path/to/module" | 
					
						
							|  |  |  |       , "\tex: telebit tcp none" | 
					
						
							|  |  |  |       ].join("\n") + "\n\n"); | 
					
						
							| 
									
										
										
										
											2018-06-01 03:50:27 -06:00
										 |  |  |     }); | 
					
						
							|  |  |  |     //if (tun.data) { conn.write(tun.data); }
 | 
					
						
							|  |  |  |     return conn; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |   function defineProps(other, tun) { | 
					
						
							|  |  |  |     Object.defineProperty(other, 'remoteFamily', { | 
					
						
							|  |  |  |       enumerable: false, | 
					
						
							|  |  |  |       configurable: true, | 
					
						
							|  |  |  |       get: function() { | 
					
						
							|  |  |  |         return tun.family; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     Object.defineProperty(other, 'remoteAddress', { | 
					
						
							|  |  |  |       enumerable: false, | 
					
						
							|  |  |  |       configurable: true, | 
					
						
							|  |  |  |       get: function() { | 
					
						
							|  |  |  |         return tun.address; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     Object.defineProperty(other, 'remotePort', { | 
					
						
							|  |  |  |       enumerable: false, | 
					
						
							|  |  |  |       configurable: true, | 
					
						
							|  |  |  |       get: function() { | 
					
						
							|  |  |  |         return parseInt(tun.port); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     Object.defineProperty(other, 'localPort', { | 
					
						
							|  |  |  |       enumerable: false, | 
					
						
							|  |  |  |       configurable: true, | 
					
						
							|  |  |  |       get: function() { | 
					
						
							|  |  |  |         return parseInt(tun.serviceport); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |   function invokeTcpHandler(conf, socket, tun, id, cb) { | 
					
						
							|  |  |  |     var conn; | 
					
						
							|  |  |  |     if (parseInt(conf.handler, 10)) { | 
					
						
							|  |  |  |       conn = getNetConn(conf.handler); | 
					
						
							|  |  |  |       cb(null, conn); | 
					
						
							|  |  |  |       return conn; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var handle = tun.port; | 
					
						
							|  |  |  |     var handler; | 
					
						
							|  |  |  |     var handlerpath = conf.handler; | 
					
						
							|  |  |  |     var homedir = os.homedir(); | 
					
						
							|  |  |  |     var localshare = path.join(homedir, '.local/share/telebit/apps'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (/^~/.test(handlerpath)) { | 
					
						
							|  |  |  |       handlerpath = path.join(homedir, handlerpath.replace(/^~(\/?)/, '')); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try { | 
					
						
							|  |  |  |       handler = require(handlerpath); | 
					
						
							|  |  |  |       console.info("Handling '" + handle + ":" + id + "' with '" + handlerpath + "'"); | 
					
						
							|  |  |  |     } catch(e1) { | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         handler = require(path.join(localshare, handlerpath)); | 
					
						
							|  |  |  |         console.info("Handling '" + handle + ":" + id + "' with '" + handlerpath + "'"); | 
					
						
							|  |  |  |       } catch(e2) { | 
					
						
							| 
									
										
										
										
											2018-06-09 15:52:15 -06:00
										 |  |  |         console.error("Failed to require('" + handlerpath + "'):", e1.message); | 
					
						
							|  |  |  |         console.error("Failed to require('" + path.join(localshare, handlerpath) + "'):", e2.message); | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |         console.warn("Using default handler for '" + handle + ":" + id + "'"); | 
					
						
							|  |  |  |         echoTcp(cb); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     var socketPair = require('socket-pair'); | 
					
						
							|  |  |  |     conn = socketPair.create(function (err, other) { | 
					
						
							|  |  |  |       handler(other, tun, id); | 
					
						
							|  |  |  |       cb(null, conn); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     return conn; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  |   var handlerservers = {}; | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  |   function invokeHandler(conf, tlsSocket, tun, id) { | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |     var conn; | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |     if (parseInt(conf.handler, 10)) { | 
					
						
							|  |  |  |       // TODO http-proxy with proper headers and ws support
 | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |       conn = getNetConn(conf.handler); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |       console.info("Port-Forwarding '" + (tun.name || tun.serviceport) + "' to '" + conf.handler + "'"); | 
					
						
							|  |  |  |       conn.pipe(tlsSocket); | 
					
						
							|  |  |  |       tlsSocket.pipe(conn); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     var handle = tun.name || tun.port; | 
					
						
							|  |  |  |     var handler; | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |     var handlerpath = conf.handler; | 
					
						
							|  |  |  |     var homedir = os.homedir(); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |     var localshare = path.join(homedir, '.local/share/telebit/apps'); | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  |     var http = require('http'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // 1. No modification handlerpath may be an aboslute path
 | 
					
						
							|  |  |  |     // 2. it may be relative to a user home directory
 | 
					
						
							|  |  |  |     // 3. it may be relative to a user local/share
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tlsSocket._tun = tun; | 
					
						
							|  |  |  |     tlsSocket._id = id; | 
					
						
							|  |  |  |     if (handlerservers[conf.handler]) { | 
					
						
							|  |  |  |       handlerservers[conf.handler].emit('connection', tlsSocket); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |     if (/^~/.test(handlerpath)) { | 
					
						
							|  |  |  |       handlerpath = path.join(homedir, handlerpath.replace(/^~(\/?)/, '')); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |     try { | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       handler = require(handlerpath); | 
					
						
							|  |  |  |       console.info("Handling '" + handle + ":" + id + "' with '" + handlerpath + "'"); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |     } catch(e1) { | 
					
						
							|  |  |  |       try { | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |         handler = require(path.join(localshare, handlerpath)); | 
					
						
							|  |  |  |         console.info("Handling '" + handle + ":" + id + "' with '" + handlerpath + "'"); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |       } catch(e2) { | 
					
						
							| 
									
										
										
										
											2018-06-09 15:52:15 -06:00
										 |  |  |         console.error("Failed to require('" + handlerpath + "'):", e1.message); | 
					
						
							|  |  |  |         console.error("Failed to require('" + path.join(localshare, handlerpath) + "'):", e2.message); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |         console.warn("Using default handler for '" + handle + ":" + id + "'"); | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  |         handler = null; | 
					
						
							|  |  |  |         // fallthru
 | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:49 -06:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-06-09 12:57:00 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (handler) { | 
					
						
							|  |  |  |       handlerservers[conf.handler] = http.createServer(handler); | 
					
						
							|  |  |  |       handlerservers[conf.handler].emit('connection', tlsSocket); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     handlers.https(tlsSocket, tun, id); | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |   function terminateTls(tun, cb) { | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |     var socketPair = require('socket-pair'); | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |     var conn = socketPair.create(function (err, other) { | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       if (err) { cb(err); return; } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |       //console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
 | 
					
						
							|  |  |  |       defineProps(other, tun); | 
					
						
							|  |  |  |       //console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       if (!state.greenlock) { | 
					
						
							|  |  |  |         state.greenlock = require('greenlock').create(state.greenlockConfig); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-06-01 01:36:29 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       if (!state.terminatorServer) { | 
					
						
							|  |  |  |         state.terminatorServer = require('tls').createServer(state.greenlock.tlsOptions, function (tlsSocket) { | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |           var Packer = require('proxy-packer'); | 
					
						
							|  |  |  |           var addr = Packer.socketToAddr(tlsSocket); | 
					
						
							|  |  |  |           var id = Packer.addrToId(addr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           defineProps(tlsSocket, addr); | 
					
						
							|  |  |  |           //console.log('[hit tls server]', tlsSocket.remoteFamily, tlsSocket.remoteAddress, tlsSocket.remotePort, tlsSocket.localPort);
 | 
					
						
							|  |  |  |           //console.log(addr);
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |           var conf = state.servernames[tlsSocket.servername]; | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |           tlsSocket.once('data', function (firstChunk) { | 
					
						
							|  |  |  |             tlsSocket.pause(); | 
					
						
							|  |  |  |             //tlsSocket.unshift(firstChunk);
 | 
					
						
							|  |  |  |             tlsSocket._handle.onread(firstChunk.length, firstChunk); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             trySsh({ data: firstChunk }, function (err, conn) { | 
					
						
							|  |  |  |               process.nextTick(function () { tlsSocket.resume(); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               if (conn) { | 
					
						
							|  |  |  |                 conn.pipe(tlsSocket); | 
					
						
							|  |  |  |                 tlsSocket.pipe(conn); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |               if (!conf || !conf.handler || 'none' === conf.handler) { | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |                 console.log('https default handler'); | 
					
						
							|  |  |  |                 handlers.https(tlsSocket); | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               console.log('https invokeHandler'); | 
					
						
							|  |  |  |               invokeHandler(conf, tlsSocket, tun, id); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |         }); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |       //console.log('[hit tcp connection]', other.remoteFamily, other.remoteAddress, other.remotePort, other.localPort);
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       state.terminatorServer.emit('connection', other); | 
					
						
							|  |  |  |       cb(null, conn); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     //if (tun.data) { conn.write(tun.data); }
 | 
					
						
							|  |  |  |     return conn; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 14:48:12 -06:00
										 |  |  |   var handled; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!tun.name && !tun.serviceport) { | 
					
						
							|  |  |  |     console.log('tun:\n',tun); | 
					
						
							|  |  |  |     //console.warn(tun.data.toString());
 | 
					
						
							|  |  |  |     cb(new Error("No routing information for ':tun_id'. Missing both 'name' and 'serviceport'.")); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ('http' === tun.service || 'https' === tun.service) { | 
					
						
							|  |  |  |     if (!tun.name) { | 
					
						
							|  |  |  |       cb(new Error("No routing information for ':tun_id'. Service '" + tun.service + "' is missing 'name'.")); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ('http' === tun.service) { | 
					
						
							|  |  |  |     // TODO match *.example.com
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |     handled = Object.keys(state.servernames).some(function (sn) { | 
					
						
							| 
									
										
										
										
											2018-05-31 14:48:12 -06:00
										 |  |  |       if (sn !== tun.name) { return; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('Found config match for PLAIN', tun.name); | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       if (!state.servernames[sn]) { return; } | 
					
						
							| 
									
										
										
										
											2018-05-31 14:48:12 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       if (false === state.servernames[sn].terminate) { | 
					
						
							| 
									
										
										
										
											2018-05-31 14:48:12 -06:00
										 |  |  |         cb(new Error("insecure http not supported yet")); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('Redirecting HTPTP for', tun.name); | 
					
						
							|  |  |  |       redirectHttp(cb); | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     if (!handled) { | 
					
						
							|  |  |  |       redirectHttp(cb); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |   if ('https' === tun.service) { | 
					
						
							|  |  |  |     // TODO match *.example.com
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |     handled = Object.keys(state.servernames).some(function (sn) { | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       if (sn !== tun.name) { return; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('Found config match for TLS', tun.name); | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       if (!state.servernames[sn]) { return; } | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       if (false === state.servernames[sn].terminate) { | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |         cb(new Error("insecure http not supported yet")); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       console.log('Terminating TLS for', tun.name); | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |       terminateTls(tun, cb); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |       return true; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     if (!handled) { | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |       terminateTls(tun, cb); | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-31 00:19:53 -06:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-01 02:10:27 -06:00
										 |  |  |   if ('tcp' === tun.service) { | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |     trySsh(tun, function (err, conn) { | 
					
						
							|  |  |  |       if (conn) { cb(null, conn); return; } | 
					
						
							| 
									
										
										
										
											2018-06-01 03:50:27 -06:00
										 |  |  |       // TODO add TCP handlers
 | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       var conf = state.ports[tun.serviceport]; | 
					
						
							|  |  |  |       if (!conf || !conf.handler || 'none' === conf.handler) { | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |         console.log('Using echo server for tcp'); | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |         echoTcp(cb); | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |         return; | 
					
						
							| 
									
										
										
										
											2018-06-08 00:46:07 -06:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var Packer = require('proxy-packer'); | 
					
						
							|  |  |  |       //var addr = Packer.socketToAddr(conn);
 | 
					
						
							|  |  |  |       var id = Packer.addrToId(tun); | 
					
						
							| 
									
										
										
										
											2018-06-08 02:50:00 -06:00
										 |  |  |       invokeTcpHandler(conf, conn, tun, id, cb); | 
					
						
							| 
									
										
										
										
											2018-06-01 02:45:38 -06:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-06-01 03:50:27 -06:00
										 |  |  |     return; | 
					
						
							| 
									
										
										
										
											2018-06-01 02:10:27 -06:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   console.warn("Unknown service '" + tun.service + "'"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |   /* | 
					
						
							| 
									
										
										
										
											2018-05-31 04:10:47 -06:00
										 |  |  |   var portList = state.services[service]; | 
					
						
							|  |  |  |   var port; | 
					
						
							| 
									
										
										
										
											2018-05-31 00:19:53 -06:00
										 |  |  |   port = portList[tun.name]; | 
					
						
							|  |  |  |   if (!port) { | 
					
						
							|  |  |  |     // Check for any wildcard domains, sorted longest to shortest so the one with the
 | 
					
						
							|  |  |  |     // biggest natural match will be found first.
 | 
					
						
							|  |  |  |     Object.keys(portList).filter(function (pattern) { | 
					
						
							|  |  |  |       return pattern[0] === '*' && pattern.length > 1; | 
					
						
							|  |  |  |     }).sort(function (a, b) { | 
					
						
							|  |  |  |       return b.length - a.length; | 
					
						
							|  |  |  |     }).some(function (pattern) { | 
					
						
							|  |  |  |       var subPiece = pattern.slice(1); | 
					
						
							|  |  |  |       if (subPiece === tun.name.slice(-subPiece.length)) { | 
					
						
							|  |  |  |         port = portList[pattern]; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (!port) { | 
					
						
							|  |  |  |     port = portList['*']; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-05-31 05:24:58 -06:00
										 |  |  |   */ | 
					
						
							| 
									
										
										
										
											2018-05-31 00:19:53 -06:00
										 |  |  | }; |