Mercurial > prosody-modules
comparison mod_component_roundrobin/mod_component_roundrobin.lua @ 406:a6d215c73c47
mod_component_roundrobin: Initial commit.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sun, 28 Aug 2011 21:41:46 +0500 |
parents | |
children | 08e50d742392 |
comparison
equal
deleted
inserted
replaced
405:fe4fdba21a23 | 406:a6d215c73c47 |
---|---|
1 -- Prosody IM | |
2 -- Copyright (C) 2008-2010 Matthew Wild | |
3 -- Copyright (C) 2008-2010 Waqas Hussain | |
4 -- | |
5 -- This project is MIT/X11 licensed. Please see the | |
6 -- COPYING file in the source package for more information. | |
7 -- | |
8 | |
9 if module:get_host_type() ~= "component" then | |
10 error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0); | |
11 end | |
12 | |
13 local hosts = _G.hosts; | |
14 | |
15 local t_concat = table.concat; | |
16 | |
17 local sha1 = require "util.hashes".sha1; | |
18 local st = require "util.stanza"; | |
19 | |
20 local log = module._log; | |
21 | |
22 local sessions = {}; | |
23 | |
24 local function on_destroy(session, err) | |
25 if sessions[session] then | |
26 sessions[session] = nil; | |
27 session.on_destroy = nil; | |
28 end | |
29 end | |
30 | |
31 local last_session; | |
32 local function handle_stanza(event) | |
33 local stanza = event.stanza; | |
34 if next(sessions) then | |
35 stanza.attr.xmlns = nil; | |
36 last_session = next(sessions, last_session) or next(sessions); | |
37 last_session.send(stanza); | |
38 else | |
39 log("warn", "Component not connected, bouncing error for: %s", stanza:top_tag()); | |
40 if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then | |
41 event.origin.send(st.error_reply(stanza, "wait", "service-unavailable", "Component unavailable")); | |
42 end | |
43 end | |
44 return true; | |
45 end | |
46 | |
47 module:hook("iq/bare", handle_stanza, -1); | |
48 module:hook("message/bare", handle_stanza, -1); | |
49 module:hook("presence/bare", handle_stanza, -1); | |
50 module:hook("iq/full", handle_stanza, -1); | |
51 module:hook("message/full", handle_stanza, -1); | |
52 module:hook("presence/full", handle_stanza, -1); | |
53 module:hook("iq/host", handle_stanza, -1); | |
54 module:hook("message/host", handle_stanza, -1); | |
55 module:hook("presence/host", handle_stanza, -1); | |
56 | |
57 --- Handle authentication attempts by components | |
58 function handle_component_auth(event) | |
59 local session, stanza = event.origin, event.stanza; | |
60 | |
61 if session.type ~= "component" then return; end | |
62 if sessions[session] then return; end | |
63 | |
64 if (not session.host) or #stanza.tags > 0 then | |
65 (session.log or log)("warn", "Invalid component handshake for host: %s", session.host); | |
66 session:close("not-authorized"); | |
67 return true; | |
68 end | |
69 | |
70 local secret = module:get_option("component_secret"); | |
71 if not secret then | |
72 (session.log or log)("warn", "Component attempted to identify as %s, but component_secret is not set", session.host); | |
73 session:close("not-authorized"); | |
74 return true; | |
75 end | |
76 | |
77 local supplied_token = t_concat(stanza); | |
78 local calculated_token = sha1(session.streamid..secret, true); | |
79 if supplied_token:lower() ~= calculated_token:lower() then | |
80 log("info", "Component authentication failed for %s", session.host); | |
81 session:close{ condition = "not-authorized", text = "Given token does not match calculated token" }; | |
82 return true; | |
83 end | |
84 | |
85 -- Add session to sessions table | |
86 sessions[session] = true; | |
87 session.on_destroy = on_destroy; | |
88 session.component_validate_from = module:get_option_boolean("validate_from_addresses", true); | |
89 log("info", "Component successfully authenticated: %s", session.host); | |
90 session.send(st.stanza("handshake")); | |
91 | |
92 return true; | |
93 end | |
94 | |
95 module:hook("stanza/jabber:component:accept:handshake", handle_component_auth); |