Skip to content

Commit 0c70cdb

Browse files
committed
xmpp_stream_in: 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.
1 parent 2a54443 commit 0c70cdb

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

src/xmpp_stream_in.erl

+11-1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
-callback tls_options(state()) -> [proplists:property()].
110110
-callback tls_required(state()) -> boolean().
111111
-callback tls_enabled(state()) -> boolean().
112+
-callback allow_unencrypted_sasl2(state()) -> boolean().
112113
-callback sasl_mechanisms([xmpp_sasl:mechanism()], state()) -> [xmpp_sasl:mechanism()].
113114
-callback sasl_options(state()) -> [tuple()].
114115
-callback unauthenticated_stream_features(state()) -> [xmpp_element()].
@@ -142,6 +143,7 @@
142143
tls_options/1,
143144
tls_required/1,
144145
tls_enabled/1,
146+
allow_unencrypted_sasl2/1,
145147
sasl_mechanisms/2,
146148
sasl_options/1,
147149
unauthenticated_stream_features/1,
@@ -668,6 +670,7 @@ process_stream(#stream_start{to = #jid{server = Server, lserver = LServer},
668670
process_element(Pkt, #{stream_state := StateName, lang := Lang,
669671
stream_encrypted := Encrypted} = State) ->
670672
Sasl2 = maps:is_key(sasl2_stream_from, State),
673+
AllowUnencryptedSasl2 = allow_unencrypted_sasl2(State),
671674
case Pkt of
672675
#starttls{} when StateName == wait_for_starttls;
673676
StateName == wait_for_sasl_request ->
@@ -698,7 +701,8 @@ process_element(Pkt, #{stream_state := StateName, lang := Lang,
698701
send_pkt(State, #sasl_failure{reason = 'aborted'});
699702
#sasl_success{} ->
700703
State;
701-
#sasl2_authenticate{} when StateName == wait_for_starttls; (not Encrypted) ->
704+
#sasl2_authenticate{} when StateName == wait_for_starttls;
705+
not (Encrypted or AllowUnencryptedSasl2) ->
702706
send_pkt(State, #sasl2_failure{reason = 'encryption-required'});
703707
#sasl2_authenticate{} when StateName == wait_for_sasl_request, Sasl2 ->
704708
process_sasl2_request(Pkt, maps:remove(sasl_state, State));
@@ -1421,6 +1425,12 @@ is_starttls_required(State) ->
14211425
catch _:{?MODULE, undef} -> false
14221426
end.
14231427

1428+
-spec allow_unencrypted_sasl2(state()) -> boolean().
1429+
allow_unencrypted_sasl2(State) ->
1430+
try callback(allow_unencrypted_sasl2, State)
1431+
catch _:{?MODULE, undef} -> false
1432+
end.
1433+
14241434
-spec set_from_to(xmpp_element(), state()) -> {ok, xmpp_element()} |
14251435
{error, stream_error()}.
14261436
set_from_to(Pkt, _State) when not ?is_stanza(Pkt) ->

0 commit comments

Comments
 (0)