# HG changeset patch # User Kim Alvefur # Date 1296516259 -3600 # Node ID 4e50e591a7fc4ee0343dfcc855e5bd1e3b54725f # Parent 100b3ad2e10c2e3db6882ef01d6e7576a7a533ac mod_pubsub_feed: Implement signature verification diff -r 100b3ad2e10c -r 4e50e591a7fc mod_pubsub_feed/mod_pubsub_feed.lua --- a/mod_pubsub_feed/mod_pubsub_feed.lua Mon Jan 31 23:32:25 2011 +0100 +++ b/mod_pubsub_feed/mod_pubsub_feed.lua Tue Feb 01 00:24:19 2011 +0100 @@ -33,6 +33,7 @@ local formencode = require "net.http".formencode; local dump = require "util.serialization".serialize; local uuid = require "util.uuid".generate; +local hmac_sha1 = require "util.hmac".sha1; local urldecode = require "net.http".urldecode; local urlencode = require "net.http".urlencode; @@ -165,13 +166,14 @@ function subscribe(feed) feed.token = uuid(); + feed.secret = uuid(); local _body, body = { ["hub.callback"] = "http://"..module.host..":5280/callback?node=" .. urlencode(feed.node); --FIXME figure out your own hostname reliably? ["hub.mode"] = "subscribe"; --TODO unsubscribe ["hub.topic"] = feed.url; ["hub.verify"] = "async"; ["hub.verify_token"] = feed.token; - --["hub.secret"] = ""; -- TODO http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.3.html#authednotify + ["hub.secret"] = feed.secret; --["hub.lease_seconds"] = ""; }, { }; for name, value in pairs(_body) do @@ -196,6 +198,7 @@ query = urlparams(query); --module:log("debug", "GET data: %s", dump(query)); end + --module:log("debug", "Headers: %s", dump(request.headers)); if method == "GET" then if query.node and feed_list[query.node] then @@ -225,6 +228,15 @@ if #body > 0 and feed_list[query.node] then module:log("debug", "got %d bytes PuSHed for %s", #body, query.node); local feed = feed_list[query.node]; + local signature = request.headers["x-hub-signature"]; + if feed.secret then + local localsig = "sha1=" .. hmac_sha1(feed.secret, body, true); + if localsig ~= signature then + module:log("debug", "Invalid signature"); + return http_response(403); + end + module:log("debug", "Valid signature"); + end feed.data = body; update_entry(feed); feed.last_update = time();