25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-22 17:28:25 +01:00

Simplify external components configuration

This commit is contained in:
Evgeniy Khramtsov 2015-11-28 17:38:10 +03:00
parent fee2530b1c
commit 9cc5a5d467

View File

@ -53,8 +53,8 @@
{socket :: ejabberd_socket:socket_state(), {socket :: ejabberd_socket:socket_state(),
sockmod = ejabberd_socket :: ejabberd_socket | ejabberd_frontend_socket, sockmod = ejabberd_socket :: ejabberd_socket | ejabberd_frontend_socket,
streamid = <<"">> :: binary(), streamid = <<"">> :: binary(),
hosts = [] :: [binary()], host_opts = dict:new() :: ?TDICT,
password = <<"">> :: binary(), host = <<"">> :: binary(),
access :: atom(), access :: atom(),
check_from = true :: boolean()}). check_from = true :: boolean()}).
@ -126,18 +126,21 @@ init([{SockMod, Socket}, Opts]) ->
{value, {_, A}} -> A; {value, {_, A}} -> A;
_ -> all _ -> all
end, end,
%% This should be improved probably HostOpts = case lists:keyfind(hosts, 1, Opts) of
{Hosts, HostOpts} = case lists:keyfind(hosts, 1, Opts) of {hosts, HOpts} ->
{_, HOpts} -> lists:foldl(
{[H || {H, _} <- HOpts], fun({H, Os}, D) ->
lists:flatten( P = proplists:get_value(
[O || {_, O} <- HOpts])}; password, Os,
_ -> p1_sha:sha(crypto:rand_bytes(20))),
{[], []} dict:store(H, P, D)
end, end, dict:new(), HOpts);
Password = gen_mod:get_opt(password, HostOpts, false ->
fun iolist_to_binary/1, Pass = proplists:get_value(
p1_sha:sha(crypto:rand_bytes(20))), password, Opts,
p1_sha:sha(crypto:rand_bytes(20))),
dict:from_list([{global, Pass}])
end,
Shaper = case lists:keysearch(shaper_rule, 1, Opts) of Shaper = case lists:keysearch(shaper_rule, 1, Opts) of
{value, {_, S}} -> S; {value, {_, S}} -> S;
_ -> none _ -> none
@ -151,7 +154,7 @@ init([{SockMod, Socket}, Opts]) ->
SockMod:change_shaper(Socket, Shaper), SockMod:change_shaper(Socket, Shaper),
{ok, wait_for_stream, {ok, wait_for_stream,
#state{socket = Socket, sockmod = SockMod, #state{socket = Socket, sockmod = SockMod,
streamid = new_id(), hosts = Hosts, password = Password, streamid = new_id(), host_opts = HostOpts,
access = Access, check_from = CheckFrom}}. access = Access, check_from = CheckFrom}}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -166,10 +169,33 @@ wait_for_stream({xmlstreamstart, _Name, Attrs},
case xml:get_attr_s(<<"xmlns">>, Attrs) of case xml:get_attr_s(<<"xmlns">>, Attrs) of
<<"jabber:component:accept">> -> <<"jabber:component:accept">> ->
To = xml:get_attr_s(<<"to">>, Attrs), To = xml:get_attr_s(<<"to">>, Attrs),
Header = io_lib:format(?STREAM_HEADER, Host = jid:nameprep(To),
[StateData#state.streamid, xml:crypt(To)]), if Host == error ->
send_text(StateData, Header), Header = io_lib:format(?STREAM_HEADER,
{next_state, wait_for_handshake, StateData}; [<<"none">>, ?MYNAME]),
send_text(StateData,
<<(list_to_binary(Header))/binary,
(?INVALID_XML_ERR)/binary,
(?STREAM_TRAILER)/binary>>),
{stop, normal, StateData};
true ->
Header = io_lib:format(?STREAM_HEADER,
[StateData#state.streamid, xml:crypt(To)]),
send_text(StateData, Header),
HostOpts = case dict:is_key(Host, StateData#state.host_opts) of
true ->
StateData#state.host_opts;
false ->
case dict:find(global, StateData#state.host_opts) of
{ok, GlobalPass} ->
dict:from_list([{Host, GlobalPass}]);
error ->
StateData#state.host_opts
end
end,
{next_state, wait_for_handshake,
StateData#state{host = Host, host_opts = HostOpts}}
end;
_ -> _ ->
send_text(StateData, ?INVALID_HEADER_ERR), send_text(StateData, ?INVALID_HEADER_ERR),
{stop, normal, StateData} {stop, normal, StateData}
@ -188,21 +214,26 @@ wait_for_handshake({xmlstreamelement, El}, StateData) ->
#xmlel{name = Name, children = Els} = El, #xmlel{name = Name, children = Els} = El,
case {Name, xml:get_cdata(Els)} of case {Name, xml:get_cdata(Els)} of
{<<"handshake">>, Digest} -> {<<"handshake">>, Digest} ->
case p1_sha:sha(<<(StateData#state.streamid)/binary, case dict:find(StateData#state.host, StateData#state.host_opts) of
(StateData#state.password)/binary>>) {ok, Password} ->
of case p1_sha:sha(<<(StateData#state.streamid)/binary,
Digest -> Password/binary>>) of
send_text(StateData, <<"<handshake/>">>), Digest ->
lists:foreach(fun (H) -> send_text(StateData, <<"<handshake/>">>),
ejabberd_router:register_route(H), lists:foreach(
?INFO_MSG("Route registered for service ~p~n", fun (H) ->
[H]) ejabberd_router:register_route(H),
end, ?INFO_MSG("Route registered for service ~p~n",
StateData#state.hosts), [H])
{next_state, stream_established, StateData}; end, dict:fetch_keys(StateData#state.host_opts)),
_ -> {next_state, stream_established, StateData};
send_text(StateData, ?INVALID_HANDSHAKE_ERR), _ ->
{stop, normal, StateData} send_text(StateData, ?INVALID_HANDSHAKE_ERR),
{stop, normal, StateData}
end;
_ ->
send_text(StateData, ?INVALID_HANDSHAKE_ERR),
{stop, normal, StateData}
end; end;
_ -> {next_state, wait_for_handshake, StateData} _ -> {next_state, wait_for_handshake, StateData}
end; end;
@ -231,7 +262,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
FromJID1 = jid:from_string(From), FromJID1 = jid:from_string(From),
case FromJID1 of case FromJID1 of
#jid{lserver = Server} -> #jid{lserver = Server} ->
case lists:member(Server, StateData#state.hosts) of case dict:is_key(Server, StateData#state.host_opts) of
true -> FromJID1; true -> FromJID1;
false -> error false -> error
end; end;
@ -349,7 +380,7 @@ terminate(Reason, StateName, StateData) ->
lists:foreach(fun (H) -> lists:foreach(fun (H) ->
ejabberd_router:unregister_route(H) ejabberd_router:unregister_route(H)
end, end,
StateData#state.hosts); dict:fetch_keys(StateData#state.host_opts));
_ -> ok _ -> ok
end, end,
(StateData#state.sockmod):close(StateData#state.socket), (StateData#state.sockmod):close(StateData#state.socket),