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)