aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2023-10-06 16:24:17 +0200
committerMarvin W <git@larma.de>2024-04-28 21:35:07 +0200
commitba83a4ba3d6886b711278b8804566dcbe8ad7621 (patch)
tree8b2fc2674e36a877b4227e73c253b4ea496e7cfd
parent657502955567dd538e56f300e075c7db52e25d74 (diff)
downloaddino-ba83a4ba3d6886b711278b8804566dcbe8ad7621.tar.gz
dino-ba83a4ba3d6886b711278b8804566dcbe8ad7621.zip
Calls: Correctly display information in partially encrypted calls
This should never happen in practice, but now we will correctly display if a call has encrypted audio, but unencrypted video, or vice-versa.
-rw-r--r--libdino/src/service/call_peer_state.vala6
-rw-r--r--main/src/ui/call_window/call_encryption_button.vala52
-rw-r--r--main/src/ui/call_window/call_window_controller.vala30
3 files changed, 60 insertions, 28 deletions
diff --git a/libdino/src/service/call_peer_state.vala b/libdino/src/service/call_peer_state.vala
index c7fa04da..3a005e01 100644
--- a/libdino/src/service/call_peer_state.vala
+++ b/libdino/src/service/call_peer_state.vala
@@ -9,7 +9,7 @@ public class Dino.PeerState : Object {
public signal void connection_ready();
public signal void session_terminated(bool we_terminated, string? reason_name, string? reason_text);
- public signal void encryption_updated(Xep.Jingle.ContentEncryption? audio_encryption, Xep.Jingle.ContentEncryption? video_encryption, bool same);
+ public signal void encryption_updated(Xep.Jingle.ContentEncryption? audio_encryption, Xep.Jingle.ContentEncryption? video_encryption);
public StreamInteractor stream_interactor;
public CallState call_state;
@@ -412,7 +412,7 @@ public class Dino.PeerState : Object {
if ((audio_encryptions != null && audio_encryptions.is_empty) || (video_encryptions != null && video_encryptions.is_empty)) {
call.encryption = Encryption.NONE;
- encryption_updated(null, null, true);
+ encryption_updated(null, null);
return;
}
@@ -462,7 +462,7 @@ public class Dino.PeerState : Object {
encryption_keys_same = true;
}
- encryption_updated(audio_encryption, video_encryption, encryption_keys_same);
+ encryption_updated(audio_encryption, video_encryption);
}
}
diff --git a/main/src/ui/call_window/call_encryption_button.vala b/main/src/ui/call_window/call_encryption_button.vala
index 1b586f28..4c417413 100644
--- a/main/src/ui/call_window/call_encryption_button.vala
+++ b/main/src/ui/call_window/call_encryption_button.vala
@@ -30,13 +30,32 @@ public class Dino.Ui.CallEncryptionButtonController : Object {
update_opacity();
}
- public void set_info(string? title, bool show_keys, Xmpp.Xep.Jingle.ContentEncryption? audio_encryption, Xmpp.Xep.Jingle.ContentEncryption? video_encryption) {
+ private static bool bytes_equal(uint8[] a1, uint8[] a2) {
+ return a1.length == a2.length && Memory.cmp(a1, a2, a1.length) == 0;
+ }
+
+ private static bool encryption_equals(Xmpp.Xep.Jingle.ContentEncryption? audio_encryption, Xmpp.Xep.Jingle.ContentEncryption? video_encryption) {
+ if (audio_encryption == null && video_encryption == null) return true;
+ if (audio_encryption == null || video_encryption == null) return false;
+ if (audio_encryption.encryption_ns != video_encryption.encryption_ns) return false;
+ if (audio_encryption.encryption_name != video_encryption.encryption_name) return false;
+ if (!bytes_equal(audio_encryption.our_key,video_encryption.our_key)) return false;
+ if (!bytes_equal(audio_encryption.peer_key,video_encryption.peer_key)) return false;
+ return true;
+ }
+
+ public void set_info(string? title, bool show_keys, bool has_audio, Xmpp.Xep.Jingle.ContentEncryption? audio_encryption, bool has_video, Xmpp.Xep.Jingle.ContentEncryption? video_encryption) {
Popover popover = new Popover();
button.set_popover(popover);
- if (audio_encryption == null) {
- popover.set_child(new Label("This call is unencrypted.") );
- return;
+ Xmpp.Xep.Jingle.ContentEncryption? single_encryption = null;
+ if (!has_audio || !has_video || encryption_equals(audio_encryption, video_encryption)) {
+ single_encryption = audio_encryption ?? video_encryption;
+
+ if (single_encryption == null) {
+ popover.set_child(new Label("This call is unencrypted.") );
+ return;
+ }
}
if (title != null && !show_keys) {
popover.set_child(new Label(title) { use_markup=true } );
@@ -44,15 +63,19 @@ public class Dino.Ui.CallEncryptionButtonController : Object {
}
Box box = new Box(Orientation.VERTICAL, 10);
- box.append(new Label("<b>%s</b>".printf(title ?? "This call is end-to-end encrypted.")) { use_markup=true, xalign=0 });
-
- if (video_encryption == null) {
- box.append(create_media_encryption_grid(audio_encryption));
+ if (single_encryption != null) {
+ box.append(new Label("<b>%s</b>".printf(title ?? "This call is end-to-end encrypted.")) { use_markup=true, xalign=0 });
+ box.append(create_media_encryption_grid(single_encryption));
} else {
- box.append(new Label("<b>Audio</b>") { use_markup=true, xalign=0 });
- box.append(create_media_encryption_grid(audio_encryption));
- box.append(new Label("<b>Video</b>") { use_markup=true, xalign=0 });
- box.append(create_media_encryption_grid(video_encryption));
+ box.append(new Label("<b>%s</b>".printf(title ?? "This call is partially end-to-end encrypted.")) { use_markup=true, xalign=0 });
+ if (has_audio) {
+ box.append(new Label("<b>Audio</b>") { use_markup=true, xalign=0 });
+ box.append(create_media_encryption_grid(audio_encryption));
+ }
+ if (has_video) {
+ box.append(new Label("<b>Video</b>") { use_markup=true, xalign=0 });
+ box.append(create_media_encryption_grid(video_encryption));
+ }
}
popover.set_child(box);
}
@@ -61,7 +84,10 @@ public class Dino.Ui.CallEncryptionButtonController : Object {
button.opacity = controls_active && has_been_set ? 1 : 0;
}
- private Grid create_media_encryption_grid(Xmpp.Xep.Jingle.ContentEncryption? encryption) {
+ private Widget create_media_encryption_grid(Xmpp.Xep.Jingle.ContentEncryption? encryption) {
+ if (encryption == null) {
+ return new Label("This content is unencrypted.") { xalign=0 };
+ }
Grid ret = new Grid() { row_spacing=3, column_spacing=5 };
if (encryption.peer_key.length > 0) {
ret.attach(new Label("Peer call key") { xalign=0 }, 1, 2, 1, 1);
diff --git a/main/src/ui/call_window/call_window_controller.vala b/main/src/ui/call_window/call_window_controller.vala
index 3fde9759..6e3eac6d 100644
--- a/main/src/ui/call_window/call_window_controller.vala
+++ b/main/src/ui/call_window/call_window_controller.vala
@@ -199,28 +199,34 @@ public class Dino.Ui.CallWindowController : Object {
call_window.set_status(peer_id, "ringing");
}
});
- peer_state.encryption_updated.connect((audio_encryption, video_encryption, same) => {
- update_encryption_indicator(participant_widgets[peer_id].encryption_button_controller, audio_encryption, video_encryption, same);
+ peer_state.encryption_updated.connect((state, audio_encryption, video_encryption) => {
+ update_encryption_indicator(participant_widgets[peer_id].encryption_button_controller, peer_states[peer_id].audio_content != null, audio_encryption, peer_states[peer_id].video_content != null, video_encryption);
});
}
- private void update_encryption_indicator(CallEncryptionButtonController encryption_button, Xep.Jingle.ContentEncryption? audio_encryption, Xep.Jingle.ContentEncryption? video_encryption, bool same) {
+ private void update_encryption_indicator(CallEncryptionButtonController encryption_button, bool has_audio, Xep.Jingle.ContentEncryption? audio_encryption, bool has_video, Xep.Jingle.ContentEncryption? video_encryption) {
string? title = null;
string? icon_name = null;
bool show_keys = true;
Plugins.Registry registry = Dino.Application.get_default().plugin_registry;
- Plugins.CallEncryptionEntry? encryption_entry = audio_encryption != null ? registry.call_encryption_entries[audio_encryption.encryption_ns] : null;
- if (encryption_entry != null) {
- Plugins.CallEncryptionWidget? encryption_widgets = encryption_entry.get_widget(call.account, audio_encryption);
- if (encryption_widgets != null) {
- title = encryption_widgets.get_title();
- icon_name = encryption_widgets.get_icon_name();
- show_keys = encryption_widgets.show_keys();
+ if (((has_audio && audio_encryption != null) || (has_video && video_encryption != null)) && (!has_audio || !has_video || (audio_encryption != null && video_encryption != null && audio_encryption.encryption_ns == video_encryption.encryption_ns))) {
+ Plugins.CallEncryptionEntry? encryption_entry = audio_encryption != null ? registry.call_encryption_entries[audio_encryption.encryption_ns] : null;
+ if (encryption_entry != null) {
+ Plugins.CallEncryptionWidget? audio_encryption_widgets = encryption_entry.get_widget(call.account, audio_encryption);
+ Plugins.CallEncryptionWidget? video_encryption_widgets = encryption_entry.get_widget(call.account, video_encryption);
+ if (audio_encryption_widgets != null && video_encryption_widgets != null) {
+ if (audio_encryption_widgets.get_title() == video_encryption_widgets.get_title())
+ title = audio_encryption_widgets.get_title();
+ if (audio_encryption_widgets.get_icon_name() == video_encryption_widgets.get_icon_name())
+ icon_name = audio_encryption_widgets.get_icon_name();
+ if (audio_encryption_widgets.show_keys() == video_encryption_widgets.show_keys())
+ show_keys = audio_encryption_widgets.show_keys();
+ }
}
}
- encryption_button.set_info(title, show_keys, audio_encryption, same ? null : video_encryption);
- encryption_button.set_icon(audio_encryption != null, icon_name);
+ encryption_button.set_info(title, show_keys, has_audio, audio_encryption, has_video, video_encryption);
+ encryption_button.set_icon((!has_audio || audio_encryption != null) && (!has_video || video_encryption != null), icon_name);
}
private void add_new_participant(string participant_id, Jid jid) {