1using Gee; 2 3using Xmpp; 4using Dino.Entities; 5 6namespace Dino { 7 8public class Register : StreamInteractionModule, Object{ 9 public static ModuleIdentity<Register> IDENTITY = new ModuleIdentity<Register>("registration"); 10 public string id { get { return IDENTITY.id; } } 11 12 private StreamInteractor stream_interactor; 13 private Database db; 14 15 public static void start(StreamInteractor stream_interactor, Database db) { 16 Register m = new Register(stream_interactor, db); 17 stream_interactor.add_module(m); 18 } 19 20 private Register(StreamInteractor stream_interactor, Database db) { 21 this.stream_interactor = stream_interactor; 22 this.db = db; 23 } 24 25 public async ConnectionManager.ConnectionError.Source? add_check_account(Account account) { 26 XmppStream stream = new XmppStream(); 27 stream.log = new XmppLog(account.bare_jid.to_string(), Application.print_xmpp); 28 stream.add_module(new Tls.Module()); 29 stream.add_module(new Iq.Module()); 30 stream.add_module(new Xep.SrvRecordsTls.Module()); 31 stream.add_module(new Sasl.Module(account.bare_jid.to_string(), account.password)); 32 33 ConnectionManager.ConnectionError.Source? ret = null; 34 35 SourceFunc callback = add_check_account.callback; 36 stream.stream_negotiated.connect(() => { 37 if (callback == null) return; 38 Idle.add((owned)callback); 39 }); 40 stream.get_module(Tls.Module.IDENTITY).invalid_certificate.connect((peer_cert, errors) => { 41 if (callback == null) return; 42 ret = ConnectionManager.ConnectionError.Source.TLS; 43 Idle.add((owned)callback); 44 }); 45 stream.get_module(Sasl.Module.IDENTITY).received_auth_failure.connect((stream, node) => { 46 if (callback == null) return; 47 ret = ConnectionManager.ConnectionError.Source.SASL; 48 Idle.add((owned)callback); 49 }); 50 stream.connect.begin(account.domainpart, (_, res) => { 51 try { 52 stream.connect.end(res); 53 } catch (Error e) { 54 debug("Error connecting to stream: %s", e.message); 55 } 56 if (callback != null) { 57 ret = ConnectionManager.ConnectionError.Source.CONNECTION; 58 Idle.add((owned)callback); 59 } 60 }); 61 62 yield; 63 64 try { 65 yield stream.disconnect(); 66 } catch (Error e) {} 67 return ret; 68 } 69 70 public class ServerAvailabilityReturn { 71 public bool available { get; set; } 72 public TlsCertificateFlags? error_flags { get; set; } 73 } 74 75 public static async ServerAvailabilityReturn check_server_availability(Jid jid) { 76 XmppStream stream = new XmppStream(); 77 stream.log = new XmppLog(jid.to_string(), Application.print_xmpp); 78 stream.add_module(new Tls.Module()); 79 stream.add_module(new Iq.Module()); 80 stream.add_module(new Xep.SrvRecordsTls.Module()); 81 82 ServerAvailabilityReturn ret = new ServerAvailabilityReturn() { available=false }; 83 SourceFunc callback = check_server_availability.callback; 84 stream.stream_negotiated.connect(() => { 85 if (callback != null) { 86 ret.available = true; 87 Idle.add((owned)callback); 88 } 89 }); 90 stream.get_module(Tls.Module.IDENTITY).invalid_certificate.connect((peer_cert, errors) => { 91 if (callback != null) { 92 ret.error_flags = errors; 93 Idle.add((owned)callback); 94 } 95 }); 96 97 stream.connect.begin(jid.domainpart, (_, res) => { 98 try { 99 stream.connect.end(res); 100 } catch (Error e) { 101 debug("Error connecting to stream: %s", e.message); 102 } 103 if (callback != null) { 104 Idle.add((owned)callback); 105 } 106 }); 107 108 yield; 109 110 try { 111 yield stream.disconnect(); 112 } catch (Error e) {} 113 return ret; 114 } 115 116 public static async Xep.InBandRegistration.Form? get_registration_form(Jid jid) { 117 XmppStream stream = new XmppStream(); 118 stream.log = new XmppLog(jid.to_string(), Application.print_xmpp); 119 stream.add_module(new Tls.Module()); 120 stream.add_module(new Iq.Module()); 121 stream.add_module(new Xep.SrvRecordsTls.Module()); 122 stream.add_module(new Xep.InBandRegistration.Module()); 123 124 SourceFunc callback = get_registration_form.callback; 125 126 stream.stream_negotiated.connect(() => { 127 if (callback != null) { 128 Idle.add((owned)callback); 129 } 130 }); 131 132 stream.connect.begin(jid.domainpart, (_, res) => { 133 try { 134 stream.connect.end(res); 135 } catch (Error e) { 136 debug("Error connecting to stream: %s", e.message); 137 } 138 if (callback != null) { 139 Idle.add((owned)callback); 140 } 141 }); 142 143 yield; 144 145 Xep.InBandRegistration.Form? form = null; 146 if (stream.negotiation_complete) { 147 form = yield stream.get_module(Xep.InBandRegistration.Module.IDENTITY).get_from_server(stream, jid); 148 } 149 try { 150 yield stream.disconnect(); 151 } catch (Error e) {} 152 153 return form; 154 } 155 156 public static async string? submit_form(Jid jid, Xep.InBandRegistration.Form form) { 157 XmppStream stream = new XmppStream(); 158 stream.log = new XmppLog(jid.to_string(), Application.print_xmpp); 159 stream.add_module(new Tls.Module()); 160 stream.add_module(new Iq.Module()); 161 stream.add_module(new Xep.SrvRecordsTls.Module()); 162 stream.add_module(new Xep.InBandRegistration.Module()); 163 164 SourceFunc callback = submit_form.callback; 165 166 stream.stream_negotiated.connect(() => { 167 if (callback != null) { 168 Idle.add((owned)callback); 169 } 170 }); 171 172 stream.connect.begin(jid.domainpart, (_, res) => { 173 try { 174 stream.connect.end(res); 175 } catch (Error e) { 176 debug("Error connecting to stream: %s", e.message); 177 } 178 if (callback != null) { 179 Idle.add((owned)callback); 180 } 181 }); 182 183 yield; 184 185 string? ret = null; 186 if (stream.negotiation_complete) { 187 ret = yield stream.get_module(Xep.InBandRegistration.Module.IDENTITY).submit_to_server(stream, jid, form); 188 } 189 try { 190 yield stream.disconnect(); 191 } catch (Error e) {} 192 return ret; 193 } 194} 195 196} 197