~singpolyma/biboumi

21a79b7bad51e755cee2890aa6d0bec5dd45f901 — louiz’ 4 years ago fc17ee0
Reject messages from unjoined resources, with an error

fix #3346
4 files changed, 43 insertions(+), 3 deletions(-)

M CHANGELOG.rst
M src/bridge/bridge.hpp
M src/xmpp/biboumi_component.cpp
M tests/end_to_end/__main__.py
M CHANGELOG.rst => CHANGELOG.rst +3 -0
@@ 2,6 2,9 @@ Version 9.0
===========

- SIGHUP is now caught and reloads the configuration like SIGUSR1 and 2.
- Messages from unjoined resources are now rejected instead of being accepted.
  This helps clients understand that they are not in the room (because of
  some connection issue for example).

Version 8.3 - 2018-06-01
========================

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +2 -0
@@ 316,7 316,9 @@ private:
   */
  void add_resource_to_chan(const ChannelKey& channel, const std::string& resource);
  void remove_resource_from_chan(const ChannelKey& channel, const std::string& resource);
public:
  bool is_resource_in_chan(const ChannelKey& channel, const std::string& resource) const;
private:
  void remove_all_resources_from_chan(const ChannelKey& channel);
  std::size_t number_of_resources_in_chan(const ChannelKey& channel) const;


M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +12 -3
@@ 273,9 273,10 @@ void BiboumiComponent::handle_message(const Stanza& stanza)

  std::string error_type("cancel");
  std::string error_name("internal-server-error");
  utils::ScopeGuard stanza_error([this, &from_str, &to_str, &id, &error_type, &error_name](){
  std::string error_text{};
  utils::ScopeGuard stanza_error([this, &from_str, &to_str, &id, &error_type, &error_name, &error_text](){
      this->send_stanza_error("message", from_str, to_str, id,
                              error_type, error_name, "");
                              error_type, error_name, error_text);
    });
  const XmlNode* body = stanza.get_child("body", COMPONENT_NS);



@@ 284,7 285,15 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
    {
      if (body && !body->get_inner().empty())
        {
          bridge->send_channel_message(iid, body->get_inner(), id);
          if (bridge->is_resource_in_chan(iid.to_tuple(), from.resource))
            bridge->send_channel_message(iid, body->get_inner(), id);
          else
            {
              error_type = "modify";
              error_name = "not-acceptable";
              error_text = "You are not a participant in this room.";
              return;
            }
        }
      const XmlNode* subject = stanza.get_child("subject", COMPONENT_NS);
      if (subject)

M tests/end_to_end/__main__.py => tests/end_to_end/__main__.py +26 -0
@@ 1404,6 1404,32 @@ if __name__ == '__main__':
                     "/message[@from='{lower_nick_two}%{irc_server_one}'][@to='{jid_one}/{resource_one}']"),
                 ]
                 ),
                Scenario("muc_message_from_unjoined_resource",
                         [
                         handshake_sequence(),
                         partial(send_stanza,
                                 "<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}' />"),
                         connection_sequence("irc.localhost", '{jid_one}/{resource_one}'),
                         partial(expect_stanza,
                                 "/message/body[text()='Mode #foo [+nt] by {irc_host_one}']"),
                         partial(expect_stanza, "/presence"),
                         partial(expect_stanza, "/message/subject"),

                         # Send a channel message
                        partial(send_stanza, "<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
                        # Receive the message
                        partial(expect_stanza,
                         ("/message[@from='#foo%{irc_server_one}/{nick_one}'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='coucou']",
                          "/message/stable_id:stanza-id[@by='#foo%{irc_server_one}'][@id]"),
                         ),

                         # Send a message from a resource that is not joined
                         partial(send_stanza, "<message from='{jid_one}/{resource_two}' to='#foo%{irc_server_one}' type='groupchat'><body>coucou</body></message>"),
                         partial(expect_stanza, ("/message[@type='error']/error[@type='modify']/stanza:text[text()='You are not a participant in this room.']",
                                                 "/message/error/stanza:not-acceptable"
                                                 ))

                         ]),
                Scenario("encoded_channel_join",
                 [
                     handshake_sequence(),