diff options
Diffstat (limited to 'src/ejabberd_s2s_in.erl')
-rw-r--r-- | src/ejabberd_s2s_in.erl | 52 |
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'")), |