From 642dac9aa0b90dd2f17df5dddd0e7914a7d306d3 Mon Sep 17 00:00:00 2001 From: hrxi Date: Sat, 20 Jul 2019 23:14:40 +0200 Subject: Add support for Jingle SOCKS5 bytestreams (XEP-0260) --- .../src/module/xep/0065_socks5_bytestreams.vala | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala (limited to 'xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala') diff --git a/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala b/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala new file mode 100644 index 00000000..1890aac3 --- /dev/null +++ b/xmpp-vala/src/module/xep/0065_socks5_bytestreams.vala @@ -0,0 +1,83 @@ +using Gee; +using Xmpp; +using Xmpp.Xep; + +namespace Xmpp.Xep.Socks5Bytestreams { + +internal const string NS_URI = "http://jabber.org/protocol/bytestreams"; + +public class Proxy : Object { + public string host { get; private set; } + public Jid jid { get; private set; } + public int port { get; private set; } + + public Proxy(string host, Jid jid, int port) { + this.host = host; + this.jid = jid; + this.port = port; + } +} + +public class Module : XmppStreamModule, Iq.Handler { + public static Xmpp.ModuleIdentity IDENTITY = new Xmpp.ModuleIdentity(NS_URI, "0065_socks5_bytestreams"); + + public override void attach(XmppStream stream) { + stream.add_flag(new Flag()); + query_availability(stream); + } + public override void detach(XmppStream stream) { } + + public void on_iq_set(XmppStream stream, Iq.Stanza iq) { } + + public Gee.List get_proxies(XmppStream stream) { + return stream.get_flag(Flag.IDENTITY).proxies; + } + + private void query_availability(XmppStream stream) { + stream.get_module(ServiceDiscovery.Module.IDENTITY).request_items(stream, stream.remote_name, (stream, items_result) => { + foreach (Xep.ServiceDiscovery.Item item in items_result.items) { + stream.get_module(ServiceDiscovery.Module.IDENTITY).request_info(stream, item.jid, (stream, info_result) => { + foreach (string feature in info_result.features) { + if (feature == NS_URI) { + StanzaNode query_ = new StanzaNode.build("query", NS_URI).add_self_xmlns(); + Iq.Stanza iq = new Iq.Stanza.get(query_) { to=item.jid }; + stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, (stream, iq) => { + if (iq.is_error()) { + return; + } + StanzaNode? query = iq.stanza.get_subnode("query", NS_URI); + StanzaNode? stream_host = query != null ? query.get_subnode("streamhost", NS_URI) : null; + if (query == null || stream_host == null) { + return; + } + 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; + int port = stream_host.get_attribute_int("port"); + if (host == null || jid == null || port <= 0 || port > 65535) { + return; + } + stream.get_flag(Flag.IDENTITY).proxies.add(new Proxy(host, jid, port)); + }); + } + } + }); + } + }); + } + + public override string get_ns() { return NS_URI; } + public override string get_id() { return IDENTITY.id; } +} + +public class Flag : XmppStreamFlag { + public static FlagIdentity IDENTITY = new FlagIdentity(NS_URI, "socks5_bytestreams"); + + public Gee.List proxies = new ArrayList(); + + public override string get_ns() { return NS_URI; } + public override string get_id() { return IDENTITY.id; } +} + + +} -- cgit v1.2.3-54-g00ecf