summaryrefslogtreecommitdiff
path: root/src/xmpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpp')
-rw-r--r--src/xmpp/xmpp_component.cpp128
-rw-r--r--src/xmpp/xmpp_component.hpp3
-rw-r--r--src/xmpp/xmpp_parser.cpp5
-rw-r--r--src/xmpp/xmpp_stanza.cpp4
-rw-r--r--src/xmpp/xmpp_stanza.hpp11
5 files changed, 65 insertions, 86 deletions
diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp
index e558e46..8e8cc91 100644
--- a/src/xmpp/xmpp_component.cpp
+++ b/src/xmpp/xmpp_component.cpp
@@ -135,11 +135,8 @@ void XmppComponent::clean()
void XmppComponent::on_remote_stream_open(const XmlNode& node)
{
log_debug("XMPP DOCUMENT OPEN: " << node.to_string());
- try
- {
- this->stream_id = node["id"];
- }
- catch (const AttributeNotFound& e)
+ 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");
@@ -255,27 +252,27 @@ void XmppComponent::handle_handshake(const Stanza& stanza)
void XmppComponent::handle_presence(const Stanza& stanza)
{
- std::string from;
- std::string id;
- try {
- id = stanza["id"];
- from = stanza["from"];
- } catch (const AttributeNotFound&) {}
+ std::string from = stanza.get_tag("from");
+ std::string id = stanza.get_tag("id");
+ std::string to_str = stanza.get_tag("to");
+ std::string type = stanza.get_tag("type");
+
+ // Check for mandatory tags
if (from.empty())
- return;
- utils::ScopeGuard malformed_stanza_error([&](){
+ {
+ log_warning("Received an invalid presence stanza: tag 'from' is missing.");
+ return;
+ }
+ if (to_str.empty())
+ {
this->send_stanza_error("presence", from, this->served_hostname, id,
- "modify", "bad-request", "");
- });
- Bridge* bridge = this->get_user_bridge(stanza["from"]);
- Jid to(stanza["to"]);
+ "modify", "bad-request", "Missing 'to' tag");
+ return;
+ }
+
+ Bridge* bridge = this->get_user_bridge(from);
+ Jid to(to_str);
Iid iid(to.local);
- std::string type;
- try {
- type = stanza["type"];
- }
- catch (const AttributeNotFound&) {}
- malformed_stanza_error.disable();
// An error stanza is sent whenever we exit this function without
// disabling this scopeguard. If error_type and error_name are not
@@ -286,7 +283,7 @@ void XmppComponent::handle_presence(const Stanza& stanza)
std::string error_type("cancel");
std::string error_name("internal-server-error");
utils::ScopeGuard stanza_error([&](){
- this->send_stanza_error("presence", stanza["from"], stanza["to"], id,
+ this->send_stanza_error("presence", from, to_str, id,
error_type, error_name, "");
});
@@ -310,41 +307,30 @@ void XmppComponent::handle_presence(const Stanza& stanza)
{
// An user wants to join an invalid IRC channel, return a presence error to him
if (type.empty())
- this->send_invalid_room_error(to.local, to.resource, stanza["from"]);
+ this->send_invalid_room_error(to.local, to.resource, from);
}
stanza_error.disable();
}
void XmppComponent::handle_message(const Stanza& stanza)
{
- std::string from;
- std::string id;
- try {
- id = stanza["id"];
- from = stanza["from"];
- } catch (const AttributeNotFound&) {}
+ std::string from = stanza.get_tag("from");
+ std::string id = stanza.get_tag("id");
+ std::string to_str = stanza.get_tag("to");
+ std::string type = stanza.get_tag("type");
+
if (from.empty())
return;
- utils::ScopeGuard malformed_stanza_error([&](){
- this->send_stanza_error("message", from, this->served_hostname, id,
- "modify", "bad-request", "");
- });
- Bridge* bridge = this->get_user_bridge(stanza["from"]);
- Jid to(stanza["to"]);
- Iid iid(to.local);
- std::string type;
- try {
- type = stanza["type"];
- }
- catch (const AttributeNotFound&) {
+ if (type.empty())
type = "normal";
- }
- malformed_stanza_error.disable();
+ Bridge* bridge = this->get_user_bridge(from);
+ Jid to(to_str);
+ Iid iid(to.local);
std::string error_type("cancel");
std::string error_name("internal-server-error");
utils::ScopeGuard stanza_error([&](){
- this->send_stanza_error("message", stanza["from"], stanza["to"], id,
+ this->send_stanza_error("message", from, to_str, id,
error_type, error_name, "");
});
XmlNode* body = stanza.get_child(COMPONENT_NS":body");
@@ -367,27 +353,27 @@ void XmppComponent::handle_message(const Stanza& stanza)
void XmppComponent::handle_iq(const Stanza& stanza)
{
- std::string id;
- std::string from;
- try {
- id = stanza["id"];
- from = stanza["from"];
- } catch (const AttributeNotFound&) {}
+ std::string id = stanza.get_tag("id");
+ std::string from = stanza.get_tag("from");
+ std::string to_str = stanza.get_tag("to");
+ std::string type = stanza.get_tag("type");
+
if (from.empty())
return;
- utils::ScopeGuard malformed_stanza_error([&](){
+ if (id.empty() || to_str.empty() || type.empty())
+ {
this->send_stanza_error("iq", from, this->served_hostname, id,
"modify", "bad-request", "");
- });
- Bridge* bridge = this->get_user_bridge(stanza["from"]);
- Jid to(stanza["to"]);
- std::string type = stanza["type"];
- malformed_stanza_error.disable();
+ return;
+ }
+
+ Bridge* bridge = this->get_user_bridge(from);
+ Jid to(from);
std::string error_type("cancel");
std::string error_name("internal-server-error");
utils::ScopeGuard stanza_error([&](){
- this->send_stanza_error("iq", stanza["from"], stanza["to"], id,
+ this->send_stanza_error("iq", from, to_str, id,
error_type, error_name, "");
});
if (type == "set")
@@ -398,18 +384,8 @@ void XmppComponent::handle_iq(const Stanza& stanza)
const XmlNode* child = query->get_child(MUC_ADMIN_NS":item");
if (child)
{
- std::string nick;
- std::string role;
- try {
- nick = (*child)["nick"];
- role = (*child)["role"];
- }
- catch (const AttributeNotFound&)
- {
- error_type = "modify";
- error_name = "bad-request";
- return;
- }
+ std::string nick = child->get_tag("nick");
+ std::string role = child->get_tag("role");
if (!nick.empty() && role == "none")
{
std::string reason;
@@ -419,6 +395,12 @@ void XmppComponent::handle_iq(const Stanza& stanza)
Iid iid(to.local);
bridge->send_irc_kick(iid, nick, reason);
}
+ else
+ {
+ error_type = "cancel";
+ error_name = "feature-not-implemented";
+ return;
+ }
}
}
}
@@ -458,11 +440,13 @@ 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)
+void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, const std::string& to, const std::string& type)
{
XmlNode node("message");
node["to"] = to;
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();
diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp
index 5a5d3d8..3e13086 100644
--- a/src/xmpp/xmpp_component.hpp
+++ b/src/xmpp/xmpp_component.hpp
@@ -81,7 +81,8 @@ public:
/**
* Send a message from from@served_hostname, with the given body
*/
- void send_message(const std::string& from, Xmpp::body&& body, const std::string& to);
+ void send_message(const std::string& from, Xmpp::body&& body,
+ const std::string& to, const std::string& type);
/**
* Send a join from a new participant
*/
diff --git a/src/xmpp/xmpp_parser.cpp b/src/xmpp/xmpp_parser.cpp
index 536d9da..6bb0d28 100644
--- a/src/xmpp/xmpp_parser.cpp
+++ b/src/xmpp/xmpp_parser.cpp
@@ -55,7 +55,8 @@ XmppParser::~XmppParser()
int XmppParser::feed(const char* data, const int len, const bool is_final)
{
int res = XML_Parse(this->parser, data, len, is_final);
- if (res == 0)
+ if (res == XML_STATUS_ERROR &&
+ (XML_GetErrorCode(this->parser) != XML_ERROR_FINISHED))
log_error("Xml_Parse encountered an error: " <<
XML_ErrorString(XML_GetErrorCode(this->parser)))
return res;
@@ -64,7 +65,7 @@ int XmppParser::feed(const char* data, const int len, const bool is_final)
int XmppParser::parse(const int len, const bool is_final)
{
int res = XML_ParseBuffer(this->parser, len, is_final);
- if (res == 0)
+ if (res == XML_STATUS_ERROR)
log_error("Xml_Parsebuffer encountered an error: " <<
XML_ErrorString(XML_GetErrorCode(this->parser)));
return res;
diff --git a/src/xmpp/xmpp_stanza.cpp b/src/xmpp/xmpp_stanza.cpp
index 23b2d25..948e5f5 100644
--- a/src/xmpp/xmpp_stanza.cpp
+++ b/src/xmpp/xmpp_stanza.cpp
@@ -216,7 +216,7 @@ bool XmlNode::has_children() const
return !this->children.empty();
}
-const std::string& XmlNode::operator[](const std::string& name) const
+const std::string XmlNode::get_tag(const std::string& name) const
{
try
{
@@ -225,7 +225,7 @@ const std::string& XmlNode::operator[](const std::string& name) const
}
catch (const std::out_of_range& e)
{
- throw AttributeNotFound();
+ return "";
}
}
diff --git a/src/xmpp/xmpp_stanza.hpp b/src/xmpp/xmpp_stanza.hpp
index d9bf81d..1c63b86 100644
--- a/src/xmpp/xmpp_stanza.hpp
+++ b/src/xmpp/xmpp_stanza.hpp
@@ -9,13 +9,6 @@ std::string xml_escape(const std::string& data);
std::string xml_unescape(const std::string& data);
/**
- * Raised on operator[] when the attribute does not exist
- */
-class AttributeNotFound: public std::exception
-{
-};
-
-/**
* Represent an XML node. It has
* - A parent XML node (in the case of the first-level nodes, the parent is
nullptr)
@@ -103,10 +96,10 @@ public:
*/
bool has_children() const;
/**
- * Gets the value for the given attribute, raises AttributeNotFound if the
+ * Gets the value for the given attribute, returns an empty string if the
* node as no such attribute.
*/
- const std::string& operator[](const std::string& name) const;
+ const std::string get_tag(const std::string& name) const;
/**
* Use this to set an attribute's value, like node["id"] = "12";
*/