1
0
Fork 0
mirror of https://github.com/processone/ejabberd synced 2025-10-03 09:49:18 +02:00

Add auth_password_types_hidden_in_scram1 option

This option allows disabling some auth mechanisms
to be offered in SASL1 features. This makes adding
new password types easier, by ensuring that new
password use will be offered only to clients that
have new type stored (SASL2 clients that send us
user info before features need to be sent), but
not to clients where we don't know if they have
new passwords.
This commit is contained in:
Pawel Chmielowski 2025-07-10 11:44:13 +02:00
parent c0fc6091b1
commit e4d424bf56
6 changed files with 50 additions and 17 deletions

View file

@ -77,7 +77,7 @@
{stringprep, "~> 1.0.31", {git, "https://github.com/processone/stringprep", {tag, "1.0.31"}}}, {stringprep, "~> 1.0.31", {git, "https://github.com/processone/stringprep", {tag, "1.0.31"}}},
{if_var_true, stun, {if_var_true, stun,
{stun, "~> 1.2.17", {git, "https://github.com/processone/stun", {tag, "1.2.17"}}}}, {stun, "~> 1.2.17", {git, "https://github.com/processone/stun", {tag, "1.2.17"}}}},
{xmpp, "~> 1.10.0", {git, "https://github.com/processone/xmpp", "9b028c110083e4d979d88c286873d0abf08fa532"}}, {xmpp, "~> 1.10.0", {git, "https://github.com/processone/xmpp", "b474d673938856a546265cd5db1139244bfb95f3"}},
{yconf, "~> 1.0.18", {git, "https://github.com/processone/yconf", {tag, "1.0.18"}}} {yconf, "~> 1.0.18", {git, "https://github.com/processone/yconf", {tag, "1.0.18"}}}
]}. ]}.

View file

