@luminati-io/luminati-proxy
Version:
A configurable local proxy for luminati.io
94 lines (88 loc) • 3.23 kB
JavaScript
// LICENSE_CODE ZON ISC
; /*jslint node:true, esnext:true*/
const path = require('path');
const fs = require('fs');
const os = require('os');
const tls = require('tls');
const forge = require('node-forge');
const pki = forge.pki;
const lpm_file = require('../util/lpm_file.js');
const date = require('../util/date.js');
const logger = require('./logger.js');
const {spawn} = require('child_process');
const E = module.exports = ssl;
let keys;
let key_path;
let crt_path;
const cust_key_path = lpm_file.get_file_path('lpm.key');
const cust_crt_path = lpm_file.get_file_path('lpm.crt');
if (fs.existsSync(cust_key_path) && fs.existsSync(cust_crt_path))
{
key_path = cust_key_path;
crt_path = cust_crt_path;
}
else
{
key_path = path.join(__dirname, '../bin/ca.key');
crt_path = path.join(__dirname, '../bin/ca.crt');
}
E.ca = {cert: fs.readFileSync(crt_path), key: fs.readFileSync(key_path)};
let iface_ips = [].concat(...Object.values(os.networkInterfaces()));
iface_ips = iface_ips.filter(i=>i.family=='IPv4').map(i=>i.address);
let ip_cert;
function gen_cert(name, alt_names){
const cert = pki.createCertificate();
cert.publicKey = pki.publicKeyFromPem(keys.publicKeyPem);
cert.serialNumber = ''+Date.now();
cert.validity.notBefore = new Date(Date.now()-1*date.ms.DAY);
cert.validity.notAfter = new Date(Date.now()+1*365*date.ms.DAY);
cert.setSubject([{name: 'commonName', value: name}]);
cert.setIssuer(pki.certificateFromPem(E.ca.cert).issuer.attributes);
cert.setExtensions([{name: 'subjectAltName', altNames: alt_names}]);
cert.sign(pki.privateKeyFromPem(E.ca.key), forge.md.sha256.create());
return cert;
}
// XXX viktor: only first call matters, make it clear that it is impossible
// to set another rsa_keys and there is no need
function ssl(rsa_keys, extra_ssl_ips){
keys = rsa_keys||keys;
if (!keys)
{
keys = pki.rsa.generateKeyPair(2048);
keys.privateKeyPem = pki.privateKeyToPem(keys.privateKey);
keys.publicKeyPem = pki.publicKeyToPem(keys.publicKey);
}
if (Array.isArray(extra_ssl_ips))
iface_ips = [...new Set(iface_ips.concat(extra_ssl_ips))];
if (!ip_cert)
ip_cert = gen_cert('localhost', iface_ips.map(ip=>({type: 7, ip})));
const hosts = {};
return {
key: keys.privateKeyPem,
cert: pki.certificateToPem(ip_cert),
ca: E.ca.cert,
SNICallback: (name, cb)=>{
if (hosts[name])
return cb(null, hosts[name]);
const cert = gen_cert(name, [{type: 2, value: name}]);
hosts[name] = tls.createSecureContext({
key: keys.privateKeyPem,
cert: pki.certificateToPem(cert),
ca: E.ca.cert,
});
cb(null, hosts[name]);
}
};
}
E.gen_cert = function(){
const child = spawn('bash', [path.join(__dirname, '../bin/cert_gen.sh'),
cust_key_path, cust_crt_path], {
stdio: ['inherit', 'inherit', 'inherit'],
});
child.on('exit', (code, signal)=>{
if (code==0)
logger.notice('CA generated successfully');
else
logger.warn('Could not generate CA');
});
};