aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_s2s_in.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_s2s_in.erl')
-rw-r--r--src/ejabberd_s2s_in.erl52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 7bc183aa7..eb8c05a6e 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -75,6 +75,7 @@
tls = false,
tls_enabled = false,
tls_required = false,
+ tls_certverify = false,
tls_options = [],
server,
authenticated = false,
@@ -152,13 +153,15 @@ init([{SockMod, Socket}, Opts]) ->
{value, {_, S}} -> S;
_ -> none
end,
- {StartTLS, TLSRequired} = case ejabberd_config:get_local_option(s2s_use_starttls) of
+ {StartTLS, TLSRequired, TLSCertverify} = case ejabberd_config:get_local_option(s2s_use_starttls) of
UseTls when (UseTls==undefined) or (UseTls==false) ->
- {false, false};
+ {false, false, false};
UseTls when (UseTls==true) or (UseTls==optional) ->
- {true, false};
+ {true, false, false};
required ->
- {true, true}
+ {true, true, false};
+ required_trusted ->
+ {true, true, true}
end,
TLSOpts = case ejabberd_config:get_local_option(s2s_certfile) of
undefined ->
@@ -175,6 +178,7 @@ init([{SockMod, Socket}, Opts]) ->
tls = StartTLS,
tls_enabled = false,
tls_required = TLSRequired,
+ tls_certverify = TLSCertverify,
tls_options = TLSOpts,
timer = Timer}}.
@@ -198,16 +202,18 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
StateData#state.tls_enabled ->
case (StateData#state.sockmod):get_peer_certificate(
StateData#state.socket) of
- {ok, _Cert} ->
- case (StateData#state.sockmod):get_verify_result(
- StateData#state.socket) of
+ {ok, Cert} ->
+ case (StateData#state.sockmod):get_verify_result(StateData#state.socket) of
0 ->
[{xmlelement, "mechanisms",
[{"xmlns", ?NS_SASL}],
[{xmlelement, "mechanism", [],
[{xmlcdata, "EXTERNAL"}]}]}];
- _ ->
- []
+ CertVerifyRes ->
+ case StateData#state.tls_certverify of
+ true -> {error_cert_verif, CertVerifyRes, Cert};
+ false -> []
+ end
end;
error ->
[]
@@ -225,14 +231,26 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
[{xmlelement, "required", [], []}]
}]
end,
- send_element(StateData,
- {xmlelement, "stream:features", [],
- SASL ++ StartTLS ++
- ejabberd_hooks:run_fold(
- s2s_stream_features,
- Server,
- [], [Server])}),
- {next_state, wait_for_feature_request, StateData#state{server = Server}};
+ case SASL of
+ {error_cert_verif, CertVerifyResult, Certificate} ->
+ CertError = tls:get_cert_verify_string(CertVerifyResult, Certificate),
+ RemoteServer = xml:get_attr_s("from", Attrs),
+ ?INFO_MSG("Closing s2s connection: ~s <--> ~s (~s)", [StateData#state.server, RemoteServer, CertError]),
+ send_text(StateData, xml:element_to_string(?SERRT_POLICY_VIOLATION("en", CertError))),
+ {atomic, Pid} = ejabberd_s2s:find_connection(jlib:make_jid("", Server, ""), jlib:make_jid("", RemoteServer, "")),
+ ejabberd_s2s_out:stop_connection(Pid),
+
+ {stop, normal, StateData};
+ _ ->
+ send_element(StateData,
+ {xmlelement, "stream:features", [],
+ SASL ++ StartTLS ++
+ ejabberd_hooks:run_fold(
+ s2s_stream_features,
+ Server,
+ [], [Server])}),
+ {next_state, wait_for_feature_request, StateData#state{server = Server}}
+ end;
{"jabber:server", _, Server, true} when
StateData#state.authenticated ->
send_text(StateData, ?STREAM_HEADER(" version='1.0'")),