diff --git a/lib/messages.js b/lib/messages.js index 6c95e35..7fffa82 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -10,8 +10,10 @@ "use strict"; var objectAssign = Object.assign || require("object-assign"); +var bufferEqual = require("buffer-equal"); var assert = require("./_util").assert; var structs = require("./structs"); +var bmcrypto = require("./crypto"); var UserAgent = require("./user-agent"); var util = require("./_util"); @@ -43,6 +45,9 @@ exports.getCommand = function(buf) { return command.slice(0, firstNonNull).toString("ascii"); }; +// Random nonce used to detect connections to self. +var randomNonce = bmcrypto.randomBytes(8); + /** * `version` message. * @see {@link https://bitmessage.org/wiki/Protocol_specification#version} @@ -51,13 +56,7 @@ exports.getCommand = function(buf) { */ var version = exports.version = { /** - * Random nonce used to detect connections to self. - * @const {Buffer} - */ - NONCE: new Buffer("20bde0a3355dad78", "hex"), - - /** - * Decode `version` message. + * Decode `version` message. * NOTE: `nonce` is copied. * @param {Buffer} buf - Message * @return {Object} Decoded `version` structure. @@ -69,7 +68,7 @@ var version = exports.version = { }, /** - * Decode `version` message payload. + * Decode `version` message payload. * NOTE: `nonce` is copied. * @param {Buffer} buf - Message payload * @return {Object} Decoded `version` structure. @@ -85,6 +84,7 @@ var version = exports.version = { var addrFrom = structs.net_addr.decode(buf.slice(46, 72), short); var nonce = new Buffer(8); buf.copy(nonce, 0, 72, 80); + assert(!bufferEqual(nonce, randomNonce), "Connection to self"); var decodedUa = UserAgent.decode(buf.slice(80)); var decodedStreamNumbers = structs.var_int_list.decode(decodedUa.rest); return { @@ -125,7 +125,7 @@ var version = exports.version = { var services = opts.services || ServicesBitfield().set(ServicesBitfield.NODE_NETWORK); var time = opts.time || new Date(); - var nonce = opts.nonce || version.NONCE; + var nonce = opts.nonce || randomNonce; assert(nonce.length === 8, "Bad nonce"); var userAgent = opts.userAgent || UserAgent.SELF; var streamNumbers = opts.streamNumbers || [1]; diff --git a/test.js b/test.js index a3fbe30..d635ba1 100644 --- a/test.js +++ b/test.js @@ -407,10 +407,12 @@ describe("Message types", function() { describe("version", function() { it("should encode and decode", function() { + var nonce = Buffer(8); var encoded = version.encode({ remoteHost: "1.2.3.4", remotePort: 48444, port: 8444, + nonce: nonce, }); expect(message.decode(encoded).command).to.equal("version"); var res = version.decode(encoded); @@ -420,7 +422,7 @@ describe("Message types", function() { expect(res.remoteHost).to.equal("1.2.3.4"); expect(res.remotePort).to.equal(48444); expect(res.port).to.equal(8444); - expect(bufferEqual(res.nonce, version.NONCE)).to.be.true; + expect(bufferEqual(res.nonce, nonce)).to.be.true; expect(UserAgent.parse(res.userAgent)).to.deep.equal(UserAgent.SELF); expect(res.streamNumbers).to.deep.equal([1]); expect(res.length).to.equal(101); @@ -432,9 +434,18 @@ describe("Message types", function() { remotePort: 48444, port: 8444, userAgent: "/test:0.0.1/", + nonce: Buffer(8), })); expect(res.userAgent).to.equal("/test:0.0.1/"); }); + + it("should fail on connection to self", function() { + expect(version.decode.bind(null, version.encode({ + remoteHost: "1.2.3.4", + remotePort: 48444, + port: 8444, + }))).to.throw(/connection to self/i); + }); }); describe("addr", function() {