]> granicus.if.org Git - ejabberd/commitdiff
Don't auto-decode forwarded payload
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 13 Nov 2016 10:41:04 +0000 (13:41 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 13 Nov 2016 10:41:04 +0000 (13:41 +0300)
include/xmpp_codec.hrl
specs/xmpp_codec.spec
src/mod_carboncopy.erl
src/mod_delegation.erl
src/mod_mam.erl
src/mod_privilege.erl
src/xmpp_codec.erl
src/xmpp_util.erl

index 981f7f4c2bb091ee66a958e082fc2b7ee26e200a..03421d98daff20bdbdb1f34233abd969753178ce 100644 (file)
 -type starttls_proceed() :: #starttls_proceed{}.
 
 -record(forwarded, {delay :: #delay{},
-                    sub_els = [] :: [xmpp_element() | fxml:xmlel()]}).
+                    xml_els = [] :: [fxml:xmlel()]}).
 -type forwarded() :: #forwarded{}.
 
 -record(privilege, {perms = [] :: [#privilege_perm{}],
index bcab7a6e5ac56944dc82ce5d682e4c5a85227aa1..0aa124ec8e3893e95ea7c095ffaea8dec202e875 100644 (file)
 -xml(forwarded,
      #elem{name = <<"forwarded">>,
            xmlns = <<"urn:xmpp:forward:0">>,
-           result = {forwarded, '$delay', '$_els'},
+           result = {forwarded, '$delay', '$_xmls'},
            refs = [#ref{name = delay, min = 0,
                         max = 1, label = '$delay'}]}).
 
index 023e8dc6f8703801a220074ba38299a3d203aae4..7d8ca533218f81f9379cda3f29ba322a0712e4e6 100644 (file)
@@ -198,7 +198,7 @@ send_copies(JID, To, Packet, Direction)->
 
 -spec build_forward_packet(jid(), message(), jid(), jid(), direction()) -> message().
 build_forward_packet(JID, #message{type = T} = Msg, Sender, Dest, Direction) ->
-    Forwarded = #forwarded{sub_els = [complete_packet(JID, Msg, Direction)]},
+    Forwarded = #forwarded{xml_els = [xmpp:encode(complete_packet(JID, Msg, Direction))]},
     Carbon = case Direction of
                 sent -> #carbons_sent{forwarded = Forwarded};
                 received -> #carbons_received{forwarded = Forwarded}
index 7fec01dcbbd8359c4e0884d2b26d6a1cafdc6b05..ad57bad44c005a212d089600df4b84b7962806e3 100644 (file)
@@ -217,7 +217,8 @@ process_iq(#iq{to = To, lang = Lang, sub_els = [SubEl]} = IQ, Type) ->
     Delegations = get_delegations(LServer),
     case dict:find({NS, Type}, Delegations) of
        {ok, {Host, _}} ->
-           Delegation = #delegation{forwarded = #forwarded{sub_els = [IQ]}},
+           Delegation = #delegation{
+                           forwarded = #forwarded{xml_els = [xmpp:encode(IQ)]}},
            NewFrom = jid:make(LServer),
            NewTo = jid:make(Host),
            ejabberd_local:route_iq(
@@ -236,14 +237,15 @@ process_iq(#iq{to = To, lang = Lang, sub_els = [SubEl]} = IQ, Type) ->
 -spec process_iq_result(iq(), iq()) -> ok.
 process_iq_result(#iq{from = From, to = To, id = ID, lang = Lang} = IQ,
                  #iq{type = result} = ResIQ) ->
-    case xmpp:get_subtag(ResIQ, #delegation{}) of
-       #delegation{
-          forwarded = #forwarded{
-                         sub_els = [#iq{from = To, to = From,
-                                        type = Type, id = ID} = Reply]}}
-         when Type == error; Type == result ->
-           ejabberd_router:route(From, To, Reply);
-       _ ->
+    try
+       #delegation{forwarded = #forwarded{xml_els = [SubEl]}} =
+           xmpp:get_subtag(ResIQ, #delegation{}),
+       case xmpp:decode(SubEl, ?NS_CLIENT, [ignore_els]) of
+           #iq{from = To, to = From, type = Type, id = ID} = Reply
+             when Type == error; Type == result ->
+               ejabberd_router:route(From, To, Reply)
+       end
+    catch _:_ ->
            ?ERROR_MSG("got iq-result with invalid delegated "
                       "payload:~n~s", [xmpp:pp(ResIQ)]),
            Txt = <<"External component failure">>,
index 8c5422f0770009ac4d22fdb60bfa76a48856ef35..f9ef104bd17b42501d70cd0596ef03cf498e4327 100644 (file)
@@ -794,7 +794,7 @@ msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer},
          MsgType, JidRequestor, #jid{lserver = LServer} = JidArchive) ->
     Pkt2 = maybe_update_from_to(Pkt1, JidRequestor, JidArchive, Peer, MsgType,
                                Nick),
-    #forwarded{sub_els = [Pkt2],
+    #forwarded{xml_els = [xmpp:encode(Pkt2)],
               delay = #delay{stamp = TS, from = jid:make(LServer)}}.
 
 maybe_update_from_to(#xmlel{} = El, JidRequestor, JidArchive, Peer,
index 50212b7aeb92138304fda9bfe048c6818cfb4f55..936c237bd55bf805a292738f0b009edd58ce0936 100644 (file)
@@ -257,25 +257,33 @@ get_permissions(ServerHost) ->
     end.
 
 forward_message(From, To, Msg) ->
-    Host = From#jid.lserver,
     ServerHost = To#jid.lserver,
+    Lang = xmpp:get_lang(Msg),
     case xmpp:get_subtag(Msg, #privilege{}) of
-       #privilege{forwarded = #forwarded{sub_els = [#message{} = SubEl]}} ->
-           case SubEl#message.from of
-               #jid{lresource = <<"">>, lserver = ServerHost} ->
-                   ejabberd_router:route(
-                     xmpp:get_from(SubEl), xmpp:get_to(SubEl), SubEl);
+       #privilege{forwarded = #forwarded{xml_els = [SubEl]}} ->
+           try xmpp:decode(SubEl, ?NS_CLIENT, [ignore_els]) of
+               #message{} = NewMsg ->
+                   case NewMsg#message.from of
+                       #jid{lresource = <<"">>, lserver = ServerHost} ->
+                           ejabberd_router:route(
+                             xmpp:get_from(NewMsg), xmpp:get_to(NewMsg), NewMsg);
+                       _ ->
+                           Lang = xmpp:get_lang(Msg),
+                           Txt = <<"Invalid 'from' attribute in forwarded message">>,
+                           Err = xmpp:err_forbidden(Txt, Lang),
+                           ejabberd_router:route_error(To, From, Msg, Err)
+                   end;
                _ ->
-                   Lang = xmpp:get_lang(Msg),
-                   Txt = <<"Invalid 'from' attribute">>,
-                   Err = xmpp:err_forbidden(Txt, Lang),
+                   Txt = <<"Message not found in forwarded payload">>,
+                   Err = xmpp:err_bad_request(Txt, Lang),
+                   ejabberd_router:route_error(To, From, Msg, Err)
+           catch _:{xmpp_codec, Why} ->
+                   Txt = xmpp:format_error(Why),
+                   Err = xmpp:err_bad_request(Txt, Lang),
                    ejabberd_router:route_error(To, From, Msg, Err)
            end;
        _ ->
-           ?ERROR_MSG("got invalid forwarded payload from external "
-                      "component '~s':~n~s", [Host, xmpp:pp(Msg)]),
-           Lang = xmpp:get_lang(Msg),
-           Txt = <<"Invalid forwarded payload">>,
+           Txt = <<"Invalid <forwarded/> element">>,
            Err = xmpp:err_bad_request(Txt, Lang),
            ejabberd_router:route_error(To, From, Msg, Err)
     end.
index 2931baaa44cf643232c019d944d8bcd98ab17a73..6089f79fc4519fe820b06c94f2d6851d0c24ba9b 100644 (file)
@@ -6639,7 +6639,7 @@ pp(mam_archived, 2) -> [by, id];
 pp(mam_result, 4) -> [xmlns, queryid, id, sub_els];
 pp(mam_prefs, 4) -> [xmlns, default, always, never];
 pp(mam_fin, 5) -> [xmlns, id, rsm, stable, complete];
-pp(forwarded, 2) -> [delay, sub_els];
+pp(forwarded, 2) -> [delay, xml_els];
 pp(carbons_disable, 0) -> [];
 pp(carbons_enable, 0) -> [];
 pp(carbons_private, 0) -> [];
@@ -11966,53 +11966,41 @@ encode_carbons_disable({carbons_disable}, __TopXMLNS) ->
 
 decode_forwarded(__TopXMLNS, __IgnoreEls,
                 {xmlel, <<"forwarded">>, _attrs, _els}) ->
-    {Delay, __Els} = decode_forwarded_els(__TopXMLNS,
-                                         __IgnoreEls, _els, undefined, []),
-    {forwarded, Delay, __Els}.
+    {Delay, __Xmls} = decode_forwarded_els(__TopXMLNS,
+                                          __IgnoreEls, _els, undefined, []),
+    {forwarded, Delay, __Xmls}.
 
 decode_forwarded_els(__TopXMLNS, __IgnoreEls, [], Delay,
-                    __Els) ->
-    {Delay, lists:reverse(__Els)};
+                    __Xmls) ->
+    {Delay, lists:reverse(__Xmls)};
 decode_forwarded_els(__TopXMLNS, __IgnoreEls,
                     [{xmlel, <<"delay">>, _attrs, _} = _el | _els], Delay,
-                    __Els) ->
+                    __Xmls) ->
     case get_attr(<<"xmlns">>, _attrs) of
       <<"urn:xmpp:delay">> ->
          decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
                               decode_delay(<<"urn:xmpp:delay">>, __IgnoreEls,
                                            _el),
-                              __Els);
+                              __Xmls);
       _ ->
          decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
-                              Delay, __Els)
+                              Delay, __Xmls)
     end;
 decode_forwarded_els(__TopXMLNS, __IgnoreEls,
-                    [{xmlel, _, _, _} = _el | _els], Delay, __Els) ->
-    if __IgnoreEls ->
-          decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
-                               Delay, [_el | __Els]);
-       true ->
-          case is_known_tag(_el, __TopXMLNS) of
-            true ->
-                decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
-                                     Delay,
-                                     [decode(_el, __TopXMLNS, []) | __Els]);
-            false ->
-                decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
-                                     Delay, __Els)
-          end
-    end;
+                    [{xmlel, _, _, _} = _el | _els], Delay, __Xmls) ->
+    decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
+                        Delay, [_el | __Xmls]);
 decode_forwarded_els(__TopXMLNS, __IgnoreEls,
-                    [_ | _els], Delay, __Els) ->
+                    [_ | _els], Delay, __Xmls) ->
     decode_forwarded_els(__TopXMLNS, __IgnoreEls, _els,
-                        Delay, __Els).
+                        Delay, __Xmls).
 
