diff --git a/src/cert/acme2.js b/src/cert/acme2.js index 7ad98dad7..868988c6b 100644 --- a/src/cert/acme2.js +++ b/src/cert/acme2.js @@ -5,7 +5,6 @@ var assert = require('assert'), crypto = require('crypto'), debug = require('debug')('box:cert/acme2'), domains = require('../domains.js'), - execSync = require('safetydance').child_process.execSync, fs = require('fs'), path = require('path'), paths = require('../paths.js'), @@ -88,7 +87,7 @@ function b64(str) { function getModulus(pem) { assert(util.isBuffer(pem)); - var stdout = execSync('openssl rsa -modulus -noout', { input: pem, encoding: 'utf8' }); + var stdout = safe.child_process.execSync('openssl rsa -modulus -noout', { input: pem, encoding: 'utf8' }); if (!stdout) return null; var match = stdout.match(/Modulus=([0-9a-fA-F]+)$/m); if (!match) return null; @@ -351,14 +350,14 @@ Acme2.prototype.createKeyAndCsr = function (hostname, callback) { // in some old releases, csr file was corrupt. so always regenerate it debug('createKeyAndCsr: reuse the key for renewal at %s', privateKeyFile); } else { - var key = execSync('openssl genrsa 4096'); + var key = safe.child_process.execSync('openssl genrsa 4096'); if (!key) return callback(new Acme2Error(Acme2Error.INTERNAL_ERROR, safe.error)); if (!safe.fs.writeFileSync(privateKeyFile, key)) return callback(new Acme2Error(Acme2Error.INTERNAL_ERROR, safe.error)); debug('createKeyAndCsr: key file saved at %s', privateKeyFile); } - var csrDer = execSync(`openssl req -new -key ${privateKeyFile} -outform DER -subj /CN=${hostname}`); + var csrDer = safe.child_process.execSync(`openssl req -new -key ${privateKeyFile} -outform DER -subj /CN=${hostname}`); if (!csrDer) return callback(new Acme2Error(Acme2Error.INTERNAL_ERROR, safe.error)); if (!safe.fs.writeFileSync(csrFile, csrDer)) return callback(new Acme2Error(Acme2Error.INTERNAL_ERROR, safe.error)); // bookkeeping diff --git a/src/logcollector.js b/src/logcollector.js index 4e7b97890..fa3179152 100644 --- a/src/logcollector.js +++ b/src/logcollector.js @@ -22,6 +22,8 @@ function collectLogs(unitName, callback) { assert.strictEqual(typeof callback, 'function'); var logs = safe.child_process.execSync('sudo ' + COLLECT_LOGS_CMD + ' ' + unitName, { encoding: 'utf8' }); + if (!logs) return callback(safe.error); + logs = logs + '\n\n=====================================\n\n'; callback(null, logs); diff --git a/src/platform.js b/src/platform.js index 82dac7ca1..fe294cfa0 100644 --- a/src/platform.js +++ b/src/platform.js @@ -16,7 +16,6 @@ var addons = require('./addons.js'), async = require('async'), config = require('./config.js'), debug = require('debug')('box:platform'), - execSync = require('child_process').execSync, fs = require('fs'), graphs = require('./graphs.js'), infra = require('./infra_version.js'), @@ -114,7 +113,9 @@ function pruneInfraImages(callback) { const images = infra.baseImages.concat(Object.keys(infra.images).map(function (addon) { return infra.images[addon]; })); async.eachSeries(images, function (image, iteratorCallback) { - let output = execSync(`docker images --digests ${image.repo} --format "{{.ID}} {{.Repository}}:{{.Tag}}@{{.Digest}}"`, { encoding: 'utf8' }); + let output = safe.child_process.execSync(`docker images --digests ${image.repo} --format "{{.ID}} {{.Repository}}:{{.Tag}}@{{.Digest}}"`, { encoding: 'utf8' }); + if (output === null) return iteratorCallback(safe.error); + let lines = output.trim().split('\n'); for (let line of lines) { if (!line) continue; diff --git a/src/reverseproxy.js b/src/reverseproxy.js index f24c43cff..7228da350 100644 --- a/src/reverseproxy.js +++ b/src/reverseproxy.js @@ -132,6 +132,7 @@ function providerMatchesSync(domainObject, certFilePath, apiOptions) { if (apiOptions.fallback) return certFilePath.includes('.host.cert'); const subjectAndIssuer = safe.child_process.execSync(`/usr/bin/openssl x509 -noout -subject -issuer -in "${certFilePath}"`, { encoding: 'utf8' }); + if (!subjectAndIssuer) return false; // something bad happenned const subject = subjectAndIssuer.match(/^subject=(.*)$/m)[1]; const domain = subject.substr(subject.indexOf('=') + 1).trim(); // subject can be /CN=, CN=, CN = and other forms @@ -167,13 +168,17 @@ function validateCertificate(location, domainObject, certificate) { const fqdn = domains.fqdn(location, domainObject); var result = safe.child_process.execSync(`openssl x509 -noout -checkhost "${fqdn}"`, { encoding: 'utf8', input: cert }); - if (!result) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'Unable to get certificate subject.'); + if (result === null) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'Unable to get certificate subject:' + safe.error.message); if (result.indexOf('does match certificate') === -1) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, `Certificate is not valid for this domain. Expecting ${fqdn}`); // http://httpd.apache.org/docs/2.0/ssl/ssl_faq.html#verify var certModulus = safe.child_process.execSync('openssl x509 -noout -modulus', { encoding: 'utf8', input: cert }); + if (certModulus === null) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, `Unable to get cert modulus: ${safe.error.message}`); + var keyModulus = safe.child_process.execSync('openssl rsa -noout -modulus', { encoding: 'utf8', input: key }); + if (keyModulus === null) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, `Unable to get key modulus: ${safe.error.message}`); + if (certModulus !== keyModulus) return new ReverseProxyError(ReverseProxyError.INVALID_CERT, 'Key does not match the certificate.'); // check expiration @@ -581,8 +586,10 @@ function configureDefaultServer(callback) { debug('configureDefaultServer: create new cert'); var cn = 'cloudron-' + (new Date()).toISOString(); // randomize date a bit to keep firefox happy - var certCommand = util.format('openssl req -x509 -newkey rsa:2048 -keyout %s -out %s -days 3650 -subj /CN=%s -nodes', keyFilePath, certFilePath, cn); - safe.child_process.execSync(certCommand); + if (!safe.child_process.execSync(`openssl req -x509 -newkey rsa:2048 -keyout ${keyFilePath} -out ${certFilePath} -days 3650 -subj /CN=${cn} -nodes`)) { + debug(`configureDefaultServer: could not generate certificate: ${safe.error.message}`); + return callback(safe.error); + } } writeAdminConfig({ certFilePath, keyFilePath }, constants.NGINX_DEFAULT_CONFIG_FILE_NAME, '', function (error) {