Fix version nonce handling

This commit is contained in:
Kagami Hiiragi 2015-02-01 17:09:46 +03:00
parent 156a3f7e56
commit 25243531e9
2 changed files with 21 additions and 10 deletions

View File

@ -10,8 +10,10 @@
"use strict"; "use strict";
var objectAssign = Object.assign || require("object-assign"); var objectAssign = Object.assign || require("object-assign");
var bufferEqual = require("buffer-equal");
var assert = require("./_util").assert; var assert = require("./_util").assert;
var structs = require("./structs"); var structs = require("./structs");
var bmcrypto = require("./crypto");
var UserAgent = require("./user-agent"); var UserAgent = require("./user-agent");
var util = require("./_util"); var util = require("./_util");
@ -43,6 +45,9 @@ exports.getCommand = function(buf) {
return command.slice(0, firstNonNull).toString("ascii"); return command.slice(0, firstNonNull).toString("ascii");
}; };
// Random nonce used to detect connections to self.
var randomNonce = bmcrypto.randomBytes(8);
/** /**
* `version` message. * `version` message.
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version} * @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
@ -51,13 +56,7 @@ exports.getCommand = function(buf) {
*/ */
var version = exports.version = { var version = exports.version = {
/** /**
* Random nonce used to detect connections to self. * Decode `version` message.
* @const {Buffer}
*/
NONCE: new Buffer("20bde0a3355dad78", "hex"),
/**
* Decode `version` message.
* NOTE: `nonce` is copied. * NOTE: `nonce` is copied.
* @param {Buffer} buf - Message * @param {Buffer} buf - Message
* @return {Object} Decoded `version` structure. * @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. * NOTE: `nonce` is copied.
* @param {Buffer} buf - Message payload * @param {Buffer} buf - Message payload
* @return {Object} Decoded `version` structure. * @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 addrFrom = structs.net_addr.decode(buf.slice(46, 72), short);
var nonce = new Buffer(8); var nonce = new Buffer(8);
buf.copy(nonce, 0, 72, 80); buf.copy(nonce, 0, 72, 80);
assert(!bufferEqual(nonce, randomNonce), "Connection to self");
var decodedUa = UserAgent.decode(buf.slice(80)); var decodedUa = UserAgent.decode(buf.slice(80));
var decodedStreamNumbers = structs.var_int_list.decode(decodedUa.rest); var decodedStreamNumbers = structs.var_int_list.decode(decodedUa.rest);
return { return {
@ -125,7 +125,7 @@ var version = exports.version = {
var services = opts.services || var services = opts.services ||
ServicesBitfield().set(ServicesBitfield.NODE_NETWORK); ServicesBitfield().set(ServicesBitfield.NODE_NETWORK);
var time = opts.time || new Date(); var time = opts.time || new Date();
var nonce = opts.nonce || version.NONCE; var nonce = opts.nonce || randomNonce;
assert(nonce.length === 8, "Bad nonce"); assert(nonce.length === 8, "Bad nonce");
var userAgent = opts.userAgent || UserAgent.SELF; var userAgent = opts.userAgent || UserAgent.SELF;
var streamNumbers = opts.streamNumbers || [1]; var streamNumbers = opts.streamNumbers || [1];

13
test.js
View File

@ -407,10 +407,12 @@ describe("Message types", function() {
describe("version", function() { describe("version", function() {
it("should encode and decode", function() { it("should encode and decode", function() {
var nonce = Buffer(8);
var encoded = version.encode({ var encoded = version.encode({
remoteHost: "1.2.3.4", remoteHost: "1.2.3.4",
remotePort: 48444, remotePort: 48444,
port: 8444, port: 8444,
nonce: nonce,
}); });
expect(message.decode(encoded).command).to.equal("version"); expect(message.decode(encoded).command).to.equal("version");
var res = version.decode(encoded); var res = version.decode(encoded);
@ -420,7 +422,7 @@ describe("Message types", function() {
expect(res.remoteHost).to.equal("1.2.3.4"); expect(res.remoteHost).to.equal("1.2.3.4");
expect(res.remotePort).to.equal(48444); expect(res.remotePort).to.equal(48444);
expect(res.port).to.equal(8444); 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(UserAgent.parse(res.userAgent)).to.deep.equal(UserAgent.SELF);
expect(res.streamNumbers).to.deep.equal([1]); expect(res.streamNumbers).to.deep.equal([1]);
expect(res.length).to.equal(101); expect(res.length).to.equal(101);
@ -432,9 +434,18 @@ describe("Message types", function() {
remotePort: 48444, remotePort: 48444,
port: 8444, port: 8444,
userAgent: "/test:0.0.1/", userAgent: "/test:0.0.1/",
nonce: Buffer(8),
})); }));
expect(res.userAgent).to.equal("/test:0.0.1/"); 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() { describe("addr", function() {