Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
// ========== global C headers ==========

#include <fcntl.h> // _O_RDWR
#include <sys/stat.h>
#include <sys/types.h>

#if defined(NODE_HAVE_I18N_SUPPORT)
Expand Down Expand Up @@ -1275,6 +1276,25 @@ InitializeOncePerProcessInternal(const std::vector<std::string>& args,
conf_file = per_process::cli_options->openssl_config.c_str();
}

// Ignore directories without suppressing errors in actual config files.
if (conf_file != nullptr) {
struct stat st;
if (stat(conf_file, &st) == 0) {
#if defined(S_ISDIR)
if (S_ISDIR(st.st_mode)) {
#else
if ((st.st_mode & S_IFMT) == S_IFDIR) {
#endif
std::string warning = "Warning: OPENSSL_CONF path is a directory; "
"ignoring: ";
warning += conf_file;
fprintf(stderr, "%s\n", warning.c_str());
// NULL would read OPENSSL_CONF again, including this directory.
conf_file = "";
}
}
}

OPENSSL_INIT_SETTINGS* settings = OPENSSL_INIT_new();
CHECK_NOT_NULL(settings);
OPENSSL_INIT_set_config_filename(settings, conf_file);
Expand Down
51 changes: 51 additions & 0 deletions test/parallel/test-openssl-config-directory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
if (process.features.openssl_is_boringssl)
common.skip('BoringSSL does not use OpenSSL configuration files');
if (!require('../common/crypto').hasOpenSSL3)
common.skip('requires OpenSSL 3');

const assert = require('node:assert');
const { spawnSync } = require('node:child_process');
const { writeFileSync } = require('node:fs');
const { join } = require('node:path');
const tmpdir = require('../common/tmpdir');
tmpdir.refresh();

function run(conf, args = []) {
return spawnSync(process.execPath, [...args, '-p', '42'], {
encoding: 'utf8',
env: { ...process.env, OPENSSL_CONF: conf },
});
}

const directory = run(tmpdir.path);
assert.ifError(directory.error);
assert.strictEqual(directory.status, 0, directory.stderr);
assert.strictEqual(directory.stdout.trim(), '42');
assert.match(directory.stderr, /OPENSSL_CONF path is a directory; ignoring:/);

const validConfig = join(tmpdir.path, 'valid.cnf');
writeFileSync(validConfig, '');
const overridden = run(tmpdir.path, [`--openssl-config=${validConfig}`]);
assert.ifError(overridden.error);
assert.strictEqual(overridden.status, 0, overridden.stderr);
assert.strictEqual(overridden.stdout.trim(), '42');
assert.strictEqual(overridden.stderr, '');

// Ignoring a directory must not turn other configuration errors into warnings.
const invalidConfig = join(tmpdir.path, 'invalid.cnf');
writeFileSync(invalidConfig, '[unterminated\n');
for (const result of [
run(invalidConfig),
run(tmpdir.path, [`--openssl-config=${invalidConfig}`]),
]) {
assert.ifError(result.error);
assert.strictEqual(result.signal, null);
assert.notStrictEqual(result.status, 0);
assert.strictEqual(result.stdout, '');
assert.match(result.stderr, /OpenSSL configuration error/);
}
Loading