aboutsummaryrefslogtreecommitdiff
path: root/libdino
diff options
context:
space:
mode:
authorfiaxh <git@lightrise.org>2021-04-08 12:07:04 +0200
committerfiaxh <git@lightrise.org>2021-04-09 22:23:13 +0200
commit8d1c6c29be7018c74ec3f8ea05f5849eac5b4069 (patch)
treedde27c13cd0ae8af31b9194b3450c58d4fe9cf02 /libdino
parent3454201e5a3da058ccbef0bbaf467599912a8c38 (diff)
downloaddino-8d1c6c29be7018c74ec3f8ea05f5849eac5b4069.tar.gz
dino-8d1c6c29be7018c74ec3f8ea05f5849eac5b4069.zip
Display+store call encryption info
Diffstat (limited to 'libdino')
-rw-r--r--libdino/src/entity/call.vala5
-rw-r--r--libdino/src/entity/encryption.vala4
-rw-r--r--libdino/src/service/calls.vala44
-rw-r--r--libdino/src/service/content_item_store.vala4
-rw-r--r--libdino/src/service/database.vala5
5 files changed, 55 insertions, 7 deletions
diff --git a/libdino/src/entity/call.vala b/libdino/src/entity/call.vala
index 7891dae7..577b3ab8 100644
--- a/libdino/src/entity/call.vala
+++ b/libdino/src/entity/call.vala
@@ -32,6 +32,7 @@ namespace Dino.Entities {
public DateTime time { get; set; }
public DateTime local_time { get; set; }
public DateTime end_time { get; set; }
+ public Encryption encryption { get; set; default=Encryption.NONE; }
public State state { get; set; }
@@ -57,6 +58,7 @@ namespace Dino.Entities {
time = new DateTime.from_unix_utc(row[db.call.time]);
local_time = new DateTime.from_unix_utc(row[db.call.local_time]);
end_time = new DateTime.from_unix_utc(row[db.call.end_time]);
+ encryption = (Encryption) row[db.call.encryption];
state = (State) row[db.call.state];
notify.connect(on_update);
@@ -74,6 +76,7 @@ namespace Dino.Entities {
.value(db.call.direction, direction)
.value(db.call.time, (long) time.to_unix())
.value(db.call.local_time, (long) local_time.to_unix())
+ .value(db.call.encryption, encryption)
.value(db.call.state, State.ENDED); // No point in persisting states that can't survive a restart
if (end_time != null) {
builder.value(db.call.end_time, (long) end_time.to_unix());
@@ -116,6 +119,8 @@ namespace Dino.Entities {
update_builder.set(db.call.local_time, (long) local_time.to_unix()); break;
case "end-time":
update_builder.set(db.call.end_time, (long) end_time.to_unix()); break;
+ case "encryption":
+ update_builder.set(db.call.encryption, encryption); break;
case "state":
// No point in persisting states that can't survive a restart
if (state == State.RINGING || state == State.ESTABLISHING || state == State.IN_PROGRESS) return;
diff --git a/libdino/src/entity/encryption.vala b/libdino/src/entity/encryption.vala
index b50556f9..25d55eb1 100644
--- a/libdino/src/entity/encryption.vala
+++ b/libdino/src/entity/encryption.vala
@@ -3,7 +3,9 @@ namespace Dino.Entities {
public enum Encryption {
NONE,
PGP,
- OMEMO
+ OMEMO,
+ DTLS_SRTP,
+ SRTP,
}
} \ No newline at end of file
diff --git a/libdino/src/service/calls.vala b/libdino/src/service/calls.vala
index 93636c03..b457c764 100644
--- a/libdino/src/service/calls.vala
+++ b/libdino/src/service/calls.vala
@@ -14,6 +14,7 @@ namespace Dino {
public signal void counterpart_ringing(Call call);
public signal void counterpart_sends_video_updated(Call call, bool mute);
public signal void info_received(Call call, Xep.JingleRtp.CallSessionInfo session_info);
+ public signal void encryption_updated(Call call, Xep.Jingle.ContentEncryption? encryption);
public signal void stream_created(Call call, string media);
@@ -22,7 +23,6 @@ namespace Dino {
private StreamInteractor stream_interactor;
private Database db;
- private Xep.JingleRtp.SessionInfoType session_info_type;
private HashMap<Account, HashMap<Call, string>> sid_by_call = new HashMap<Account, HashMap<Call, string>>(Account.hash_func, Account.equals_func);
private HashMap<Account, HashMap<string, Call>> call_by_sid = new HashMap<Account, HashMap<string, Call>>(Account.hash_func, Account.equals_func);
@@ -38,7 +38,10 @@ namespace Dino {
private HashMap<Call, Xep.JingleRtp.Parameters> audio_content_parameter = new HashMap<Call, Xep.JingleRtp.Parameters>(Call.hash_func, Call.equals_func);
private HashMap<Call, Xep.JingleRtp.Parameters> video_content_parameter = new HashMap<Call, Xep.JingleRtp.Parameters>(Call.hash_func, Call.equals_func);
+ private HashMap<Call, Xep.Jingle.Content> audio_content = new HashMap<Call, Xep.Jingle.Content>(Call.hash_func, Call.equals_func);
private HashMap<Call, Xep.Jingle.Content> video_content = new HashMap<Call, Xep.Jingle.Content>(Call.hash_func, Call.equals_func);
+ private HashMap<Call, Xep.Jingle.ContentEncryption> video_encryption = new HashMap<Call, Xep.Jingle.ContentEncryption>(Call.hash_func, Call.equals_func);
+ private HashMap<Call, Xep.Jingle.ContentEncryption> audio_encryption = new HashMap<Call, Xep.Jingle.ContentEncryption>(Call.hash_func, Call.equals_func);
public static void start(StreamInteractor stream_interactor, Database db) {
Calls m = new Calls(stream_interactor, db);
@@ -290,7 +293,7 @@ namespace Dino {
}
// Session might have already been accepted via Jingle Message Initiation
- bool already_accepted = jmi_sid.contains(account) &&
+ bool already_accepted = jmi_sid.has_key(account) &&
jmi_sid[account] == session.sid && jmi_call[account].account.equals(account) &&
jmi_call[account].counterpart.equals_bare(session.peer_full_jid) &&
jmi_video[account] == counterpart_wants_video;
@@ -365,6 +368,7 @@ namespace Dino {
if (call.state == Call.State.RINGING || call.state == Call.State.ESTABLISHING) {
call.state = Call.State.IN_PROGRESS;
}
+ update_call_encryption(call);
}
private void on_call_terminated(Call call, bool we_terminated, string? reason_name, string? reason_text) {
@@ -429,6 +433,7 @@ namespace Dino {
private void connect_content_signals(Call call, Xep.Jingle.Content content, Xep.JingleRtp.Parameters rtp_content_parameter) {
if (rtp_content_parameter.media == "audio") {
+ audio_content[call] = content;
audio_content_parameter[call] = rtp_content_parameter;
} else if (rtp_content_parameter.media == "video") {
video_content[call] = content;
@@ -450,6 +455,36 @@ namespace Dino {
on_counterpart_mute_update(call, false, "video");
}
});
+
+ content.notify["encryption"].connect((obj, _) => {
+ if (rtp_content_parameter.media == "audio") {
+ audio_encryption[call] = ((Xep.Jingle.Content) obj).encryption;
+ } else if (rtp_content_parameter.media == "video") {
+ video_encryption[call] = ((Xep.Jingle.Content) obj).encryption;
+ }
+ });
+ }
+
+ private void update_call_encryption(Call call) {
+ if (audio_encryption[call] == null) {
+ call.encryption = Encryption.NONE;
+ encryption_updated(call, null);
+ return;
+ }
+
+ bool consistent_encryption = video_encryption[call] != null && audio_encryption[call].encryption_ns == video_encryption[call].encryption_ns;
+
+ if (video_content[call] == null || consistent_encryption) {
+ if (audio_encryption[call].encryption_ns == Xep.JingleIceUdp.DTLS_NS_URI) {
+ call.encryption = Encryption.DTLS_SRTP;
+ } else if (audio_encryption[call].encryption_name == "SRTP") {
+ call.encryption = Encryption.SRTP;
+ }
+ encryption_updated(call, audio_encryption[call]);
+ } else {
+ call.encryption = Encryption.NONE;
+ encryption_updated(call, null);
+ }
}
private void remove_call_from_datastructures(Call call) {
@@ -465,7 +500,10 @@ namespace Dino {
audio_content_parameter.unset(call);
video_content_parameter.unset(call);
+ audio_content.unset(call);
video_content.unset(call);
+ audio_encryption.unset(call);
+ video_encryption.unset(call);
}
private void on_account_added(Account account) {
@@ -526,7 +564,7 @@ namespace Dino {
} else if (from.equals_bare(call_by_sid[account][sid].counterpart)) { // Message from our peer
// We proposed the call
if (jmi_sid.has_key(account) && jmi_sid[account] == sid) {
- call_resource(account, from, jmi_call[account], jmi_video[account], jmi_sid[account]);
+ call_resource.begin(account, from, jmi_call[account], jmi_video[account], jmi_sid[account]);
jmi_call.unset(account);
jmi_sid.unset(account);
jmi_video.unset(account);
diff --git a/libdino/src/service/content_item_store.vala b/libdino/src/service/content_item_store.vala
index cde8dd10..6ab0529c 100644
--- a/libdino/src/service/content_item_store.vala
+++ b/libdino/src/service/content_item_store.vala
@@ -316,10 +316,12 @@ public class CallItem : ContentItem {
public Conversation conversation;
public CallItem(Call call, Conversation conversation, int id) {
- base(id, TYPE, call.from, call.time, Encryption.NONE, Message.Marked.NONE);
+ base(id, TYPE, call.from, call.time, call.encryption, Message.Marked.NONE);
this.call = call;
this.conversation = conversation;
+
+ call.bind_property("encryption", this, "encryption");
}
}
diff --git a/libdino/src/service/database.vala b/libdino/src/service/database.vala
index 98e18d16..9703260a 100644
--- a/libdino/src/service/database.vala
+++ b/libdino/src/service/database.vala
@@ -7,7 +7,7 @@ using Dino.Entities;
namespace Dino {
public class Database : Qlite.Database {
- private const int VERSION = 20;
+ private const int VERSION = 21;
public class AccountTable : Table {
public Column<int> id = new Column.Integer("id") { primary_key = true, auto_increment = true };
@@ -165,11 +165,12 @@ public class Database : Qlite.Database {
public Column<long> time = new Column.Long("time") { not_null = true };
public Column<long> local_time = new Column.Long("local_time") { not_null = true };
public Column<long> end_time = new Column.Long("end_time");
+ public Column<int> encryption = new Column.Integer("encryption") { min_version=21 };
public Column<int> state = new Column.Integer("state");
internal CallTable(Database db) {
base(db, "call");
- init({id, account_id, counterpart_id, counterpart_resource, our_resource, direction, time, local_time, end_time, state});
+ init({id, account_id, counterpart_id, counterpart_resource, our_resource, direction, time, local_time, end_time, encryption, state});
}
}