Also support caps on irc server JIDs
This commit is contained in:
@@ -576,9 +576,10 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
|
|||||||
}
|
}
|
||||||
else if (iid.type == Iid::Type::Server)
|
else if (iid.type == Iid::Type::Server)
|
||||||
{
|
{
|
||||||
if (node.empty())
|
const std::string expected_node_name = std::string(NODE_NAME) + "#" + get_irc_server_ver(to_str);
|
||||||
|
if (node.empty() || node == expected_node_name)
|
||||||
{
|
{
|
||||||
this->send_irc_server_disco_info(id, from, to_str);
|
this->send_irc_server_disco_info(id, from, to_str, node);
|
||||||
stanza_error.disable();
|
stanza_error.disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1074,28 +1075,35 @@ void BiboumiComponent::send_self_disco_info(const std::string& id, const std::st
|
|||||||
this->send_stanza(iq);
|
this->send_stanza(iq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiboumiComponent::send_irc_server_disco_info(const std::string& id, const std::string& jid_to, const std::string& jid_from)
|
void BiboumiComponent::send_irc_server_disco_info(const std::string& id, const std::string& jid_to,
|
||||||
|
const std::string& jid_from, const std::string& node)
|
||||||
{
|
{
|
||||||
Jid from(jid_from);
|
Stanza iq = get_irc_server_disco_info(jid_from, node);
|
||||||
Stanza iq("iq");
|
|
||||||
{
|
|
||||||
iq["type"] = "result";
|
|
||||||
iq["id"] = id;
|
iq["id"] = id;
|
||||||
iq["to"] = jid_to;
|
iq["to"] = jid_to;
|
||||||
iq["from"] = jid_from;
|
iq["from"] = jid_from;
|
||||||
|
this->send_stanza(iq);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stanza BiboumiComponent::get_irc_server_disco_info(const std::string& jid_from, const std::string& node)
|
||||||
|
{
|
||||||
|
Jid from(jid_from);
|
||||||
|
Stanza iq("iq");
|
||||||
|
iq["type"] = "result";
|
||||||
XmlSubNode query(iq, "query");
|
XmlSubNode query(iq, "query");
|
||||||
query["xmlns"] = DISCO_INFO_NS;
|
query["xmlns"] = DISCO_INFO_NS;
|
||||||
|
if (!node.empty())
|
||||||
|
query["node"] = node;
|
||||||
XmlSubNode identity(query, "identity");
|
XmlSubNode identity(query, "identity");
|
||||||
identity["category"] = "gateway";
|
identity["category"] = "gateway";
|
||||||
identity["type"] = "irc";
|
identity["type"] = "irc";
|
||||||
identity["name"] = "IRC server " + from.local + " over Biboumi";
|
identity["name"] = "IRC server " + from.local + " over Biboumi";
|
||||||
for (const char *ns: {DISCO_INFO_NS, ADHOC_NS, PING_NS, VERSION_NS})
|
for (const char *ns: {DISCO_INFO_NS, CAPS_NS, ADHOC_NS, PING_NS, VERSION_NS})
|
||||||
{
|
{
|
||||||
XmlSubNode feature(query, "feature");
|
XmlSubNode feature(query, "feature");
|
||||||
feature["var"] = ns;
|
feature["var"] = ns;
|
||||||
}
|
}
|
||||||
}
|
return iq;
|
||||||
this->send_stanza(iq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BiboumiComponent::send_irc_channel_muc_traffic_info(const std::string& id, const std::string& jid_to, const std::string& jid_from)
|
void BiboumiComponent::send_irc_channel_muc_traffic_info(const std::string& id, const std::string& jid_to, const std::string& jid_from)
|
||||||
@@ -1303,12 +1311,23 @@ void BiboumiComponent::send_presence_to_contact(const std::string& from, const s
|
|||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
presence["id"] = id;
|
presence["id"] = id;
|
||||||
|
|
||||||
if (type.empty() && from == this->served_hostname) {
|
if (type.empty())
|
||||||
|
{
|
||||||
|
Jid from_jid(from);
|
||||||
|
const Iid from_iid(from_jid.local, {'&', '#', '+', '!'});
|
||||||
|
const std::string fixed_irc_server = Config::get("fixed_irc_server", "");
|
||||||
|
const bool is_server_jid = !from_jid.local.empty() && from_jid.resource.empty() &&
|
||||||
|
((fixed_irc_server.empty() && from_iid.type == Iid::Type::Server) ||
|
||||||
|
(!fixed_irc_server.empty() && from_jid.local == fixed_irc_server));
|
||||||
|
if (from == this->served_hostname ||
|
||||||
|
(from_jid.domain == this->served_hostname && is_server_jid))
|
||||||
|
{
|
||||||
XmlSubNode c(presence, "c");
|
XmlSubNode c(presence, "c");
|
||||||
c["xmlns"] = CAPS_NS;
|
c["xmlns"] = CAPS_NS;
|
||||||
c["hash"] = "sha-1";
|
c["hash"] = "sha-1";
|
||||||
c["node"] = NODE_NAME;
|
c["node"] = NODE_NAME;
|
||||||
c["ver"] = this->get_self_ver();
|
c["ver"] = from == this->served_hostname ? this->get_self_ver() : get_irc_server_ver(from);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this->send_stanza(presence);
|
this->send_stanza(presence);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Send a result IQ with the disco informations regarding IRC server JIDs.
|
* Send a result IQ with the disco informations regarding IRC server JIDs.
|
||||||
*/
|
*/
|
||||||
void send_irc_server_disco_info(const std::string& id, const std::string& jid_to, const std::string& jid_from);
|
void send_irc_server_disco_info(const std::string& id, const std::string& jid_to,
|
||||||
|
const std::string& jid_from, const std::string& node);
|
||||||
/**
|
/**
|
||||||
* Sends the allowed namespaces in MUC message, according to
|
* Sends the allowed namespaces in MUC message, according to
|
||||||
* http://xmpp.org/extensions/xep-0045.html#impl-service-traffic
|
* http://xmpp.org/extensions/xep-0045.html#impl-service-traffic
|
||||||
@@ -93,6 +94,9 @@ private:
|
|||||||
void send_invitation_from_fulljid(const std::string& room_target, const std::string& jid_to, const std::string& from);
|
void send_invitation_from_fulljid(const std::string& room_target, const std::string& jid_to, const std::string& from);
|
||||||
static Stanza get_self_disco_info(const std::string &node);
|
static Stanza get_self_disco_info(const std::string &node);
|
||||||
static std::string get_self_ver() { return Xmpp::hash_disco_sha1(get_self_disco_info("")); };
|
static std::string get_self_ver() { return Xmpp::hash_disco_sha1(get_self_disco_info("")); };
|
||||||
|
static Stanza get_irc_server_disco_info(const std::string& jid_from, const std::string& node);
|
||||||
|
static std::string get_irc_server_ver(const std::string& jid_from)
|
||||||
|
{ return Xmpp::hash_disco_sha1(get_irc_server_disco_info(jid_from, "")); }
|
||||||
#ifdef CURL_FOUND
|
#ifdef CURL_FOUND
|
||||||
std::optional<Stanza> handle_iq_gateway(const Stanza *stanza, const Jid *from, const std::string to, const std::string id);
|
std::optional<Stanza> handle_iq_gateway(const Stanza *stanza, const Jid *from, const std::string to, const std::string id);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
from scenarios import *
|
||||||
|
|
||||||
|
scenario = (
|
||||||
|
# IRC server JIDs advertise caps for their own disco info
|
||||||
|
send_stanza("<iq type='get' id='get6' from='{jid_one}/{resource_one}' to='{irc_server_one}'><query xmlns='http://jabber.org/protocol/disco#info'/></iq>"),
|
||||||
|
expect_stanza("/iq[@from='{irc_server_one}'][@to='{jid_one}/{resource_one}'][@type='result']/disco_info:query/disco_info:identity[@category='gateway'][@type='irc']",
|
||||||
|
"/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/disco#info']",
|
||||||
|
"/iq/disco_info:query/disco_info:feature[@var='http://jabber.org/protocol/caps']"
|
||||||
|
),
|
||||||
|
send_stanza("<presence from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_one}'><x xmlns='http://jabber.org/protocol/muc'/></presence>"),
|
||||||
|
sequences.connection(),
|
||||||
|
scenarios.simple_channel_join.expect_self_join_presence(),
|
||||||
|
send_stanza("<presence from='{jid_one}/{resource_one}' to='{irc_server_one}' type='subscribe'/>"),
|
||||||
|
expect_stanza("/presence[@from='{irc_server_one}'][@to='{jid_one}'][@type='subscribed']"),
|
||||||
|
expect_stanza("/presence[@from='{irc_server_one}'][@to='{jid_one}']/caps:c[@hash='sha-1'][@node][@ver]",
|
||||||
|
after = (
|
||||||
|
save_value("server_ver", extract_attribute("/presence/caps:c[@hash='sha-1'][@node][@ver]", "ver")),
|
||||||
|
save_value("server_node", extract_attribute("/presence/caps:c[@hash='sha-1'][@node][@ver]", "node")),
|
||||||
|
)
|
||||||
|
),
|
||||||
|
send_stanza("<iq type='get' id='get8' from='{jid_one}/{resource_one}' to='{irc_server_one}'><query xmlns='http://jabber.org/protocol/disco#info' node='{server_node}#{server_ver}'/></iq>"),
|
||||||
|
expect_stanza("/iq[@from='{irc_server_one}'][@type='result']/disco_info:query[@node='{server_node}#{server_ver}']"),
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user