Skip to content

Commit 6723da8

Browse files
author
Stefan-Gabriel Muscalu
committed
FIx: host fingerprint same tick duplication
1 parent 124047f commit 6723da8

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/v1/internal/ch-node.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,30 @@ function loadFingerprint( serverId, knownHostsPath, cb ) {
5656
});
5757
}
5858

59-
function storeFingerprint(serverId, knownHostsPath, fingerprint) {
59+
const _lockFingerprintFromAppending = {};
60+
function storeFingerprint( serverId, knownHostsPath, fingerprint ) {
61+
// we check if the serverId has been appended
62+
if(!!_lockFingerprintFromAppending[serverId]){
63+
// if it has, we ignore it
64+
return;
65+
}
66+
67+
// we make the line as appended
68+
// ( 1 is more efficient to store than true because true is an oddball )
69+
_lockFingerprintFromAppending[serverId] = 1;
70+
71+
// we append to file
6072
fs.appendFile(knownHostsPath, serverId + " " + fingerprint + EOL, "utf8", (err) => {
6173
if (err) {
6274
console.log(err);
6375
}
6476
});
77+
78+
// since the error occurs in the span of one tick
79+
// after one tick we clean up to not interfere with anything else
80+
setImmediate(() => {
81+
delete _lockFingerprintFromAppending[serverId];
82+
});
6583
}
6684

6785
const TrustStrategy = {

test/internal/tls.test.js

+30
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,36 @@ describe('trust-on-first-use', function() {
139139
});
140140
});
141141

142+
it('should not duplicate fingerprint entries', function(done) {
143+
// Assuming we only run this test on NodeJS with TOFU support
144+
if( !hasFeature("trust_on_first_use") ) {
145+
done();
146+
return;
147+
}
148+
149+
// Given
150+
var knownHostsPath = "build/known_hosts";
151+
if( fs.existsSync(knownHostsPath) ) {
152+
fs.unlinkSync(knownHostsPath);
153+
}
154+
fs.writeFileSync(knownHostsPath, '');
155+
156+
driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"), {
157+
encrypted: true,
158+
trust: "TRUST_ON_FIRST_USE",
159+
knownHosts: knownHostsPath
160+
});
161+
162+
// When
163+
driver.session();
164+
driver.session();
165+
166+
setTimeout(function() {
167+
expect( fs.readFileSync(knownHostsPath, 'utf8').split('\n').length ).toBe( 1 );
168+
done();
169+
}, 1000);
170+
});
171+
142172
it('should should give helpful error if database cert does not match stored certificate', function(done) {
143173
// Assuming we only run this test on NodeJS with TOFU support
144174
if( !hasFeature("trust_on_first_use") ) {

0 commit comments

Comments
 (0)