# HG changeset patch # User Matthew Wild # Date 1701779940 0 # Node ID 3a7349aa95c747a8e20d71dc7efd5219c8219fc9 # Parent 5ff8022466ab1418abaab09a9eb9d57fb90cc04d mod_sasl_ssdp: New module implementing XEP-0474 SASL SCRAM Downgrade Protection diff -r 5ff8022466ab -r 3a7349aa95c7 mod_sasl_ssdp/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_sasl_ssdp/README.markdown Tue Dec 05 12:39:00 2023 +0000 @@ -0,0 +1,30 @@ +--- +labels: +- 'Stage-Alpha' +summary: 'XEP-0474: SASL SCRAM Downgrade Protection' +... + +Introduction +============ + +This module implements the experimental XEP-0474: SASL SCRAM Downgrade +Protection. It provides an alternative downgrade protection mechanism to +client-side pinning which is currently the most common method of downgrade +protection. + +**Note:** This module implements version 0.3.0 of XEP-0474. As of 2023-12-05, +this version is not yet published on xmpp.org. Version 0.3.0 of the XEP is +implemented in Monal 6.0.1. No other clients are currently known to implement +the XEP at the time of writing. + +# Configuration + +There are no configuration options for this module, just load it as normal. + +# Compatibility + +For SASL2 (XEP-0388) clients, it is compatible with the mod_sasl2 community module. + +For clients using RFC 6120 SASL, it requires Prosody trunk 33e5edbd6a4a or +later. It is not compatible with Prosody 0.12 (it will load, but simply +won't do anything) for "legacy SASL". diff -r 5ff8022466ab -r 3a7349aa95c7 mod_sasl_ssdp/mod_sasl_ssdp.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_sasl_ssdp/mod_sasl_ssdp.lua Tue Dec 05 12:39:00 2023 +0000 @@ -0,0 +1,36 @@ +local array = require "util.array"; +local hashes = require "util.hashes"; +local it = require "util.iterators"; +local base64_enc = require "util.encodings".base64.encode; + +local hash_functions = { + ["SCRAM-SHA-1"] = hashes.sha1; + ["SCRAM-SHA-1-PLUS"] = hashes.sha1; + ["SCRAM-SHA-256"] = hashes.sha256; + ["SCRAM-SHA-256-PLUS"] = hashes.sha256; +}; + +function add_ssdp_info(event) + local sasl_handler = event.session.sasl_handler; + local hash = hash_functions[sasl_handler.selected]; + if not hash then + module:log("debug", "Not enabling SSDP for unsupported mechanism: %s", sasl_handler.selected); + return; + end + local mechanism_list = array.collect(it.keys(sasl_handler:mechanisms())):sort(); + local cb = sasl_handler.profile.cb; + local cb_list = cb and array.collect(it.keys(cb)):sort(); + local ssdp_string; + if cb_list then + ssdp_string = mechanism_list:concat(",").."|"..cb_list:concat(","); + else + ssdp_string = mechanism_list:concat(","); + end + module:log("debug", "Calculated SSDP string: %s", ssdp_string); + event.message = event.message..",d="..base64_enc(hash(ssdp_string)); + sasl_handler.state.server_first_message = event.message; +end + +module:hook("sasl/reply/challenge", add_ssdp_info, 1); +module:hook("sasl2/c2s/challenge", add_ssdp_info, 1); +