From 9cb9113a340dfac4516fa92f435d5107b66c665f Mon Sep 17 00:00:00 2001 From: Thaddee Tyl Date: Wed, 8 Nov 2017 23:39:44 +0100 Subject: [PATCH] Add endpoint to obtain logs It goes through a WebSocket; the secret is sent, and if valid, the logs are sent back. --- lib/log.js | 20 +++++++++++++++-- lib/sys/monitor.js | 44 ++++++++++++++++++++++++++++++++------ lib/sys/secret-is-valid.js | 2 ++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/lib/log.js b/lib/log.js index b8406e1edca58..7cd76a40285dd 100644 --- a/lib/log.js +++ b/lib/log.js @@ -1,5 +1,7 @@ 'use strict'; +const listeners = []; + // Zero-pad a number in a string. // eg. 4 becomes 04 but 17 stays 17. function pad(string) { @@ -19,9 +21,23 @@ function date() { } module.exports = function log(...msg) { - console.log(date(), ...msg); + const d = date(); + listeners.forEach(f => f(d, ...msg)) + console.log(d, ...msg); }; module.exports.error = function error(...msg) { - console.error(date(), ...msg); + const d = date(); + listeners.forEach(f => f(d, ...msg)) + console.error(d, ...msg); +}; + +module.exports.addListener = function addListener(func) { + listeners.push(func); +}; + +module.exports.removeListener = function removeListener(func) { + const index = listeners.indexOf(func); + if (index < 0) { return; } + listeners.splice(index, 1); }; diff --git a/lib/sys/monitor.js b/lib/sys/monitor.js index dda1d8e7a4249..10e7bfa62b11c 100644 --- a/lib/sys/monitor.js +++ b/lib/sys/monitor.js @@ -1,15 +1,45 @@ +'use strict'; + const secretIsValid = require('./secret-is-valid'); const serverSecrets = require('../server-secrets'); +const log = require('../log'); + +function secretInvalid(req, res) { + if (!secretIsValid(req.password)) { + // An unknown entity tries to connect. Let the connection linger for a minute. + setTimeout(function() { + res.json({errors: [{code: 'invalid_secrets'}]}); + }, 10000); + return true; + } + return false; +} function setRoutes(server) { - server.get('/sys/network', (req, res) => { - if (!secretIsValid(req.password)) { - // An unknown entity tries to connect. Let the connection linger for a minute. - return setTimeout(function() { - res.end(JSON.stringify({errors: [{code: 'invalid_secrets'}]})); - }, 10000); + server.handle(function(req, res, next) { + if (req.url.startsWith('/sys/')) { + if (secretInvalid(req, res)) { return; } } - res.end(JSON.stringify({ips: serverSecrets.shieldsIps})); + next(); + }); + + server.get('/sys/network', (req, res) => { + res.json({ips: serverSecrets.shieldsIps}); + }); + + server.ws('/sys/logs', socket => { + const listener = (...msg) => socket.send(msg.join(' ')); + socket.on('close', () => log.removeListener(listener)); + socket.on('message', msg => { + let req; + try { + req = JSON.parse(msg); + } catch(e) { return; } + if (!secretIsValid(req.secret)) { + return socket.close(); + } + log.addListener(listener); + }); }); } diff --git a/lib/sys/secret-is-valid.js b/lib/sys/secret-is-valid.js index c13c4600da699..57726a7af0910 100644 --- a/lib/sys/secret-is-valid.js +++ b/lib/sys/secret-is-valid.js @@ -1,3 +1,5 @@ +'use strict'; + const serverSecrets = require('../server-secrets'); function secretIsValid(secret = '') {