Files
cloudron-box/src/blobs.js
T

105 lines
4.4 KiB
JavaScript
Raw Normal View History

2021-05-02 21:12:38 -07:00
/* jslint node:true */
2021-04-30 21:54:53 -07:00
'use strict';
exports = module.exports = {
get,
set,
del,
2021-05-02 23:28:41 -07:00
initSecrets,
ACME_ACCOUNT_KEY: 'acme_account_key',
ADDON_TURN_SECRET: 'addon_turn_secret',
DHPARAMS: 'dhparams',
SFTP_PUBLIC_KEY: 'sftp_public_key',
SFTP_PRIVATE_KEY: 'sftp_private_key',
2021-05-07 20:19:18 -07:00
CERT_PREFIX: 'cert',
2021-05-02 21:12:38 -07:00
_clear: clear
2021-04-30 21:54:53 -07:00
};
const assert = require('assert'),
2021-05-02 23:28:41 -07:00
BoxError = require('./boxerror.js'),
constants = require('./constants.js'),
crypto = require('crypto'),
database = require('./database.js'),
debug = require('debug')('box:blobs'),
paths = require('./paths.js'),
safe = require('safetydance');
2021-04-30 21:54:53 -07:00
2021-05-02 21:12:38 -07:00
const BLOBS_FIELDS = [ 'id', 'value' ].join(',');
2021-04-30 21:54:53 -07:00
2021-05-02 21:12:38 -07:00
async function get(id) {
assert.strictEqual(typeof id, 'string');
2021-04-30 21:54:53 -07:00
2021-05-02 21:12:38 -07:00
const result = await database.query(`SELECT ${BLOBS_FIELDS} FROM blobs WHERE id = ?`, [ id ]);
if (result.length === 0) return null;
return result[0].value;
2021-04-30 21:54:53 -07:00
}
2021-05-02 21:12:38 -07:00
async function set(id, value) {
2021-04-30 22:26:51 -07:00
assert.strictEqual(typeof id, 'string');
2021-05-02 21:12:38 -07:00
assert(value === null || Buffer.isBuffer(value));
2021-04-30 21:54:53 -07:00
2021-05-02 21:12:38 -07:00
await database.query('INSERT INTO blobs (id, value) VALUES (?, ?) ON DUPLICATE KEY UPDATE value=VALUES(value)', [ id, value ]);
}
2021-04-30 21:54:53 -07:00
async function del(id) {
await database.query('DELETE FROM blobs WHERE id=?', [ id ]);
}
2021-05-02 21:12:38 -07:00
async function clear() {
await database.query('DELETE FROM blobs');
2021-04-30 21:54:53 -07:00
}
2021-05-02 23:28:41 -07:00
async function initSecrets() {
let acmeAccountKey = await get(exports.ACME_ACCOUNT_KEY);
if (!acmeAccountKey) {
acmeAccountKey = safe.child_process.execSync('openssl genrsa 4096');
if (!acmeAccountKey) throw new BoxError(BoxError.OPENSSL_ERROR, `Could not generate acme account key: ${safe.error.message}`);
await set(exports.ACME_ACCOUNT_KEY, acmeAccountKey);
2021-05-02 23:28:41 -07:00
}
let turnSecret = await get(exports.ADDON_TURN_SECRET);
if (!turnSecret) {
turnSecret = 'a' + crypto.randomBytes(15).toString('hex'); // prefix with a to ensure string starts with a letter
await set(exports.ADDON_TURN_SECRET, Buffer.from(turnSecret));
2021-05-02 23:28:41 -07:00
}
// TODO maybe skip this in tests if possible again
let dhparams = await get(exports.DHPARAMS);
if (!dhparams) {
2021-11-16 09:53:12 -08:00
debug('initSecrets: generating dhparams.pem');
2021-09-16 16:34:28 -07:00
if (constants.TEST) dhparams = safe.fs.readFileSync('/tmp/dhparams.pem');
2021-11-16 09:53:12 -08:00
// https://security.stackexchange.com/questions/95178/diffie-hellman-parameters-still-calculating-after-24-hours
if (!dhparams) dhparams = safe.child_process.execSync('openssl dhparam -dsaparam 2048');
if (!dhparams) throw new BoxError(BoxError.OPENSSL_ERROR, safe.error);
2021-09-16 16:34:28 -07:00
if (constants.TEST) safe.fs.writeFileSync('/tmp/dhparams.pem', dhparams);
if (!safe.fs.writeFileSync(paths.DHPARAMS_FILE, dhparams)) throw new BoxError(BoxError.FS_ERROR, `Could not save dhparams.pem: ${safe.error.message}`);
await set(exports.DHPARAMS, dhparams);
} else if (!safe.fs.existsSync(paths.DHPARAMS_FILE)) {
if (!safe.fs.writeFileSync(paths.DHPARAMS_FILE, dhparams)) throw new BoxError(BoxError.FS_ERROR, `Could not save dhparams.pem: ${safe.error.message}`);
2021-05-02 23:28:41 -07:00
}
let sftpPrivateKey = await get(exports.SFTP_PRIVATE_KEY);
let sftpPublicKey = await get(exports.SFTP_PUBLIC_KEY);
if (!sftpPrivateKey || !sftpPublicKey) {
2021-05-02 23:28:41 -07:00
debug('initSecrets: generate sftp keys');
if (constants.TEST) {
2021-05-04 15:50:02 -07:00
safe.fs.unlinkSync(paths.SFTP_PUBLIC_KEY_FILE);
safe.fs.unlinkSync(paths.SFTP_PRIVATE_KEY_FILE);
2021-05-02 23:28:41 -07:00
}
2021-05-04 10:45:36 -07:00
if (!safe.child_process.execSync(`ssh-keygen -m PEM -t rsa -f "${paths.SFTP_KEYS_DIR}/ssh_host_rsa_key" -q -N ""`)) throw new BoxError(BoxError.OPENSSL_ERROR, `Could not generate sftp ssh keys: ${safe.error.message}`);
2021-05-04 15:50:02 -07:00
sftpPublicKey = safe.fs.readFileSync(paths.SFTP_PUBLIC_KEY_FILE);
await set(exports.SFTP_PUBLIC_KEY, sftpPublicKey);
2021-05-04 15:50:02 -07:00
sftpPrivateKey = safe.fs.readFileSync(paths.SFTP_PRIVATE_KEY_FILE);
await set(exports.SFTP_PRIVATE_KEY, sftpPrivateKey);
2021-05-04 15:50:02 -07:00
} else if (!safe.fs.existsSync(paths.SFTP_PUBLIC_KEY_FILE) || !safe.fs.existsSync(paths.SFTP_PRIVATE_KEY_FILE)) {
if (!safe.fs.writeFileSync(paths.SFTP_PUBLIC_KEY_FILE, sftpPublicKey)) throw new BoxError(BoxError.FS_ERROR, `Could not save sftp public key: ${safe.error.message}`);
if (!safe.fs.writeFileSync(paths.SFTP_PRIVATE_KEY_FILE, sftpPrivateKey)) throw new BoxError(BoxError.FS_ERROR, `Could not save sftp private key: ${safe.error.message}`);
2021-05-02 23:28:41 -07:00
}
}