From f594620c68fe2da6fcd622bb7bbf4403779d4d03 Mon Sep 17 00:00:00 2001 From: Pawel Chmielowski Date: Tue, 5 Aug 2025 10:08:14 +0200 Subject: [PATCH] Only offer upgrades to methods that aren't already stored --- src/ejabberd_c2s.erl | 4 ++-- src/mod_auth_fast.erl | 4 ++-- src/mod_carboncopy.erl | 4 ++-- src/mod_scram_upgrade.erl | 24 ++++++++++++++++++------ src/mod_stream_mgmt.erl | 4 ++-- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index f0f225bee..ef9312ef5 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -416,8 +416,8 @@ unauthenticated_stream_features(#{lserver := LServer}) -> authenticated_stream_features(#{lserver := LServer}) -> ejabberd_hooks:run_fold(c2s_post_auth_features, LServer, [], [LServer]). -inline_stream_features(#{lserver := LServer}) -> - ejabberd_hooks:run_fold(c2s_inline_features, LServer, {[], [], []}, [LServer]). +inline_stream_features(#{lserver := LServer} = State) -> + ejabberd_hooks:run_fold(c2s_inline_features, LServer, {[], [], []}, [LServer, State]). sasl_mechanisms(Mechs, #{lserver := LServer, stream_encrypted := Encrypted} = State) -> Type = ejabberd_auth:store_type(LServer), diff --git a/src/mod_auth_fast.erl b/src/mod_auth_fast.erl index c26c21072..c72153267 100644 --- a/src/mod_auth_fast.erl +++ b/src/mod_auth_fast.erl @@ -29,7 +29,7 @@ -export([start/2, stop/1, reload/3, depends/2, mod_options/1, mod_opt_type/1]). -export([mod_doc/0]). %% Hooks --export([c2s_inline_features/2, c2s_handle_sasl2_inline/1, +-export([c2s_inline_features/3, c2s_handle_sasl2_inline/1, get_tokens/3, get_mechanisms/1, remove_user_tokens/2]). -include_lib("xmpp/include/xmpp.hrl"). @@ -131,7 +131,7 @@ get_tokens(LServer, LUser, UA) -> {{Type, CreatedAt < ToRefresh}, Token} end, Mod:get_tokens(LServer, LUser, ua_hash(UA))). -c2s_inline_features({Sasl, Bind, Extra}, Host) -> +c2s_inline_features({Sasl, Bind, Extra}, Host, _State) -> {Sasl ++ [#fast{mechs = get_mechanisms(Host)}], Bind, Extra}. gen_token(#{sasl2_ua_id := UA, server := Server, user := User}) -> diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index b2e1ff544..d040d948f 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -38,7 +38,7 @@ iq_handler/1, disco_features/5, depends/2, mod_options/1, mod_doc/0]). -export([c2s_copy_session/2, c2s_session_opened/1, c2s_session_resumed/1, - c2s_inline_features/2, c2s_handle_bind2_inline/1]). + c2s_inline_features/3, c2s_handle_bind2_inline/1]). %% For debugging purposes -export([list/2]). @@ -145,7 +145,7 @@ c2s_session_resumed(State) -> c2s_session_opened(State) -> maps:remove(carboncopy, State). -c2s_inline_features({Sasl, Bind, Extra} = Acc, Host) -> +c2s_inline_features({Sasl, Bind, Extra} = Acc, Host, _State) -> case gen_mod:is_loaded(Host, ?MODULE) of true -> {Sasl, [#bind2_feature{var = ?NS_CARBONS_2} | Bind], Extra}; diff --git a/src/mod_scram_upgrade.erl b/src/mod_scram_upgrade.erl index 4bf335248..37af47b46 100644 --- a/src/mod_scram_upgrade.erl +++ b/src/mod_scram_upgrade.erl @@ -27,7 +27,7 @@ -export([start/2, stop/1, reload/3, depends/2, mod_options/1, mod_opt_type/1]). -export([mod_doc/0]). %% Hooks --export([c2s_inline_features/2, c2s_handle_sasl2_inline/1, +-export([c2s_inline_features/3, c2s_handle_sasl2_inline/1, c2s_handle_sasl2_task_next/4, c2s_handle_sasl2_task_data/3]). -include_lib("xmpp/include/xmpp.hrl"). @@ -76,11 +76,23 @@ mod_doc() -> " - sha256", " - sha512"]}. -c2s_inline_features({Sasl, Bind, Extra}, Host) -> - Methods = lists:map( - fun(sha256) -> #sasl_upgrade{cdata = <<"UPGR-SCRAM-SHA-256">>}; - (sha512) -> #sasl_upgrade{cdata = <<"UPGR-SCRAM-SHA-512">>} - end, mod_scram_upgrade_opt:offered_upgrades(Host)), +c2s_inline_features({Sasl, Bind, Extra}, Host, State) -> + KnowTypes = case State of + #{sasl2_password_fun := Fun} -> + case Fun(<<>>) of + {Pass, _} -> lists:filtermap( + fun(#scram{hash = sha256}) -> {true, sha256}; + (#scram{hash = sha512}) -> {true, sha512}; + (_) -> false + end, Pass); + _ -> [] + end; + _ -> [] + end, + Methods = lists:filtermap( + fun(sha256) -> {true, #sasl_upgrade{cdata = <<"UPGR-SCRAM-SHA-256">>}}; + (sha512) -> {true, #sasl_upgrade{cdata = <<"UPGR-SCRAM-SHA-512">>}} + end, mod_scram_upgrade_opt:offered_upgrades(Host) -- KnowTypes), {Sasl, Bind, Methods ++ Extra}. c2s_handle_sasl2_inline({State, Els, _Results} = Acc) -> diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index 359d2601e..f3a641a7a 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -33,7 +33,7 @@ c2s_authenticated_packet/2, c2s_unauthenticated_packet/2, c2s_unbinded_packet/2, c2s_closed/2, c2s_terminated/2, c2s_handle_send/3, c2s_handle_info/2, c2s_handle_cast/2, - c2s_handle_call/3, c2s_handle_recv/3, c2s_inline_features/2, + c2s_handle_call/3, c2s_handle_recv/3, c2s_inline_features/3, c2s_handle_sasl2_inline/1, c2s_handle_sasl2_inline_post/3, c2s_handle_bind2_inline/1]). %% adjust pending session timeout / access queue @@ -122,7 +122,7 @@ c2s_stream_features(Acc, Host) -> Acc end. -c2s_inline_features({Sasl, Bind, Extra} = Acc, Host) -> +c2s_inline_features({Sasl, Bind, Extra} = Acc, Host, _State) -> case gen_mod:is_loaded(Host, ?MODULE) of true -> {[#feature_sm{xmlns = ?NS_STREAM_MGMT_3} | Sasl],