Comparison

plugins/mod_component.lua @ 6774:3965662ae091

Merge 0.9->0.10
author Kim Alvefur <zash@zash.se>
date Mon, 10 Aug 2015 22:16:05 +0200
parent 6382:57d23c26039b
parent 6773:ef22c17cc24d
child 6913:c7a0d5299933
comparison
equal deleted inserted replaced
6772:805baeca56b6 6774:3965662ae091
31 31
32 function module.add_host(module) 32 function module.add_host(module)
33 if module:get_host_type() ~= "component" then 33 if module:get_host_type() ~= "component" then
34 error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0); 34 error("Don't load mod_component manually, it should be for a component, please see http://prosody.im/doc/components", 0);
35 end 35 end
36 36
37 local env = module.environment; 37 local env = module.environment;
38 env.connected = false; 38 env.connected = false;
39 39
40 local send; 40 local send;
41 41
42 local function on_destroy(session, err) 42 local function on_destroy(session, err)
43 env.connected = false; 43 env.connected = false;
44 send = nil; 44 send = nil;
45 session.on_destroy = nil; 45 session.on_destroy = nil;
46 end 46 end
47 47
48 -- Handle authentication attempts by component 48 -- Handle authentication attempts by component
49 local function handle_component_auth(event) 49 local function handle_component_auth(event)
50 local session, stanza = event.origin, event.stanza; 50 local session, stanza = event.origin, event.stanza;
51 51
52 if session.type ~= "component_unauthed" then return; end 52 if session.type ~= "component_unauthed" then return; end
53 53
54 if (not session.host) or #stanza.tags > 0 then 54 if (not session.host) or #stanza.tags > 0 then
55 (session.log or log)("warn", "Invalid component handshake for host: %s", session.host); 55 (session.log or log)("warn", "Invalid component handshake for host: %s", session.host);
56 session:close("not-authorized"); 56 session:close("not-authorized");
57 return true; 57 return true;
58 end 58 end
59 59
60 local secret = module:get_option("component_secret"); 60 local secret = module:get_option("component_secret");
61 if not secret then 61 if not secret then
62 (session.log or log)("warn", "Component attempted to identify as %s, but component_secret is not set", session.host); 62 (session.log or log)("warn", "Component attempted to identify as %s, but component_secret is not set", session.host);
63 session:close("not-authorized"); 63 session:close("not-authorized");
64 return true; 64 return true;
65 end 65 end
66 66
67 local supplied_token = t_concat(stanza); 67 local supplied_token = t_concat(stanza);
68 local calculated_token = sha1(session.streamid..secret, true); 68 local calculated_token = sha1(session.streamid..secret, true);
69 if supplied_token:lower() ~= calculated_token:lower() then 69 if supplied_token:lower() ~= calculated_token:lower() then
70 module:log("info", "Component authentication failed for %s", session.host); 70 module:log("info", "Component authentication failed for %s", session.host);
71 session:close{ condition = "not-authorized", text = "Given token does not match calculated token" }; 71 session:close{ condition = "not-authorized", text = "Given token does not match calculated token" };
72 return true; 72 return true;
73 end 73 end
74 74
75 if env.connected then 75 if env.connected then
76 module:log("error", "Second component attempted to connect, denying connection"); 76 module:log("error", "Second component attempted to connect, denying connection");
77 session:close{ condition = "conflict", text = "Component already connected" }; 77 session:close{ condition = "conflict", text = "Component already connected" };
78 return true; 78 return true;
79 end 79 end
80 80
81 env.connected = true; 81 env.connected = true;
82 send = session.send; 82 send = session.send;
83 session.on_destroy = on_destroy; 83 session.on_destroy = on_destroy;
84 session.component_validate_from = module:get_option_boolean("validate_from_addresses", true); 84 session.component_validate_from = module:get_option_boolean("validate_from_addresses", true);
85 session.type = "component"; 85 session.type = "component";
86 module:log("info", "External component successfully authenticated"); 86 module:log("info", "External component successfully authenticated");
87 session.send(st.stanza("handshake")); 87 session.send(st.stanza("handshake"));
88 88 module:fire_event("component-authenticated", { session = session });
89
89 return true; 90 return true;
90 end 91 end
91 module:hook("stanza/jabber:component:accept:handshake", handle_component_auth, -1); 92 module:hook("stanza/jabber:component:accept:handshake", handle_component_auth, -1);
92 93
93 -- Handle stanzas addressed to this component 94 -- Handle stanzas addressed to this component
114 event.origin.send(st.error_reply(stanza, "wait", "service-unavailable", "Component unavailable")); 115 event.origin.send(st.error_reply(stanza, "wait", "service-unavailable", "Component unavailable"));
115 end 116 end
116 end 117 end
117 return true; 118 return true;
118 end 119 end
119 120
120 module:hook("iq/bare", handle_stanza, -1); 121 module:hook("iq/bare", handle_stanza, -1);
121 module:hook("message/bare", handle_stanza, -1); 122 module:hook("message/bare", handle_stanza, -1);
122 module:hook("presence/bare", handle_stanza, -1); 123 module:hook("presence/bare", handle_stanza, -1);
123 module:hook("iq/full", handle_stanza, -1); 124 module:hook("iq/full", handle_stanza, -1);
124 module:hook("message/full", handle_stanza, -1); 125 module:hook("message/full", handle_stanza, -1);
271 session.close = session_close; 272 session.close = session_close;
272 273
273 if opt_keepalives then 274 if opt_keepalives then
274 conn:setoption("keepalive", opt_keepalives); 275 conn:setoption("keepalive", opt_keepalives);
275 end 276 end
276 277
277 session.log("info", "Incoming Jabber component connection"); 278 session.log("info", "Incoming Jabber component connection");
278 279
279 local stream = new_xmpp_stream(session, stream_callbacks); 280 local stream = new_xmpp_stream(session, stream_callbacks);
280 session.stream = stream; 281 session.stream = stream;
281 282
282 session.notopen = true; 283 session.notopen = true;
283 284
284 function session.reset_stream() 285 function session.reset_stream()
285 session.notopen = true; 286 session.notopen = true;
286 session.stream:reset(); 287 session.stream:reset();
287 end 288 end
288 289
290 local ok, err = stream:feed(data); 291 local ok, err = stream:feed(data);
291 if ok then return; end 292 if ok then return; end
292 module:log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_")); 293 module:log("debug", "Received invalid XML (%s) %d bytes: %s", tostring(err), #data, data:sub(1, 300):gsub("[\r\n]+", " "):gsub("[%z\1-\31]", "_"));
293 session:close("not-well-formed"); 294 session:close("not-well-formed");
294 end 295 end
295 296
296 session.dispatch_stanza = stream_callbacks.handlestanza; 297 session.dispatch_stanza = stream_callbacks.handlestanza;
297 298
298 sessions[conn] = session; 299 sessions[conn] = session;
299 end 300 end
300 function listener.onincoming(conn, data) 301 function listener.onincoming(conn, data)