Comparison

plugins/mod_s2s/mod_s2s.lua @ 5363:f29c26da7ecc

mod_s2s: Add controls for certificate validation via the s2s_secure_auth option. Plugins can now return false from handling s2s-check-certificate to prevent connection establishment (s2sin+s2sout)
author Matthew Wild <mwild1@gmail.com>
date Fri, 22 Mar 2013 14:21:02 +0000
parent 5362:612467e263af
child 5365:cd480ea490f1
comparison
equal deleted inserted replaced
5362:612467e263af 5363:f29c26da7ecc
31 local s2sout = module:require("s2sout"); 31 local s2sout = module:require("s2sout");
32 32
33 local connect_timeout = module:get_option_number("s2s_timeout", 90); 33 local connect_timeout = module:get_option_number("s2s_timeout", 90);
34 local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5); 34 local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5);
35 35
36 local secure_auth = module:get_option_boolean("s2s_secure_auth", false); -- One day...
37 local secure_domains, insecure_domains =
38 module:get_option_set("s2s_secure_domains", {})._items, module:get_option_set("s2s_insecure_domains", {})._items;
36 local require_encryption = module:get_option_boolean("s2s_require_encryption", secure_auth); 39 local require_encryption = module:get_option_boolean("s2s_require_encryption", secure_auth);
37 40
38 local sessions = module:shared("sessions"); 41 local sessions = module:shared("sessions");
39 42
40 local log = module._log; 43 local log = module._log;
237 session.cert_identity_status = "invalid" 240 session.cert_identity_status = "invalid"
238 end 241 end
239 end 242 end
240 end 243 end
241 end 244 end
242 module:fire_event("s2s-check-certificate", { host = host, session = session, cert = cert }); 245 return module:fire_event("s2s-check-certificate", { host = host, session = session, cert = cert });
243 end 246 end
244 247
245 --- XMPP stream event handlers 248 --- XMPP stream event handlers
246 249
247 local stream_callbacks = { default_ns = "jabber:server", handlestanza = core_process_stanza }; 250 local stream_callbacks = { default_ns = "jabber:server", handlestanza = core_process_stanza };
316 }); 319 });
317 return; 320 return;
318 end 321 end
319 end 322 end
320 323
321 if session.secure and not session.cert_chain_status then check_cert_status(session); end 324 if session.secure and not session.cert_chain_status then
325 if check_cert_status(session) == false then
326 return;
327 end
328 end
322 329
323 session:open_stream() 330 session:open_stream()
324 if session.version >= 1.0 then 331 if session.version >= 1.0 then
325 local features = st.stanza("stream:features"); 332 local features = st.stanza("stream:features");
326 333
336 elseif session.direction == "outgoing" then 343 elseif session.direction == "outgoing" then
337 -- If we are just using the connection for verifying dialback keys, we won't try and auth it 344 -- If we are just using the connection for verifying dialback keys, we won't try and auth it
338 if not attr.id then error("stream response did not give us a streamid!!!"); end 345 if not attr.id then error("stream response did not give us a streamid!!!"); end
339 session.streamid = attr.id; 346 session.streamid = attr.id;
340 347
341 if session.secure and not session.cert_chain_status then check_cert_status(session); end 348 if session.secure and not session.cert_chain_status then
349 if check_cert_status(session) == false then
350 return;
351 end
352 end
342 353
343 -- Send unauthed buffer 354 -- Send unauthed buffer
344 -- (stanzas which are fine to send before dialback) 355 -- (stanzas which are fine to send before dialback)
345 -- Note that this is *not* the stanza queue (which 356 -- Note that this is *not* the stanza queue (which
346 -- we can only send if auth succeeds) :) 357 -- we can only send if auth succeeds) :)
596 session.direction = "outgoing"; 607 session.direction = "outgoing";
597 sessions[conn] = session; 608 sessions[conn] = session;
598 initialize_session(session); 609 initialize_session(session);
599 end 610 end
600 611
612 function check_auth_policy(event)
613 local host, session = event.host, event.session;
614
615 if not secure_auth and secure_domains[host] then
616 secure_auth = true;
617 elseif secure_auth and insecure_domains[host] then
618 secure_auth = false;
619 end
620
621 if secure_auth and not session.cert_identity_status then
622 module:log("warn", "Forbidding insecure connection to/from %s", host);
623 session:close(false);
624 return false;
625 end
626 end
627
628 module:hook("s2s-check-certificate", check_auth_policy, -1);
629
601 s2sout.set_listener(listener); 630 s2sout.set_listener(listener);
602 631
603 module:hook("server-stopping", function(event) 632 module:hook("server-stopping", function(event)
604 local reason = event.reason; 633 local reason = event.reason;
605 for _, session in pairs(sessions) do 634 for _, session in pairs(sessions) do