aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfiaxh <git@mx.ax.lt>2017-08-09 20:44:15 +0200
committerfiaxh <git@mx.ax.lt>2017-08-11 11:56:37 +0200
commitb29d52fddae832d275e66dbd1b494e06ce11d0da (patch)
tree93dc3108c947d476dc5a847d4633d8802710ed77
parente3e6a426f486ddef3c3ed299e30d8de3507b79a2 (diff)
downloaddino-b29d52fddae832d275e66dbd1b494e06ce11d0da.tar.gz
dino-b29d52fddae832d275e66dbd1b494e06ce11d0da.zip
SRV records for XMPP over TLS
-rw-r--r--libdino/src/entity/conversation.vala12
-rw-r--r--libdino/src/service/module_manager.vala1
-rw-r--r--main/src/ui/unified_window.vala4
-rw-r--r--plugins/http-files/src/contact_titlebar_entry.vala9
-rw-r--r--xmpp-vala/CMakeLists.txt1
-rw-r--r--xmpp-vala/src/core/xmpp_stream.vala56
-rw-r--r--xmpp-vala/src/module/tls.vala2
-rw-r--r--xmpp-vala/src/module/xep/0333_chat_markers.vala2
-rw-r--r--xmpp-vala/src/module/xep/0368_srv_records_tls.vala53
9 files changed, 124 insertions, 16 deletions
diff --git a/libdino/src/entity/conversation.vala b/libdino/src/entity/conversation.vala
index 40bff1c2..fa78c619 100644
--- a/libdino/src/entity/conversation.vala
+++ b/libdino/src/entity/conversation.vala
@@ -73,17 +73,19 @@ public class Conversation : Object {
.value(db.conversation.jid_id, db.get_jid_id(counterpart))
.value(db.conversation.type_, type_)
.value(db.conversation.encryption, encryption)
- .value(db.conversation.read_up_to, read_up_to.id)
- .value(db.conversation.active, active);
+ .value(db.conversation.active, active)
+ .value(db.conversation.notification, notify_setting)
+ .value(db.conversation.send_typing, send_typing)
+ .value(db.conversation.send_marker, send_marker);
+ if (read_up_to != null) {
+ insert.value(db.conversation.read_up_to, read_up_to.id);
+ }
if (counterpart.is_full()) {
insert.value(db.conversation.resource, counterpart.resourcepart);
}
if (last_active != null) {
insert.value(db.conversation.last_active, (long) last_active.to_unix());
}
- insert.value(db.conversation.notification, notify_setting);
- insert.value(db.conversation.send_typing, send_typing);
- insert.value(db.conversation.send_marker, send_marker);
id = (int) insert.perform();
notify.connect(on_update);
}
diff --git a/libdino/src/service/module_manager.vala b/libdino/src/service/module_manager.vala
index 9f2a05d0..b10765f1 100644
--- a/libdino/src/service/module_manager.vala
+++ b/libdino/src/service/module_manager.vala
@@ -46,6 +46,7 @@ public class ModuleManager {
lock(module_map) {
module_map[account] = new ArrayList<Core.XmppStreamModule>();
module_map[account].add(new Tls.Module());
+ module_map[account].add(new Xep.SrvRecordsTls.Module());
module_map[account].add(new Session.Module());
module_map[account].add(new Roster.Module());
module_map[account].add(new Xep.ServiceDiscovery.Module.with_identity("client", "pc"));
diff --git a/main/src/ui/unified_window.vala b/main/src/ui/unified_window.vala
index c0bf0487..c0a74731 100644
--- a/main/src/ui/unified_window.vala
+++ b/main/src/ui/unified_window.vala
@@ -145,7 +145,7 @@ public class NoAccountsPlaceholder : UnifiedWindowPlaceholder {
public class NoConversationsPlaceholder : UnifiedWindowPlaceholder {
public NoConversationsPlaceholder() {
label.label = _("No conversation active");
- primary_button.label = _("Add Chat");
+ primary_button.label = _("Start Chat");
secondary_button.label = _("Join Conference");
secondary_button.visible = true;
}
@@ -158,4 +158,4 @@ public class UnifiedWindowPlaceholder : Box {
[GtkChild] public Button secondary_button;
}
-} \ No newline at end of file
+}
diff --git a/plugins/http-files/src/contact_titlebar_entry.vala b/plugins/http-files/src/contact_titlebar_entry.vala
index a87c7ddf..74966c0e 100644
--- a/plugins/http-files/src/contact_titlebar_entry.vala
+++ b/plugins/http-files/src/contact_titlebar_entry.vala
@@ -54,9 +54,12 @@ public class ConversationTitlebarWidget : Button, Plugins.ConversationTitlebarWi
}
public void on_upload_available(Account account) {
- if (conversation.account.equals(account)) {
- visible = true;
- }
+ Idle.add(() => {
+ if (conversation != null && conversation.account.equals(account)) {
+ visible = true;
+ }
+ return false;
+ });
}
public new void set_conversation(Conversation conversation) {
diff --git a/xmpp-vala/CMakeLists.txt b/xmpp-vala/CMakeLists.txt
index 54bd3886..779540cc 100644
--- a/xmpp-vala/CMakeLists.txt
+++ b/xmpp-vala/CMakeLists.txt
@@ -60,6 +60,7 @@ SOURCES
"src/module/xep/0203_delayed_delivery.vala"
"src/module/xep/0280_message_carbons.vala"
"src/module/xep/0333_chat_markers.vala"
+ "src/module/xep/0368_srv_records_tls.vala"
"src/module/xep/pixbuf_storage.vala"
PACKAGES
${ENGINE_PACKAGES}
diff --git a/xmpp-vala/src/core/xmpp_stream.vala b/xmpp-vala/src/core/xmpp_stream.vala
index 715e7832..eb6ffaa5 100644
--- a/xmpp-vala/src/core/xmpp_stream.vala
+++ b/xmpp-vala/src/core/xmpp_stream.vala
@@ -21,8 +21,9 @@ public class XmppStream {
private StanzaReader? reader;
private StanzaWriter? writer;
- private ArrayList<XmppStreamFlag> flags = new ArrayList<XmppStreamFlag>();
- private ArrayList<XmppStreamModule> modules = new ArrayList<XmppStreamModule>();
+ private Gee.List<XmppStreamFlag> flags = new ArrayList<XmppStreamFlag>();
+ private Gee.List<XmppStreamModule> modules = new ArrayList<XmppStreamModule>();
+ private Gee.List<ConnectionProvider> connection_providers = new ArrayList<ConnectionProvider>();
private bool setup_needed = false;
private bool negotiation_complete = false;
@@ -35,11 +36,24 @@ public class XmppStream {
public signal void received_nonza(XmppStream stream, StanzaNode node);
public signal void stream_negotiated(XmppStream stream);
+ public XmppStream() {
+ register_connection_provider(new StartTlsConnectionProvider());
+ }
+
public void connect(string? remote_name = null) throws IOStreamError {
if (remote_name != null) this.remote_name = (!)remote_name;
- SocketClient client = new SocketClient();
try {
- SocketConnection? stream = client.connect(new NetworkService("xmpp-client", "tcp", this.remote_name));
+ int min_priority = -1;
+ ConnectionProvider? best_provider = null;
+ foreach (ConnectionProvider connection_provider in connection_providers) {
+ int? priority = connection_provider.get_priority(remote_name);
+ if (priority != null && (priority < min_priority || min_priority == -1)) {
+ min_priority = priority;
+ best_provider = connection_provider;
+ }
+ }
+ if (best_provider == null) throw new IOStreamError.CONNECT("no suitable connection provider");
+ IOStream? stream = best_provider.connect(this);
if (stream == null) throw new IOStreamError.CONNECT("client.connect() returned null");
reset_stream((!)stream);
} catch (Error e) {
@@ -142,6 +156,10 @@ public class XmppStream {
return null;
}
+ public void register_connection_provider(ConnectionProvider connection_provider) {
+ connection_providers.add(connection_provider);
+ }
+
private void setup() throws IOStreamError {
StanzaNode outs = new StanzaNode.build("stream", "http://etherx.jabber.org/streams")
.put_attribute("to", remote_name)
@@ -294,4 +312,34 @@ public abstract class XmppStreamNegotiationModule : XmppStreamModule {
public abstract bool negotiation_active(XmppStream stream);
}
+public abstract class ConnectionProvider {
+ public abstract int? get_priority(string remote_name);
+ public abstract IOStream? connect(XmppStream stream);
+ public abstract string get_id();
+}
+
+public class StartTlsConnectionProvider : ConnectionProvider {
+ private SrvTarget? srv_target;
+
+ public override int? get_priority(string remote_name) {
+ GLib.List<SrvTarget>? xmpp_target = null;
+ try {
+ Resolver resolver = Resolver.get_default();
+ xmpp_target = resolver.lookup_service("xmpp-client", "tcp", remote_name, 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 override IOStream? connect(XmppStream stream) {
+ SocketClient client = new SocketClient();
+ return client.connect_to_host(srv_target.get_hostname(), srv_target.get_port());
+ }
+
+ public override string get_id() { return "start_tls"; }
+}
+
}
diff --git a/xmpp-vala/src/module/tls.vala b/xmpp-vala/src/module/tls.vala
index 8cc7ad16..dd4fd82d 100644
--- a/xmpp-vala/src/module/tls.vala
+++ b/xmpp-vala/src/module/tls.vala
@@ -81,7 +81,7 @@ namespace Xmpp.Tls {
public class Flag : XmppStreamFlag {
public static FlagIdentity<Flag> IDENTITY = new FlagIdentity<Flag>(NS_URI, "tls");
public TlsCertificate? peer_certificate;
- public bool finished = false;
+ public bool finished { get; set; default=false; }
public override string get_ns() { return NS_URI; }
public override string get_id() { return IDENTITY.id; }
diff --git a/xmpp-vala/src/module/xep/0333_chat_markers.vala b/xmpp-vala/src/module/xep/0333_chat_markers.vala
index 11817a22..9c1b9c74 100644
--- a/xmpp-vala/src/module/xep/0333_chat_markers.vala
+++ b/xmpp-vala/src/module/xep/0333_chat_markers.vala
@@ -45,7 +45,7 @@ public class Module : XmppStreamModule {
}
public static void require(XmppStream stream) {
- if (stream.get_module(IDENTITY) == null) stream.add_module(new ChatMarkers.Module());
+ if (stream.get_module(IDENTITY) == null) stream.add_module(new Module());
}
public override string get_ns() { return NS_URI; }
diff --git a/xmpp-vala/src/module/xep/0368_srv_records_tls.vala b/xmpp-vala/src/module/xep/0368_srv_records_tls.vala
new file mode 100644
index 00000000..da70b513
--- /dev/null
+++ b/xmpp-vala/src/module/xep/0368_srv_records_tls.vala
@@ -0,0 +1,53 @@
+using Gee;
+
+using Xmpp.Core;
+
+namespace Xmpp.Xep.SrvRecordsTls {
+
+public class Module : XmppStreamNegotiationModule {
+ public static ModuleIdentity<Module> IDENTITY = new ModuleIdentity<Module>("", "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 static void require(XmppStream stream) {
+ if (stream.get_module(IDENTITY) == null) stream.add_module(new Module());
+ }
+
+ 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 override int? get_priority(string remote_name) {
+ GLib.List<SrvTarget>? xmpp_target = null;
+ try {
+ Resolver resolver = Resolver.get_default();
+ xmpp_target = resolver.lookup_service("xmpps-client", "tcp", remote_name, 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 override IOStream? connect(XmppStream stream) {
+ SocketClient client = new SocketClient();
+ IOStream? io_stream = client.connect_to_host(srv_target.get_hostname(), srv_target.get_port());
+ io_stream = TlsClientConnection.new(io_stream, new NetworkAddress(srv_target.get_hostname(), srv_target.get_port()));
+ stream.add_flag(new Tls.Flag() { finished=true });
+ return io_stream;
+ }
+
+ public override string get_id() { return "start_tls"; }
+}
+
+}