Skip to content

Commit 66205cf

Browse files
authored
Merge pull request #4356 from pouriya/ref-new-hook-to-customize-resource-binding
Add c2s_handle_bind hook
2 parents b38d861 + 051093f commit 66205cf

File tree

1 file changed

+64
-29
lines changed

1 file changed

+64
-29
lines changed

src/ejabberd_c2s.erl

+64-29
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@
4949
get_fast_tokens_fun/2, fast_mechanisms/1]).
5050
%% Hooks
5151
-export([handle_unexpected_cast/2, handle_unexpected_call/3,
52-
process_auth_result/3, reject_unauthenticated_packet/2,
53-
process_closed/2, process_terminated/2, process_info/2]).
52+
process_auth_result/3, c2s_handle_bind/1,
53+
reject_unauthenticated_packet/2, process_closed/2,
54+
process_terminated/2, process_info/2]).
5455
%% API
5556
-export([get_presence/1, set_presence/2, resend_presence/1, resend_presence/2,
5657
open_session/1, call/3, cast/2, send/2, close/1, close/2, stop_async/1,
@@ -165,6 +166,7 @@ host_up(Host) ->
165166
ejabberd_hooks:add(c2s_closed, Host, ?MODULE, process_closed, 100),
166167
ejabberd_hooks:add(c2s_terminated, Host, ?MODULE,
167168
process_terminated, 100),
169+
ejabberd_hooks:add(c2s_handle_bind, Host, ?MODULE, c2s_handle_bind, 100),
168170
ejabberd_hooks:add(c2s_unauthenticated_packet, Host, ?MODULE,
169171
reject_unauthenticated_packet, 100),
170172
ejabberd_hooks:add(c2s_handle_info, Host, ?MODULE,
@@ -181,6 +183,7 @@ host_down(Host) ->
181183
ejabberd_hooks:delete(c2s_closed, Host, ?MODULE, process_closed, 100),
182184
ejabberd_hooks:delete(c2s_terminated, Host, ?MODULE,
183185
process_terminated, 100),
186+
ejabberd_hooks:delete(c2s_handle_bind, Host, ?MODULE, c2s_handle_bind, 100),
184187
ejabberd_hooks:delete(c2s_unauthenticated_packet, Host, ?MODULE,
185188
reject_unauthenticated_packet, 100),
186189
ejabberd_hooks:delete(c2s_handle_info, Host, ?MODULE,
@@ -285,6 +288,11 @@ handle_unexpected_cast(State, Msg) ->
285288
?WARNING_MSG("Unexpected cast: ~p", [Msg]),
286289
State.
287290

291+
c2s_handle_bind({<<"">>, {ok, State}}) ->
292+
{new_uniq_id(), {ok, State}};
293+
c2s_handle_bind(Acc) ->
294+
Acc.
295+
288296
reject_unauthenticated_packet(State, _Pkt) ->
289297
Err = xmpp:serr_not_authorized(),
290298
send(State, Err).
@@ -480,33 +488,60 @@ fast_mechanisms(#{lserver := LServer}) ->
480488
_ -> mod_auth_fast:get_mechanisms(LServer)
481489
end.
482490

483-
bind(<<"">>, State) ->
484-
bind(new_uniq_id(), State);
485-
bind(R, #{user := U, server := S, access := Access, lang := Lang,
486-
lserver := LServer, socket := Socket,
487-
ip := IP} = State) ->
488-
case resource_conflict_action(U, S, R) of
489-
closenew ->
490-
{error, xmpp:err_conflict(), State};
491-
{accept_resource, Resource} ->
492-
JID = jid:make(U, S, Resource),
493-
case acl:match_rule(LServer, Access,
494-
#{usr => jid:split(JID), ip => IP}) of
495-
allow ->
496-
State1 = open_session(State#{resource => Resource,
497-
sid => ejabberd_sm:make_sid()}),
498-
State2 = ejabberd_hooks:run_fold(
499-
c2s_session_opened, LServer, State1, []),
500-
?INFO_MSG("(~ts) Opened c2s session for ~ts",
501-
[xmpp_socket:pp(Socket), jid:encode(JID)]),
502-
{ok, State2};
503-
deny ->
504-
ejabberd_hooks:run(forbidden_session_hook, LServer, [JID]),
505-
?WARNING_MSG("(~ts) Forbidden c2s session for ~ts",
506-
[xmpp_socket:pp(Socket), jid:encode(JID)]),
507-
Txt = ?T("Access denied by service policy"),
508-
{error, xmpp:err_not_allowed(Txt, Lang), State}
509-
end
491+
bind(
492+
R,
493+
#{
494+
user := U,
495+
server := S,
496+
lserver := LServer,
497+
access := Access,
498+
lang := Lang,
499+
socket := Socket,
500+
ip := IP
501+
}=State
502+
) ->
503+
case ejabberd_hooks:run_fold(c2s_handle_bind, LServer, {R, {ok, State}}, []) of
504+
{R2, {ok, State2}} ->
505+
case resource_conflict_action(U, S, R2) of
506+
closenew ->
507+
{error, xmpp:err_conflict(), State2};
508+
{accept_resource, Resource} ->
509+
JID = jid:make(U, S, Resource),
510+
case acl:match_rule(LServer, Access, #{usr => jid:split(JID), ip => IP}) of
511+
allow ->
512+
State3 = open_session(
513+
State2#{resource => Resource, sid => ejabberd_sm:make_sid()}
514+
),
515+
State4 = ejabberd_hooks:run_fold(
516+
c2s_session_opened, LServer, State3, []
517+
),
518+
?INFO_MSG(
519+
"(~ts) Opened c2s session for ~ts", [xmpp_socket:pp(Socket), jid:encode(JID)]
520+
),
521+
{ok, State4};
522+
deny ->
523+
ejabberd_hooks:run(forbidden_session_hook, LServer, [JID]),
524+
?WARNING_MSG(
525+
"(~ts) Forbidden c2s session for ~ts",
526+
[xmpp_socket:pp(Socket), jid:encode(JID)]
527+
),
528+
Txt = ?T("Access denied by service policy"),
529+
{error, xmpp:err_not_allowed(Txt, Lang), State2}
530+
end
531+
end;
532+
{R2, {error, XmppErr, _State2}=Err} ->
533+
case XmppErr of
534+
#stanza_error{reason = 'not-allowed'} ->
535+
JID = jid:make(U, S, R2),
536+
ejabberd_hooks:run(forbidden_session_hook, LServer, [JID]),
537+
?WARNING_MSG(
538+
"(~ts) Forbidden c2s session for ~ts",
539+
[xmpp_socket:pp(Socket), jid:encode(JID)]
540+
);
541+
_ ->
542+
ok
543+
end,
544+
Err
510545
end.
511546

512547
handle_stream_start(StreamStart, #{lserver := LServer} = State) ->

0 commit comments

Comments
 (0)