From 4723283896eb4b50c2c48336627436a38947b852 Mon Sep 17 00:00:00 2001 From: Holger Weiss Date: Sun, 29 Sep 2024 20:40:01 +0200 Subject: [PATCH] ejabberd_c2s: Optionally allow unencrypted SASL2 XEP-0388 says: "SASL2 MUST only be used by Clients or offered by Servers after TLS negotiation". Therefore, we reject SASL2 negotiations over unencrypted transports by default. However, TLS might be terminated outside of ejabberd. Add the 'allow_unencrypted_sasl2' option to support this use case. --- mix.exs | 2 +- mix.lock | 2 +- rebar.config | 2 +- rebar.lock | 2 +- src/ejabberd_c2s.erl | 28 ++++++++++++++++++---------- 5 files changed, 22 insertions(+), 14 deletions(-) diff --git a/mix.exs b/mix.exs index 171e8762b..b2784a9c3 100644 --- a/mix.exs +++ b/mix.exs @@ -144,7 +144,7 @@ defmodule Ejabberd.MixProject do {:p1_utils, "~> 1.0"}, {:pkix, "~> 1.0"}, {:stringprep, ">= 1.0.26"}, - {:xmpp, git: "https://github.com/processone/xmpp.git", ref: "2a54443436dc8a942969f2ef7c5654d5acab7533", override: true}, + {:xmpp, git: "https://github.com/processone/xmpp.git", ref: "ff0dd5390acc3c1ee8cd1c7e6dc60a0c3cb1d127", override: true}, {:yconf, "~> 1.0"}] ++ cond_deps() end diff --git a/mix.lock b/mix.lock index 065ae647e..3507f001c 100644 --- a/mix.lock +++ b/mix.lock @@ -32,6 +32,6 @@ "stringprep": {:hex, :stringprep, "1.0.30", "46cf0ff631b3e7328f61f20b454d59428d87738f25d709798b5dcbb9b83c23f1", [:rebar3], [{:p1_utils, "1.0.26", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "f6fc9b3384a03877830f89b2f38580caf3f4a27448a4a333d6a8c3975c220b9a"}, "stun": {:hex, :stun, "1.2.14", "6f538ac80c842131dbd149055570d116bfabc9b5ebff4bd6af2e7888958c660c", [:rebar3], [{:fast_tls, "1.1.21", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.26", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "e134807b1b7a8dffd94e64eefee00e65c7b4042f3d14e16f8f43566d20371583"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, - "xmpp": {:git, "https://github.com/processone/xmpp.git", "2a54443436dc8a942969f2ef7c5654d5acab7533", [ref: "2a54443436dc8a942969f2ef7c5654d5acab7533"]}, + "xmpp": {:git, "https://github.com/processone/xmpp.git", "ff0dd5390acc3c1ee8cd1c7e6dc60a0c3cb1d127", [ref: "ff0dd5390acc3c1ee8cd1c7e6dc60a0c3cb1d127"]}, "yconf": {:hex, :yconf, "1.0.16", "d59521d66ff89f219411b6e9277cd6feec7cc6fce11554e67de02a8d0a470479", [:rebar3], [{:fast_yaml, "1.0.37", [hex: :fast_yaml, repo: "hexpm", optional: false]}], "hexpm", "e947813273f38711c7b2e5a8e4acc9a51c7bbe854f744a345f60300b38586c89"}, } diff --git a/rebar.config b/rebar.config index 5fcc1e5bb..7478a836a 100644 --- a/rebar.config +++ b/rebar.config @@ -69,7 +69,7 @@ {stringprep, "~> 1.0.29", {git, "https://github.com/processone/stringprep", {tag, "1.0.30"}}}, {if_var_true, stun, {stun, "~> 1.2.12", {git, "https://github.com/processone/stun", {tag, "1.2.14"}}}}, - {xmpp, "~> 1.8.3", {git, "https://github.com/processone/xmpp", "2a54443436dc8a942969f2ef7c5654d5acab7533"}}, + {xmpp, "~> 1.8.3", {git, "https://github.com/processone/xmpp", "ff0dd5390acc3c1ee8cd1c7e6dc60a0c3cb1d127"}}, {yconf, "~> 1.0.15", {git, "https://github.com/processone/yconf", {tag, "1.0.16"}}} ]}. diff --git a/rebar.lock b/rebar.lock index b539c60b8..90bfef76f 100644 --- a/rebar.lock +++ b/rebar.lock @@ -32,7 +32,7 @@ {<<"unicode_util_compat">>,{pkg,<<"unicode_util_compat">>,<<"0.7.0">>},1}, {<<"xmpp">>, {git,"https://github.com/processone/xmpp", - {ref,"2a54443436dc8a942969f2ef7c5654d5acab7533"}}, + {ref,"ff0dd5390acc3c1ee8cd1c7e6dc60a0c3cb1d127"}}, 0}, {<<"yconf">>,{pkg,<<"yconf">>,<<"1.0.16">>},0}]}. [ diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 8f7c04c41..66200fcdd 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -35,16 +35,16 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([tls_options/1, tls_required/1, tls_enabled/1, - compress_methods/1, bind/2, sasl_mechanisms/2, - get_password_fun/2, check_password_fun/2, check_password_digest_fun/2, - unauthenticated_stream_features/1, authenticated_stream_features/1, - handle_stream_start/2, handle_stream_end/2, - handle_unauthenticated_packet/2, handle_authenticated_packet/2, - handle_auth_success/4, handle_auth_failure/4, handle_send/3, - handle_recv/3, handle_cdata/2, handle_unbinded_packet/2, - inline_stream_features/1, handle_sasl2_inline/2, - handle_sasl2_inline_post/3, handle_bind2_inline/2, - handle_bind2_inline_post/3, sasl_options/1]). + allow_unencrypted_sasl2/1, compress_methods/1, bind/2, + sasl_mechanisms/2, get_password_fun/2, check_password_fun/2, + check_password_digest_fun/2, unauthenticated_stream_features/1, + authenticated_stream_features/1, handle_stream_start/2, + handle_stream_end/2, handle_unauthenticated_packet/2, + handle_authenticated_packet/2, handle_auth_success/4, + handle_auth_failure/4, handle_send/3, handle_recv/3, handle_cdata/2, + handle_unbinded_packet/2, inline_stream_features/1, + handle_sasl2_inline/2, handle_sasl2_inline_post/3, + handle_bind2_inline/2, handle_bind2_inline_post/3, sasl_options/1]). %% Hooks -export([handle_unexpected_cast/2, handle_unexpected_call/3, process_auth_result/3, reject_unauthenticated_packet/2, @@ -392,6 +392,9 @@ tls_enabled(#{tls_enabled := TLSEnabled, tls_verify := TLSVerify}) -> TLSEnabled or TLSRequired or TLSVerify. +allow_unencrypted_sasl2(#{allow_unencrypted_sasl2 := AllowUnencryptedSasl2}) -> + AllowUnencryptedSasl2. + compress_methods(#{zlib := true}) -> [<<"zlib">>]; compress_methods(_) -> @@ -604,12 +607,14 @@ init([State, Opts]) -> TLSEnabled = proplists:get_bool(starttls, Opts), TLSRequired = proplists:get_bool(starttls_required, Opts), TLSVerify = proplists:get_bool(tls_verify, Opts), + AllowUnencryptedSasl2 = proplists:get_bool(allow_unencrypted_sasl2, Opts), Zlib = proplists:get_bool(zlib, Opts), Timeout = ejabberd_option:negotiation_timeout(), State1 = State#{tls_options => TLSOpts2, tls_required => TLSRequired, tls_enabled => TLSEnabled, tls_verify => TLSVerify, + allow_unencrypted_sasl2 => AllowUnencryptedSasl2, pres_a => ?SETS:new(), zlib => Zlib, lang => ejabberd_option:language(), @@ -1047,6 +1052,8 @@ listen_opt_type(starttls) -> econf:bool(); listen_opt_type(starttls_required) -> econf:bool(); +listen_opt_type(allow_unencrypted_sasl2) -> + econf:bool(); listen_opt_type(tls_verify) -> econf:bool(); listen_opt_type(zlib) -> @@ -1069,6 +1076,7 @@ listen_options() -> {tls_compression, false}, {starttls, false}, {starttls_required, false}, + {allow_unencrypted_sasl2, false}, {tls_verify, false}, {zlib, false}, {max_stanza_size, infinity},