-encode_forwarded({forwarded, Delay, __Els},
+encode_forwarded({forwarded, Delay, __Xmls},
                 __TopXMLNS) ->
     __NewTopXMLNS =
        choose_top_xmlns(<<"urn:xmpp:forward:0">>, [],
                         __TopXMLNS),
-    _els = [encode(_el, __NewTopXMLNS) || _el <- __Els] ++
+    _els = __Xmls ++
             lists:reverse('encode_forwarded_$delay'(Delay,
                                                     __NewTopXMLNS, [])),
     _attrs = enc_xmlns_attrs(__NewTopXMLNS, __TopXMLNS),
index a07dae78be237b43666c4cd85ef6a8116e6096f0..57440b50ea102cc6834967934c0a68fc6cef8be9 100644 (file)
@@ -42,16 +42,20 @@ add_delay_info(Stz, From, Time, Desc) ->
 
 -spec unwrap_carbon(stanza()) -> xmpp_element().
 unwrap_carbon(#message{} = Msg) ->
-    case xmpp:get_subtag(Msg, #carbons_sent{}) of
-       #carbons_sent{forwarded = #forwarded{sub_els = [El]}} ->
-           El;
-       _ ->
-           case xmpp:get_subtag(Msg, #carbons_received{}) of
-               #carbons_received{forwarded = #forwarded{sub_els = [El]}} ->
-                   El;
-               _ ->
-                   Msg
-           end
+    try
+       case xmpp:get_subtag(Msg, #carbons_sent{}) of
+           #carbons_sent{forwarded = #forwarded{xml_els = [El]}} ->
+               xmpp:decode(El, ?NS_CLIENT, [ignore_els]);
+           _ ->
+               case xmpp:get_subtag(Msg, #carbons_received{}) of
+                   #carbons_received{forwarded = #forwarded{xml_els = [El]}} ->
+                       xmpp:decode(El, ?NS_CLIENT, [ignore_els]);
+                   _ ->
+                       Msg
+               end
+       end
+    catch _:{xmpp_codec, _} ->
+           Msg
     end;
 unwrap_carbon(Stanza) -> Stanza.