aboutsummaryrefslogtreecommitdiff
path: root/plugins/omemo/src/stream_module.vala
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/omemo/src/stream_module.vala')
-rw-r--r--plugins/omemo/src/stream_module.vala95
1 files changed, 53 insertions, 42 deletions
diff --git a/plugins/omemo/src/stream_module.vala b/plugins/omemo/src/stream_module.vala
index 6e6772ca..2c792a2f 100644
--- a/plugins/omemo/src/stream_module.vala
+++ b/plugins/omemo/src/stream_module.vala
@@ -26,8 +26,6 @@ public class StreamModule : XmppStreamModule {
public signal void store_created(Store store);
public signal void device_list_loaded(Jid jid);
public signal void bundle_fetched(Jid jid, int device_id, Bundle bundle);
- public signal void session_started(Jid jid, int device_id);
- public signal void session_start_failed(Jid jid, int device_id);
public EncryptState encrypt(MessageStanza message, Jid self_jid) {
EncryptState status = new EncryptState();
@@ -103,6 +101,27 @@ public class StreamModule : XmppStreamModule {
return status;
}
+ public void untrust_device(Jid jid, int device_id) {
+ if (device_lists.has_key(jid) && device_lists[jid].contains(device_id)) {
+ device_lists[jid].remove(device_id);
+ }
+ if (store.contains_session(new Address(jid.bare_jid.to_string(), device_id))) {
+ store.delete_session(new Address(jid.bare_jid.to_string(), device_id));
+ }
+ }
+
+ public void trust_device(Jid jid, int device_id) {
+ if (is_ignored_device(jid, device_id)){
+ ignored_devices[jid].remove(device_id);
+ }
+ if (!device_lists.has_key(jid)) {
+ device_lists[jid] = new ArrayList<int32>();
+ }
+ if (!device_lists[jid].contains(device_id)) {
+ device_lists[jid].add(device_id);
+ }
+ }
+
private StanzaNode create_encrypted_key(uint8[] key, Address address) throws GLib.Error {
SessionCipher cipher = store.create_session_cipher(address);
CiphertextMessage device_key = cipher.encrypt(key);
@@ -164,7 +183,7 @@ public class StreamModule : XmppStreamModule {
device_list_loaded(jid);
}
- public void start_sessions_with(XmppStream stream, Jid jid) {
+ public void fetch_bundles(XmppStream stream, Jid jid) {
if (!device_lists.has_key(jid)) {
return;
}
@@ -174,7 +193,7 @@ public class StreamModule : XmppStreamModule {
address.device_id = device_id;
try {
if (!store.contains_session(address)) {
- start_session_with(stream, jid, device_id);
+ fetch_bundle(stream, jid, device_id);
}
} catch (Error e) {
// Ignore
@@ -184,21 +203,11 @@ public class StreamModule : XmppStreamModule {
address.device_id = 0;
}
- public void start_session_with(XmppStream stream, Jid jid, int device_id) {
- if (active_bundle_requests.add(jid.bare_jid.to_string() + @":$device_id")) {
- if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $(jid.bare_jid.to_string()):$device_id\n");
- stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid.bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
- on_other_bundle_result(stream, jid, device_id, id, node);
- });
- }
- }
-
public void fetch_bundle(XmppStream stream, Jid jid, int device_id) {
if (active_bundle_requests.add(jid.bare_jid.to_string() + @":$device_id")) {
if (Plugin.DEBUG) print(@"OMEMO: Asking for bundle from $(jid.bare_jid.to_string()):$device_id\n");
stream.get_module(Pubsub.Module.IDENTITY).request(stream, jid.bare_jid, @"$NODE_BUNDLES:$device_id", (stream, jid, id, node) => {
- stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$device_id");
- bundle_fetched(jid, device_id, new Bundle(node));
+ on_other_bundle_result(stream, jid, device_id, id, node);
});
}
}
@@ -223,7 +232,6 @@ public class StreamModule : XmppStreamModule {
}
ignored_devices[jid].add(device_id);
}
- session_start_failed(jid, device_id);
}
public bool is_ignored_device(Jid jid, int32 device_id) {
@@ -234,47 +242,50 @@ public class StreamModule : XmppStreamModule {
}
private void on_other_bundle_result(XmppStream stream, Jid jid, int device_id, string? id, StanzaNode? node) {
- bool fail = false;
if (node == null) {
// Device not registered, shouldn't exist
- fail = true;
+ stream.get_module(IDENTITY).ignore_device(jid, device_id);
} else {
Bundle bundle = new Bundle(node);
bundle_fetched(jid, device_id, bundle);
- int32 signed_pre_key_id = bundle.signed_pre_key_id;
- ECPublicKey? signed_pre_key = bundle.signed_pre_key;
- uint8[] signed_pre_key_signature = bundle.signed_pre_key_signature;
- ECPublicKey? identity_key = bundle.identity_key;
+ }
+ stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$device_id");
+ }
- ArrayList<Bundle.PreKey> pre_keys = bundle.pre_keys;
- if (signed_pre_key_id < 0 || signed_pre_key == null || identity_key == null || pre_keys.size == 0) {
+ public bool start_session(XmppStream stream, Jid jid, int32 device_id, Bundle bundle) {
+ bool fail = false;
+ int32 signed_pre_key_id = bundle.signed_pre_key_id;
+ ECPublicKey? signed_pre_key = bundle.signed_pre_key;
+ uint8[] signed_pre_key_signature = bundle.signed_pre_key_signature;
+ ECPublicKey? identity_key = bundle.identity_key;
+
+ ArrayList<Bundle.PreKey> pre_keys = bundle.pre_keys;
+ if (signed_pre_key_id < 0 || signed_pre_key == null || identity_key == null || pre_keys.size == 0) {
+ fail = true;
+ } else {
+ int pre_key_idx = Random.int_range(0, pre_keys.size);
+ int32 pre_key_id = pre_keys[pre_key_idx].key_id;
+ ECPublicKey? pre_key = pre_keys[pre_key_idx].key;
+ if (pre_key_id < 0 || pre_key == null) {
fail = true;
} else {
- int pre_key_idx = Random.int_range(0, pre_keys.size);
- int32 pre_key_id = pre_keys[pre_key_idx].key_id;
- ECPublicKey? pre_key = pre_keys[pre_key_idx].key;
- if (pre_key_id < 0 || pre_key == null) {
- fail = true;
- } else {
- Address address = new Address(jid.bare_jid.to_string(), device_id);
- try {
- if (store.contains_session(address)) {
- return;
- }
- SessionBuilder builder = store.create_session_builder(address);
- builder.process_pre_key_bundle(create_pre_key_bundle(device_id, device_id, pre_key_id, pre_key, signed_pre_key_id, signed_pre_key, signed_pre_key_signature, identity_key));
- stream.get_module(IDENTITY).session_started(jid, device_id);
- } catch (Error e) {
- fail = true;
+ Address address = new Address(jid.bare_jid.to_string(), device_id);
+ try {
+ if (store.contains_session(address)) {
+ return false;
}
- address.device_id = 0; // TODO: Hack to have address obj live longer
+ SessionBuilder builder = store.create_session_builder(address);
+ builder.process_pre_key_bundle(create_pre_key_bundle(device_id, device_id, pre_key_id, pre_key, signed_pre_key_id, signed_pre_key, signed_pre_key_signature, identity_key));
+ } catch (Error e) {
+ fail = true;
}
+ address.device_id = 0; // TODO: Hack to have address obj live longer
}
}
if (fail) {
stream.get_module(IDENTITY).ignore_device(jid, device_id);
}
- stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$device_id");
+ return true;
}
public void publish_bundles_if_needed(XmppStream stream, Jid jid) {