Skip to content

Commit d6aebb6

Browse files
author
Zhen Li
authored
Merge pull request #116 from oskarhane/1.0-fix-known-hosts-path-creation
Create full path to file in knownHostsPath
2 parents c64c727 + abe5da4 commit d6aebb6

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

src/v1/internal/ch-node.js

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,35 @@ function userHome() {
3636
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
3737
}
3838

39+
function mkFullPath(pathToCreate) {
40+
let joinedDirs = [];
41+
let pathToKnownHostsParts = pathToCreate.split(path.sep)
42+
pathToKnownHostsParts = pathToKnownHostsParts.map((part) => {
43+
if( !part.length ) return path.sep
44+
return part;
45+
});
46+
pathToKnownHostsParts.forEach((dir) => {
47+
joinedDirs.push(dir);
48+
let newPath = path.join.apply(null, joinedDirs)
49+
try {
50+
fs.accessSync( newPath );
51+
return;
52+
}
53+
catch (_) {
54+
try {
55+
fs.mkdirSync( newPath );
56+
} catch(e) {
57+
if ( e.code != 'EEXIST' ) throw e;
58+
}
59+
}
60+
});
61+
}
62+
3963
function loadFingerprint( serverId, knownHostsPath, cb ) {
40-
if( !fs.existsSync( knownHostsPath )) {
41-
cb(null);
42-
return;
64+
try {
65+
fs.accessSync( knownHostsPath );
66+
} catch(e) {
67+
return cb(null)
4368
}
4469
let found = false;
4570
require('readline').createInterface({
@@ -57,6 +82,13 @@ function loadFingerprint( serverId, knownHostsPath, cb ) {
5782
}
5883

5984
function storeFingerprint(serverId, knownHostsPath, fingerprint) {
85+
// If file doesn't exist, create full path to it
86+
try {
87+
fs.accessSync(knownHostsPath);
88+
} catch (_) {
89+
let pathWithoutFile = [].concat(knownHostsPath.split(path.sep)).slice(0, -1).join(path.sep);
90+
mkFullPath(pathWithoutFile);
91+
}
6092
fs.appendFile(knownHostsPath, serverId + " " + fingerprint + EOL, "utf8", (err) => {
6193
if (err) {
6294
console.log(err);

test/internal/tls.test.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,39 @@ describe('trust-on-first-use', function() {
7676

7777
var driver;
7878

79+
it("should create known_hosts file including full path if it doesn't exist", function(done) {
80+
// Assuming we only run this test on NodeJS with TOFU support
81+
if( !hasFeature("trust_on_first_use") ) {
82+
done();
83+
return;
84+
}
85+
86+
// Given
87+
// Non existing directory
88+
var knownHostsDir = "build/hosts"
89+
var knownHostsPath = knownHostsDir + "/known_hosts";
90+
try {
91+
fs.unlinkSync(knownHostsPath);
92+
} catch (_) { }
93+
try {
94+
fs.rmdirSync(knownHostsDir);
95+
} catch (_) { }
96+
97+
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
98+
encrypted: true,
99+
trust: "TRUST_ON_FIRST_USE",
100+
knownHosts: knownHostsPath
101+
});
102+
103+
// When
104+
driver.session().run( "RETURN 1").then( function() {
105+
// Then we get to here.
106+
// And then the known_hosts file should have been created
107+
expect( function() { fs.accessSync(knownHostsPath) }).not.toThrow()
108+
done();
109+
});
110+
});
111+
79112
it('should not throw an error if the host file contains two host duplicates', function(done) {
80113
'use strict';
81114
// Assuming we only run this test on NodeJS with TOFU support

0 commit comments

Comments
 (0)