From 8f7e865d491af2c04a78c4a1b31206f975dd31fe Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 25 Sep 2018 02:18:38 -0600 Subject: [PATCH] move from json-in-querystring to POST bodies --- bin/telebit-remote.js | 20 ++++-- bin/telebitd.js | 143 +++++++++++++++++++++++++----------------- lib/rc/index.js | 1 + 3 files changed, 102 insertions(+), 62 deletions(-) diff --git a/bin/telebit-remote.js b/bin/telebit-remote.js index 0d53829..3ba1b1e 100755 --- a/bin/telebit-remote.js +++ b/bin/telebit-remote.js @@ -524,16 +524,28 @@ function parseConfig(err, text) { } else { if ('http' === body.module) { // TODO we'll support slingshot-ing in the future - if (String(body.local) === String(parseInt(body.local, 10))) { - console.info('> Forwarding https://' + body.remote + ' => localhost:' + body.local); + if (body.local) { + if (String(body.local) === String(parseInt(body.local, 10))) { + console.info('> Forwarding https://' + body.remote + ' => localhost:' + body.local); + } else { + console.info('> Serving ' + body.local + ' as https://' + body.remote); + } } else { - console.info('> Serving ' + body.local + ' as https://' + body.remote); + console.info('> Rejecting End-to-End Encrypted HTTPS for now'); } } else if ('tcp' === body.module) { + if (body.local) { console.info('> Forwarding ' + state.config.relay + ':' + body.remote + ' => localhost:' + body.local); + } else { + console.info('> Rejecting Legacy TCP'); + } } else if ('ssh' === body.module) { - //console.info('> Forwarding ' + state.config.relay + ' -p ' + JSON.stringify(body) + ' => localhost:' + body.local); + //console.info('> Forwarding ' + state.config.relay + ' -p ' + JSON.stringify(body) + ' => localhost:' + body.local); + if (body.local) { console.info('> Forwarding ssh+https (openssl proxy) => localhost:' + body.local); + } else { + console.info('> Rejecting SSH-over-HTTPS for now'); + } } else { console.info(JSON.stringify(body, null, 2)); } diff --git a/bin/telebitd.js b/bin/telebitd.js index 74bbdb1..ee76d64 100755 --- a/bin/telebitd.js +++ b/bin/telebitd.js @@ -245,11 +245,11 @@ controllers.tcp = function (req, res, opts) { if (remotePort) { if (!state.ports[remotePort]) { active = false; - return; + } else { + // forward-to port-or-module + // TODO with the connect event bug fixed, we should now be able to send files over tcp + state.ports[remotePort].handler = portOrPath; } - // forward-to port-or-module - // TODO we can't send files over tcp until we fix the connect event bug - state.ports[remotePort].handler = portOrPath; } else { if (!Object.keys(state.ports).some(function (key) { if (!state.ports[key].handler) { @@ -329,7 +329,7 @@ controllers.ssh = function (req, res, opts) { function serveControlsHelper() { controlServer = http.createServer(function (req, res) { var opts = url.parse(req.url, true); - if (opts.query._body) { + if (false && opts.query._body) { try { opts.body = JSON.parse(decodeURIComponent(opts.query._body, true)); } catch(e) { @@ -591,63 +591,90 @@ function serveControlsHelper() { )); } - if (/\b(config)\b/.test(opts.pathname) && /get/i.test(req.method)) { - getConfigOnly(); - return; + function route() { + if (/\b(config)\b/.test(opts.pathname) && /get/i.test(req.method)) { + getConfigOnly(); + return; + } + if (/\b(init|config)\b/.test(opts.pathname)) { + initOrConfig(); + return; + } + if (/restart/.test(opts.pathname)) { + restart(); + return; + } + // + // Check for proper config + // + if (!state.config.relay || !state.config.email || !state.config.agreeTos) { + invalidConfig(); + return; + } + // + // With proper config + // + if (/http/.test(opts.pathname)) { + controllers.http(req, res, opts); + return; + } + if (/tcp/.test(opts.pathname)) { + controllers.tcp(req, res, opts); + return; + } + if (/save|commit/.test(opts.pathname)) { + saveAndCommit(); + return; + } + if (/ssh/.test(opts.pathname)) { + controllers.ssh(req, res, opts); + return; + } + if (/enable/.test(opts.pathname)) { + enable(); + return; + } + if (/disable/.test(opts.pathname)) { + disable(); + return; + } + if (/status/.test(opts.pathname)) { + getStatus(); + return; + } + if (/list/.test(opts.pathname)) { + listSuccess(); + return; + } + + res.setHeader('Content-Type', 'application/json'); + res.end(JSON.stringify({"error":{"message":"unrecognized rpc"}})); } - if (/\b(init|config)\b/.test(opts.pathname)) { - initOrConfig(); - return; - } - if (/restart/.test(opts.pathname)) { - restart(); - return; - } - // - // Check for proper config - // - if (!state.config.relay || !state.config.email || !state.config.agreeTos) { - invalidConfig(); - return; - } - // - // With proper config - // - if (/http/.test(opts.pathname)) { - controllers.http(req, res, opts); - return; - } - if (/tcp/.test(opts.pathname)) { - controllers.tcp(req, res, opts); - return; - } - if (/save|commit/.test(opts.pathname)) { - saveAndCommit(); - return; - } - if (/ssh/.test(opts.pathname)) { - controllers.ssh(req, res, opts); - return; - } - if (/enable/.test(opts.pathname)) { - enable(); - return; - } - if (/disable/.test(opts.pathname)) { - disable(); - return; - } - if (/status/.test(opts.pathname)) { - getStatus(); - return; - } - if (/list/.test(opts.pathname)) { - listSuccess(); + + if (!req.headers['content-length'] && !req.headers['content-type']) { + route(); return; } - res.setHeader('Content-Type', 'application/json'); - res.end(JSON.stringify({"error":{"message":"unrecognized rpc"}})); + var body = ''; + req.on('readable', function () { + var data; + while (true) { + data = req.read(); + if (!data) { break; } + body += data.toString(); + } + }); + req.on('end', function () { + try { + opts.body = JSON.parse(body); + } catch(e) { + res.statusCode = 400; + res.end('{"error":{"message":"POST body is not valid json"}}'); + return; + } + route(); + }); }); if (fs.existsSync(state._ipc.path)) { diff --git a/lib/rc/index.js b/lib/rc/index.js index 389458d..acd0dc7 100644 --- a/lib/rc/index.js +++ b/lib/rc/index.js @@ -108,6 +108,7 @@ module.exports.create = function (state) { fn(err); }); if ('POST' === method && opts.data) { + req.setHeader("content-type", 'application/json'); req.write(json || opts.data); } req.end();