correctly verify http-signature

This commit is contained in:
lesion
2019-08-02 17:29:55 +02:00
parent 40f7ffa99e
commit 9b2015f46f
5 changed files with 39 additions and 51 deletions

View File

@@ -103,12 +103,12 @@ api.get('/event/:month/:year', eventController.getAll)
// Handle 404
api.use(function(req, res) {
res.send('404: Page not Found', 404)
res.status(404).send('404: Page not Found')
})
// Handle 500
api.use(function(error, req, res, next) {
res.send('500: Internal Server Error', 500)
res.status(500).send('500: Internal Server Error')
})

View File

@@ -1,7 +1,10 @@
const fetch = require('fetch')
const fetch = require('node-fetch')
const request = require('request')
const crypto = require('crypto')
const config = require('config')
const httpSignature = require('http-signature')
const actorCache = []
const Helpers = {
async signAndSend(message, user, to) {//, domain, req, res, targetOrigin) {
@@ -57,24 +60,38 @@ const Helpers = {
}
},
// TODO: cache
// user: les@mastodon.cisti.org
async getFederatedUser(address) {
address = address.trim()
let [ user, host ] = address.split('@')
const url = `https://${host}/.well-known/webfinger?resource=acct:${user}@${host}`
console.error('get federated user at => ', address, url)
const [ username, host ] = address.split('@')
const url = `https://${host}/.well-known/webfinger?resource=acct:${username}@${host}`
return Helpers.getActor(url)
},
// TODO: cache
async getActor(url, force=false) {
// try with cache first if not forced
if (!force && actorCache[url]) return actorCache[url]
const user = await fetch(url, { headers: {'Accept': 'application/jrd+json, application/json'} })
.then(res => res.json())
actorCache[url] = user
return user
},
async verifySignature(req, res) {
console.error(req.headers['signature'])
// https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
const signature_header = req.headers['signature'].split(',')
.map(pair => pair.split('='))
console.error(signature_header)
return true
// ref: https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/
async verifySignature(req, res, next) {
let user = Helpers.getActor(req.body.actor)
// little hack -> https://github.com/joyent/node-http-signature/pull/83
req.headers.authorization = 'Signature ' + req.headers.signature
const parsed = httpSignature.parseRequest(req)
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
// signature not valid, try without cache
user = Helpers.getActor(req.body.actor, true)
if (httpSignature.verifySignature(parsed, user.publicKey.publicKeyPem)) return next()
// still not valid
res.send('Request signature could not be verified', 401)
}
}

View File

@@ -29,11 +29,7 @@ router.get('/m/:event_id', async (req, res) => {
// get any message coming from federation
// Federation is calling!
router.post('/u/:name/inbox', async (req, res) => {
if (!Helpers.verifySignature(req, res)) {
res.send('Request signature could not be verified', 401)
}
router.post('/u/:name/inbox', Helpers.verifySignature, async (req, res) => {
const b = req.body
console.error('> INBOX ', b.type, b)
@@ -55,28 +51,24 @@ router.post('/u/:name/inbox', async (req, res) => {
}
break
case 'Announce':
console.error('This is a boost ?')
Ego.boost(req, res)
break
case 'Note':
console.error('This is a note ! I probably should not receive this')
break
case 'Like':
console.error('This is a like!')
Ego.like(req, res)
break
case 'Delete':
console.error('Delete a comment ?!?!')
console.error('Delete ?!?!')
break
case 'Create':
// this is a reply
if (b.object.type === 'Note' && b.object.inReplyTo) {
console.error('this is a reply to an event')
Comments.create(b)
} else {
console.error('Create what? ', b.object.type)
}
break
}
})