v0.9.2: add comments, tame wild domains (use '_')
This commit is contained in:
parent
cfb335902c
commit
9f61e34a8a
73
index.js
73
index.js
|
@ -31,14 +31,24 @@ var os = require("os");
|
||||||
module.exports.create = function (config) {
|
module.exports.create = function (config) {
|
||||||
|
|
||||||
// This file has been laid out in the order that options are used and calls are made
|
// This file has been laid out in the order that options are used and calls are made
|
||||||
// greenlock.approveDomains)
|
// SNICallback() // le-sni-auto has a cache
|
||||||
// greenlock.store.certificates.checkAsync()
|
// greenlock.approveDomains()
|
||||||
// greenlock.store.accounts.checkAsync()
|
// // you get opts.domain passed to you from SNI
|
||||||
// greenlock.store.accounts.setKeypairAsync()
|
// // you should set opts.subject as the cert "id" domain
|
||||||
// greenlock.store.accounts.setAsync()
|
// // you should set opts.domains as all domains on the cert
|
||||||
// greenlock.store.certificates.checkKeypairAsync()
|
// // you should set opts.account.id, otherwise opts.email will be used
|
||||||
// greenlock.store.certificates.setKeypairAsync()
|
// greenlock.store.certificates.checkAsync() // on success -> SNI cache, on fail \/
|
||||||
// greenlock.store.certificates.setAsync()
|
// greenlock.store.accounts.checkAsync() // optional (you can always return null)
|
||||||
|
// greenlock.store.accounts.checkKeypairAsync()
|
||||||
|
// greenlock.core.RSA.generateKeypair() // TODO double check name
|
||||||
|
// greenlock.core.accounts.register() // TODO double check name
|
||||||
|
// greenlock.store.accounts.setKeypairAsync() // TODO make sure this only happens on generate
|
||||||
|
// greenlock.store.accounts.setAsync() // optional
|
||||||
|
// greenlock.store.certificates.checkKeypairAsync()
|
||||||
|
// greenlock.core.RSA.generateKeypair() // TODO double check name
|
||||||
|
// greenlock.core.certificates.register() // TODO double check name
|
||||||
|
// greenlock.store.certificates.setKeypairAsync()
|
||||||
|
// greenlock.store.certificates.setAsync()
|
||||||
|
|
||||||
// store
|
// store
|
||||||
// Bear in mind that the only time any of this gets called is on first access after startup, new registration,
|
// Bear in mind that the only time any of this gets called is on first access after startup, new registration,
|
||||||
|
@ -100,9 +110,9 @@ module.exports.create = function (config) {
|
||||||
var chainPath = opts.chainPath || path.join(liveDir, 'chain.pem');
|
var chainPath = opts.chainPath || path.join(liveDir, 'chain.pem');
|
||||||
|
|
||||||
return PromiseA.all([
|
return PromiseA.all([
|
||||||
readFileAsync(privkeyPath, 'ascii') // 0
|
readFileAsync(tameWild(privkeyPath, opts.subject), 'ascii') // 0
|
||||||
, readFileAsync(certPath, 'ascii') // 1
|
, readFileAsync(tameWild(certPath, opts.subject), 'ascii') // 1
|
||||||
, readFileAsync(chainPath, 'ascii') // 2
|
, readFileAsync(tameWild(chainPath, opts.subject), 'ascii') // 2
|
||||||
]).then(function (all) {
|
]).then(function (all) {
|
||||||
return {
|
return {
|
||||||
privkey: all[0]
|
privkey: all[0]
|
||||||
|
@ -154,7 +164,8 @@ module.exports.create = function (config) {
|
||||||
console.log('accounts.checkKeypairAsync for', id);
|
console.log('accounts.checkKeypairAsync for', id);
|
||||||
if (!opts.account.id) { return Promise.reject(new Error("'account.id' should have been set in approveDomains()")); }
|
if (!opts.account.id) { return Promise.reject(new Error("'account.id' should have been set in approveDomains()")); }
|
||||||
|
|
||||||
return readFileAsync(path.join(opts.accountsDir, sanitizeFilename(id) + '.json'), 'utf8').then(function (blob) {
|
var pathname = path.join(tameWild(opts.accountsDir, opts.subject), sanitizeFilename(id) + '.json');
|
||||||
|
return readFileAsync(tameWild(pathname, opts.subject), 'utf8').then(function (blob) {
|
||||||
// keypair is an opaque object that should be treated as blob
|
// keypair is an opaque object that should be treated as blob
|
||||||
return JSON.parse(blob);
|
return JSON.parse(blob);
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
|
@ -175,9 +186,10 @@ module.exports.create = function (config) {
|
||||||
console.log('accounts.setKeypairAsync for', id);
|
console.log('accounts.setKeypairAsync for', id);
|
||||||
keypair = opts.keypair || keypair;
|
keypair = opts.keypair || keypair;
|
||||||
if (!opts.account.id) { return Promise.reject(new Error("'account.id' should have been set in approveDomains()")); }
|
if (!opts.account.id) { return Promise.reject(new Error("'account.id' should have been set in approveDomains()")); }
|
||||||
return mkdirpAsync(opts.accountsDir).then(function () {
|
return mkdirpAsync(tameWild(opts.accountsDir, opts.subject)).then(function () {
|
||||||
// keypair is an opaque object that should be treated as blob
|
// keypair is an opaque object that should be treated as blob
|
||||||
return writeFileAsync(path.join(opts.accountsDir, sanitizeFilename(id) + '.json'), JSON.stringify(keypair), 'utf8');
|
var pathname = tameWild(path.join(opts.accountsDir, sanitizeFilename(id) + '.json'), opts.subject);
|
||||||
|
return writeFileAsync(tameWild(pathname, opts.subject), JSON.stringify(keypair), 'utf8');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -200,7 +212,7 @@ module.exports.create = function (config) {
|
||||||
console.log('certificates.checkKeypairAsync:');
|
console.log('certificates.checkKeypairAsync:');
|
||||||
var liveDir = opts.liveDir || path.join(opts.configDir, 'live', opts.subject);
|
var liveDir = opts.liveDir || path.join(opts.configDir, 'live', opts.subject);
|
||||||
var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
||||||
return readFileAsync(privkeyPath, 'ascii').then(function (key) {
|
return readFileAsync(tameWild(privkeyPath, opts.subject), 'ascii').then(function (key) {
|
||||||
// keypair is normally an opaque object, but here it's a pem for the filesystem
|
// keypair is normally an opaque object, but here it's a pem for the filesystem
|
||||||
return { privateKeyPem: key };
|
return { privateKeyPem: key };
|
||||||
}).catch(function (err) {
|
}).catch(function (err) {
|
||||||
|
@ -217,8 +229,8 @@ module.exports.create = function (config) {
|
||||||
var liveDir = opts.liveDir || path.join(opts.configDir, 'live', opts.subject);
|
var liveDir = opts.liveDir || path.join(opts.configDir, 'live', opts.subject);
|
||||||
var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
||||||
// keypair is normally an opaque object, but here it's a PEM for the FS
|
// keypair is normally an opaque object, but here it's a PEM for the FS
|
||||||
return mkdirpAsync(path.dirname(privkeyPath)).then(function () {
|
return mkdirpAsync(tameWild(path.dirname(privkeyPath), opts.subject)).then(function () {
|
||||||
return writeFileAsync(privkeyPath, keypair.privateKeyPem, 'ascii').then(function () {
|
return writeFileAsync(tameWild(privkeyPath, opts.subject), keypair.privateKeyPem, 'ascii').then(function () {
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -242,18 +254,19 @@ module.exports.create = function (config) {
|
||||||
//var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
//var privkeyPath = opts.privkeyPath || opts.domainKeyPath || path.join(liveDir, 'privkey.pem');
|
||||||
var bundlePath = opts.bundlePath || path.join(liveDir, 'bundle.pem');
|
var bundlePath = opts.bundlePath || path.join(liveDir, 'bundle.pem');
|
||||||
|
|
||||||
return mkdirpAsync(path.dirname(certPath)).then(function () {
|
return mkdirpAsync(path.dirname(tameWild(certPath, opts.subject))).then(function () {
|
||||||
return mkdirpAsync(path.dirname(chainPath)).then(function () {
|
return mkdirpAsync(path.dirname(tameWild(chainPath, opts.subject))).then(function () {
|
||||||
return mkdirpAsync(path.dirname(fullchainPath)).then(function () {
|
return mkdirpAsync(path.dirname(tameWild(fullchainPath, opts.subject))).then(function () {
|
||||||
return mkdirpAsync(path.dirname(bundlePath)).then(function () {
|
return mkdirpAsync(path.dirname(tameWild(bundlePath, opts.subject))).then(function () {
|
||||||
|
var fullchainPem = [ pems.cert, pems.chain ].join('\n'); // for Apache, Nginx, etc
|
||||||
|
var bundlePem = [ pems.privkey, pems.cert, pems.chain ].join('\n'); // for HAProxy
|
||||||
return PromiseA.all([
|
return PromiseA.all([
|
||||||
sfs.writeFileAsync(certPath, pems.cert, 'ascii')
|
sfs.writeFileAsync(tameWild(certPath, opts.subject), pems.cert, 'ascii')
|
||||||
, sfs.writeFileAsync(chainPath, pems.chain, 'ascii')
|
, sfs.writeFileAsync(tameWild(chainPath, opts.subject), pems.chain, 'ascii')
|
||||||
// Most platforms need these two
|
// Most web servers need these two
|
||||||
, sfs.writeFileAsync(fullchainPath, [ pems.cert, pems.chain ].join('\n'), 'ascii')
|
, sfs.writeFileAsync(tameWild(fullchainPath, opts.subject), fullchainPem, 'ascii')
|
||||||
//, sfs.writeFileAsync(privkeyPath, pems.privkey, 'ascii')
|
|
||||||
// HAProxy needs "bundle.pem" aka "combined.pem"
|
// HAProxy needs "bundle.pem" aka "combined.pem"
|
||||||
, sfs.writeFileAsync(bundlePath, [ pems.privkey, pems.cert, pems.chain ].join('\n'), 'ascii')
|
, sfs.writeFileAsync(tameWild(bundlePath, opts.subject), bundlePem, 'ascii')
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -297,3 +310,9 @@ function mergeOptions(configs) {
|
||||||
function sanitizeFilename(id) {
|
function sanitizeFilename(id) {
|
||||||
return id.replace(/(\.\.)|\\|\//g, '_').replace(/[^!-~]/g, '_');
|
return id.replace(/(\.\.)|\\|\//g, '_').replace(/[^!-~]/g, '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// because not all file systems like '*' in a name (and they're scary)
|
||||||
|
function tameWild(path, wild) {
|
||||||
|
var tame = wild.replace(/\*/g, '_');
|
||||||
|
return path.replace(wild, tame);
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "le-store-fs",
|
"name": "le-store-fs",
|
||||||
"version": "0.9.1",
|
"version": "0.9.2",
|
||||||
"description": "A file-based certificate store for greenlock that supports wildcards.",
|
"description": "A file-based certificate store for greenlock that supports wildcards.",
|
||||||
"homepage": "https://git.coolaj86.com/coolaj86/le-store-fs.js",
|
"homepage": "https://git.coolaj86.com/coolaj86/le-store-fs.js",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|
Loading…
Reference in New Issue