aboutsummaryrefslogtreecommitdiff
path: root/plugins/omemo/src/database.vala
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2018-11-09 10:42:23 -0600
committerMarvin W <git@larma.de>2018-11-10 08:05:54 -0600
commit214906e1a527e618852fcef20e3d941ec3285301 (patch)
tree0651b415dd2a029e14011da401b98baccecc8e3c /plugins/omemo/src/database.vala
parentdfb75e2cda1eb9edbbdd9ea88c131d9cb31742ed (diff)
downloaddino-214906e1a527e618852fcef20e3d941ec3285301.tar.gz
dino-214906e1a527e618852fcef20e3d941ec3285301.zip
Hide OMEMO messages from untrusted sources
Diffstat (limited to 'plugins/omemo/src/database.vala')
-rw-r--r--plugins/omemo/src/database.vala39
1 files changed, 36 insertions, 3 deletions
diff --git a/plugins/omemo/src/database.vala b/plugins/omemo/src/database.vala
index 247c00f6..1bcd7cae 100644
--- a/plugins/omemo/src/database.vala
+++ b/plugins/omemo/src/database.vala
@@ -6,7 +6,7 @@ using Dino.Entities;
namespace Dino.Plugins.Omemo {
public class Database : Qlite.Database {
- private const int VERSION = 2;
+ private const int VERSION = 4;
public class IdentityMetaTable : Table {
public enum TrustLevel {
@@ -57,11 +57,17 @@ public class Database : Qlite.Database {
public int64 insert_device_bundle(int32 identity_id, string address_name, int device_id, Bundle bundle, TrustLevel trust) {
if (bundle == null || bundle.identity_key == null) return -1;
+ // Do not replace identity_key if it was known before, it should never change!
+ string identity_key = Base64.encode(bundle.identity_key.serialize());
+ RowOption row = with_address(identity_id, address_name).with(this.device_id, "=", device_id).single().row();
+ if (row.is_present() && row[identity_key_public_base64] != null && row[identity_key_public_base64] != identity_key) {
+ error("Tried to change the identity key for a known device id. Likely an attack.");
+ }
return upsert()
.value(this.identity_id, identity_id, true)
.value(this.address_name, address_name, true)
.value(this.device_id, device_id, true)
- .value(this.identity_key_public_base64, Base64.encode(bundle.identity_key.serialize()))
+ .value(this.identity_key_public_base64, identity_key)
.value(this.trust_level, trust).perform();
}
@@ -173,12 +179,38 @@ public class Database : Qlite.Database {
}
}
+ public class ContentItemMetaTable : Table {
+ public Column<int> content_item_id = new Column.Integer("message_id") { primary_key = true };
+ public Column<int> identity_id = new Column.Integer("identity_id") { not_null = true };
+ public Column<string> address_name = new Column.Text("address_name") { not_null = true };
+ public Column<int> device_id = new Column.Integer("device_id") { not_null = true };
+ public Column<bool> trusted_when_received = new Column.BoolInt("trusted_when_received") { not_null = true, default = "1" };
+
+ internal ContentItemMetaTable(Database db) {
+ base(db, "content_item_meta");
+ init({content_item_id, identity_id, address_name, device_id, trusted_when_received});
+ index("content_item_meta_device_idx", {identity_id, device_id, address_name});
+ }
+
+ public RowOption with_content_item(ContentItem item) {
+ return row_with(content_item_id, item.id);
+ }
+
+ public QueryBuilder with_device(int identity_id, string address_name, int device_id) {
+ return select()
+ .with(this.identity_id, "=", identity_id)
+ .with(this.address_name, "=", address_name)
+ .with(this.device_id, "=", device_id);
+ }
+ }
+
public IdentityMetaTable identity_meta { get; private set; }
public TrustTable trust { get; private set; }
public IdentityTable identity { get; private set; }
public SignedPreKeyTable signed_pre_key { get; private set; }
public PreKeyTable pre_key { get; private set; }
public SessionTable session { get; private set; }
+ public ContentItemMetaTable content_item_meta { get; private set; }
public Database(string fileName) {
base(fileName, VERSION);
@@ -188,7 +220,8 @@ public class Database : Qlite.Database {
signed_pre_key = new SignedPreKeyTable(this);
pre_key = new PreKeyTable(this);
session = new SessionTable(this);
- init({identity_meta, trust, identity, signed_pre_key, pre_key, session});
+ content_item_meta = new ContentItemMetaTable(this);
+ init({identity_meta, trust, identity, signed_pre_key, pre_key, session, content_item_meta});
try {
exec("PRAGMA synchronous=0");
} catch (Error e) { }