@ -35,7 +35,7 @@
{<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},1}, {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.1">>},1},
{<<"xmpp">>, {<<"xmpp">>,
{git,"https://github.com/processone/xmpp", {git,"https://github.com/processone/xmpp",
{ref,"9b028c110083e4d979d88c286873d0abf08fa532"}}, {ref,"b474d673938856a546265cd5db1139244bfb95f3"}},
0}, 0},
{<<"yconf">>,{pkg,<<"yconf">>,<<"1.0.18">>},0}]}. {<<"yconf">>,{pkg,<<"yconf">>,<<"1.0.18">>},0}]}.
[ [

View file

@ -440,21 +440,32 @@ sasl_mechanisms(Mechs, #{lserver := LServer, stream_encrypted := Encrypted} = St
end, end,
%% I re-created it from cyrsasl ets magic, but I think it's wrong %% I re-created it from cyrsasl ets magic, but I think it's wrong
%% TODO: need to check before 18.09 release %% TODO: need to check before 18.09 release
lists:filter( Mechs2 = lists:filter(
fun(<<"ANONYMOUS">>) -> fun(<<"ANONYMOUS">>) ->
ejabberd_auth_anonymous:is_sasl_anonymous_enabled(LServer); ejabberd_auth_anonymous:is_sasl_anonymous_enabled(LServer);
(<<"DIGEST-MD5">>) -> Digest; (<<"DIGEST-MD5">>) -> Digest;
(<<"SCRAM-SHA-1">>) -> ShaAv; (<<"SCRAM-SHA-1">>) -> ShaAv;
(<<"SCRAM-SHA-1-PLUS">>) -> ShaAv andalso Encrypted; (<<"SCRAM-SHA-1-PLUS">>) -> ShaAv andalso Encrypted;
(<<"SCRAM-SHA-256">>) -> Sha256Av; (<<"SCRAM-SHA-256">>) -> Sha256Av;
(<<"SCRAM-SHA-256-PLUS">>) -> Sha256Av andalso Encrypted; (<<"SCRAM-SHA-256-PLUS">>) -> Sha256Av andalso Encrypted;
(<<"SCRAM-SHA-512">>) -> Sha512Av; (<<"SCRAM-SHA-512">>) -> Sha512Av;
(<<"SCRAM-SHA-512-PLUS">>) -> Sha512Av andalso Encrypted; (<<"SCRAM-SHA-512-PLUS">>) -> Sha512Av andalso Encrypted;
(<<"PLAIN">>) -> true; (<<"PLAIN">>) -> true;
(<<"X-OAUTH2">>) -> [ejabberd_auth_anonymous] /= ejabberd_auth:auth_modules(LServer); (<<"X-OAUTH2">>) -> [ejabberd_auth_anonymous] /= ejabberd_auth:auth_modules(LServer);
(<<"EXTERNAL">>) -> maps:get(tls_verify, State, false); (<<"EXTERNAL">>) -> maps:get(tls_verify, State, false);
(_) -> false (_) -> false
end, Mechs -- Mechs1). end, Mechs -- Mechs1),
case ejabberd_option:auth_password_types_hidden_in_scram1() of
[] -> Mechs2;
List ->
Mechs3 = lists:foldl(
fun(plain, Acc) -> Acc -- [<<"PLAIN">>];
(scram_sha1, Acc) -> Acc -- [<<"SCRAM-SHA-1">>, <<"SCRAM-SHA-1-PLUS">>];
(scram_sha256, Acc) -> Acc -- [<<"SCRAM-SHA-256">>, <<"SCRAM-SHA-256-PLUS">>];
(scram_sha512, Acc) -> Acc -- [<<"SCRAM-SHA-512">>, <<"SCRAM-SHA-512-PLUS">>]
end, Mechs2, List),
{Mechs3, Mechs2}
end.
sasl_options(#{lserver := LServer}) -> sasl_options(#{lserver := LServer}) ->
case ejabberd_option:disable_sasl_scram_downgrade_protection(LServer) of case ejabberd_option:disable_sasl_scram_downgrade_protection(LServer) of

View file

@ -18,6 +18,7 @@
-export([auth_method/0, auth_method/1]). -export([auth_method/0, auth_method/1]).
-export([auth_opts/0, auth_opts/1]). -export([auth_opts/0, auth_opts/1]).
-export([auth_password_format/0, auth_password_format/1]). -export([auth_password_format/0, auth_password_format/1]).
-export([auth_password_types_hidden_in_scram1/0, auth_password_types_hidden_in_scram1/1]).
-export([auth_scram_hash/0, auth_scram_hash/1]). -export([auth_scram_hash/0, auth_scram_hash/1]).
-export([auth_stored_password_types/0, auth_stored_password_types/1]). -export([auth_stored_password_types/0, auth_stored_password_types/1]).
-export([auth_use_cache/0, auth_use_cache/1]). -export([auth_use_cache/0, auth_use_cache/1]).
@ -263,6 +264,13 @@ auth_password_format() ->
auth_password_format(Host) -> auth_password_format(Host) ->
ejabberd_config:get_option({auth_password_format, Host}). ejabberd_config:get_option({auth_password_format, Host}).
-spec auth_password_types_hidden_in_scram1() -> ['plain' | 'scram_sha1' | 'scram_sha256' | 'scram_sha512'].
auth_password_types_hidden_in_scram1() ->
auth_password_types_hidden_in_scram1(global).
-spec auth_password_types_hidden_in_scram1(global | binary()) -> ['plain' | 'scram_sha1' | 'scram_sha256' | 'scram_sha512'].
auth_password_types_hidden_in_scram1(Host) ->
ejabberd_config:get_option({auth_password_types_hidden_in_scram1, Host}).
-spec auth_scram_hash() -> 'sha' | 'sha256' | 'sha512'. -spec auth_scram_hash() -> 'sha' | 'sha256' | 'sha512'.
auth_scram_hash() -> auth_scram_hash() ->
auth_scram_hash(global). auth_scram_hash(global).

View file

@ -79,6 +79,8 @@ opt_type(auth_opts) ->
end; end;
opt_type(auth_stored_password_types) -> opt_type(auth_stored_password_types) ->
econf:list(econf:enum([plain, scram_sha1, scram_sha256, scram_sha512])); econf:list(econf:enum([plain, scram_sha1, scram_sha256, scram_sha512]));
opt_type(auth_password_types_hidden_in_scram1) ->
econf:list(econf:enum([plain, scram_sha1, scram_sha256, scram_sha512]));
opt_type(auth_password_format) -> opt_type(auth_password_format) ->
econf:enum([plain, scram]); econf:enum([plain, scram]);
opt_type(auth_scram_hash) -> opt_type(auth_scram_hash) ->
@ -564,6 +566,7 @@ options() ->
{auth_password_format, plain}, {auth_password_format, plain},
{auth_scram_hash, sha}, {auth_scram_hash, sha},
{auth_stored_password_types, []}, {auth_stored_password_types, []},
{auth_password_types_hidden_in_scram1, []},
{auth_external_user_exists_check, true}, {auth_external_user_exists_check, true},
{auth_use_cache, {auth_use_cache,
fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end}, fun(Host) -> ejabberd_config:get_option({use_cache, Host}) end},

View file

@ -392,6 +392,17 @@ doc() ->
"SASL PLAIN and SASL SCRAM-SHA-1/256/512(-PLUS). The SCRAM variant " "SASL PLAIN and SASL SCRAM-SHA-1/256/512(-PLUS). The SCRAM variant "
"depends on the _`auth_scram_hash`_ option."), "", "depends on the _`auth_scram_hash`_ option."), "",
?T("The default value is 'plain'."), ""]}}, ?T("The default value is 'plain'."), ""]}},
{auth_password_types_hidden_in_scram1,
#{value => "[plain | scram_sha1 | scram_sha256 | scram_sha512]",
note => "added in 25.07",
desc =>
?T("List of password types that should not be offered in SCRAM1 authenticatication. "
"Because SCRAM1, unlike SCRAM2, can't have list of available mechanisms tailored to "
"individual user, it's possible that offered mechanisms will not be compatible "
"with stored password, especially if new password type was added recently. "
"This option allows disabling offering some mechanisms in SASL1, to a time until new "
"password type will be available for all users.")}},
{auth_scram_hash, {auth_scram_hash,
#{value => "sha | sha256 | sha512", #{value => "sha | sha256 | sha512",
desc => desc =>