~ubuntu-branches/ubuntu/precise/ejabberd/precise-updates

« back to all changes in this revision

Viewing changes to src/ejabberd_c2s.erl

  • Committer: Bazaar Package Importer
  • Author(s): Konstantin Khomoutov, Konstantin Khomoutov
  • Date: 2011-10-03 20:27:12 UTC
  • mfrom: (21.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20111003202712-7j03r8c8hobtc5m6
Tags: 2.1.9-1
[ Konstantin Khomoutov ]
* New upstream release.
* Remove obsoleted version.patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
6
6
%%%
7
7
%%%
8
 
%%% ejabberd, Copyright (C) 2002-2010   ProcessOne
 
8
%%% ejabberd, Copyright (C) 2002-2011   ProcessOne
9
9
%%%
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,
774
774
                                     user = U});
 
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}],
 
781
                                  [{xmlcdata,
 
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,
 
788
                                   StateData#state{
 
789
                                     streamid = new_id(),
 
790
                                     authenticated = true,
 
791
                                     auth_module = AuthModule,
 
792
                                     user = U});
775
793
                {continue, ServerOut, NewSASLState} ->
776
794
                    send_element(StateData,
777
795
                                 {xmlelement, "challenge",
818
836
    {stop, normal, StateData}.
819
837
 
820
838
 
 
839
resource_conflict_action(U, S, R) ->
 
840
    OptionRaw = case ejabberd_sm:is_existing_resource(U, S, R) of
 
841
                    true ->
 
842
                        ejabberd_config:get_local_option({resource_conflict,S});
 
843
                    false ->
 
844
                        acceptnew
 
845
                end,
 
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
 
852
             end,
 
853
    case Option of
 
854
        acceptnew ->
 
855
            {accept_resource, R};
 
856
        closenew ->
 
857
            closenew;
 
858
        setresource ->
 
859
            Rnew = lists:concat([randoms:get_string() | tuple_to_list(now())]),
 
860
            {accept_resource, Rnew}
 
861
    end.
821
862
 
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);
839
880
                _ ->
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", [],
854
 
                                             [{xmlcdata,
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
 
891
                        closenew ->
 
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", [],
 
901
                                                     [{xmlcdata,
 
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})
 
906
                    end
859
907
            end;
860
908
        _ ->
861
909
            fsm_next_state(wait_for_bind, StateData)
1051
1099
                        end;
1052
1100
                    "iq" ->
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);
1057
1107
                            _ ->
1283
1333
                                send_element(StateData, PrivPushEl),
1284
1334
                                {false, Attrs, StateData#state{privacy_list = NewPL}}
1285
1335
                        end;
 
1336
                    [{blocking, What}] ->
 
1337
                        route_blocking(What, StateData),
 
1338
                        {false, Attrs, StateData};
1286
1339
                    _ ->
1287
1340
                        {false, Attrs, StateData}
1288
1341
                end;
1733
1786
                StateData#state.pres_invis,
1734
1787
            ?DEBUG("from unavail = ~p~n", [FromUnavail]),
1735
1788
            NewState =
 
1789
                NewStateData = StateData#state{pres_last = Packet,
 
1790
                                               pres_invis = false,
 
1791
                                               pres_timestamp = Timestamp},
1736
1792
                if
1737
1793
                    FromUnavail ->
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);
1744
1800
                           true ->
1745
1801
                                ok
1746
1802
                        end,
1747
 
                        presence_broadcast_first(
1748
 
                          From, StateData#state{pres_last = Packet,
1749
 
                                                pres_invis = false,
1750
 
                                                pres_timestamp = Timestamp
1751
 
                                               }, Packet);
 
1803
                        presence_broadcast_first(From, NewStateData, Packet);
1752
1804
                    true ->
1753
 
                        presence_broadcast_to_trusted(StateData,
 
1805
                        presence_broadcast_to_trusted(NewStateData,
1754
1806
                                                      From,
1755
 
                                                      StateData#state.pres_f,
1756
 
                                                      StateData#state.pres_a,
 
1807
                                                      NewStateData#state.pres_f,
 
1808
                                                      NewStateData#state.pres_a,
1757
1809
                                                      Packet),
1758
1810
                        if OldPriority < 0, NewPriority >= 0 ->
1759
 
                                resend_offline_messages(StateData);
 
1811
                                resend_offline_messages(NewStateData);
1760
1812
                           true ->
1761
1813
                                ok
1762
1814
                        end,
1763
 
                        StateData#state{pres_last = Packet,
1764
 
                                        pres_invis = false,
1765
 
                                        pres_timestamp = Timestamp
1766
 
                                       }
 
1815
                        NewStateData
1767
1816
                end,
1768
1817
            NewState
1769
1818
    end.
2059
2108
        Rs when is_list(Rs) ->
2060
2109
            lists:foreach(
2061
2110
              fun({route,
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
2064
2113
                                 allow ->
2065
2114
                                     true;
2068
2117
                             end,
2069
2118
                      if
2070
2119
                          Pass ->
2071
 
                              Attrs2 = jlib:replace_from_to_attrs(
2072
 
                                         jlib:jid_to_string(From),
2073
 
                                         jlib:jid_to_string(To),
2074
 
                                         Attrs),
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),
 
2123
                              %%                 Attrs),
 
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]);
2081
2132
                          true ->
2082
2133
                              ok
2083
2134
                      end
2240
2291
    end.
2241
2292
 
2242
2293
%%%----------------------------------------------------------------------
 
2294
%%% XEP-0191
 
2295
%%%----------------------------------------------------------------------
 
2296
 
 
2297
route_blocking(What, StateData) ->
 
2298
    SubEl =
 
2299
        case What of
 
2300
            {block, JIDs} ->
 
2301
                {xmlelement, "block",
 
2302
                 [{"xmlns", ?NS_BLOCKING}],
 
2303
                 lists:map(
 
2304
                   fun(JID) ->
 
2305
                           {xmlelement, "item",
 
2306
                            [{"jid", jlib:jid_to_string(JID)}],
 
2307
                            []}
 
2308
                                       end, JIDs)};
 
2309
            {unblock, JIDs} ->
 
2310
                {xmlelement, "unblock",
 
2311
                 [{"xmlns", ?NS_BLOCKING}],
 
2312
                 lists:map(
 
2313
                   fun(JID) ->
 
2314
                           {xmlelement, "item",
 
2315
                            [{"jid", jlib:jid_to_string(JID)}],
 
2316
                            []}
 
2317
                   end, JIDs)};
 
2318
            unblock_all ->
 
2319
                {xmlelement, "unblock",
 
2320
                 [{"xmlns", ?NS_BLOCKING}], []}
 
2321
        end,
 
2322
    PrivPushIQ =
 
2323
        #iq{type = set, xmlns = ?NS_BLOCKING,
 
2324
            id = "push",
 
2325
            sub_el = [SubEl]},
 
2326
    PrivPushEl =
 
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
 
2336
    ok.
 
2337
 
 
2338
%%%----------------------------------------------------------------------
2243
2339
%%% JID Set memory footprint reduction code
2244
2340
%%%----------------------------------------------------------------------
2245
2341