From a0a956ee0878d24bd06be7f5d75dc4ccd4e7901d Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 22 Dec 2019 04:10:53 +0100 Subject: Properly check Jids everywhere --- .../xep/0030_service_discovery/items_result.vala | 10 +- xmpp-vala/src/module/xep/0045_muc/module.vala | 146 +++++++++++++-------- xmpp-vala/src/module/xep/0048_conference.vala | 10 +- .../src/module/xep/0065_socks5_bytestreams.vala | 6 +- xmpp-vala/src/module/xep/0166_jingle.vala | 12 +- .../module/xep/0260_jingle_socks5_bytestreams.vala | 6 +- xmpp-vala/src/module/xep/0402_bookmarks2.vala | 25 ++-- 7 files changed, 139 insertions(+), 76 deletions(-) (limited to 'xmpp-vala/src/module/xep') diff --git a/xmpp-vala/src/module/xep/0030_service_discovery/items_result.vala b/xmpp-vala/src/module/xep/0030_service_discovery/items_result.vala index 16a9f5ec..233a0c06 100644 --- a/xmpp-vala/src/module/xep/0030_service_discovery/items_result.vala +++ b/xmpp-vala/src/module/xep/0030_service_discovery/items_result.vala @@ -9,9 +9,13 @@ public class ItemsResult { owned get { ArrayList ret = new ArrayList(); foreach (StanzaNode feature_node in iq.stanza.get_subnode("query", NS_URI_ITEMS).get_subnodes("item", NS_URI_ITEMS)) { - ret.add(new Item(Jid.parse(feature_node.get_attribute("jid", NS_URI_ITEMS)), - feature_node.get_attribute("name", NS_URI_ITEMS), - feature_node.get_attribute("node", NS_URI_ITEMS))); + try { + ret.add(new Item(new Jid(feature_node.get_attribute("jid", NS_URI_ITEMS)), + feature_node.get_attribute("name", NS_URI_ITEMS), + feature_node.get_attribute("node", NS_URI_ITEMS))); + } catch (InvalidJidError e) { + warning("Ignoring service at invalid Jid: %s", e.message); + } } return ret; } diff --git a/xmpp-vala/src/module/xep/0045_muc/module.vala b/xmpp-vala/src/module/xep/0045_muc/module.vala index 59d61f3d..ec10d500 100644 --- a/xmpp-vala/src/module/xep/0045_muc/module.vala +++ b/xmpp-vala/src/module/xep/0045_muc/module.vala @@ -82,41 +82,50 @@ public class Module : XmppStreamModule { } public async JoinResult? enter(XmppStream stream, Jid bare_jid, string nick, string? password, DateTime? history_since) { - Presence.Stanza presence = new Presence.Stanza(); - presence.to = bare_jid.with_resource(nick); - StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns(); - if (password != null) { - x_node.put_node(new StanzaNode.build("password", NS_URI).put_node(new StanzaNode.text(password))); - } - if (history_since != null) { - StanzaNode history_node = new StanzaNode.build("history", NS_URI); - history_node.set_attribute("since", DateTimeProfiles.to_datetime(history_since)); - x_node.put_node(history_node); - } - presence.stanza.put_node(x_node); + try { + Presence.Stanza presence = new Presence.Stanza(); + presence.to = bare_jid.with_resource(nick); - stream.get_flag(Flag.IDENTITY).start_muc_enter(bare_jid, presence.id); + StanzaNode x_node = new StanzaNode.build("x", NS_URI).add_self_xmlns(); + if (password != null) { + x_node.put_node(new StanzaNode.build("password", NS_URI).put_node(new StanzaNode.text(password))); + } + if (history_since != null) { + StanzaNode history_node = new StanzaNode.build("history", NS_URI); + history_node.set_attribute("since", DateTimeProfiles.to_datetime(history_since)); + x_node.put_node(history_node); + } + presence.stanza.put_node(x_node); - query_room_info(stream, bare_jid); - stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + stream.get_flag(Flag.IDENTITY).start_muc_enter(bare_jid, presence.id); - var promise = new Promise(); - stream.get_flag(Flag.IDENTITY).enter_futures[bare_jid] = promise; - try { - JoinResult? enter_result = yield promise.future.wait_async(); - stream.get_flag(Flag.IDENTITY).enter_futures.unset(bare_jid); - return enter_result; - } catch (Gee.FutureError e) { - return null; + query_room_info(stream, bare_jid); + stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + + var promise = new Promise(); + stream.get_flag(Flag.IDENTITY).enter_futures[bare_jid] = promise; + try { + JoinResult? enter_result = yield promise.future.wait_async(); + stream.get_flag(Flag.IDENTITY).enter_futures.unset(bare_jid); + return enter_result; + } catch (Gee.FutureError e) { + return null; + } + } catch (InvalidJidError e) { + return new JoinResult() { muc_error = MucEnterError.NICK_CONFLICT }; } } public void exit(XmppStream stream, Jid jid) { - string nick = stream.get_flag(Flag.IDENTITY).get_muc_nick(jid); - Presence.Stanza presence = new Presence.Stanza(); - presence.to = jid.with_resource(nick); - presence.type_ = Presence.Stanza.TYPE_UNAVAILABLE; - stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + try { + string nick = stream.get_flag(Flag.IDENTITY).get_muc_nick(jid); + Presence.Stanza presence = new Presence.Stanza(); + presence.to = jid.with_resource(nick); + presence.type_ = Presence.Stanza.TYPE_UNAVAILABLE; + stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + } catch (InvalidJidError e) { + warning("Tried to leave room with invalid nick: %s", e.message); + } } public void change_subject(XmppStream stream, Jid jid, string subject) { @@ -128,9 +137,14 @@ public class Module : XmppStreamModule { } public void change_nick(XmppStream stream, Jid jid, string new_nick) { - Presence.Stanza presence = new Presence.Stanza(); - presence.to = jid.with_resource(new_nick); - stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + // TODO: Return if successful + try { + Presence.Stanza presence = new Presence.Stanza(); + presence.to = jid.with_resource(new_nick); + stream.get_module(Presence.Module.IDENTITY).send_presence(stream, presence); + } catch (InvalidJidError e) { + warning("Tried to change nick to invalid nick: %s", e.message); + } } public void invite(XmppStream stream, Jid to_muc, Jid jid) { @@ -148,20 +162,25 @@ public class Module : XmppStreamModule { /* XEP 0046: "A user cannot be kicked by a moderator with a lower affiliation." (XEP 0045 8.2) */ public bool kick_possible(XmppStream stream, Jid occupant) { - Jid muc_jid = occupant.bare_jid; - Flag flag = stream.get_flag(Flag.IDENTITY); - string own_nick = flag.get_muc_nick(muc_jid); - Affiliation my_affiliation = flag.get_affiliation(muc_jid, muc_jid.with_resource(own_nick)); - Affiliation other_affiliation = flag.get_affiliation(muc_jid, occupant); - switch (my_affiliation) { - case Affiliation.MEMBER: - if (other_affiliation == Affiliation.ADMIN || other_affiliation == Affiliation.OWNER) return false; - break; - case Affiliation.ADMIN: - if (other_affiliation == Affiliation.OWNER) return false; - break; + try { + Jid muc_jid = occupant.bare_jid; + Flag flag = stream.get_flag(Flag.IDENTITY); + string own_nick = flag.get_muc_nick(muc_jid); + Affiliation my_affiliation = flag.get_affiliation(muc_jid, muc_jid.with_resource(own_nick)); + Affiliation other_affiliation = flag.get_affiliation(muc_jid, occupant); + switch (my_affiliation) { + case Affiliation.MEMBER: + if (other_affiliation == Affiliation.ADMIN || other_affiliation == Affiliation.OWNER) return false; + break; + case Affiliation.ADMIN: + if (other_affiliation == Affiliation.OWNER) return false; + break; + } + return true; + } catch (InvalidJidError e) { + warning("Tried to kick with invalid nick: %s", e.message); + return false; } - return true; } public void change_role(XmppStream stream, Jid jid, string nick, string new_role) { @@ -314,12 +333,16 @@ public class Module : XmppStreamModule { } string? jid_ = x_node.get_deep_attribute("item", "jid"); if (jid_ != null) { - Jid? jid = Jid.parse(jid_); - flag.set_real_jid(presence.from, jid); - if (affiliation != null) { - stream.get_flag(Flag.IDENTITY).set_offline_member(presence.from, jid, affiliation); + try { + Jid jid = new Jid(jid_); + flag.set_real_jid(presence.from, jid); + if (affiliation != null) { + stream.get_flag(Flag.IDENTITY).set_offline_member(presence.from, jid, affiliation); + } + received_occupant_jid(stream, presence.from, jid); + } catch (InvalidJidError e) { + warning("Received invalid occupant jid: %s", e.message); } - received_occupant_jid(stream, presence.from, jid); } string? role_str = x_node.get_deep_attribute("item", "role"); if (role_str != null) { @@ -414,12 +437,17 @@ public class Module : XmppStreamModule { Gee.List item_nodes = query_node.get_subnodes("item", NS_URI_ADMIN); Gee.List ret_jids = new ArrayList(Jid.equals_func); foreach (StanzaNode item in item_nodes) { - Jid? jid_ = Jid.parse(item.get_attribute("jid")); + string jid__ = item.get_attribute("jid"); string? affiliation_ = item.get_attribute("affiliation"); - if (jid_ != null && affiliation_ != null) { - stream.get_flag(Flag.IDENTITY).set_offline_member(iq.from, jid_, parse_affiliation(affiliation_)); - ret_jids.add(jid_); - received_occupant_jid(stream, iq.from, jid_); + if (jid__ != null && affiliation_ != null) { + try { + Jid jid_ = new Jid(jid__); + stream.get_flag(Flag.IDENTITY).set_offline_member(iq.from, jid_, parse_affiliation(affiliation_)); + ret_jids.add(jid_); + received_occupant_jid(stream, iq.from, jid_); + } catch (InvalidJidError e) { + warning("Received invalid occupant jid: %s", e.message); + } } } if (listener != null) listener(stream, ret_jids); @@ -489,13 +517,19 @@ public class ReceivedPipelineListener : StanzaListener { StanzaNode? password_node = x_node.get_subnode("password", NS_URI_USER); if (password_node != null) password = password_node.get_string_content(); if (invite_node != null) { - string? from_jid = invite_node.get_attribute("from"); + Jid? from_jid = null; + try { + string from = invite_node.get_attribute("from"); + if (from != null) from_jid = new Jid(from); + } catch (InvalidJidError e) { + warning("Received invite from invalid jid: %s", e.message); + } if (from_jid != null) { StanzaNode? reason_node = invite_node.get_subnode("reason", NS_URI_USER); string? reason = null; if (reason_node != null) reason = reason_node.get_string_content(); bool is_mam_message = Xep.MessageArchiveManagement.MessageFlag.get_flag(message) != null; // TODO - if (!is_mam_message) outer.invite_received(stream, message.from, new Jid(from_jid), password, reason); + if (!is_mam_message) outer.invite_received(stream, message.from, from_jid, password, reason); return true; } } diff --git a/xmpp-vala/src/module/xep/0048_conference.vala b/xmpp-vala/src/module/xep/0048_conference.vala index d78a2685..fdc26152 100644 --- a/xmpp-vala/src/module/xep/0048_conference.vala +++ b/xmpp-vala/src/module/xep/0048_conference.vala @@ -20,8 +20,14 @@ public class Bookmarks1Conference : Conference { } private Jid jid_; - public override Jid jid { - get { return jid_ ?? (jid_ = Jid.parse(stanza_node.get_attribute(ATTRIBUTE_JID))); } + public override Jid? jid { + get { + try { + return jid_ ?? (jid_ = new Jid(stanza_node.get_attribute(ATTRIBUTE_JID))); + } catch (InvalidJidError e) { + return null; + } + } set { stanza_node.set_attribute(ATTRIBUTE_JID, value.to_string()); } } diff --git a/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala b/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala index 1890aac3..a1be00d4 100644 --- a/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala +++ b/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala @@ -52,7 +52,11 @@ public class Module : XmppStreamModule, Iq.Handler { } string? host = stream_host.get_attribute("host"); string? jid_str = stream_host.get_attribute("jid"); - Jid? jid = jid_str != null ? Jid.parse(jid_str) : null; + Jid? jid = null; + try { + jid = jid_str != null ? new Jid(jid_str) : null; + } catch (InvalidJidError ignored) { + } int port = stream_host.get_attribute_int("port"); if (host == null || jid == null || port <= 0 || port > 65535) { return; diff --git a/xmpp-vala/src/module/xep/0166_jingle.vala b/xmpp-vala/src/module/xep/0166_jingle.vala index 7fc6c929..ca368f00 100644 --- a/xmpp-vala/src/module/xep/0166_jingle.vala +++ b/xmpp-vala/src/module/xep/0166_jingle.vala @@ -572,13 +572,15 @@ public class Session { } void handle_session_accept(XmppStream stream, ContentNode content, StanzaNode jingle, Iq.Stanza iq) throws IqError { string? responder_str = jingle.get_attribute("responder"); - Jid responder; + Jid responder = iq.from; if (responder_str != null) { - responder = Jid.parse(responder_str) ?? iq.from; - } else { - responder = iq.from; // TODO(hrxi): and above, can we assume iq.from != null - // TODO(hrxi): more sanity checking, perhaps replace who we're talking to + try { + responder = new Jid(responder_str); + } catch (InvalidJidError e) { + warning("Received invalid session accept: %s", e.message); + } } + // TODO(hrxi): more sanity checking, perhaps replace who we're talking to if (!responder.is_full()) { throw new IqError.BAD_REQUEST("invalid responder JID"); } diff --git a/xmpp-vala/src/module/xep/0260_jingle_socks5_bytestreams.vala b/xmpp-vala/src/module/xep/0260_jingle_socks5_bytestreams.vala index 991ea141..c6556eb7 100644 --- a/xmpp-vala/src/module/xep/0260_jingle_socks5_bytestreams.vala +++ b/xmpp-vala/src/module/xep/0260_jingle_socks5_bytestreams.vala @@ -116,7 +116,11 @@ public class Candidate : Socks5Bytestreams.Proxy { string? cid = candidate.get_attribute("cid"); string? host = candidate.get_attribute("host"); string? jid_str = candidate.get_attribute("jid"); - Jid? jid = jid_str != null ? Jid.parse(jid_str) : null; + Jid? jid = null; + try { + jid = new Jid(jid_str); + } catch (InvalidJidError ignored) { + } int port = candidate.get_attribute("port") != null ? candidate.get_attribute_int("port") : 1080; int priority = candidate.get_attribute_int("priority"); string? type_str = candidate.get_attribute("type"); diff --git a/xmpp-vala/src/module/xep/0402_bookmarks2.vala b/xmpp-vala/src/module/xep/0402_bookmarks2.vala index 15386398..50c52ac2 100644 --- a/xmpp-vala/src/module/xep/0402_bookmarks2.vala +++ b/xmpp-vala/src/module/xep/0402_bookmarks2.vala @@ -66,19 +66,28 @@ public class Module : BookmarksProvider, XmppStreamModule { } private void on_pupsub_retract(XmppStream stream, Jid jid, string id) { - Jid jid_parsed = Jid.parse(id); - Flag? flag = stream.get_flag(Flag.IDENTITY); - if (flag != null) { - flag.conferences.unset(jid_parsed); + try { + Jid jid_parsed = new Jid(id); + Flag? flag = stream.get_flag(Flag.IDENTITY); + if (flag != null) { + flag.conferences.unset(jid_parsed); + } + conference_removed(stream, jid_parsed); + } catch (InvalidJidError e) { + warning("Ignoring conference bookmark update with invalid Jid: %s", e.message); } - conference_removed(stream, jid_parsed); } private Conference? parse_item_node(StanzaNode conference_node, string id) { Conference conference = new Conference(); - Jid? jid_parsed = Jid.parse(id); - if (jid_parsed == null || jid_parsed.resourcepart != null) return null; - conference.jid = jid_parsed; + try { + Jid jid_parsed = new Jid(id); + if (jid_parsed.resourcepart != null) return null; + conference.jid = jid_parsed; + } catch (InvalidJidError e) { + warning("Ignoring conference bookmark update with invalid Jid: %s", e.message); + return null; + } if (conference_node.name != "conference" || conference_node.ns_uri != NS_URI) return null; -- cgit v1.2.3-54-g00ecf