Diff

mod_pubsub_feed/mod_pubsub_feed.lua @ 325:4e50e591a7fc

mod_pubsub_feed: Implement signature verification
author Kim Alvefur <zash@zash.se>
date Tue, 01 Feb 2011 00:24:19 +0100
parent 324:100b3ad2e10c
child 400:f42fe4229f8a
line wrap: on
line diff
--- 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();