Skip to content

Instantly share code, notes, and snippets.

@michielbdejong
Created February 3, 2016 19:54
Show Gist options
  • Save michielbdejong/9deb7c99c49d6348c010 to your computer and use it in GitHub Desktop.
Save michielbdejong/9deb7c99c49d6348c010 to your computer and use it in GitHub Desktop.
#!/usr/bin/env node
'use strict';
var http = require('http');
var https = require('https');
var fs = require('fs');
var qr = require('qr-image');
var boxHost = 'foxbox.local';
var ports = {
qr: 12345,
web: 12346,
browser: 12347
};
// Step 1: add '127.0.0.1 foxbox.local' to your /etc/hosts
// Step 2: use https://github.com/coolaj86/nodejs-self-signed-certificate-example
// to generate the certs for 'foxbox.local', and edit the following line to point
// to the certs dir inside your local checkout of that repo:
var certDir = '/Users/Michiel/repos/nodejs-self-signed-certificate-example/certs/';
// Step 3: Browse to http://foxbox.local:12345/ to see the QR code, and copy the
// string below it (in real usage you would scan this QR code from a sticker or
// display on your foxbox).
// Step 4: Browse to http://foxbox.local:12347 which is a basically a simplistic
// browser written in node, and itself exposed on a web interface.
// Step 5: Paste the string from the QR code, and hit 'Go'
// Step 6: See how the contents of https://foxbox.local:12346 ('It works!') is
// successfully retrieved.
// To do: Show a warning if the cert presented is not signed by the
// root ca from the QR code.
// serve QR code on a screen on the local device:
http.createServer((req, res) => {
var qrCodeString = JSON.stringify({
host: boxHost,
port: ports.web.toString(),
path: '/',
ca: fs.readFileSync(certDir + 'client/my-root-ca.crt.pem').toString()
});
res.writeHead(200);
res.write('<html><body style="width: 400px; height: 400px">');
res.write(qr.imageSync(qrCodeString, { type: 'svg' }));
res.write('<p>' + qrCodeString + '</p>');
res.end('</body></html>');
}).listen(ports.qr);
// serve a web server on the local network:
https.createServer({
key: fs.readFileSync(certDir + 'server/my-server.key.pem'),
cert: fs.readFileSync(certDir + 'server/my-server.crt.pem'),
ca: fs.readFileSync(certDir + 'server/my-root-ca.crt.pem'),
}, (req, res) => {
res.writeHead(200);
res.end('It works!');
}).listen(ports.web);
// serve a browser:
var htmlHeader = '<!DOCTYPE html><html><head>' +
'<title>QR-code enabled browser</title>' +
'<meta charset="utf-8"></head><body>';
var browserChrome = '<h1>QR-code enabled browser</h1>' +
'<p>This is a browser, written in node.js, that can connect securely to a' +
' local device. To do so, read a QR-code on the device containing the device\'s' +
' local https URL and the fingerprint of its self-signed certificate.' +
' It will then try to open the page on that URL over https, while checking' +
' the fingerprint of the TLS certificate presented. If the TLS certificate' +
' does not match the fingerprint specified in the QR-code, a warning will' +
' be displayed.' +
'</p>' +
'<p>In this first test-version, you have to paste the string from the QR' +
' code in the field below, and click \'Go\':' +
'</p>' +
'<form method="POST">' +
' <label for="qr-code">QR code string:</label><input name="qr-code">' +
'<input type="submit" value="Go">' +
'</form>';
var htmlFooter = '</body></html>';
http.createServer((req, res) => {
var incoming = '';
req.on('data', function(chunk) {
incoming += chunk;
})
req.on('end', function () {
function respond(html) {
res.writeHead(200);
res.write(htmlHeader);
res.write(browserChrome);
res.write('<h1>' + html + '</h1>');
res.end(htmlFooter);
}
if (incoming.length) {
var options = JSON.parse(decodeURIComponent(incoming.substring('qr-code='.length)));
options.ca = new Buffer(options.ca
.replace('-----BEGIN+CERTIFICATE-----', '-----BEGIN CERTIFICATE-----')
.replace('-----END+CERTIFICATE-----', '-----END CERTIFICATE-----'));
options.agent = new https.Agent(options);
https.get(options, function(res2) {
var html = '';
res2.on('data', function(chunk) {
html += chunk.toString();
});
res2.on('end', function() {
respond(html);
});
});
} else {
respond('');
}
});
}).listen(ports.browser);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment