From 0ec82c104ded01a44ed36d20e25220fa41887fd0 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Feb 2015 12:18:34 +0100 Subject: Add louloulibs as a submodule --- louloulibs | 1 + 1 file changed, 1 insertion(+) create mode 160000 louloulibs (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs new file mode 160000 index 0000000..b6af145 --- /dev/null +++ b/louloulibs @@ -0,0 +1 @@ +Subproject commit b6af145bfb9561a1bb1ecb940f50163c5ce4dbbb -- cgit v1.2.3 From e6569a1090be063f34624474f0d4578f37a169ae Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Feb 2015 12:40:50 +0100 Subject: Only use include_directory() if the directory path is defined --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index b6af145..d6a3724 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit b6af145bfb9561a1bb1ecb940f50163c5ce4dbbb +Subproject commit d6a3724c6a0127a49a9e7adb1090bb7438c8d0f2 -- cgit v1.2.3 From e4c696861d86b62305ca0ec8136e79f147837b94 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 2 Mar 2015 11:06:40 +0100 Subject: Update louloulibs to last revision --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index d6a3724..5f3a1bb 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit d6a3724c6a0127a49a9e7adb1090bb7438c8d0f2 +Subproject commit 5f3a1bb54df4de5f332282bbdf791bdce07c71c4 -- cgit v1.2.3 From d88ec5fdf10ecb168355bc38dc81d83ff59a0234 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 2 Mar 2015 11:32:18 +0100 Subject: Update to latest louloulibs revision --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index 5f3a1bb..d0b8695 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit 5f3a1bb54df4de5f332282bbdf791bdce07c71c4 +Subproject commit d0b8695ceb13e0c6d72821fe605de36e494afcdf -- cgit v1.2.3 From c243fea660723eba00b65e639b76d0783cb59064 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 4 Mar 2015 05:56:44 +0100 Subject: Update to latest louloulibs revision --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index d0b8695..99757a4 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit d0b8695ceb13e0c6d72821fe605de36e494afcdf +Subproject commit 99757a44b49619ff59cae9e6d983a3b7c20c56bf -- cgit v1.2.3 From ad0465b32051e224f6a234f3ed36494905e59cbf Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 20 Apr 2015 20:33:02 +0200 Subject: Decode incoming JIDs local part according to xep 0106 This let users send message to nicks such as Q@CServe.quakenet.org fix #3047 --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index 99757a4..88d2b13 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit 99757a44b49619ff59cae9e6d983a3b7c20c56bf +Subproject commit 88d2b136e5f133f0d0dc01f59449284f663d53ea -- cgit v1.2.3 From 0d706741c6b3a8bdf6b4f8ca0b1ac00cb27bd8b8 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 20 Apr 2015 20:35:32 +0200 Subject: Update louloulibs submodule to the correct revision --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index 88d2b13..b53ae92 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit 88d2b136e5f133f0d0dc01f59449284f663d53ea +Subproject commit b53ae922f48f1465a7fa61136f65ec39e38a452e -- cgit v1.2.3 From a8225dc54c019788722bda3bda8d55151c1ccdef Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 21 Apr 2015 15:35:10 +0200 Subject: Properly check for connecting or connected status before reconnecting Note, in our context, is_connecting() includes the resolving part as well as the actual connection (if we are using c-ares) fix #3048 --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index b53ae92..6c812cd 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit b53ae922f48f1465a7fa61136f65ec39e38a452e +Subproject commit 6c812cd86e31569db61cac4e30f77e296d207191 -- cgit v1.2.3 From 71fec776c4d7b99b76a44deae6f333d9cffa1496 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 7 May 2015 17:42:37 +0200 Subject: Update to latest louloulibs fix #3042 --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index 6c812cd..eaa4fbb 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit 6c812cd86e31569db61cac4e30f77e296d207191 +Subproject commit eaa4fbba814b56b4fe7ffb62984fddfbb9280291 -- cgit v1.2.3 From fbeb5af364db54c8a82f5ea30b83df441988ea4b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 13 May 2015 20:17:43 +0200 Subject: Update to latest louloulibs revision, and add test for hostname validity fix #2694 --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index eaa4fbb..89398b5 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit eaa4fbba814b56b4fe7ffb62984fddfbb9280291 +Subproject commit 89398b5d886744c3812b65195308cae57eca2b53 -- cgit v1.2.3 From 897b281e67dc82700db9fd9c2dedc5e01e5871ee Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Wed, 27 May 2015 23:44:23 +0200 Subject: Avoid some potential race conditions by blocking the signals we manage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are atomically unblocked in the ppoll/epoll_pwait calls, avoiding any race condition on the check of the “stop” or “reload” booleans. --- louloulibs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs index 89398b5..0f3c118 160000 --- a/louloulibs +++ b/louloulibs @@ -1 +1 @@ -Subproject commit 89398b5d886744c3812b65195308cae57eca2b53 +Subproject commit 0f3c1183e2bf0941ae2bffd3f31577bce4f3001c -- cgit v1.2.3 From e1a7114c8daa10589c830ce972cf461c3540111b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Thu, 28 May 2015 23:42:52 +0200 Subject: louloulibs is directly included, instead of being a submodule Because this is a nightmare to manage --- louloulibs | 1 - louloulibs/xmpp/xmpp_component.cpp | 716 +++++++++++++++++++++++++++++++++++++ 2 files changed, 716 insertions(+), 1 deletion(-) delete mode 160000 louloulibs create mode 100644 louloulibs/xmpp/xmpp_component.cpp (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs b/louloulibs deleted file mode 160000 index 0f3c118..0000000 --- a/louloulibs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0f3c1183e2bf0941ae2bffd3f31577bce4f3001c diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp new file mode 100644 index 0000000..1048f86 --- /dev/null +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -0,0 +1,716 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include +#ifdef SYSTEMD_FOUND +# include +#endif + +using namespace std::string_literals; + +static std::set kickable_errors{ + "gone", + "internal-server-error", + "item-not-found", + "jid-malformed", + "recipient-unavailable", + "redirect", + "remote-server-not-found", + "remote-server-timeout", + "service-unavailable", + "malformed-error" + }; + +XmppComponent::XmppComponent(std::shared_ptr poller, const std::string& hostname, const std::string& secret): + TCPSocketHandler(poller), + ever_auth(false), + first_connection_try(true), + secret(secret), + authenticated(false), + doc_open(false), + served_hostname(hostname), + stanza_handlers{}, + adhoc_commands_handler(this) +{ + this->parser.add_stream_open_callback(std::bind(&XmppComponent::on_remote_stream_open, this, + std::placeholders::_1)); + this->parser.add_stanza_callback(std::bind(&XmppComponent::on_stanza, this, + std::placeholders::_1)); + this->parser.add_stream_close_callback(std::bind(&XmppComponent::on_remote_stream_close, this, + std::placeholders::_1)); + this->stanza_handlers.emplace("handshake", + std::bind(&XmppComponent::handle_handshake, this,std::placeholders::_1)); + this->stanza_handlers.emplace("error", + std::bind(&XmppComponent::handle_error, this,std::placeholders::_1)); +} + +void XmppComponent::start() +{ + this->connect("127.0.0.1", Config::get("port", "5347"), false); +} + +bool XmppComponent::is_document_open() const +{ + return this->doc_open; +} + +void XmppComponent::send_stanza(const Stanza& stanza) +{ + std::string str = stanza.to_string(); + log_debug("XMPP SENDING: " << str); + this->send_data(std::move(str)); +} + +void XmppComponent::on_connection_failed(const std::string& reason) +{ + this->first_connection_try = false; + log_error("Failed to connect to the XMPP server: " << reason); +#ifdef SYSTEMD_FOUND + sd_notifyf(0, "STATUS=Failed to connect to the XMPP server: %s", reason.data()); +#endif +} + +void XmppComponent::on_connected() +{ + log_info("connected to XMPP server"); + this->first_connection_try = true; + XmlNode node("", nullptr); + node.set_name("stream:stream"); + node["xmlns"] = COMPONENT_NS; + node["xmlns:stream"] = STREAM_NS; + node["to"] = this->served_hostname; + this->send_stanza(node); + this->doc_open = true; + // We may have some pending data to send: this happens when we try to send + // some data before we are actually connected. We send that data right now, if any + this->send_pending_data(); +} + +void XmppComponent::on_connection_close(const std::string& error) +{ + if (error.empty()) + { + log_info("XMPP server closed connection"); + } + else + { + log_info("XMPP server closed connection: " << error); + } +} + +void XmppComponent::parse_in_buffer(const size_t size) +{ + if (!this->in_buf.empty()) + { // This may happen if the parser could not allocate enough space for + // us. We try to feed it the data that was read into our in_buf + // instead. If this fails again we are in trouble. + this->parser.feed(this->in_buf.data(), this->in_buf.size(), false); + this->in_buf.clear(); + } + else + { // Just tell the parser to parse the data that was placed into the + // buffer it provided to us with GetBuffer + this->parser.parse(size, false); + } +} + +void XmppComponent::on_remote_stream_open(const XmlNode& node) +{ + log_debug("XMPP DOCUMENT OPEN: " << node.to_string()); + this->stream_id = node.get_tag("id"); + if (this->stream_id.empty()) + { + log_error("Error: no attribute 'id' found"); + this->send_stream_error("bad-format", "missing 'id' attribute"); + this->close_document(); + return ; + } + + // Try to authenticate + char digest[HASH_LENGTH * 2 + 1]; + sha1nfo sha1; + sha1_init(&sha1); + sha1_write(&sha1, this->stream_id.data(), this->stream_id.size()); + sha1_write(&sha1, this->secret.data(), this->secret.size()); + const uint8_t* result = sha1_result(&sha1); + for (int i=0; i < HASH_LENGTH; i++) + sprintf(digest + (i*2), "%02x", result[i]); + digest[HASH_LENGTH * 2] = '\0'; + + Stanza handshake(COMPONENT_NS":handshake"); + handshake.set_inner(digest); + handshake.close(); + this->send_stanza(handshake); +} + +void XmppComponent::on_remote_stream_close(const XmlNode& node) +{ + log_debug("XMPP DOCUMENT CLOSE " << node.to_string()); + this->doc_open = false; +} + +void XmppComponent::reset() +{ + this->parser.reset(); +} + +void XmppComponent::on_stanza(const Stanza& stanza) +{ + log_debug("XMPP RECEIVING: " << stanza.to_string()); + std::function handler; + try + { + handler = this->stanza_handlers.at(stanza.get_name()); + } + catch (const std::out_of_range& exception) + { + log_warning("No handler for stanza of type " << stanza.get_name()); + return; + } + handler(stanza); +} + +void XmppComponent::send_stream_error(const std::string& name, const std::string& explanation) +{ + XmlNode node("stream:error", nullptr); + XmlNode error(name, nullptr); + error["xmlns"] = STREAM_NS; + if (!explanation.empty()) + error.set_inner(explanation); + error.close(); + node.add_child(std::move(error)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_stanza_error(const std::string& kind, const std::string& to, const std::string& from, + const std::string& id, const std::string& error_type, + const std::string& defined_condition, const std::string& text, + const bool fulljid) +{ + Stanza node(kind); + if (!to.empty()) + node["to"] = to; + if (!from.empty()) + { + if (fulljid) + node["from"] = from; + else + node["from"] = from + "@" + this->served_hostname; + } + if (!id.empty()) + node["id"] = id; + node["type"] = "error"; + XmlNode error("error"); + error["type"] = error_type; + XmlNode inner_error(defined_condition); + inner_error["xmlns"] = STANZA_NS; + inner_error.close(); + error.add_child(std::move(inner_error)); + if (!text.empty()) + { + XmlNode text_node("text"); + text_node["xmlns"] = STANZA_NS; + text_node.set_inner(text); + text_node.close(); + error.add_child(std::move(text_node)); + } + error.close(); + node.add_child(std::move(error)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::close_document() +{ + log_debug("XMPP SENDING: "); + this->send_data(""); + this->doc_open = false; +} + +void XmppComponent::handle_handshake(const Stanza& stanza) +{ + (void)stanza; + this->authenticated = true; + this->ever_auth = true; + log_info("Authenticated with the XMPP server"); +#ifdef SYSTEMD_FOUND + sd_notify(0, "READY=1"); + // Install an event that sends a keepalive to systemd. If biboumi crashes + // or hangs for too long, systemd will restart it. + uint64_t usec; + if (sd_watchdog_enabled(0, &usec) > 0) + { + TimedEventsManager::instance().add_event(TimedEvent( + std::chrono::duration_cast(std::chrono::microseconds(usec / 2)), + []() { sd_notify(0, "WATCHDOG=1"); })); + } +#endif + this->after_handshake(); +} + +void XmppComponent::handle_error(const Stanza& stanza) +{ + XmlNode* text = stanza.get_child("text", STREAMS_NS); + std::string error_message("Unspecified error"); + if (text) + error_message = text->get_inner(); + log_error("Stream error received from the XMPP server: " << error_message); +#ifdef SYSTEMD_FOUND + if (!this->ever_auth) + sd_notifyf(0, "STATUS=Failed to authenticate to the XMPP server: %s", error_message.data()); +#endif + +} + +void* XmppComponent::get_receive_buffer(const size_t size) const +{ + return this->parser.get_buffer(size); +} + +void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to, const std::string& type, const bool fulljid) +{ + XmlNode node("message"); + node["to"] = to; + if (fulljid) + node["from"] = from; + else + node["from"] = from + "@" + this->served_hostname; + if (!type.empty()) + node["type"] = type; + XmlNode body_node("body"); + body_node.set_inner(std::get<0>(body)); + body_node.close(); + node.add_child(std::move(body_node)); + if (std::get<1>(body)) + { + XmlNode html("html"); + html["xmlns"] = XHTMLIM_NS; + // Pass the ownership of the pointer to this xmlnode + html.add_child(std::get<1>(body).release()); + html.close(); + node.add_child(std::move(html)); + } + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_user_join(const std::string& from, + const std::string& nick, + const std::string& realjid, + const std::string& affiliation, + const std::string& role, + const std::string& to, + const bool self) +{ + XmlNode node("presence"); + node["to"] = to; + node["from"] = from + "@" + this->served_hostname + "/" + nick; + + XmlNode x("x"); + x["xmlns"] = MUC_USER_NS; + + XmlNode item("item"); + if (!affiliation.empty()) + item["affiliation"] = affiliation; + if (!role.empty()) + item["role"] = role; + if (!realjid.empty()) + { + const std::string preped_jid = jidprep(realjid); + if (!preped_jid.empty()) + item["jid"] = preped_jid; + } + item.close(); + x.add_child(std::move(item)); + + if (self) + { + XmlNode status("status"); + status["code"] = "110"; + status.close(); + x.add_child(std::move(status)); + } + x.close(); + node.add_child(std::move(x)); + node.close(); + this->send_stanza(node); +} + +void XmppComponent::send_invalid_room_error(const std::string& muc_name, + const std::string& nick, + const std::string& to) +{ + Stanza presence("presence"); + if (!muc_name.empty()) + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + else + presence["from"] = this->served_hostname; + presence["to"] = to; + presence["type"] = "error"; + XmlNode x("x"); + x["xmlns"] = MUC_NS; + x.close(); + presence.add_child(std::move(x)); + XmlNode error("error"); + error["by"] = muc_name + "@" + this->served_hostname; + error["type"] = "cancel"; + XmlNode item_not_found("item-not-found"); + item_not_found["xmlns"] = STANZA_NS; + item_not_found.close(); + error.add_child(std::move(item_not_found)); + XmlNode text("text"); + text["xmlns"] = STANZA_NS; + text["xml:lang"] = "en"; + text.set_inner(muc_name + + " is not a valid IRC channel name. A correct room jid is of the form: #%@" + + this->served_hostname); + text.close(); + error.add_child(std::move(text)); + error.close(); + presence.add_child(std::move(error)); + presence.close(); + this->send_stanza(presence); +} + +void XmppComponent::send_invalid_user_error(const std::string& user_name, const std::string& to) +{ + Stanza message("message"); + message["from"] = user_name + "@" + this->served_hostname; + message["to"] = to; + message["type"] = "error"; + XmlNode x("x"); + x["xmlns"] = MUC_NS; + x.close(); + message.add_child(std::move(x)); + XmlNode error("error"); + error["type"] = "cancel"; + XmlNode item_not_found("item-not-found"); + item_not_found["xmlns"] = STANZA_NS; + item_not_found.close(); + error.add_child(std::move(item_not_found)); + XmlNode text("text"); + text["xmlns"] = STANZA_NS; + text["xml:lang"] = "en"; + text.set_inner(user_name + + " is not a valid IRC user name. A correct user jid is of the form: !@" + + this->served_hostname); + text.close(); + error.add_child(std::move(text)); + error.close(); + message.add_child(std::move(error)); + message.close(); + this->send_stanza(message); +} + +void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to) +{ + XmlNode message("message"); + message["to"] = to; + message["from"] = from + "@" + this->served_hostname; + message["type"] = "groupchat"; + XmlNode subject("subject"); + subject.set_inner(std::get<0>(topic)); + subject.close(); + message.add_child(std::move(subject)); + message.close(); + this->send_stanza(message); +} + +void XmppComponent::send_muc_message(const std::string& muc_name, const std::string& nick, Xmpp::body&& xmpp_body, const std::string& jid_to) +{ + Stanza message("message"); + message["to"] = jid_to; + if (!nick.empty()) + message["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + else // Message from the room itself + message["from"] = muc_name + "@" + this->served_hostname; + message["type"] = "groupchat"; + XmlNode body("body"); + body.set_inner(std::get<0>(xmpp_body)); + body.close(); + message.add_child(std::move(body)); + if (std::get<1>(xmpp_body)) + { + XmlNode html("html"); + html["xmlns"] = XHTMLIM_NS; + // Pass the ownership of the pointer to this xmlnode + html.add_child(std::get<1>(xmpp_body).release()); + html.close(); + message.add_child(std::move(html)); + } + message.close(); + this->send_stanza(message); +} + +void XmppComponent::send_muc_leave(const std::string& muc_name, std::string&& nick, Xmpp::body&& message, const std::string& jid_to, const bool self) +{ + Stanza presence("presence"); + presence["to"] = jid_to; + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nick; + presence["type"] = "unavailable"; + const std::string message_str = std::get<0>(message); + XmlNode x("x"); + x["xmlns"] = MUC_USER_NS; + if (self) + { + XmlNode status("status"); + status["code"] = "110"; + status.close(); + x.add_child(std::move(status)); + } + x.close(); + presence.add_child(std::move(x)); + if (!message_str.empty()) + { + XmlNode status("status"); + status.set_inner(message_str); + status.close(); + presence.add_child(std::move(status)); + } + presence.close(); + this->send_stanza(presence); +} + +void XmppComponent::send_nick_change(const std::string& muc_name, + const std::string& old_nick, + const std::string& new_nick, + const std::string& affiliation, + const std::string& role, + const std::string& jid_to, + const bool self) +{ + Stanza presence("presence"); + presence["to"] = jid_to; + presence["from"] = muc_name + "@" + this->served_hostname + "/" + old_nick; + presence["type"] = "unavailable"; + XmlNode x("x"); + x["xmlns"] = MUC_USER_NS; + XmlNode item("item"); + item["nick"] = new_nick; + item.close(); + x.add_child(std::move(item)); + XmlNode status("status"); + status["code"] = "303"; + status.close(); + x.add_child(std::move(status)); + if (self) + { + XmlNode status2("status"); + status2["code"] = "110"; + status2.close(); + x.add_child(std::move(status2)); + } + x.close(); + presence.add_child(std::move(x)); + presence.close(); + this->send_stanza(presence); + + this->send_user_join(muc_name, new_nick, "", affiliation, role, jid_to, self); +} + +void XmppComponent::kick_user(const std::string& muc_name, + const std::string& target, + const std::string& txt, + const std::string& author, + const std::string& jid_to) +{ + Stanza presence("presence"); + presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; + presence["to"] = jid_to; + presence["type"] = "unavailable"; + XmlNode x("x"); + x["xmlns"] = MUC_USER_NS; + XmlNode item("item"); + item["affiliation"] = "none"; + item["role"] = "none"; + XmlNode actor("actor"); + actor["nick"] = author; + actor["jid"] = author; // backward compatibility with old clients + actor.close(); + item.add_child(std::move(actor)); + XmlNode reason("reason"); + reason.set_inner(txt); + reason.close(); + item.add_child(std::move(reason)); + item.close(); + x.add_child(std::move(item)); + XmlNode status("status"); + status["code"] = "307"; + status.close(); + x.add_child(std::move(status)); + x.close(); + presence.add_child(std::move(x)); + presence.close(); + this->send_stanza(presence); +} + +void XmppComponent::send_presence_error(const std::string& muc_name, + const std::string& nickname, + const std::string& jid_to, + const std::string& type, + const std::string& condition, + const std::string& error_code, + const std::string& /* text */) +{ + Stanza presence("presence"); + presence["from"] = muc_name + "@" + this->served_hostname + "/" + nickname; + presence["to"] = jid_to; + presence["type"] = "error"; + XmlNode x("x"); + x["xmlns"] = MUC_NS; + x.close(); + presence.add_child(std::move(x)); + XmlNode error("error"); + error["by"] = muc_name + "@" + this->served_hostname; + error["type"] = type; + if (!error_code.empty()) + error["code"] = error_code; + XmlNode subnode(condition); + subnode["xmlns"] = STANZA_NS; + subnode.close(); + error.add_child(std::move(subnode)); + error.close(); + presence.add_child(std::move(error)); + presence.close(); + this->send_stanza(presence); +} + +void XmppComponent::send_affiliation_role_change(const std::string& muc_name, + const std::string& target, + const std::string& affiliation, + const std::string& role, + const std::string& jid_to) +{ + Stanza presence("presence"); + presence["from"] = muc_name + "@" + this->served_hostname + "/" + target; + presence["to"] = jid_to; + XmlNode x("x"); + x["xmlns"] = MUC_USER_NS; + XmlNode item("item"); + item["affiliation"] = affiliation; + item["role"] = role; + item.close(); + x.add_child(std::move(item)); + x.close(); + presence.add_child(std::move(x)); + presence.close(); + this->send_stanza(presence); +} + +void XmppComponent::send_version(const std::string& id, const std::string& jid_to, const std::string& jid_from, + const std::string& version) +{ + Stanza iq("iq"); + iq["type"] = "result"; + iq["id"] = id; + iq["to"] = jid_to; + iq["from"] = jid_from; + XmlNode query("query"); + query["xmlns"] = VERSION_NS; + if (version.empty()) + { + XmlNode name("name"); + name.set_inner("biboumi"); + name.close(); + query.add_child(std::move(name)); + XmlNode version("version"); + version.set_inner(SOFTWARE_VERSION); + version.close(); + query.add_child(std::move(version)); + XmlNode os("os"); + os.set_inner(SYSTEM_NAME); + os.close(); + query.add_child(std::move(os)); + } + else + { + XmlNode name("name"); + name.set_inner(version); + name.close(); + query.add_child(std::move(name)); + } + query.close(); + iq.add_child(std::move(query)); + iq.close(); + this->send_stanza(iq); +} + +void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid) +{ + Stanza iq("iq"); + iq["type"] = "result"; + iq["id"] = id; + iq["to"] = requester_jid; + iq["from"] = this->served_hostname; + XmlNode query("query"); + query["xmlns"] = DISCO_ITEMS_NS; + query["node"] = ADHOC_NS; + for (const auto& kv: this->adhoc_commands_handler.get_commands()) + { + XmlNode item("item"); + item["jid"] = this->served_hostname; + item["node"] = kv.first; + item["name"] = kv.second.name; + item.close(); + query.add_child(std::move(item)); + } + query.close(); + iq.add_child(std::move(query)); + iq.close(); + this->send_stanza(iq); +} + +void XmppComponent::send_iq_version_request(const std::string& from, + const std::string& jid_to) +{ + Stanza iq("iq"); + iq["type"] = "get"; + iq["id"] = "version_"s + XmppComponent::next_id(); + iq["from"] = from + "@" + this->served_hostname; + iq["to"] = jid_to; + XmlNode query("query"); + query["xmlns"] = VERSION_NS; + query.close(); + iq.add_child(std::move(query)); + iq.close(); + this->send_stanza(iq); +} + +void XmppComponent::send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from_local_part) +{ + Stanza iq("iq"); + if (!from_local_part.empty()) + iq["from"] = from_local_part + "@" + this->served_hostname; + else + iq["from"] = this->served_hostname; + iq["to"] = to_jid; + iq["id"] = id; + iq["type"] = "result"; + iq.close(); + this->send_stanza(iq); +} + +std::string XmppComponent::next_id() +{ + char uuid_str[37]; + uuid_t uuid; + uuid_generate(uuid); + uuid_unparse(uuid, uuid_str); + return uuid_str; +} -- cgit v1.2.3 From 7f7c429ae4c49e856a43816138991135ffb7f840 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 9 Jun 2015 14:52:46 +0200 Subject: Do not send the admin-only adhoc commands to non-admin users They were not able to execute them anyway, so this was just a little usability issue. --- louloulibs/xmpp/xmpp_component.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 1048f86..8e89208 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -651,7 +651,7 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t this->send_stanza(iq); } -void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid) +void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const bool with_admin_only) { Stanza iq("iq"); iq["type"] = "result"; @@ -663,6 +663,8 @@ void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::s query["node"] = ADHOC_NS; for (const auto& kv: this->adhoc_commands_handler.get_commands()) { + if (kv.second.is_admin_only() && !with_admin_only) + continue; XmlNode item("item"); item["jid"] = this->served_hostname; item["node"] = kv.first; -- cgit v1.2.3 From e8f22efe34415db0e1e5cb94635b089b18efe055 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 1 Sep 2015 04:42:12 +0200 Subject: XmlNodes are now always closed Remove the close() method and closed attribute. Remove all the calls to close(). (Save one bool per XmlNode, yay, and save a few ifs and some useless function calls. At best it should be unnoticeably faster and lighter and save a few keystrokes in the future) --- louloulibs/xmpp/xmpp_component.cpp | 78 +++----------------------------------- 1 file changed, 6 insertions(+), 72 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 8e89208..19111ba 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -89,12 +89,9 @@ void XmppComponent::on_connected() { log_info("connected to XMPP server"); this->first_connection_try = true; - XmlNode node("", nullptr); - node.set_name("stream:stream"); - node["xmlns"] = COMPONENT_NS; - node["xmlns:stream"] = STREAM_NS; - node["to"] = this->served_hostname; - this->send_stanza(node); + this->send_data(""); this->doc_open = true; // We may have some pending data to send: this happens when we try to send // some data before we are actually connected. We send that data right now, if any @@ -152,10 +149,9 @@ void XmppComponent::on_remote_stream_open(const XmlNode& node) sprintf(digest + (i*2), "%02x", result[i]); digest[HASH_LENGTH * 2] = '\0'; - Stanza handshake(COMPONENT_NS":handshake"); - handshake.set_inner(digest); - handshake.close(); - this->send_stanza(handshake); + this->send_data(""); + this->send_data(digest); + this->send_data(""); } void XmppComponent::on_remote_stream_close(const XmlNode& node) @@ -192,9 +188,7 @@ void XmppComponent::send_stream_error(const std::string& name, const std::string error["xmlns"] = STREAM_NS; if (!explanation.empty()) error.set_inner(explanation); - error.close(); node.add_child(std::move(error)); - node.close(); this->send_stanza(node); } @@ -220,19 +214,15 @@ void XmppComponent::send_stanza_error(const std::string& kind, const std::string error["type"] = error_type; XmlNode inner_error(defined_condition); inner_error["xmlns"] = STANZA_NS; - inner_error.close(); error.add_child(std::move(inner_error)); if (!text.empty()) { XmlNode text_node("text"); text_node["xmlns"] = STANZA_NS; text_node.set_inner(text); - text_node.close(); error.add_child(std::move(text_node)); } - error.close(); node.add_child(std::move(error)); - node.close(); this->send_stanza(node); } @@ -295,7 +285,6 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con node["type"] = type; XmlNode body_node("body"); body_node.set_inner(std::get<0>(body)); - body_node.close(); node.add_child(std::move(body_node)); if (std::get<1>(body)) { @@ -303,10 +292,8 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con html["xmlns"] = XHTMLIM_NS; // Pass the ownership of the pointer to this xmlnode html.add_child(std::get<1>(body).release()); - html.close(); node.add_child(std::move(html)); } - node.close(); this->send_stanza(node); } @@ -336,19 +323,15 @@ void XmppComponent::send_user_join(const std::string& from, if (!preped_jid.empty()) item["jid"] = preped_jid; } - item.close(); x.add_child(std::move(item)); if (self) { XmlNode status("status"); status["code"] = "110"; - status.close(); x.add_child(std::move(status)); } - x.close(); node.add_child(std::move(x)); - node.close(); this->send_stanza(node); } @@ -365,14 +348,12 @@ void XmppComponent::send_invalid_room_error(const std::string& muc_name, presence["type"] = "error"; XmlNode x("x"); x["xmlns"] = MUC_NS; - x.close(); presence.add_child(std::move(x)); XmlNode error("error"); error["by"] = muc_name + "@" + this->served_hostname; error["type"] = "cancel"; XmlNode item_not_found("item-not-found"); item_not_found["xmlns"] = STANZA_NS; - item_not_found.close(); error.add_child(std::move(item_not_found)); XmlNode text("text"); text["xmlns"] = STANZA_NS; @@ -380,11 +361,8 @@ void XmppComponent::send_invalid_room_error(const std::string& muc_name, text.set_inner(muc_name + " is not a valid IRC channel name. A correct room jid is of the form: #%@" + this->served_hostname); - text.close(); error.add_child(std::move(text)); - error.close(); presence.add_child(std::move(error)); - presence.close(); this->send_stanza(presence); } @@ -396,13 +374,11 @@ void XmppComponent::send_invalid_user_error(const std::string& user_name, const message["type"] = "error"; XmlNode x("x"); x["xmlns"] = MUC_NS; - x.close(); message.add_child(std::move(x)); XmlNode error("error"); error["type"] = "cancel"; XmlNode item_not_found("item-not-found"); item_not_found["xmlns"] = STANZA_NS; - item_not_found.close(); error.add_child(std::move(item_not_found)); XmlNode text("text"); text["xmlns"] = STANZA_NS; @@ -410,11 +386,8 @@ void XmppComponent::send_invalid_user_error(const std::string& user_name, const text.set_inner(user_name + " is not a valid IRC user name. A correct user jid is of the form: !@" + this->served_hostname); - text.close(); error.add_child(std::move(text)); - error.close(); message.add_child(std::move(error)); - message.close(); this->send_stanza(message); } @@ -426,9 +399,7 @@ void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, cons message["type"] = "groupchat"; XmlNode subject("subject"); subject.set_inner(std::get<0>(topic)); - subject.close(); message.add_child(std::move(subject)); - message.close(); this->send_stanza(message); } @@ -443,7 +414,6 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str message["type"] = "groupchat"; XmlNode body("body"); body.set_inner(std::get<0>(xmpp_body)); - body.close(); message.add_child(std::move(body)); if (std::get<1>(xmpp_body)) { @@ -451,10 +421,8 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str html["xmlns"] = XHTMLIM_NS; // Pass the ownership of the pointer to this xmlnode html.add_child(std::get<1>(xmpp_body).release()); - html.close(); message.add_child(std::move(html)); } - message.close(); this->send_stanza(message); } @@ -471,19 +439,15 @@ void XmppComponent::send_muc_leave(const std::string& muc_name, std::string&& ni { XmlNode status("status"); status["code"] = "110"; - status.close(); x.add_child(std::move(status)); } - x.close(); presence.add_child(std::move(x)); if (!message_str.empty()) { XmlNode status("status"); status.set_inner(message_str); - status.close(); presence.add_child(std::move(status)); } - presence.close(); this->send_stanza(presence); } @@ -503,22 +467,17 @@ void XmppComponent::send_nick_change(const std::string& muc_name, x["xmlns"] = MUC_USER_NS; XmlNode item("item"); item["nick"] = new_nick; - item.close(); x.add_child(std::move(item)); XmlNode status("status"); status["code"] = "303"; - status.close(); x.add_child(std::move(status)); if (self) { XmlNode status2("status"); status2["code"] = "110"; - status2.close(); x.add_child(std::move(status2)); } - x.close(); presence.add_child(std::move(x)); - presence.close(); this->send_stanza(presence); this->send_user_join(muc_name, new_nick, "", affiliation, role, jid_to, self); @@ -542,21 +501,15 @@ void XmppComponent::kick_user(const std::string& muc_name, XmlNode actor("actor"); actor["nick"] = author; actor["jid"] = author; // backward compatibility with old clients - actor.close(); item.add_child(std::move(actor)); XmlNode reason("reason"); reason.set_inner(txt); - reason.close(); item.add_child(std::move(reason)); - item.close(); x.add_child(std::move(item)); XmlNode status("status"); status["code"] = "307"; - status.close(); x.add_child(std::move(status)); - x.close(); presence.add_child(std::move(x)); - presence.close(); this->send_stanza(presence); } @@ -574,7 +527,6 @@ void XmppComponent::send_presence_error(const std::string& muc_name, presence["type"] = "error"; XmlNode x("x"); x["xmlns"] = MUC_NS; - x.close(); presence.add_child(std::move(x)); XmlNode error("error"); error["by"] = muc_name + "@" + this->served_hostname; @@ -583,11 +535,8 @@ void XmppComponent::send_presence_error(const std::string& muc_name, error["code"] = error_code; XmlNode subnode(condition); subnode["xmlns"] = STANZA_NS; - subnode.close(); error.add_child(std::move(subnode)); - error.close(); presence.add_child(std::move(error)); - presence.close(); this->send_stanza(presence); } @@ -605,11 +554,8 @@ void XmppComponent::send_affiliation_role_change(const std::string& muc_name, XmlNode item("item"); item["affiliation"] = affiliation; item["role"] = role; - item.close(); x.add_child(std::move(item)); - x.close(); presence.add_child(std::move(x)); - presence.close(); this->send_stanza(presence); } @@ -627,27 +573,21 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t { XmlNode name("name"); name.set_inner("biboumi"); - name.close(); query.add_child(std::move(name)); XmlNode version("version"); version.set_inner(SOFTWARE_VERSION); - version.close(); query.add_child(std::move(version)); XmlNode os("os"); os.set_inner(SYSTEM_NAME); - os.close(); query.add_child(std::move(os)); } else { XmlNode name("name"); name.set_inner(version); - name.close(); query.add_child(std::move(name)); } - query.close(); iq.add_child(std::move(query)); - iq.close(); this->send_stanza(iq); } @@ -669,12 +609,9 @@ void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::s item["jid"] = this->served_hostname; item["node"] = kv.first; item["name"] = kv.second.name; - item.close(); query.add_child(std::move(item)); } - query.close(); iq.add_child(std::move(query)); - iq.close(); this->send_stanza(iq); } @@ -688,9 +625,7 @@ void XmppComponent::send_iq_version_request(const std::string& from, iq["to"] = jid_to; XmlNode query("query"); query["xmlns"] = VERSION_NS; - query.close(); iq.add_child(std::move(query)); - iq.close(); this->send_stanza(iq); } @@ -704,7 +639,6 @@ void XmppComponent::send_iq_result(const std::string& id, const std::string& to_ iq["to"] = to_jid; iq["id"] = id; iq["type"] = "result"; - iq.close(); this->send_stanza(iq); } -- cgit v1.2.3 From f3b3d937ae274d0eec4a737d11ba19a7f4ceef03 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 1 Sep 2015 14:47:57 +0200 Subject: =?UTF-8?q?Use=20unique=5Fptr=20to=20store=20the=20XmlNode?= =?UTF-8?q?=E2=80=99s=20children?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also fix some constness things --- louloulibs/xmpp/xmpp_component.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 19111ba..8cd722d 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -256,7 +256,7 @@ void XmppComponent::handle_handshake(const Stanza& stanza) void XmppComponent::handle_error(const Stanza& stanza) { - XmlNode* text = stanza.get_child("text", STREAMS_NS); + const XmlNode* text = stanza.get_child("text", STREAMS_NS); std::string error_message("Unspecified error"); if (text) error_message = text->get_inner(); @@ -291,7 +291,7 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con XmlNode html("html"); html["xmlns"] = XHTMLIM_NS; // Pass the ownership of the pointer to this xmlnode - html.add_child(std::get<1>(body).release()); + html.add_child(std::move(std::get<1>(body))); node.add_child(std::move(html)); } this->send_stanza(node); @@ -420,7 +420,7 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str XmlNode html("html"); html["xmlns"] = XHTMLIM_NS; // Pass the ownership of the pointer to this xmlnode - html.add_child(std::get<1>(xmpp_body).release()); + html.add_child(std::move(std::get<1>(xmpp_body))); message.add_child(std::move(html)); } this->send_stanza(message); -- cgit v1.2.3 From c3309d0acfedaed867ae1bc14cd7a65fe5be1419 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Tue, 1 Sep 2015 20:01:44 +0200 Subject: Trivial cleanup --- louloulibs/xmpp/xmpp_component.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 8cd722d..2214ecf 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -101,13 +101,9 @@ void XmppComponent::on_connected() void XmppComponent::on_connection_close(const std::string& error) { if (error.empty()) - { - log_info("XMPP server closed connection"); - } + log_info("XMPP server closed connection"); else - { - log_info("XMPP server closed connection: " << error); - } + log_info("XMPP server closed connection: " << error); } void XmppComponent::parse_in_buffer(const size_t size) -- cgit v1.2.3 From 45e8fe56a688ec03201cdfc3dfea6ae186af682d Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 18 Sep 2015 21:55:21 +0200 Subject: Add an AdhocCommandsHandler to store commands specific to IRC servers --- louloulibs/xmpp/xmpp_component.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 2214ecf..3017c0b 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -587,22 +587,22 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t this->send_stanza(iq); } -void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const bool with_admin_only) +void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const std::string& from_jid, const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler) { Stanza iq("iq"); iq["type"] = "result"; iq["id"] = id; iq["to"] = requester_jid; - iq["from"] = this->served_hostname; + iq["from"] = from_jid; XmlNode query("query"); query["xmlns"] = DISCO_ITEMS_NS; query["node"] = ADHOC_NS; - for (const auto& kv: this->adhoc_commands_handler.get_commands()) + for (const auto& kv: adhoc_handler.get_commands()) { if (kv.second.is_admin_only() && !with_admin_only) continue; XmlNode item("item"); - item["jid"] = this->served_hostname; + item["jid"] = from_jid; item["node"] = kv.first; item["name"] = kv.second.name; query.add_child(std::move(item)); -- cgit v1.2.3 From 8ddbe8d3e6a5a5001537379aa4f1a418c6cb6d23 Mon Sep 17 00:00:00 2001 From: Stuart Mumford Date: Fri, 11 Dec 2015 15:19:40 +0000 Subject: Make the XMPP server address configurable. fix #3145 --- louloulibs/xmpp/xmpp_component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 3017c0b..ce9552f 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -61,7 +61,7 @@ XmppComponent::XmppComponent(std::shared_ptr poller, const std::string& void XmppComponent::start() { - this->connect("127.0.0.1", Config::get("port", "5347"), false); + this->connect(Config::get("xmpp_server_ip", "127.0.0.1"), Config::get("port", "5347"), false); } bool XmppComponent::is_document_open() const -- cgit v1.2.3 From 9714d02018904b0c207a3f4d7de0be1a6a22774b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 21 Dec 2015 21:15:03 +0100 Subject: Also store a reference instead of a pointer, in AdhocCommandsHandler --- louloulibs/xmpp/xmpp_component.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index ce9552f..a82892d 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -45,7 +45,7 @@ XmppComponent::XmppComponent(std::shared_ptr poller, const std::string& doc_open(false), served_hostname(hostname), stanza_handlers{}, - adhoc_commands_handler(this) + adhoc_commands_handler(*this) { this->parser.add_stream_open_callback(std::bind(&XmppComponent::on_remote_stream_open, this, std::placeholders::_1)); -- cgit v1.2.3 From 37fd6ff18a6e51ee5c4127b7e1269e3944d71b44 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 22 Feb 2016 17:01:10 +0100 Subject: log the handshake + stream opening/close in a more consistent way --- louloulibs/xmpp/xmpp_component.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index a82892d..c5906e5 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -89,9 +89,10 @@ void XmppComponent::on_connected() { log_info("connected to XMPP server"); this->first_connection_try = true; - this->send_data(""); + auto data = ""; + log_debug("XMPP SENDING: " << data); + this->send_data(std::move(data)); this->doc_open = true; // We may have some pending data to send: this happens when we try to send // some data before we are actually connected. We send that data right now, if any @@ -124,7 +125,7 @@ void XmppComponent::parse_in_buffer(const size_t size) void XmppComponent::on_remote_stream_open(const XmlNode& node) { - log_debug("XMPP DOCUMENT OPEN: " << node.to_string()); + log_debug("XMPP RECEIVING: " << node.to_string()); this->stream_id = node.get_tag("id"); if (this->stream_id.empty()) { @@ -145,14 +146,14 @@ void XmppComponent::on_remote_stream_open(const XmlNode& node) sprintf(digest + (i*2), "%02x", result[i]); digest[HASH_LENGTH * 2] = '\0'; - this->send_data(""); - this->send_data(digest); - this->send_data(""); + auto data = ""s + digest + ""; + log_debug("XMPP SENDING: " << data); + this->send_data(std::move(data)); } void XmppComponent::on_remote_stream_close(const XmlNode& node) { - log_debug("XMPP DOCUMENT CLOSE " << node.to_string()); + log_debug("XMPP RECEIVING: " << node.to_string()); this->doc_open = false; } -- cgit v1.2.3 From 04d28f968b227067e77e365d317fc251d3c965f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Tue, 19 Apr 2016 02:43:26 +0200 Subject: Forward the topic authors, handle the author from 333 messages fix #2 --- louloulibs/xmpp/xmpp_component.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index c5906e5..8a0ca52 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -388,11 +388,14 @@ void XmppComponent::send_invalid_user_error(const std::string& user_name, const this->send_stanza(message); } -void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to) +void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, const std::string& to, const std::string& who) { XmlNode message("message"); message["to"] = to; - message["from"] = from + "@" + this->served_hostname; + if (who.empty()) + message["from"] = from + "@" + this->served_hostname; + else + message["from"] = from + "@" + this->served_hostname + "/" + who; message["type"] = "groupchat"; XmlNode subject("subject"); subject.set_inner(std::get<0>(topic)); -- cgit v1.2.3 From 1e56c59e8241dbfc6a2526c371cc2e894f9d0f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 25 Apr 2016 11:29:52 +0200 Subject: Include the Configure ad-hoc command on biboumi's JID for fixed_irc_server MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because a jid like “freenode.example.org” is both the JID for the configured IRC server, and biboumi’s JID. fix #3175 --- louloulibs/xmpp/xmpp_component.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 8a0ca52..b92d9a3 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -591,7 +591,9 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t this->send_stanza(iq); } -void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, const std::string& from_jid, const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler) +void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::string& requester_jid, + const std::string& from_jid, + const bool with_admin_only, const AdhocCommandsHandler& adhoc_handler) { Stanza iq("iq"); iq["type"] = "result"; -- cgit v1.2.3 From 5a2e61161792cf51209f240e40e28036195f35be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Mon, 13 Jun 2016 19:59:17 +0200 Subject: Show off, with some variadic templates, for the logger module --- louloulibs/xmpp/xmpp_component.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index b92d9a3..1be7a06 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -72,14 +72,14 @@ bool XmppComponent::is_document_open() const void XmppComponent::send_stanza(const Stanza& stanza) { std::string str = stanza.to_string(); - log_debug("XMPP SENDING: " << str); + log_debug("XMPP SENDING: ", str); this->send_data(std::move(str)); } void XmppComponent::on_connection_failed(const std::string& reason) { this->first_connection_try = false; - log_error("Failed to connect to the XMPP server: " << reason); + log_error("Failed to connect to the XMPP server: ", reason); #ifdef SYSTEMD_FOUND sd_notifyf(0, "STATUS=Failed to connect to the XMPP server: %s", reason.data()); #endif @@ -91,7 +91,7 @@ void XmppComponent::on_connected() this->first_connection_try = true; auto data = ""; - log_debug("XMPP SENDING: " << data); + log_debug("XMPP SENDING: ", data); this->send_data(std::move(data)); this->doc_open = true; // We may have some pending data to send: this happens when we try to send @@ -104,7 +104,7 @@ void XmppComponent::on_connection_close(const std::string& error) if (error.empty()) log_info("XMPP server closed connection"); else - log_info("XMPP server closed connection: " << error); + log_info("XMPP server closed connection: ", error); } void XmppComponent::parse_in_buffer(const size_t size) @@ -125,7 +125,7 @@ void XmppComponent::parse_in_buffer(const size_t size) void XmppComponent::on_remote_stream_open(const XmlNode& node) { - log_debug("XMPP RECEIVING: " << node.to_string()); + log_debug("XMPP RECEIVING: ", node.to_string()); this->stream_id = node.get_tag("id"); if (this->stream_id.empty()) { @@ -147,13 +147,13 @@ void XmppComponent::on_remote_stream_open(const XmlNode& node) digest[HASH_LENGTH * 2] = '\0'; auto data = ""s + digest + ""; - log_debug("XMPP SENDING: " << data); + log_debug("XMPP SENDING: ", data); this->send_data(std::move(data)); } void XmppComponent::on_remote_stream_close(const XmlNode& node) { - log_debug("XMPP RECEIVING: " << node.to_string()); + log_debug("XMPP RECEIVING: ", node.to_string()); this->doc_open = false; } @@ -164,7 +164,7 @@ void XmppComponent::reset() void XmppComponent::on_stanza(const Stanza& stanza) { - log_debug("XMPP RECEIVING: " << stanza.to_string()); + log_debug("XMPP RECEIVING: ", stanza.to_string()); std::function handler; try { @@ -172,7 +172,7 @@ void XmppComponent::on_stanza(const Stanza& stanza) } catch (const std::out_of_range& exception) { - log_warning("No handler for stanza of type " << stanza.get_name()); + log_warning("No handler for stanza of type ", stanza.get_name()); return; } handler(stanza); @@ -257,7 +257,7 @@ void XmppComponent::handle_error(const Stanza& stanza) std::string error_message("Unspecified error"); if (text) error_message = text->get_inner(); - log_error("Stream error received from the XMPP server: " << error_message); + log_error("Stream error received from the XMPP server: ", error_message); #ifdef SYSTEMD_FOUND if (!this->ever_auth) sd_notifyf(0, "STATUS=Failed to authenticate to the XMPP server: %s", error_message.data()); -- cgit v1.2.3 From b2e7edeea8bf08b6b7e75d60af3af0c30fdaa4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?louiz=E2=80=99?= Date: Fri, 24 Jun 2016 11:23:01 +0200 Subject: =?UTF-8?q?Properly=20set=20the=20=E2=80=9Cfrom=E2=80=9D=20of=20th?= =?UTF-8?q?e=20ping=20results=20to=20the=20correct=20full=20JID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- louloulibs/xmpp/xmpp_component.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'louloulibs/xmpp/xmpp_component.cpp') diff --git a/louloulibs/xmpp/xmpp_component.cpp b/louloulibs/xmpp/xmpp_component.cpp index 1be7a06..e87cdf7 100644 --- a/louloulibs/xmpp/xmpp_component.cpp +++ b/louloulibs/xmpp/xmpp_component.cpp @@ -631,6 +631,16 @@ void XmppComponent::send_iq_version_request(const std::string& from, this->send_stanza(iq); } +void XmppComponent::send_iq_result_full_jid(const std::string& id, const std::string& to_jid, const std::string& from_full_jid) +{ + Stanza iq("iq"); + iq["from"] = from_full_jid; + iq["to"] = to_jid; + iq["id"] = id; + iq["type"] = "result"; + this->send_stanza(iq); +} + void XmppComponent::send_iq_result(const std::string& id, const std::string& to_jid, const std::string& from_local_part) { Stanza iq("iq"); -- cgit v1.2.3