Comparison

plugins/mod_s2s/mod_s2s.lua @ 10455:698ff3610e57

mod_s2s: Improve error in bounces due to cert validation problems
author Kim Alvefur <zash@zash.se>
date Wed, 27 Nov 2019 23:26:59 +0100
parent 10426:dd4eb84d92a8
child 10456:2ab1cbb1c6b0
comparison
equal deleted inserted replaced
10454:6c3fccb75b38 10455:698ff3610e57
28 local fire_global_event = prosody.events.fire_event; 28 local fire_global_event = prosody.events.fire_event;
29 local runner = require "util.async".runner; 29 local runner = require "util.async".runner;
30 local connect = require "net.connect".connect; 30 local connect = require "net.connect".connect;
31 local service = require "net.resolvers.service"; 31 local service = require "net.resolvers.service";
32 local errors = require "util.error"; 32 local errors = require "util.error";
33 local set = require "util.set";
33 34
34 local connect_timeout = module:get_option_number("s2s_timeout", 90); 35 local connect_timeout = module:get_option_number("s2s_timeout", 90);
35 local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5); 36 local stream_close_timeout = module:get_option_number("s2s_close_timeout", 5);
36 local opt_keepalives = module:get_option_boolean("s2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true)); 37 local opt_keepalives = module:get_option_boolean("s2s_tcp_keepalives", module:get_option_boolean("tcp_keepalives", true));
37 local secure_auth = module:get_option_boolean("s2s_secure_auth", false); -- One day... 38 local secure_auth = module:get_option_boolean("s2s_secure_auth", false); -- One day...
723 sessions[conn] = session; 724 sessions[conn] = session;
724 initialize_session(session); 725 initialize_session(session);
725 end 726 end
726 end 727 end
727 728
729 -- Complete the sentence "Your certificate " with what's wrong
730 local function friendly_cert_error(session) --> string
731 if session.cert_chain_status == "invalid" then
732 if session.cert_chain_errors then
733 local cert_errors = set.new(session.cert_chain_errors[1]);
734 if cert_errors:contains("certificate has expired") then
735 return "has expired";
736 elseif cert_errors:contains("self signed certificate") then
737 return "is self-signed";
738 end
739 end
740 return "is not trusted"; -- for some other reason
741 elseif session.cert_identity_status == "invalid" then
742 return "is not valid for this name";
743 end
744 -- this should normally be unreachable except if no s2s auth module was loaded
745 return "could not be validated";
746 end
747
728 function check_auth_policy(event) 748 function check_auth_policy(event)
729 local host, session = event.host, event.session; 749 local host, session = event.host, event.session;
730 local must_secure = secure_auth; 750 local must_secure = secure_auth;
731 751
732 if not must_secure and secure_domains[host] then 752 if not must_secure and secure_domains[host] then
735 must_secure = false; 755 must_secure = false;
736 end 756 end
737 757
738 if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then 758 if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then
739 module:log("warn", "Forbidding insecure connection to/from %s", host or session.ip or "(unknown host)"); 759 module:log("warn", "Forbidding insecure connection to/from %s", host or session.ip or "(unknown host)");
760 local reason = friendly_cert_error(session);
740 if session.direction == "incoming" then 761 if session.direction == "incoming" then
741 session:close({ condition = "not-authorized", text = "Your server's certificate is invalid, expired, or not trusted by "..session.to_host }, 762 session:close({ condition = "not-authorized", text = "Your server's certificate "..reason },
742 nil, "Remote server's certificate is invalid, expired, or not trusted"); 763 nil, "Remote server's certificate "..reason);
743 else -- Close outgoing connections without warning 764 else -- Close outgoing connections without warning
744 session:close(false, nil, "Remote server's certificate is invalid, expired, or not trusted"); 765 session:close(false, nil, "Remote server's certificate "..reason);
745 end 766 end
746 return false; 767 return false;
747 end 768 end
748 end 769 end
749 770