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 ,
2021-05-18 13:28:48 -07:00
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
2021-05-18 13:28:48 -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 ( ) {
2021-05-04 12:17:17 -07:00
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
}
2021-05-04 12:17:17 -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
}
2021-05-04 12:17:17 -07:00
if ( ! constants . TEST ) {
let dhparams = await get ( exports . DHPARAMS ) ;
if ( ! dhparams ) {
debug ( 'initSecrets: generating dhparams.pem. this takes forever' ) ;
dhparams = safe . child _process . execSync ( 'openssl dhparam 2048' ) ;
if ( ! dhparams ) throw new BoxError ( BoxError . OPENSSL _ERROR , safe . error ) ;
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
}
2021-05-04 12:17:17 -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 ) ;
2021-05-04 12:17:17 -07:00
await set ( exports . SFTP _PUBLIC _KEY , sftpPublicKey ) ;
2021-05-04 15:50:02 -07:00
sftpPrivateKey = safe . fs . readFileSync ( paths . SFTP _PRIVATE _KEY _FILE ) ;
2021-05-04 12:17:17 -07:00
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
}
}