5
5
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
8
%%% ejabberd, Copyright (C) 2002-2010 ProcessOne
8
%%% ejabberd, Copyright (C) 2002-2011 ProcessOne
10
10
%%% This program is free software; you can redistribute it and/or
11
11
%%% modify it under the terms of the GNU General Public License as
772
772
authenticated = true,
773
773
auth_module = AuthModule,
775
{ok, Props, ServerOut} ->
776
(StateData#state.sockmod):reset_stream(
777
StateData#state.socket),
778
send_element(StateData,
779
{xmlelement, "success",
780
[{"xmlns", ?NS_SASL}],
782
jlib:encode_base64(ServerOut)}]}),
783
U = xml:get_attr_s(username, Props),
784
AuthModule = xml:get_attr_s(auth_module, Props),
785
?INFO_MSG("(~w) Accepted authentication for ~s by ~p",
786
[StateData#state.socket, U, AuthModule]),
787
fsm_next_state(wait_for_stream,
790
authenticated = true,
791
auth_module = AuthModule,
775
793
{continue, ServerOut, NewSASLState} ->
776
794
send_element(StateData,
777
795
{xmlelement, "challenge",
818
836
{stop, normal, StateData}.
839
resource_conflict_action(U, S, R) ->
840
OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of
842
ejabberd_config:get_local_option({resource_conflict,S});
846
Option = case OptionRaw of
847
setresource -> setresource;
848
closeold -> acceptnew; %% ejabberd_sm will close old session
849
closenew -> closenew;
850
acceptnew -> acceptnew;
851
_ -> acceptnew %% default ejabberd behavior
855
{accept_resource, R};
859
Rnew = lists:concat([randoms:get_string() | tuple_to_list(now())]),
860
{accept_resource, Rnew}
822
863
wait_for_bind({xmlstreamelement, El}, StateData) ->
823
864
case jlib:iq_query_info(El) of
837
878
send_element(StateData, Err),
838
879
fsm_next_state(wait_for_bind, StateData);
840
JID = jlib:make_jid(U, StateData#state.server, R),
841
881
%%Server = StateData#state.server,
842
882
%%RosterVersioningFeature =
843
883
%% ejabberd_hooks:run_fold(
847
887
%% RosterVersioningFeature],
848
888
%%send_element(StateData, {xmlelement, "stream:features",
849
889
%% [], StreamFeatures}),
850
Res = IQ#iq{type = result,
851
sub_el = [{xmlelement, "bind",
852
[{"xmlns", ?NS_BIND}],
853
[{xmlelement, "jid", [],
855
jlib:jid_to_string(JID)}]}]}]},
856
send_element(StateData, jlib:iq_to_xml(Res)),
857
fsm_next_state(wait_for_session,
858
StateData#state{resource = R, jid = JID})
890
case resource_conflict_action(U, StateData#state.server, R) of
892
Err = jlib:make_error_reply(El, ?STANZA_ERROR("409", "modify", "conflict")),
893
send_element(StateData, Err),
894
fsm_next_state(wait_for_bind, StateData);
895
{accept_resource, R2} ->
896
JID = jlib:make_jid(U, StateData#state.server, R2),
897
Res = IQ#iq{type = result,
898
sub_el = [{xmlelement, "bind",
899
[{"xmlns", ?NS_BIND}],
900
[{xmlelement, "jid", [],
902
jlib:jid_to_string(JID)}]}]}]},
903
send_element(StateData, jlib:iq_to_xml(Res)),
904
fsm_next_state(wait_for_session,
905
StateData#state{resource = R2, jid = JID})
861
909
fsm_next_state(wait_for_bind, StateData)
1053
1101
case jlib:iq_query_info(NewEl) of
1054
#iq{xmlns = ?NS_PRIVACY} = IQ ->
1102
#iq{xmlns = Xmlns} = IQ
1103
when Xmlns == ?NS_PRIVACY;
1104
Xmlns == ?NS_BLOCKING ->
1055
1105
process_privacy_iq(
1056
1106
FromJID, ToJID, IQ, StateData);
1283
1333
send_element(StateData, PrivPushEl),
1284
1334
{false, Attrs, StateData#state{privacy_list = NewPL}}
1336
[{blocking, What}] ->
1337
route_blocking(What, StateData),
1338
{false, Attrs, StateData};
1287
1340
{false, Attrs, StateData}
1733
1786
StateData#state.pres_invis,
1734
1787
?DEBUG("from unavail = ~p~n", [FromUnavail]),
1789
NewStateData = StateData#state{pres_last = Packet,
1791
pres_timestamp = Timestamp},
1738
1794
ejabberd_hooks:run(user_available_hook,
1739
StateData#state.server,
1740
[StateData#state.jid]),
1795
NewStateData#state.server,
1796
[NewStateData#state.jid]),
1741
1797
if NewPriority >= 0 ->
1742
resend_offline_messages(StateData),
1743
resend_subscription_requests(StateData);
1798
resend_offline_messages(NewStateData),
1799
resend_subscription_requests(NewStateData);
1747
presence_broadcast_first(
1748
From, StateData#state{pres_last = Packet,
1750
pres_timestamp = Timestamp
1803
presence_broadcast_first(From, NewStateData, Packet);
1753
presence_broadcast_to_trusted(StateData,
1805
presence_broadcast_to_trusted(NewStateData,
1755
StateData#state.pres_f,
1756
StateData#state.pres_a,
1807
NewStateData#state.pres_f,
1808
NewStateData#state.pres_a,
1758
1810
if OldPriority < 0, NewPriority >= 0 ->
1759
resend_offline_messages(StateData);
1811
resend_offline_messages(NewStateData);
1763
StateData#state{pres_last = Packet,
1765
pres_timestamp = Timestamp
2059
2108
Rs when is_list(Rs) ->
2062
From, To, {xmlelement, Name, Attrs, Els} = Packet}) ->
2111
From, To, {xmlelement, _Name, _Attrs, _Els} = Packet}) ->
2063
2112
Pass = case privacy_check_packet(StateData, From, To, Packet, in) of
2071
Attrs2 = jlib:replace_from_to_attrs(
2072
jlib:jid_to_string(From),
2073
jlib:jid_to_string(To),
2075
FixedPacket = {xmlelement, Name, Attrs2, Els},
2076
send_element(StateData, FixedPacket),
2077
ejabberd_hooks:run(user_receive_packet,
2078
StateData#state.server,
2079
[StateData#state.jid,
2080
From, To, FixedPacket]);
2120
%% Attrs2 = jlib:replace_from_to_attrs(
2121
%% jlib:jid_to_string(From),
2122
%% jlib:jid_to_string(To),
2124
%% FixedPacket = {xmlelement, Name, Attrs2, Els},
2125
%% Use route instead of send_element to go through standard workflow
2126
ejabberd_router:route(From, To, Packet);
2127
%% send_element(StateData, FixedPacket),
2128
%% ejabberd_hooks:run(user_receive_packet,
2129
%% StateData#state.server,
2130
%% [StateData#state.jid,
2131
%% From, To, FixedPacket]);
2242
2293
%%%----------------------------------------------------------------------
2295
%%%----------------------------------------------------------------------
2297
route_blocking(What, StateData) ->
2301
{xmlelement, "block",
2302
[{"xmlns", ?NS_BLOCKING}],
2305
{xmlelement, "item",
2306
[{"jid", jlib:jid_to_string(JID)}],
2310
{xmlelement, "unblock",
2311
[{"xmlns", ?NS_BLOCKING}],
2314
{xmlelement, "item",
2315
[{"jid", jlib:jid_to_string(JID)}],
2319
{xmlelement, "unblock",
2320
[{"xmlns", ?NS_BLOCKING}], []}
2323
#iq{type = set, xmlns = ?NS_BLOCKING,
2327
jlib:replace_from_to(
2328
jlib:jid_remove_resource(
2329
StateData#state.jid),
2330
StateData#state.jid,
2331
jlib:iq_to_xml(PrivPushIQ)),
2332
send_element(StateData, PrivPushEl),
2333
%% No need to replace active privacy list here,
2334
%% blocking pushes are always accompanied by
2335
%% Privacy List pushes
2338
%%%----------------------------------------------------------------------
2243
2339
%%% JID Set memory footprint reduction code
2244
2340
%%%----------------------------------------------------------------------