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

Make C2S session establishment optional (ECS-11)

This commit is contained in:
Alexey Shchepin 2016-01-18 16:33:37 +03:00
parent bd383fb8c1
commit a150bf8fdc

View File

@ -59,7 +59,7 @@
-export([init/1, wait_for_stream/2, wait_for_auth/2, -export([init/1, wait_for_stream/2, wait_for_auth/2,
wait_for_feature_request/2, wait_for_bind/2, wait_for_feature_request/2, wait_for_bind/2,
wait_for_session/2, wait_for_sasl_response/2, wait_for_sasl_response/2,
wait_for_resume/2, session_established/2, wait_for_resume/2, session_established/2,
handle_event/3, handle_sync_event/4, code_change/4, handle_event/3, handle_sync_event/4, code_change/4,
handle_info/3, terminate/3, print_state/1, opt_type/1]). handle_info/3, terminate/3, print_state/1, opt_type/1]).
@ -473,7 +473,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
children = []}, children = []},
#xmlel{name = <<"session">>, #xmlel{name = <<"session">>,
attrs = [{<<"xmlns">>, ?NS_SESSION}], attrs = [{<<"xmlns">>, ?NS_SESSION}],
children = []}] children =
[#xmlel{name = <<"optional">>}]}]
++ ++
RosterVersioningFeature ++ RosterVersioningFeature ++
StreamManagementFeature ++ StreamManagementFeature ++
@ -492,7 +493,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
#xmlel{name = <<"stream:features">>, #xmlel{name = <<"stream:features">>,
attrs = [], attrs = [],
children = []}), children = []}),
fsm_next_state(wait_for_session, fsm_next_state(session_established,
StateData#state{server = Server, lang = Lang}) StateData#state{server = Server, lang = Lang})
end end
end; end;
@ -1059,20 +1060,32 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
send_element(StateData, Err), send_element(StateData, Err),
fsm_next_state(wait_for_bind, StateData); fsm_next_state(wait_for_bind, StateData);
{accept_resource, R2} -> {accept_resource, R2} ->
JID = jid:make(U, StateData#state.server, R2), JID = jid:make(U, StateData#state.server, R2),
Res = IQ#iq{type = result, StateData2 =
sub_el = StateData#state{resource = R2, jid = JID},
[#xmlel{name = <<"bind">>, case open_session(StateData2) of
attrs = [{<<"xmlns">>, ?NS_BIND}], {ok, StateData3} ->
children = Res =
[#xmlel{name = <<"jid">>, IQ#iq{
attrs = [], type = result,
children = sub_el =
[{xmlcdata, [#xmlel{name = <<"bind">>,
jid:to_string(JID)}]}]}]}, attrs = [{<<"xmlns">>, ?NS_BIND}],
send_element(StateData, jlib:iq_to_xml(Res)), children =
fsm_next_state(wait_for_session, [#xmlel{name = <<"jid">>,
StateData#state{resource = R2, jid = JID}) attrs = [],
children =
[{xmlcdata,
jid:to_string(JID)}]}]}]},
send_element(StateData3, jlib:iq_to_xml(Res)),
fsm_next_state_pack(
session_established,
StateData3);
{error, Error} ->
Err = jlib:make_error_reply(El, Error),
send_element(StateData, Err),
fsm_next_state(wait_for_bind, StateData)
end
end end
end; end;
_ -> fsm_next_state(wait_for_bind, StateData) _ -> fsm_next_state(wait_for_bind, StateData)
@ -1090,75 +1103,49 @@ wait_for_bind(closed, StateData) ->
wait_for_bind(stop, StateData) -> wait_for_bind(stop, StateData) ->
{stop, normal, StateData}. {stop, normal, StateData}.
wait_for_session({xmlstreamelement, #xmlel{name = Name} = El}, StateData) open_session(StateData) ->
when ?IS_STREAM_MGMT_TAG(Name) -> U = StateData#state.user,
fsm_next_state(wait_for_session, dispatch_stream_mgmt(El, StateData)); R = StateData#state.resource,
wait_for_session({xmlstreamelement, El}, StateData) -> JID = StateData#state.jid,
NewStateData = update_num_stanzas_in(StateData, El), case acl:match_rule(StateData#state.server,
case jlib:iq_query_info(El) of StateData#state.access, JID) of
#iq{type = set, xmlns = ?NS_SESSION} -> allow ->
U = NewStateData#state.user, ?INFO_MSG("(~w) Opened session for ~s",
R = NewStateData#state.resource, [StateData#state.socket, jid:to_string(JID)]),
JID = NewStateData#state.jid, change_shaper(StateData, JID),
case acl:match_rule(NewStateData#state.server, {Fs, Ts} = ejabberd_hooks:run_fold(
NewStateData#state.access, JID) of roster_get_subscription_lists,
allow -> StateData#state.server,
?INFO_MSG("(~w) Opened session for ~s", {[], []},
[NewStateData#state.socket, jid:to_string(JID)]), [U, StateData#state.server]),
Res = jlib:make_result_iq_reply(El#xmlel{children = []}), LJID = jid:tolower(jid:remove_resource(JID)),
NewState = send_stanza(NewStateData, Res), Fs1 = [LJID | Fs],
change_shaper(NewState, JID), Ts1 = [LJID | Ts],
{Fs, Ts} = ejabberd_hooks:run_fold( PrivList =
roster_get_subscription_lists, ejabberd_hooks:run_fold(
NewState#state.server, privacy_get_user_list,
{[], []}, StateData#state.server,
[U, NewState#state.server]), #userlist{},
LJID = jid:tolower(jid:remove_resource(JID)), [U, StateData#state.server]),
Fs1 = [LJID | Fs], Conn = get_conn_type(StateData),
Ts1 = [LJID | Ts], Info = [{ip, StateData#state.ip}, {conn, Conn},
PrivList = {auth_module, StateData#state.auth_module}],
ejabberd_hooks:run_fold( ejabberd_sm:open_session(
privacy_get_user_list, StateData#state.sid, U, StateData#state.server, R, Info),
NewState#state.server, UpdatedStateData =
#userlist{}, StateData#state{
[U, NewState#state.server]), conn = Conn,
Conn = get_conn_type(NewState), pres_f = ?SETS:from_list(Fs1),
Info = [{ip, NewState#state.ip}, {conn, Conn}, pres_t = ?SETS:from_list(Ts1),
{auth_module, NewState#state.auth_module}], privacy_list = PrivList},
ejabberd_sm:open_session( {ok, UpdatedStateData};
NewState#state.sid, U, NewState#state.server, R, Info), _ ->
UpdatedStateData = ejabberd_hooks:run(forbidden_session_hook,
NewState#state{ StateData#state.server, [JID]),
conn = Conn, ?INFO_MSG("(~w) Forbidden session for ~s",
pres_f = ?SETS:from_list(Fs1), [StateData#state.socket, jid:to_string(JID)]),
pres_t = ?SETS:from_list(Ts1), {error, ?ERR_NOT_ALLOWED}
privacy_list = PrivList}, end.
fsm_next_state_pack(session_established,
UpdatedStateData);
_ ->
ejabberd_hooks:run(forbidden_session_hook,
NewStateData#state.server, [JID]),
?INFO_MSG("(~w) Forbidden session for ~s",
[NewStateData#state.socket, jid:to_string(JID)]),
Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
send_element(NewStateData, Err),
fsm_next_state(wait_for_session, NewStateData)
end;
_ ->
fsm_next_state(wait_for_session, NewStateData)
end;
wait_for_session(timeout, StateData) ->
{stop, normal, StateData};
wait_for_session({xmlstreamend, _Name}, StateData) ->
send_trailer(StateData), {stop, normal, StateData};
wait_for_session({xmlstreamerror, _}, StateData) ->
send_element(StateData, ?INVALID_XML_ERR),
send_trailer(StateData),
{stop, normal, StateData};
wait_for_session(closed, StateData) ->
{stop, normal, StateData};
wait_for_session(stop, StateData) ->
{stop, normal, StateData}.
session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData) session_established({xmlstreamelement, #xmlel{name = Name} = El}, StateData)
when ?IS_STREAM_MGMT_TAG(Name) -> when ?IS_STREAM_MGMT_TAG(Name) ->
@ -1274,6 +1261,10 @@ session_established2(El, StateData) ->
Xmlns == (?NS_BLOCKING) -> Xmlns == (?NS_BLOCKING) ->
process_privacy_iq(FromJID, ToJID, IQ, process_privacy_iq(FromJID, ToJID, IQ,
NewStateData); NewStateData);
#iq{xmlns = ?NS_SESSION} ->
Res = jlib:make_result_iq_reply(
NewEl#xmlel{children = []}),
send_stanza(NewStateData, Res);
_ -> _ ->
NewEl0 = ejabberd_hooks:run_fold( NewEl0 = ejabberd_hooks:run_fold(
user_send_packet, Server, NewEl, user_send_packet, Server, NewEl,