Mercurial > prosody-hg
comparison plugins/mod_saslauth.lua @ 10411:db2a06b9ff98
Merge 0.11->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 16 Nov 2019 16:52:31 +0100 |
| parents | 5c6912289ce3 |
| children | 7a3c04789d5c |
comparison
equal
deleted
inserted
replaced
| 10410:659b577f280c | 10411:db2a06b9ff98 |
|---|---|
| 10 | 10 |
| 11 local st = require "util.stanza"; | 11 local st = require "util.stanza"; |
| 12 local sm_bind_resource = require "core.sessionmanager".bind_resource; | 12 local sm_bind_resource = require "core.sessionmanager".bind_resource; |
| 13 local sm_make_authenticated = require "core.sessionmanager".make_authenticated; | 13 local sm_make_authenticated = require "core.sessionmanager".make_authenticated; |
| 14 local base64 = require "util.encodings".base64; | 14 local base64 = require "util.encodings".base64; |
| 15 local set = require "util.set"; | |
| 15 | 16 |
| 16 local usermanager_get_sasl_handler = require "core.usermanager".get_sasl_handler; | 17 local usermanager_get_sasl_handler = require "core.usermanager".get_sasl_handler; |
| 17 local tostring = tostring; | |
| 18 | 18 |
| 19 local secure_auth_only = module:get_option_boolean("c2s_require_encryption", module:get_option_boolean("require_encryption", false)); | 19 local secure_auth_only = module:get_option_boolean("c2s_require_encryption", module:get_option_boolean("require_encryption", false)); |
| 20 local allow_unencrypted_plain_auth = module:get_option_boolean("allow_unencrypted_plain_auth", false) | 20 local allow_unencrypted_plain_auth = module:get_option_boolean("allow_unencrypted_plain_auth", false) |
| 21 local insecure_mechanisms = module:get_option_set("insecure_sasl_mechanisms", allow_unencrypted_plain_auth and {} or {"PLAIN", "LOGIN"}); | 21 local insecure_mechanisms = module:get_option_set("insecure_sasl_mechanisms", allow_unencrypted_plain_auth and {} or {"PLAIN", "LOGIN"}); |
| 22 local disabled_mechanisms = module:get_option_set("disable_sasl_mechanisms", { "DIGEST-MD5" }); | 22 local disabled_mechanisms = module:get_option_set("disable_sasl_mechanisms", { "DIGEST-MD5" }); |
| 65 | 65 |
| 66 local function sasl_process_cdata(session, stanza) | 66 local function sasl_process_cdata(session, stanza) |
| 67 local text = stanza[1]; | 67 local text = stanza[1]; |
| 68 if text then | 68 if text then |
| 69 text = base64.decode(text); | 69 text = base64.decode(text); |
| 70 --log("debug", "AUTH: %s", text:gsub("[%z\001-\008\011\012\014-\031]", " ")); | |
| 71 if not text then | 70 if not text then |
| 72 session.sasl_handler = nil; | 71 session.sasl_handler = nil; |
| 73 session.send(build_reply("failure", "incorrect-encoding")); | 72 session.send(build_reply("failure", "incorrect-encoding")); |
| 74 return true; | 73 return true; |
| 75 end | 74 end |
| 76 end | 75 end |
| 77 local status, ret, err_msg = session.sasl_handler:process(text); | 76 local status, ret, err_msg = session.sasl_handler:process(text); |
| 78 status, ret, err_msg = handle_status(session, status, ret, err_msg); | 77 status, ret, err_msg = handle_status(session, status, ret, err_msg); |
| 79 local s = build_reply(status, ret, err_msg); | 78 local s = build_reply(status, ret, err_msg); |
| 80 log("debug", "sasl reply: %s", tostring(s)); | |
| 81 session.send(s); | 79 session.send(s); |
| 82 return true; | 80 return true; |
| 83 end | 81 end |
| 84 | 82 |
| 85 module:hook_tag(xmlns_sasl, "success", function (session) | 83 module:hook_tag(xmlns_sasl, "success", function (session) |
| 246 return; | 244 return; |
| 247 end | 245 end |
| 248 local sasl_handler = usermanager_get_sasl_handler(module.host, origin) | 246 local sasl_handler = usermanager_get_sasl_handler(module.host, origin) |
| 249 origin.sasl_handler = sasl_handler; | 247 origin.sasl_handler = sasl_handler; |
| 250 if origin.encrypted then | 248 if origin.encrypted then |
| 251 -- check wether LuaSec has the nifty binding to the function needed for tls-unique | 249 -- check whether LuaSec has the nifty binding to the function needed for tls-unique |
| 252 -- FIXME: would be nice to have this check only once and not for every socket | 250 -- FIXME: would be nice to have this check only once and not for every socket |
| 253 if sasl_handler.add_cb_handler then | 251 if sasl_handler.add_cb_handler then |
| 254 local socket = origin.conn:socket(); | 252 local socket = origin.conn:socket(); |
| 255 if socket.getpeerfinished then | 253 if socket.getpeerfinished then |
| 254 log("debug", "Channel binding 'tls-unique' supported"); | |
| 256 sasl_handler:add_cb_handler("tls-unique", tls_unique); | 255 sasl_handler:add_cb_handler("tls-unique", tls_unique); |
| 256 else | |
| 257 log("debug", "Channel binding 'tls-unique' not supported (by LuaSec?)"); | |
| 257 end | 258 end |
| 258 sasl_handler["userdata"] = { | 259 sasl_handler["userdata"] = { |
| 259 ["tls-unique"] = socket; | 260 ["tls-unique"] = socket; |
| 260 }; | 261 }; |
| 262 else | |
| 263 log("debug", "Channel binding not supported by SASL handler"); | |
| 261 end | 264 end |
| 262 end | 265 end |
| 263 local mechanisms = st.stanza("mechanisms", mechanisms_attr); | 266 local mechanisms = st.stanza("mechanisms", mechanisms_attr); |
| 264 local sasl_mechanisms = sasl_handler:mechanisms() | 267 local sasl_mechanisms = sasl_handler:mechanisms() |
| 268 local available_mechanisms = set.new(); | |
| 265 for mechanism in pairs(sasl_mechanisms) do | 269 for mechanism in pairs(sasl_mechanisms) do |
| 266 if disabled_mechanisms:contains(mechanism) then | 270 available_mechanisms:add(mechanism); |
| 267 log("debug", "Not offering disabled mechanism %s", mechanism); | 271 end |
| 268 elseif not origin.secure and insecure_mechanisms:contains(mechanism) then | 272 log("debug", "SASL mechanisms supported by handler: %s", available_mechanisms); |
| 269 log("debug", "Not offering mechanism %s on insecure connection", mechanism); | 273 |
| 270 else | 274 local usable_mechanisms = available_mechanisms - disabled_mechanisms; |
| 271 log("debug", "Offering mechanism %s", mechanism); | 275 |
| 276 local available_disabled = set.intersection(available_mechanisms, disabled_mechanisms); | |
| 277 if not available_disabled:empty() then | |
| 278 log("debug", "Not offering disabled mechanisms: %s", available_disabled); | |
| 279 end | |
| 280 | |
| 281 local available_insecure = set.intersection(available_mechanisms, insecure_mechanisms); | |
| 282 if not origin.secure and not available_insecure:empty() then | |
| 283 log("debug", "Session is not secure, not offering insecure mechanisms: %s", available_insecure); | |
| 284 usable_mechanisms = usable_mechanisms - insecure_mechanisms; | |
| 285 end | |
| 286 | |
| 287 if not usable_mechanisms:empty() then | |
| 288 log("debug", "Offering usable mechanisms: %s", usable_mechanisms); | |
| 289 for mechanism in available_mechanisms do | |
| 272 mechanisms:tag("mechanism"):text(mechanism):up(); | 290 mechanisms:tag("mechanism"):text(mechanism):up(); |
| 273 end | 291 end |
| 274 end | |
| 275 if mechanisms[1] then | |
| 276 features:add_child(mechanisms); | 292 features:add_child(mechanisms); |
| 277 elseif not next(sasl_mechanisms) then | 293 return; |
| 278 log("warn", "No available SASL mechanisms, verify that the configured authentication module is working"); | 294 end |
| 279 else | 295 |
| 280 log("warn", "All available authentication mechanisms are either disabled or not suitable for an insecure connection"); | 296 local authmod = module:get_option_string("authentication", "internal_plain"); |
| 281 end | 297 if available_mechanisms:empty() then |
| 298 log("warn", "No available SASL mechanisms, verify that the configured authentication module '%s' is loaded and configured correctly", authmod); | |
| 299 return; | |
| 300 end | |
| 301 | |
| 302 if not origin.secure and not available_insecure:empty() then | |
| 303 if not available_disabled:empty() then | |
| 304 log("warn", "All SASL mechanisms provided by authentication module '%s' are forbidden on insecure connections (%s) or disabled (%s)", | |
| 305 authmod, available_insecure, available_disabled); | |
| 306 else | |
| 307 log("warn", "All SASL mechanisms provided by authentication module '%s' are forbidden on insecure connections (%s)", | |
| 308 authmod, available_insecure); | |
| 309 end | |
| 310 elseif not available_disabled:empty() then | |
| 311 log("warn", "All SASL mechanisms provided by authentication module '%s' are disabled (%s)", | |
| 312 authmod, available_disabled); | |
| 313 end | |
| 314 | |
| 282 else | 315 else |
| 283 features:tag("bind", bind_attr):tag("required"):up():up(); | 316 features:tag("bind", bind_attr):tag("required"):up():up(); |
| 284 features:tag("session", xmpp_session_attr):tag("optional"):up():up(); | 317 features:tag("session", xmpp_session_attr):tag("optional"):up():up(); |
| 285 end | 318 end |
| 286 end); | 319 end); |
