comparison mod_pubsub_post/mod_pubsub_post.lua @ 3501:1df139b157fb

mod_pubsub_post: Add support for WebSub authentication
author Kim Alvefur <zash@zash.se>
date Fri, 24 Aug 2018 14:52:09 +0200
parents 64d1dfbd1740
children 882180b459a0
comparison
equal deleted inserted replaced
3500:e86315c9b5c4 3501:1df139b157fb
3 local st = require "util.stanza"; 3 local st = require "util.stanza";
4 local json = require "util.json"; 4 local json = require "util.json";
5 local xml = require "util.xml"; 5 local xml = require "util.xml";
6 local uuid_generate = require "util.uuid".generate; 6 local uuid_generate = require "util.uuid".generate;
7 local timestamp_generate = require "util.datetime".datetime; 7 local timestamp_generate = require "util.datetime".datetime;
8 local hashes = require "util.hashes";
9 local from_hex = require "util.hex".from;
10 local hmacs = {
11 sha1 = hashes.hmac_sha1;
12 sha256 = hashes.hmac_sha256;
13 sha384 = hashes.hmac_sha384;
14 sha512 = hashes.hmac_sha512;
15 };
8 16
9 local pubsub_service = module:depends("pubsub").service; 17 local pubsub_service = module:depends("pubsub").service;
10 18
11 local error_mapping = { 19 local error_mapping = {
12 ["forbidden"] = 403; 20 ["forbidden"] = 403;
66 return publish_payload(node, actor, "current", xmlpayload); 74 return publish_payload(node, actor, "current", xmlpayload);
67 end 75 end
68 end 76 end
69 77
70 local actor_source = module:get_option_string("pubsub_post_actor", "superuser"); 78 local actor_source = module:get_option_string("pubsub_post_actor", "superuser");
79 local actor_secret = module:get_option_string("pubsub_post_secret");
80 local actor_secrets = module:get_option("pubsub_post_secrets");
81
82 local function verify_signature(secret, body, signature)
83 if not signature then return false; end
84 local algo, digest = signature:match("^([^=]+)=(%x+)");
85 if not algo then return false; end
86 local hmac = hmacs[algo];
87 if not algo then return false; end
88 return hmac(secret, body) == from_hex(digest);
89 end
71 90
72 function handle_POST(event, path) 91 function handle_POST(event, path)
73 local request = event.request; 92 local request = event.request;
74 module:log("debug", "Handling POST: \n%s\n", tostring(request.body)); 93 module:log("debug", "Handling POST: \n%s\n", tostring(request.body));
75 94
76 local content_type = request.headers.content_type or "application/octet-stream"; 95 local content_type = request.headers.content_type or "application/octet-stream";
77 local actor; 96 local actor;
97
98 local secret = actor_secrets and actor_secrets[path] or actor_secret;
99 if secret and not verify_signature(secret, request.body, request.headers.x_hub_signature) then
100 return 401;
101 end
78 102
79 if actor_source == "request.ip" then 103 if actor_source == "request.ip" then
80 actor = request.ip or request.conn:ip(); 104 actor = request.ip or request.conn:ip();
81 elseif actor_source == "superuser" then 105 elseif actor_source == "superuser" then
82 actor = true; 106 actor = true;