Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security] Fixed issue #214 #216

Merged
merged 2 commits into from
Aug 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 12 additions & 5 deletions lib/handlers/connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var connectActions = [
fetchSubs,
restoreSubs,
storeWill,
registerClient,
doConnack,
emptyQueue
]
Expand All @@ -41,7 +42,7 @@ function handleConnect (client, packet, done) {
}

client.id = packet.clientId || uuid.v4()
client.will = packet.will
client._will = packet.will
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please restore this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restoring this would mean that the LWT is still sent in case the authentication fails or the client times out before the authentication is resolved

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add the definition of this property to lib/client.js with a comment explaining it?


clearTimeout(client._connectTimer)
client._connectTimer = null
Expand Down Expand Up @@ -71,29 +72,28 @@ function authenticate (arg, done) {
function negate (err, successful) {
var errCode
if (!err && successful) {
client.broker.registerClient(client)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not removed but moved to a separate function which is executed after the will was stored. Check line 21

return done()
} else if (err) {
if (err.returnCode && (err.returnCode >= 1 && err.returnCode <= 3)) {
errCode = err.returnCode
write(client, {
cmd: 'connack',
returnCode: err.returnCode
}, client.close.bind(client, done))
}, client.close.bind(client, done.bind(this, err)))
} else {
// If errorCode is 4 or not a number
errCode = 4
write(client, {
cmd: 'connack',
returnCode: 4
}, client.close.bind(client, done))
}, client.close.bind(client, done.bind(this, err)))
}
} else {
errCode = 5
write(client, {
cmd: 'connack',
returnCode: 5
}, client.close.bind(client, done))
}, client.close.bind(client, done.bind(this, new Error(errorMessages[errCode]))))
}
var error = new Error(errorMessages[errCode])
error.errorCode = errCode
Expand Down Expand Up @@ -132,6 +132,7 @@ function restoreSubs (arg, done) {
}

function storeWill (arg, done) {
this.client.will = this.client._will
if (this.client.will) {
this.client.broker.persistence.putWill(
this.client,
Expand All @@ -142,6 +143,12 @@ function storeWill (arg, done) {
}
}

function registerClient (arg, done) {
var client = this.client
client.broker.registerClient(client)
done()
}

function Connack (arg) {
this.cmd = 'connack'
this.returnCode = 0
Expand Down
40 changes: 40 additions & 0 deletions test/will.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,43 @@ test('does not deliver a will without authorization', function (t) {

s.conn.destroy()
})

test('does not deliver a will without authentication', function (t) {
let authenticated = false
var opts = {}
// willConnect populates opts with a will
var s = willConnect(setup(aedes({ authenticate: (_1, _2, _3, callback) => { authenticated = true; callback(new Error(), false) } })), opts)

s.broker.on('clientError', function () {
t.equal(authenticated, true, 'authentication called')
t.end()
})

s.broker.mq.on('mywill', function (packet, cb) {
t.fail('received will without authentication')
cb()
})
})

test('does not deliver will if keepalive is triggered during authentication', function (t) {
var opts = {}
opts.keepalive = 1
var broker = aedes({
authenticate: function (c, u, p, cb) {
setTimeout(function () {
cb(null, true)
}, 3000)
}
})

broker.on('keepaliveTimeout', function () {
t.end()
})

broker.mq.on('mywill', function (packet, cb) {
cb()
t.fail('Received will when it was not expected')
})

willConnect(setup(broker), opts)
})