Created
February 3, 2016 19:54
-
-
Save michielbdejong/9deb7c99c49d6348c010 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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