using Gee; namespace Xmpp.Xep.SrvRecordsTls { public class Module : XmppStreamNegotiationModule { public static ModuleIdentity IDENTITY = new ModuleIdentity("", "0363_srv_records_for_xmpp_over_tls"); public override void attach(XmppStream stream) { stream.register_connection_provider(new TlsConnectionProvider()); } public override void detach(XmppStream stream) { } public override bool mandatory_outstanding(XmppStream stream) { return false; } public override bool negotiation_active(XmppStream stream) { return false; } public override string get_ns() { return IDENTITY.ns; } public override string get_id() { return IDENTITY.id; } } public class TlsConnectionProvider : ConnectionProvider { private SrvTarget? srv_target; public async override int? get_priority(Jid remote_name) { GLib.List? xmpp_target = null; try { GLibFixes.Resolver resolver = GLibFixes.Resolver.get_default(); xmpp_target = yield resolver.lookup_service_async("xmpps-client", "tcp", remote_name.to_string(), null); } catch (Error e) { return null; } xmpp_target.sort((a, b) => { return a.get_priority() - b.get_priority(); }); srv_target = xmpp_target.nth(0).data; return xmpp_target.nth(0).data.get_priority(); } public async override IOStream? connect(XmppStream stream) { SocketClient client = new SocketClient(); try { debug("Connecting to %s %i (tls)", srv_target.get_hostname(), srv_target.get_port()); IOStream? io_stream = yield client.connect_to_host_async(srv_target.get_hostname(), srv_target.get_port()); TlsConnection tls_connection = TlsClientConnection.new(io_stream, new NetworkAddress(stream.remote_name.to_string(), srv_target.get_port())); tls_connection.accept_certificate.connect(stream.get_module(Tls.Module.IDENTITY).on_invalid_certificate); stream.add_flag(new Tls.Flag() { finished=true }); return tls_connection; } catch (Error e) { return null; } } public override string get_id() { return "srv_records"; } } }