diff --git a/lib/relay.js b/lib/relay.js index d499bf8..9493702 100644 --- a/lib/relay.js +++ b/lib/relay.js @@ -186,6 +186,9 @@ module.exports.create = function (state) { function addToken(jwtoken) { function onAuth(token) { + if ('string' !== typeof jwtoken) { + jwtoken = JSON.stringify(jwtoken); + } var err; if (!token) { err = new Error("invalid access token"); @@ -193,6 +196,20 @@ module.exports.create = function (state) { return state.Promise.reject(err); } + if (token.jwt && jwtoken !== token.jwt) { + // Access Token + sendTunnelMsg( + null + , [ 3 + , 'access_token' + , { jwt: token.jwt } + ] + , 'control' + ); + // these aren't needed internally once they're sent + token.jwt = null; + } + if (!Array.isArray(token.domains)) { if ('string' === typeof token.name) { token.domains = [ token.name ]; @@ -241,49 +258,58 @@ module.exports.create = function (state) { Devices.add(state.deviceLists, domainname, token); }); + function onDynTcpReady() { + var serviceport = this.address().port; + console.info('[DynTcpConn] Port', serviceport, 'now open for', token.deviceId); + //token.dynamicPorts.push(serviceport); + Devices.add(state.deviceLists, serviceport, token); + //var hri = require('human-readable-ids').hri; + //var hrname = hri.random() + '.telebit.cloud'; + //token.dynamicNames.push(hrname); + // TODO restrict to authenticated device + // TODO pull servername from config + // TODO remove hrname on disconnect + //Devices.add(state.deviceLists, hrname, token); + sendTunnelMsg( + null + , [ 2 + , 'grant' + , [ ['ssh+https', token.domains[0], 443 ] + , ['ssh', 'ssh.telebit.cloud', serviceport ] + , ['tcp', 'tcp.telebit.cloud', serviceport] + , ['https', token.domains[0] ] + ] + ] + , 'control' + ); + } + console.log('[DEBUG] got to firstToken check'); + if (!token.ports) { + token.ports = []; + } if (!firstToken || firstToken === jwtoken) { - firstToken = jwtoken; - token.dynamicPorts = []; - token.dynamicNames = []; - - function onDynTcpReady() { - var serviceport = this.address().port; - console.info('[DynTcpConn] Port', serviceport, 'now open for', token.deviceId); - token.dynamicPorts.push(serviceport); - Devices.add(state.deviceLists, serviceport, token); - var hri = require('human-readable-ids').hri; - var hrname = hri.random() + '.telebit.cloud'; - token.dynamicNames.push(hrname); - // TODO restrict to authenticated device - // TODO pull servername from config - // TODO remove hrname on disconnect - Devices.add(state.deviceLists, hrname, token); - sendTunnelMsg( - null - , [ 2 - , 'grant' - , [ ['ssh+https', hrname, 443 ] - , ['ssh', 'ssh.telebit.cloud', serviceport ] - , ['tcp', 'tcp.telebit.cloud', serviceport] - , ['https', hrname ] - ] - ] - , 'control' - ); + if (!token.ports.length) { + token.ports.push( 0 ); } + firstToken = token.jwt || jwtoken; + } - try { - token.server = require('net').createServer(onDynTcpConn).listen(0, onDynTcpReady); - token.server.on('error', function (e) { - console.error("Server Error assigning a dynamic port to a new connection:", e); - }); - } catch(e) { - // what a wonderful problem it will be the day that this bug needs to be fixed - // (i.e. there are enough users to run out of ports) - console.error("Error assigning a dynamic port to a new connection:", e); - } + //token.dynamicPorts = []; + //token.dynamicNames = []; + + var onePortForNow = parseInt(token.ports[0], 10) || 0; + // TODO try again with random port + try { + token.server = require('net').createServer(onDynTcpConn).listen(onePortForNow, onDynTcpReady); + token.server.on('error', function (e) { + console.error("Server Error assigning a dynamic port to a new connection:", e); + }); + } catch(e) { + // what a wonderful problem it will be the day that this bug needs to be fixed + // (i.e. there are enough users to run out of ports) + console.error("Error assigning a dynamic port to a new connection:", e); } remotes[jwtoken] = token; @@ -310,7 +336,7 @@ module.exports.create = function (state) { remote.domains.forEach(function (domainname) { Devices.remove(state.deviceLists, domainname, remote); }); - remote.dynamicPorts.forEach(function (portnumber) { + remote.ports.forEach(function (portnumber) { Devices.remove(state.deviceLists, portnumber, remote); }); remote.ws = null;