~singpolyma/biboumi

0a6b673b14efc4f623ea445045e6fc60e9842a25 — Florent Le Coz 9 years ago e24ed4f
Support raw IRC messages

Messages received on an IRC server JID are forwarded as raw IRC messages.

fix #2486
M doc/biboumi.1.md => doc/biboumi.1.md +14 -0
@@ 357,6 357,20 @@ Biboumi supports a few ad-hoc commands, as described in the XEP 0050.
    “Gateway shutdown” quit message, except that biboumi does not exit when
    using this ad-hoc command.

### Raw IRC messages

Biboumi tries to support as many IRC features as possible, but doesn’t
handle everything yet (or ever).  In order to let the user send any
arbitrary IRC message, biboumi forwards any XMPP message received on an IRC
Server JID (see *ADDRESSING*) as a raw command to that IRC server.

For example, to WHOIS the user Foo on the server irc.example.com, a user can
send the message “WHOIS Foo” to “irc.example.com@biboumi.example.com”.

The message will be forwarded as is, without any modification appart from
adding "\r\n" at the end (to make it a valid IRC message).  You need to have
a little bit of understanding of the IRC protocol to use this feature.

SECURITY
--------


M src/bridge/bridge.cpp => src/bridge/bridge.cpp +11 -0
@@ 273,6 273,17 @@ void Bridge::send_private_message(const Iid& iid, const std::string& body, const
    }
}

void Bridge::send_raw_message(const std::string& hostname, const std::string& body)
{
  IrcClient* irc = this->get_irc_client(hostname);
  if (!irc)
    {
      log_warning("Cannot send message: no client exist for server " << hostname);
      return ;
    }
  irc->send_raw(body);
}

void Bridge::leave_irc_channel(Iid&& iid, std::string&& status_message)
{
  IrcClient* irc = this->get_irc_client(iid.get_server());

M src/bridge/bridge.hpp => src/bridge/bridge.hpp +1 -0
@@ 61,6 61,7 @@ public:
  bool join_irc_channel(const Iid& iid, const std::string& username, const std::string& password);
  void send_channel_message(const Iid& iid, const std::string& body);
  void send_private_message(const Iid& iid, const std::string& body, const std::string& type="PRIVMSG");
  void send_raw_message(const std::string& hostname, const std::string& body);
  void leave_irc_channel(Iid&& iid, std::string&& status_message);
  void send_irc_nick_change(const Iid& iid, const std::string& new_nick);
  void send_irc_kick(const Iid& iid, const std::string& target, const std::string& reason,

M src/irc/irc_client.cpp => src/irc/irc_client.cpp +5 -0
@@ 181,6 181,11 @@ void IrcClient::send_message(IrcMessage&& message)
  this->send_data(std::move(res));
}

void IrcClient::send_raw(const std::string& txt)
{
  this->send_data(txt + "\r\n");
}

void IrcClient::send_user_command(const std::string& username, const std::string& realname)
{
  this->send_message(IrcMessage("USER", {username, "ignored", "ignored", realname}));

M src/irc/irc_client.hpp => src/irc/irc_client.hpp +1 -0
@@ 66,6 66,7 @@ public:
   * for send events to be ready)
   */
  void send_message(IrcMessage&& message);
  void send_raw(const std::string& txt);
  /**
   * Send the PONG irc command
   */

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +5 -0
@@ 211,6 211,11 @@ void BiboumiComponent::handle_message(const Stanza& stanza)
              bridge->send_private_message(user_iid, body->get_inner());
              bridge->set_preferred_from_jid(user_iid.get_local(), to_str);
            }
          else if (!iid.is_user && !iid.is_channel)
            { // Message sent to the server JID
              // Convert the message body into a raw IRC message
              bridge->send_raw_message(iid.get_server(), body->get_inner());
            }
        }
    }
  else if (iid.is_user)