Software /
code /
prosody
Changeset
6428:3ee09bfe16e1
Merge 0.10->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 23 Sep 2014 23:22:13 +0200 |
parents | 6423:1c78f10f05d0 (current diff) 6427:7653bbd5247e (diff) |
children | 6429:675aea867574 |
files | |
diffstat | 3 files changed, 45 insertions(+), 72 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/mod_dialback.lua Tue Sep 23 01:44:16 2014 +0200 +++ b/plugins/mod_dialback.lua Tue Sep 23 23:22:13 2014 +0200 @@ -176,14 +176,6 @@ end end); -module:hook_stanza("urn:ietf:params:xml:ns:xmpp-sasl", "failure", function (origin, stanza) - if origin.external_auth == "failed" then - module:log("debug", "SASL EXTERNAL failed, falling back to dialback"); - initiate_dialback(origin); - return true; - end -end, 100); - module:hook_stanza(xmlns_stream, "features", function (origin, stanza) if not origin.external_auth or origin.external_auth == "failed" then module:log("debug", "Initiating dialback...");
--- a/plugins/mod_s2s/mod_s2s.lua Tue Sep 23 01:44:16 2014 +0200 +++ b/plugins/mod_s2s/mod_s2s.lua Tue Sep 23 23:22:13 2014 +0200 @@ -154,6 +154,10 @@ -- so the stream is ready for stanzas. RFC 6120 Section 4.3 mark_connected(session); return true; + elseif not session.dialback_verifying then + session.log("warn", "No SASL EXTERNAL offer and Dialback doesn't seem to be enabled, giving up"); + session:close(); + return false; end end, -1); end
--- a/plugins/mod_saslauth.lua Tue Sep 23 01:44:16 2014 +0200 +++ b/plugins/mod_saslauth.lua Tue Sep 23 23:22:13 2014 +0200 @@ -13,8 +13,6 @@ local sm_make_authenticated = require "core.sessionmanager".make_authenticated; local base64 = require "util.encodings".base64; -local cert_verify_identity = require "util.x509".verify_identity; - local usermanager_get_sasl_handler = require "core.usermanager".get_sasl_handler; local tostring = tostring; @@ -28,15 +26,15 @@ local function build_reply(status, ret, err_msg) local reply = st.stanza(status, {xmlns = xmlns_sasl}); - if status == "challenge" then - --log("debug", "CHALLENGE: %s", ret or ""); - reply:text(base64.encode(ret or "")); - elseif status == "failure" then + if status == "failure" then reply:tag(ret):up(); if err_msg then reply:tag("text"):text(err_msg); end - elseif status == "success" then - --log("debug", "SUCCESS: %s", ret or ""); - reply:text(base64.encode(ret or "")); + elseif status == "challenge" or status == "success" then + if ret == "" then + reply:text("=") + elseif ret then + reply:text(base64.encode(ret)); + end else module:log("error", "Unknown sasl status: %s", status); end @@ -99,12 +97,10 @@ module:log("info", "SASL EXTERNAL with %s failed", session.to_host) -- TODO: Log the failure reason session.external_auth = "failed" + session:close(); + return true; end, 500) -module:hook_stanza(xmlns_sasl, "failure", function (session, stanza) - -- TODO: Dialback wasn't loaded. Do something useful. -end, 90) - module:hook_stanza("http://etherx.jabber.org/streams", "features", function (session, stanza) if session.type ~= "s2sout_unauthed" or not session.secure then return; end @@ -124,71 +120,52 @@ end, 150); local function s2s_external_auth(session, stanza) + if session.external_auth ~= "offered" then return end -- Unexpected request + local mechanism = stanza.attr.mechanism; - if not session.secure then - if mechanism == "EXTERNAL" then - session.sends2s(build_reply("failure", "encryption-required")) - else - session.sends2s(build_reply("failure", "invalid-mechanism")) - end + if mechanism ~= "EXTERNAL" then + session.sends2s(build_reply("failure", "invalid-mechanism")); return true; end - if mechanism ~= "EXTERNAL" or session.cert_chain_status ~= "valid" then - session.sends2s(build_reply("failure", "invalid-mechanism")) + if not session.secure then + session.sends2s(build_reply("failure", "encryption-required")); return true; end - local text = stanza[1] + local text = stanza[1]; if not text then - session.sends2s(build_reply("failure", "malformed-request")) - return true - end - - -- Either the value is "=" and we've already verified the external - -- cert identity, or the value is a string and either matches the - -- from_host ( - - text = base64.decode(text) - if not text then - session.sends2s(build_reply("failure", "incorrect-encoding")) + session.sends2s(build_reply("failure", "malformed-request")); return true; end - if session.cert_identity_status == "valid" then - if text ~= "" and text ~= session.from_host then - session.sends2s(build_reply("failure", "invalid-authzid")) - return true - end - else - if text == "" then - session.sends2s(build_reply("failure", "invalid-authzid")) - return true - end + text = base64.decode(text); + if not text then + session.sends2s(build_reply("failure", "incorrect-encoding")); + return true; + end - local cert = session.conn:socket():getpeercertificate() - if (cert_verify_identity(text, "xmpp-server", cert)) then - session.cert_identity_status = "valid" - else - session.cert_identity_status = "invalid" - session.sends2s(build_reply("failure", "invalid-authzid")) - return true - end + -- The text value is either "" or equals session.from_host + if not ( text == "" or text == session.from_host ) then + session.sends2s(build_reply("failure", "invalid-authzid")); + return true; end - session.external_auth = "succeeded" - - if not session.from_host then - session.from_host = text; + -- We've already verified the external cert identity before offering EXTERNAL + if session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid" then + session.sends2s(build_reply("failure", "not-authorized")); + session:close(); + return true; end - session.sends2s(build_reply("success")) - local domain = text ~= "" and text or session.from_host; - module:log("info", "Accepting SASL EXTERNAL identity from %s", domain); - module:fire_event("s2s-authenticated", { session = session, host = domain }); + -- Success! + session.external_auth = "succeeded"; + session.sends2s(build_reply("success")); + module:log("info", "Accepting SASL EXTERNAL identity from %s", session.from_host); + module:fire_event("s2s-authenticated", { session = session, host = session.from_host }); session:reset_stream(); - return true + return true; end module:hook("stanza/urn:ietf:params:xml:ns:xmpp-sasl:auth", function(event) @@ -268,10 +245,10 @@ module:hook("s2s-stream-features", function(event) local origin, features = event.origin, event.features; if origin.secure and origin.type == "s2sin_unauthed" then - -- Offer EXTERNAL if chain is valid and either we didn't validate - -- the identity or it passed. - if origin.cert_chain_status == "valid" and origin.cert_identity_status ~= "invalid" then --TODO: Configurable - module:log("debug", "Offering SASL EXTERNAL") + -- Offer EXTERNAL only if both chain and identity is valid. + if origin.cert_chain_status == "valid" and origin.cert_identity_status == "valid" then + module:log("debug", "Offering SASL EXTERNAL"); + origin.external_auth = "offered" features:tag("mechanisms", { xmlns = xmlns_sasl }) :tag("mechanism"):text("EXTERNAL") :up():up();