From 2647595273e8059dfe48ee34a3568bc3a8eec145 Mon Sep 17 00:00:00 2001 From: Jacob Heun Date: Fri, 2 Aug 2019 16:01:53 +0200 Subject: [PATCH] fix: crypto challenge stall due to callback usage of async/await (#37) License: MIT Signed-off-by: Jacob Heun --- package.json | 10 ++++---- src/routes.js | 56 ++++++++++++++++++++++++----------------- src/utils.js | 16 ++++++------ test/rendezvous.spec.js | 8 +++--- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/package.json b/package.json index f0d714d..89c658a 100644 --- a/package.json +++ b/package.json @@ -41,19 +41,19 @@ "minimist": "^1.2.0", "multiaddr": "^6.1.0", "once": "^1.4.0", - "peer-id": "~0.13.1", + "peer-id": "~0.13.2", "peer-info": "~0.16.0", "prom-client": "^11.5.3", - "socket.io": "^2.0.4", - "socket.io-client": "^2.0.4", - "socket.io-pull-stream": "^0.1.1", + "socket.io": "^2.2.0", + "socket.io-client": "^2.2.0", + "socket.io-pull-stream": "^0.1.5", "uuid": "^3.1.0" }, "directories": { "test": "test" }, "devDependencies": { - "aegir": "^19.0.5", + "aegir": "^20.0.0", "chai": "^4.2.0", "dirty-chai": "^2.0.1", "lodash": "^4.17.11" diff --git a/src/routes.js b/src/routes.js index 8811df1..27daf8c 100644 --- a/src/routes.js +++ b/src/routes.js @@ -65,7 +65,7 @@ module.exports = (config, http) => { } // join this signaling server network - function join (socket, multiaddr, pub, cb) { + async function join (socket, multiaddr, pub, cb) { const log = socket.log = config.log.bind(config.log, '[' + socket.id + ']') if (getConfig().strictMultiaddr && !util.validateMa(multiaddr)) { @@ -88,36 +88,46 @@ module.exports = (config, http) => { if (nonces[socket.id][multiaddr]) { log('response cryptoChallenge', multiaddr) - nonces[socket.id][multiaddr].key.verify( - Buffer.from(nonces[socket.id][multiaddr].nonce), - Buffer.from(pub, 'hex'), - (err, ok) => { - if (err || !ok) { - joinsTotal.inc() - joinsFailureTotal.inc() - } - if (err) { return cb('Crypto error') } // the errors NEED to be a string otherwise JSON.stringify() turns them into {} - if (!ok) { return cb('Signature Invalid') } - - joinFinalize(socket, multiaddr, cb) - }) + let ok + try { + ok = await nonces[socket.id][multiaddr].key.verify( + Buffer.from(nonces[socket.id][multiaddr].nonce), + Buffer.from(pub, 'hex') + ) + } catch (err) { + log('crypto error', err) + } + + if (!ok) { + joinsTotal.inc() + joinsFailureTotal.inc() + } + + if (ok === undefined) { return cb('Crypto error') } // the errors NEED to be a string otherwise JSON.stringify() turns them into {} + if (ok !== true) { return cb('Signature Invalid') } + + joinFinalize(socket, multiaddr, cb) } else { joinsTotal.inc() const addr = multiaddr.split('ipfs/').pop() log('do cryptoChallenge', multiaddr, addr) - util.getIdAndValidate(pub, addr, (err, key) => { - if (err) { joinsFailureTotal.inc(); return cb(err) } - const nonce = uuid() + uuid() - - socket.once('disconnect', () => { - delete nonces[socket.id] - }) + let key + try { + key = await util.getIdAndValidate(pub, addr) + } catch (err) { + joinsFailureTotal.inc() + return cb(err) + } - nonces[socket.id][multiaddr] = { nonce: nonce, key: key } - cb(null, nonce) + const nonce = uuid() + uuid() + socket.once('disconnect', () => { + delete nonces[socket.id] }) + + nonces[socket.id][multiaddr] = { nonce: nonce, key: key } + cb(null, nonce) } } else { joinsTotal.inc() diff --git a/src/utils.js b/src/utils.js index b026b7c..7bbfc0c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -81,7 +81,7 @@ function Protocol (log) { } this.handleSocket = (socket) => { socket.r = {} - for (let request in this.requests) { + for (const request in this.requests) { if (Object.prototype.hasOwnProperty.call(this.requests, request)) { const r = this.requests[request] socket.on(request, function () { @@ -100,15 +100,13 @@ function Protocol (log) { } } -function getIdAndValidate (pub, id, cb) { - Id.createFromPubKey(Buffer.from(pub, 'hex')) - .then(_id => { - if (_id.toB58String() !== id) { - throw Error('Id is not matching') - } +async function getIdAndValidate (pub, id) { + const _id = await Id.createFromPubKey(Buffer.from(pub, 'hex')) + if (_id.toB58String() !== id) { + throw Error('Id is not matching') + } - return crypto.keys.unmarshalPublicKey(Buffer.from(pub, 'hex')) - }, cb) + return crypto.keys.unmarshalPublicKey(Buffer.from(pub, 'hex')) } exports = module.exports diff --git a/test/rendezvous.spec.js b/test/rendezvous.spec.js index 5d29db5..41f95c5 100644 --- a/test/rendezvous.spec.js +++ b/test/rendezvous.spec.js @@ -50,10 +50,10 @@ describe('signalling server client', () => { let c3 let c4 - let c1mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1') - let c2mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2') - let c3mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3') - let c4mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') + const c1mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo1') + const c2mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo2') + const c3mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo3') + const c4mh = multiaddr('/ip4/127.0.0.1/tcp/9090/ws/p2p-websocket-star/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') before(async () => { const options = {