From b69ee7125d49493bea86c6e3095f1236ad895980 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 14 May 2015 15:25:52 +0200 Subject: Force Nameprepping of JID domain parts The IDN.toAscii()/IDN.toUnicode() family only namepreps the original domain passed to it if it contained non-ASCII characters. This means that for all-ASCII domains, no canonicalization is performed, which leads to issues like case-sensitivity. This workaround explicitly namepreps domain parts before calling IDN.toAscii() on them, in order to get a canonicalized representation (most notably, case invariance). A basic DB migration is also included. --- .../conversations/persistance/DatabaseBackend.java | 87 +++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 28e1c47e..ed88e434 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -4,11 +4,13 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import eu.siacs.conversations.Config; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Roster; +import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; import android.content.Context; @@ -16,13 +18,14 @@ import android.database.Cursor; import android.database.sqlite.SQLiteCantOpenDatabaseException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 13; + private static final int DATABASE_VERSION = 14; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -130,6 +133,88 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("delete from "+Contact.TABLENAME); db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); } + if (oldVersion < 14 && newVersion >= 14) { + // migrate db to new, canonicalized JID domainpart representation + + // Conversation table + Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID " + +cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Conversation.UUID)), + }; + db.execSQL("update " + Conversation.TABLENAME + + " set " + Conversation.CONTACTJID + " = ? " + + " where " + Conversation.UUID + " = ?", updateArgs); + } + cursor.close(); + + // Contact table + cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newJid; + try { + newJid = Jid.fromString( + cursor.getString(cursor.getColumnIndex(Contact.JID)) + ).toString(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Contact JID " + +cursor.getString(cursor.getColumnIndex(Contact.JID)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newJid, + cursor.getString(cursor.getColumnIndex(Contact.ACCOUNT)), + cursor.getString(cursor.getColumnIndex(Contact.JID)), + }; + db.execSQL("update " + Contact.TABLENAME + + " set " + Contact.JID + " = ? " + + " where " + Contact.ACCOUNT + " = ? " + + " AND " + Contact.JID + " = ?", updateArgs); + } + cursor.close(); + + // Account table + cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]); + while(cursor.moveToNext()) { + String newServer; + try { + newServer = Jid.fromParts( + cursor.getString(cursor.getColumnIndex(Account.USERNAME)), + cursor.getString(cursor.getColumnIndex(Account.SERVER)), + "mobile" + ).getDomainpart(); + } catch (InvalidJidException ignored) { + Log.e(Config.LOGTAG, "Failed to migrate Account SERVER " + +cursor.getString(cursor.getColumnIndex(Account.SERVER)) + +": " + ignored +". Skipping..."); + continue; + } + + String updateArgs[] = { + newServer, + cursor.getString(cursor.getColumnIndex(Account.UUID)), + }; + db.execSQL("update " + Account.TABLENAME + + " set " + Account.SERVER + " = ? " + + " where " + Account.UUID + " = ?", updateArgs); + } + cursor.close(); + } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From d30fb6f0a15fe574069694732bb23c339f0c30d1 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 3 Jul 2015 21:32:46 +0200 Subject: avoid very rare npe --- src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index ed88e434..d11b02fa 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -386,8 +386,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; String args[] = { roster.getAccount().getUuid() }; - cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", - args, null, null, null); + cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null); while (cursor.moveToNext()) { roster.initContact(Contact.fromCursor(cursor)); } -- cgit v1.2.3 From b8048a5538293b3855c2b2eae55d35645e614f11 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 29 May 2015 11:17:26 +0200 Subject: CryptoNext persistance layer mockup Initial sketch of the peripheral storage infrastructure for the new axolotl-based encryption scheme. --- .../conversations/persistance/DatabaseBackend.java | 263 ++++++++++++++++++++- 1 file changed, 262 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index d11b02fa..8d6d63c0 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -1,10 +1,12 @@ package eu.siacs.conversations.persistance; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import eu.siacs.conversations.Config; +import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -13,6 +15,7 @@ import eu.siacs.conversations.entities.Roster; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; +import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteCantOpenDatabaseException; @@ -20,6 +23,11 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; +import org.whispersystems.libaxolotl.AxolotlAddress; +import org.whispersystems.libaxolotl.state.PreKeyRecord; +import org.whispersystems.libaxolotl.state.SessionRecord; +import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; + public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; @@ -39,6 +47,40 @@ public class DatabaseBackend extends SQLiteOpenHelper { + ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", " + Contact.JID + ") ON CONFLICT REPLACE);"; + private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE " + + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " + + AxolotlService.SQLiteAxolotlStore.ID + + ") ON CONFLICT REPLACE" + +");"; + + private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE " + + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " + + AxolotlService.SQLiteAxolotlStore.ID + + ") ON CONFLICT REPLACE"+ + ");"; + + private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE " + + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID+ " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " + + AxolotlService.SQLiteAxolotlStore.NAME + + ") ON CONFLICT REPLACE" + +");"; + private DatabaseBackend(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -311,7 +353,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { }; Cursor cursor = db.query(Conversation.TABLENAME, null, Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID - + " like ? OR "+Conversation.CONTACTJID+"=?)", selectionArgs, null, null, null); + + " like ? OR " + Conversation.CONTACTJID + "=?)", selectionArgs, null, null, null); if (cursor.getCount() == 0) return null; cursor.moveToFirst(); @@ -481,4 +523,223 @@ public class DatabaseBackend extends SQLiteOpenHelper { cursor.close(); return list; } + + private Cursor getCursorForSession(Account account, AxolotlAddress contact) { + final SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = null; + String[] selectionArgs = {account.getUuid(), + contact.getName(), + Integer.toString(contact.getDeviceId())}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " = ? ", + selectionArgs, + null, null, null); + + return cursor; + } + + public SessionRecord loadSession(Account account, AxolotlAddress contact) { + SessionRecord session = null; + Cursor cursor = getCursorForSession(account, contact); + if(cursor.getCount() != 0) { + cursor.moveToFirst(); + try { + session = new SessionRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + } catch (IOException e) { + throw new AssertionError(e); + } + } + cursor.close(); + return session; + } + + public List getSubDeviceSessions(Account account, AxolotlAddress contact) { + List devices = new ArrayList<>(); + final SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = {AxolotlService.SQLiteAxolotlStore.DEVICE_ID}; + String[] selectionArgs = {account.getUuid(), + contact.getName()}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND ", + selectionArgs, + null, null, null); + + while(cursor.moveToNext()) { + devices.add(cursor.getInt( + cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.DEVICE_ID))); + } + + cursor.close(); + return devices; + } + + public boolean containsSession(Account account, AxolotlAddress contact) { + Cursor cursor = getCursorForSession(account, contact); + int count = cursor.getCount(); + cursor.close(); + return count != 0; + } + + public void storeSession(Account account, AxolotlAddress contact, SessionRecord session) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName()); + values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, session.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values); + } + + public void deleteSession(Account account, AxolotlAddress contact) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] args = {account.getUuid(), + contact.getName(), + Integer.toString(contact.getDeviceId())}; + db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " = ? ", + args); + } + + public void deleteAllSessions(Account account, AxolotlAddress contact) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] args = {account.getUuid(), contact.getName()}; + db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", + args); + } + + private Cursor getCursorForPreKey(Account account, int preKeyId) { + SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] selectionArgs = {account.getUuid(), Integer.toString(preKeyId)}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + + AxolotlService.SQLiteAxolotlStore.ID + "=?", + selectionArgs, + null, null, null); + + return cursor; + } + + public PreKeyRecord loadPreKey(Account account, int preKeyId) { + PreKeyRecord record = null; + Cursor cursor = getCursorForPreKey(account, preKeyId); + if(cursor.getCount() != 0) { + cursor.moveToFirst(); + try { + record = new PreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + } catch (IOException e ) { + throw new AssertionError(e); + } + } + cursor.close(); + return record; + } + + public boolean containsPreKey(Account account, int preKeyId) { + Cursor cursor = getCursorForPreKey(account, preKeyId); + int count = cursor.getCount(); + cursor.close(); + return count != 0; + } + + public void storePreKey(Account account, PreKeyRecord record) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, record.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, null, values); + } + + public void deletePreKey(Account account, int preKeyId) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] args = {account.getUuid(), Integer.toString(preKeyId)}; + db.delete(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + + AxolotlService.SQLiteAxolotlStore.ID + "=?", + args); + } + + private Cursor getCursorForSignedPreKey(Account account, int signedPreKeyId) { + SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] selectionArgs = {account.getUuid(), Integer.toString(signedPreKeyId)}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + AxolotlService.SQLiteAxolotlStore.ID + "=?", + selectionArgs, + null, null, null); + + return cursor; + } + + public SignedPreKeyRecord loadSignedPreKey(Account account, int signedPreKeyId) { + SignedPreKeyRecord record = null; + Cursor cursor = getCursorForPreKey(account, signedPreKeyId); + if(cursor.getCount() != 0) { + cursor.moveToFirst(); + try { + record = new SignedPreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + } catch (IOException e ) { + throw new AssertionError(e); + } + } + cursor.close(); + return record; + } + + public List loadSignedPreKeys(Account account) { + List prekeys = new ArrayList<>(); + SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] selectionArgs = {account.getUuid()}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=?", + selectionArgs, + null, null, null); + + while(cursor.moveToNext()) { + try { + prekeys.add(new SignedPreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes())); + } catch (IOException ignored) { + } + } + return prekeys; + } + + public boolean containsSignedPreKey(Account account, int signedPreKeyId) { + Cursor cursor = getCursorForPreKey(account, signedPreKeyId); + int count = cursor.getCount(); + cursor.close(); + return count != 0; + } + + public void storeSignedPreKey(Account account, SignedPreKeyRecord record) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, record.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values); + } + + public void deleteSignedPreKey(Account account, int signedPreKeyId) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] args = {account.getUuid(), Integer.toString(signedPreKeyId)}; + db.delete(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + + AxolotlService.SQLiteAxolotlStore.ID + "=?", + args); + } } -- cgit v1.2.3 From f73aa1a2006beb741bc39026bfd10e6166d7951a Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 25 Jun 2015 16:56:34 +0200 Subject: Reworked axolotl protocol layer Numerous fixes --- .../conversations/persistance/DatabaseBackend.java | 90 +++++++++++++++------- 1 file changed, 63 insertions(+), 27 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 8d6d63c0..af0e2fa8 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -1,5 +1,19 @@ package eu.siacs.conversations.persistance; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteCantOpenDatabaseException; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Base64; +import android.util.Log; + +import org.whispersystems.libaxolotl.AxolotlAddress; +import org.whispersystems.libaxolotl.state.PreKeyRecord; +import org.whispersystems.libaxolotl.state.SessionRecord; +import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; + import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -15,25 +29,12 @@ import eu.siacs.conversations.entities.Roster; import eu.siacs.conversations.xmpp.jid.InvalidJidException; import eu.siacs.conversations.xmpp.jid.Jid; -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteCantOpenDatabaseException; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; - -import org.whispersystems.libaxolotl.AxolotlAddress; -import org.whispersystems.libaxolotl.state.PreKeyRecord; -import org.whispersystems.libaxolotl.state.SessionRecord; -import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; - public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 14; + private static final int DATABASE_VERSION = 15; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -49,8 +50,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " @@ -60,8 +62,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " @@ -71,13 +74,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID+ " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + "TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.NAME + + AxolotlService.SQLiteAxolotlStore.NAME + ", " + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + ") ON CONFLICT REPLACE" +");"; @@ -257,6 +263,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { } cursor.close(); } + if (oldVersion < 15 && newVersion >= 15) { + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); + db.execSQL(CREATE_SESSIONS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME); + db.execSQL(CREATE_PREKEYS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); + db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); + } } public static synchronized DatabaseBackend getInstance(Context context) { @@ -547,7 +561,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - session = new SessionRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e) { throw new AssertionError(e); } @@ -590,7 +604,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName()); values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, session.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(),Base64.DEFAULT)); values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values); } @@ -616,6 +630,28 @@ public class DatabaseBackend extends SQLiteOpenHelper { args); } + public boolean isTrustedSession(Account account, AxolotlAddress contact) { + boolean trusted = false; + Cursor cursor = getCursorForSession(account, contact); + if(cursor.getCount() != 0) { + cursor.moveToFirst(); + trusted = cursor.getInt(cursor.getColumnIndex( + AxolotlService.SQLiteAxolotlStore.TRUSTED)) > 0; + } + cursor.close(); + return trusted; + } + + public void setTrustedSession(Account account, AxolotlAddress contact, boolean trusted) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName()); + values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); + values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted?1:0); + db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values); + } + private Cursor getCursorForPreKey(Account account, int preKeyId) { SQLiteDatabase db = this.getReadableDatabase(); String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; @@ -636,7 +672,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new PreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e ) { throw new AssertionError(e); } @@ -656,7 +692,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, record.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, null, values); } @@ -685,11 +721,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { public SignedPreKeyRecord loadSignedPreKey(Account account, int signedPreKeyId) { SignedPreKeyRecord record = null; - Cursor cursor = getCursorForPreKey(account, signedPreKeyId); + Cursor cursor = getCursorForSignedPreKey(account, signedPreKeyId); if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new SignedPreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes()); + record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e ) { throw new AssertionError(e); } @@ -711,7 +747,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { while(cursor.moveToNext()) { try { - prekeys.add(new SignedPreKeyRecord(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)).getBytes())); + prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)), Base64.DEFAULT))); } catch (IOException ignored) { } } @@ -729,7 +765,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, record.serialize()); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values); } -- cgit v1.2.3 From 299bbdf27f0144e6eed99e70a3b2e46f9a3aa301 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 26 Jun 2015 15:41:02 +0200 Subject: Reformat code to use tabs This really sucks to do it like this. Sorry. :( --- .../conversations/persistance/DatabaseBackend.java | 34 +++++++++++----------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index af0e2fa8..ee6c7636 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -42,7 +42,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Contact.JID + " TEXT," + Contact.KEYS + " TEXT," + Contact.PHOTOURI + " TEXT," + Contact.OPTIONS + " NUMBER," + Contact.SYSTEMACCOUNT + " NUMBER, " + Contact.AVATAR + " TEXT, " - + Contact.LAST_PRESENCE + " TEXT, " + Contact.LAST_TIME + " NUMBER, " + + Contact.LAST_PRESENCE + " TEXT, " + Contact.LAST_TIME + " NUMBER, " + Contact.GROUPS + " TEXT, FOREIGN KEY(" + Contact.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, UNIQUE(" + Contact.ACCOUNT + ", " @@ -75,14 +75,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME + "(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.NAME + ", " + + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " + + AxolotlService.SQLiteAxolotlStore.NAME + ", " + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + ") ON CONFLICT REPLACE" +");"; @@ -157,12 +157,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Conversation.TABLENAME + " ADD COLUMN " + Conversation.ATTRIBUTES + " TEXT"); } - if (oldVersion < 9 && newVersion >= 9) { - db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " - + Contact.LAST_TIME + " NUMBER"); - db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " - + Contact.LAST_PRESENCE + " TEXT"); - } + if (oldVersion < 9 && newVersion >= 9) { + db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + + Contact.LAST_TIME + " NUMBER"); + db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + + Contact.LAST_PRESENCE + " TEXT"); + } if (oldVersion < 10 && newVersion >= 10) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.RELATIVE_FILE_PATH + " TEXT"); @@ -557,7 +557,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public SessionRecord loadSession(Account account, AxolotlAddress contact) { SessionRecord session = null; - Cursor cursor = getCursorForSession(account, contact); + Cursor cursor = getCursorForSession(account, contact); if(cursor.getCount() != 0) { cursor.moveToFirst(); try { @@ -565,8 +565,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { } catch (IOException e) { throw new AssertionError(e); } - } - cursor.close(); + } + cursor.close(); return session; } @@ -635,7 +635,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { Cursor cursor = getCursorForSession(account, contact); if(cursor.getCount() != 0) { cursor.moveToFirst(); - trusted = cursor.getInt(cursor.getColumnIndex( + trusted = cursor.getInt(cursor.getColumnIndex( AxolotlService.SQLiteAxolotlStore.TRUSTED)) > 0; } cursor.close(); -- cgit v1.2.3 From 9e07fc5651015dc60e54bcb2f796d0f932d5f925 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 13:40:56 +0200 Subject: DatabaseBackend bugfixes Don't leak cursors, initially create tables --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index ee6c7636..966734ba 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -123,6 +123,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { + ") ON DELETE CASCADE);"); db.execSQL(CREATE_CONTATCS_STATEMENT); + db.execSQL(CREATE_SESSIONS_STATEMENT); + db.execSQL(CREATE_PREKEYS_STATEMENT); + db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); } @Override @@ -563,6 +566,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { try { session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e) { + cursor.close(); throw new AssertionError(e); } } @@ -751,6 +755,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } catch (IOException ignored) { } } + cursor.close(); return prekeys; } -- cgit v1.2.3 From 74026b742bd7e1d4b79fd839f887a0beb940b0dc Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 29 Jun 2015 13:53:39 +0200 Subject: Save IdentityKeys in database --- .../conversations/persistance/DatabaseBackend.java | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 966734ba..c70ffad2 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -10,13 +10,18 @@ import android.util.Base64; import android.util.Log; import org.whispersystems.libaxolotl.AxolotlAddress; +import org.whispersystems.libaxolotl.IdentityKey; +import org.whispersystems.libaxolotl.IdentityKeyPair; +import org.whispersystems.libaxolotl.InvalidKeyException; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.io.IOException; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import eu.siacs.conversations.Config; @@ -87,6 +92,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { + ") ON CONFLICT REPLACE" +");"; + private static String CREATE_IDENTITIES_STATEMENT = "CREATE TABLE " + + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME + "(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + + AxolotlService.SQLiteAxolotlStore.OWN + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE " + +");"; + private DatabaseBackend(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @@ -126,6 +141,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL(CREATE_SESSIONS_STATEMENT); db.execSQL(CREATE_PREKEYS_STATEMENT); db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); + db.execSQL(CREATE_IDENTITIES_STATEMENT); } @Override @@ -273,6 +289,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL(CREATE_PREKEYS_STATEMENT); db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME); + db.execSQL(CREATE_IDENTITIES_STATEMENT); } } @@ -783,4 +801,71 @@ public class DatabaseBackend extends SQLiteOpenHelper { + AxolotlService.SQLiteAxolotlStore.ID + "=?", args); } + + private Cursor getIdentityKeyCursor(Account account, String name, boolean own) { + final SQLiteDatabase db = this.getReadableDatabase(); + String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] selectionArgs = {account.getUuid(), + name, + own?"1":"0"}; + Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, + columns, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.OWN + " = ? ", + selectionArgs, + null, null, null); + + return cursor; + } + + public IdentityKeyPair loadOwnIdentityKeyPair(Account account, String name) { + IdentityKeyPair identityKeyPair = null; + Cursor cursor = getIdentityKeyCursor(account, name, true); + if(cursor.getCount() != 0) { + cursor.moveToFirst(); + try { + identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + } catch (InvalidKeyException e) { + Log.d(Config.LOGTAG, "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); + } + } + cursor.close(); + + return identityKeyPair; + } + + public Set loadIdentityKeys(Account account, String name) { + Set identityKeys = new HashSet<>(); + Cursor cursor = getIdentityKeyCursor(account, name, false); + + while(cursor.moveToNext()) { + try { + identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); + } catch (InvalidKeyException e) { + Log.d(Config.LOGTAG, "Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name); + } + } + cursor.close(); + + return identityKeys; + } + + private void storeIdentityKey(Account account, String name, boolean own, String base64Serialized) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + values.put(AxolotlService.SQLiteAxolotlStore.NAME, name); + values.put(AxolotlService.SQLiteAxolotlStore.OWN, own?1:0); + values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); + db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); + } + + public void storeIdentityKey(Account account, String name, IdentityKey identityKey) { + storeIdentityKey(account, name, false, Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); + } + + public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { + storeIdentityKey(account, name, true, Base64.encodeToString(identityKeyPair.serialize(),Base64.DEFAULT)); + } } -- cgit v1.2.3 From 7a962e51801cdf3e0ababc8f740a5d73afce0857 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 7 Jul 2015 19:30:08 +0200 Subject: Refactor axolotl database recreation --- .../conversations/persistance/DatabaseBackend.java | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index c70ffad2..a3868a1d 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -283,14 +283,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { cursor.close(); } if (oldVersion < 15 && newVersion >= 15) { - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); - db.execSQL(CREATE_SESSIONS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME); - db.execSQL(CREATE_PREKEYS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); - db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME); - db.execSQL(CREATE_IDENTITIES_STATEMENT); + recreateAxolotlDb(); } } @@ -868,4 +861,17 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { storeIdentityKey(account, name, true, Base64.encodeToString(identityKeyPair.serialize(),Base64.DEFAULT)); } + + public void recreateAxolotlDb() { + Log.d(Config.LOGTAG, ">>> (RE)CREATING AXOLOTL DATABASE <<<"); + SQLiteDatabase db = this.getWritableDatabase(); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); + db.execSQL(CREATE_SESSIONS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME); + db.execSQL(CREATE_PREKEYS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); + db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); + db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME); + db.execSQL(CREATE_IDENTITIES_STATEMENT); + } } -- cgit v1.2.3 From 7049904c326e6dabc02138fa436d209bf724e0bc Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 7 Jul 2015 19:36:22 +0200 Subject: Add basic PEP managemend UI to EditAccountActivity EditAccountActivity now show own fingerprint, and gives an option to regenerate local keying material (and wipe all sessions associated with the old keys in the process). It also now displays a list of other own devices, and gives an option to remove all but the current device. --- .../conversations/persistance/DatabaseBackend.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index a3868a1d..1aa2bade 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -874,4 +874,25 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME); db.execSQL(CREATE_IDENTITIES_STATEMENT); } + + public void wipeAxolotlDb(Account account) { + String accountName = account.getUuid(); + Log.d(Config.LOGTAG, ">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<"); + SQLiteDatabase db = this.getWritableDatabase(); + String[] deleteArgs= { + accountName + }; + db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + deleteArgs); + db.delete(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + deleteArgs); + db.delete(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + deleteArgs); + db.delete(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + deleteArgs); + } } -- cgit v1.2.3 From 3458f5bb9182ca99dd800e4cde21168323260da4 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 8 Jul 2015 17:44:24 +0200 Subject: Clean up logging Add a fixed prefix to axolotl-related log messages, set log levels sensibly. --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 1aa2bade..e408fa7f 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -820,7 +820,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { try { identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); } } cursor.close(); @@ -836,7 +836,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { try { identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, "Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name); } } cursor.close(); @@ -863,7 +863,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void recreateAxolotlDb() { - Log.d(Config.LOGTAG, ">>> (RE)CREATING AXOLOTL DATABASE <<<"); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+">>> (RE)CREATING AXOLOTL DATABASE <<<"); SQLiteDatabase db = this.getWritableDatabase(); db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); db.execSQL(CREATE_SESSIONS_STATEMENT); @@ -877,7 +877,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void wipeAxolotlDb(Account account) { String accountName = account.getUuid(); - Log.d(Config.LOGTAG, ">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<"); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<"); SQLiteDatabase db = this.getWritableDatabase(); String[] deleteArgs= { accountName -- cgit v1.2.3 From 03614a0262639d1f16b0fd13ec2f4ee0767205c9 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 9 Jul 2015 14:15:59 +0200 Subject: Fix getSubDeviceSessions SQL query --- src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index e408fa7f..4fb01942 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -594,7 +594,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, columns, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND ", + + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", selectionArgs, null, null, null); -- cgit v1.2.3 From d173913ebabbf8de2725dd296ae6428defd4b3b3 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Thu, 9 Jul 2015 14:23:17 +0200 Subject: Overhauled Message tagging Messages are now tagged with the IdentityKey fingerprint of the originating session. IdentityKeys have one of three trust states: undecided (default), trusted, and untrusted/not yet trusted. --- .../conversations/persistance/DatabaseBackend.java | 93 ++++++++++++++-------- 1 file changed, 58 insertions(+), 35 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 4fb01942..0da52010 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -82,7 +82,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " @@ -97,6 +96,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + AxolotlService.SQLiteAxolotlStore.OWN + " INTEGER, " + + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " TEXT PRIMARY KEY ON CONFLICT IGNORE, " + + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE " @@ -132,6 +133,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Message.STATUS + " NUMBER," + Message.TYPE + " NUMBER, " + Message.RELATIVE_FILE_PATH + " TEXT, " + Message.SERVER_MSG_ID + " TEXT, " + + Message.FINGERPRINT + " TEXT, " + Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY(" + Message.CONVERSATION + ") REFERENCES " + Conversation.TABLENAME + "(" + Conversation.UUID @@ -284,6 +286,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { } if (oldVersion < 15 && newVersion >= 15) { recreateAxolotlDb(); + db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + + Message.FINGERPRINT + " TEXT"); } } @@ -645,28 +649,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { args); } - public boolean isTrustedSession(Account account, AxolotlAddress contact) { - boolean trusted = false; - Cursor cursor = getCursorForSession(account, contact); - if(cursor.getCount() != 0) { - cursor.moveToFirst(); - trusted = cursor.getInt(cursor.getColumnIndex( - AxolotlService.SQLiteAxolotlStore.TRUSTED)) > 0; - } - cursor.close(); - return trusted; - } - - public void setTrustedSession(Account account, AxolotlAddress contact, boolean trusted) { - SQLiteDatabase db = this.getWritableDatabase(); - ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName()); - values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); - values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted?1:0); - db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values); - } - private Cursor getCursorForPreKey(Account account, int preKeyId) { SQLiteDatabase db = this.getReadableDatabase(); String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; @@ -796,17 +778,28 @@ public class DatabaseBackend extends SQLiteOpenHelper { } private Cursor getIdentityKeyCursor(Account account, String name, boolean own) { + return getIdentityKeyCursor(account, name, own, null); + } + + private Cursor getIdentityKeyCursor(Account account, String name, boolean own, String fingerprint) { final SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; - String[] selectionArgs = {account.getUuid(), - name, - own?"1":"0"}; + String[] columns = {AxolotlService.SQLiteAxolotlStore.TRUSTED, + AxolotlService.SQLiteAxolotlStore.KEY}; + ArrayList selectionArgs = new ArrayList<>(4); + selectionArgs.add(account.getUuid()); + selectionArgs.add(name); + selectionArgs.add(own?"1":"0"); + String selectionString = AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.OWN + " = ? "; + if (fingerprint != null){ + selectionArgs.add(fingerprint); + selectionString += "AND " +AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? "; + } Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.OWN + " = ? ", - selectionArgs, + selectionString, + selectionArgs.toArray(new String[selectionArgs.size()]), null, null, null); return cursor; @@ -844,22 +837,52 @@ public class DatabaseBackend extends SQLiteOpenHelper { return identityKeys; } - private void storeIdentityKey(Account account, String name, boolean own, String base64Serialized) { + private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); values.put(AxolotlService.SQLiteAxolotlStore.NAME, name); - values.put(AxolotlService.SQLiteAxolotlStore.OWN, own?1:0); + values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0); + values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint); values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } + public AxolotlService.SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String name, String fingerprint) { + Cursor cursor = getIdentityKeyCursor(account, name, false, fingerprint); + AxolotlService.SQLiteAxolotlStore.Trust trust = null; + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + int trustValue = cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)); + trust = AxolotlService.SQLiteAxolotlStore.Trust.values()[trustValue]; + } + cursor.close(); + return trust; + } + + public boolean setIdentityKeyTrust(Account account, String name, String fingerprint, AxolotlService.SQLiteAxolotlStore.Trust trust) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] selectionArgs = { + account.getUuid(), + name, + fingerprint + }; + ContentValues values = new ContentValues(); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal()); + int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? " + + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", + selectionArgs); + return rows == 1; + } + public void storeIdentityKey(Account account, String name, IdentityKey identityKey) { - storeIdentityKey(account, name, false, Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); + storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); } public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { - storeIdentityKey(account, name, true, Base64.encodeToString(identityKeyPair.serialize(),Base64.DEFAULT)); + storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT)); } public void recreateAxolotlDb() { -- cgit v1.2.3 From 160e4017dfbd458325b8b63cf527f190b3f5bc2d Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 10 Jul 2015 02:24:33 +0200 Subject: Fix IdentityKey storage model Added proper UNIQUE statement --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 0da52010..0ba2876a 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -96,11 +96,15 @@ public class DatabaseBackend extends SQLiteOpenHelper { + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " + AxolotlService.SQLiteAxolotlStore.OWN + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " TEXT PRIMARY KEY ON CONFLICT IGNORE, " + + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " TEXT, " + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + AxolotlService.SQLiteAxolotlStore.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE " + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " + + AxolotlService.SQLiteAxolotlStore.NAME + ", " + + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + + ") ON CONFLICT IGNORE" +");"; private DatabaseBackend(Context context) { -- cgit v1.2.3 From 31d375c2c374dc8a36539a78582f44accc13592e Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 10 Jul 2015 02:25:28 +0200 Subject: Fix setIdentityKeyTrust update statement --- src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 0ba2876a..4c6bf221 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -874,8 +874,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal()); int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", selectionArgs); return rows == 1; -- cgit v1.2.3 From 4038af2f4764f1d35d82822514d65d17ab45b302 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 15 Jul 2015 16:32:42 +0200 Subject: Fix trust status for outgoing messages Tag sent messages with own fingerprint, set own fingerprint as always trusted, include own fingerprint in database trust search, explicitly reset trust colorfilter --- .../conversations/persistance/DatabaseBackend.java | 37 ++++++++++++++-------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 4c6bf221..39ef5d36 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -785,20 +785,28 @@ public class DatabaseBackend extends SQLiteOpenHelper { return getIdentityKeyCursor(account, name, own, null); } - private Cursor getIdentityKeyCursor(Account account, String name, boolean own, String fingerprint) { + private Cursor getIdentityKeyCursor(Account account, String fingerprint) { + return getIdentityKeyCursor(account, null, null, fingerprint); + } + + private Cursor getIdentityKeyCursor(Account account, String name, Boolean own, String fingerprint) { final SQLiteDatabase db = this.getReadableDatabase(); String[] columns = {AxolotlService.SQLiteAxolotlStore.TRUSTED, AxolotlService.SQLiteAxolotlStore.KEY}; ArrayList selectionArgs = new ArrayList<>(4); selectionArgs.add(account.getUuid()); - selectionArgs.add(name); - selectionArgs.add(own?"1":"0"); - String selectionString = AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.OWN + " = ? "; + String selectionString = AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?"; + if (name != null){ + selectionArgs.add(name); + selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.NAME + " = ?"; + } if (fingerprint != null){ selectionArgs.add(fingerprint); - selectionString += "AND " +AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? "; + selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ?"; + } + if (own != null){ + selectionArgs.add(own?"1":"0"); + selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.OWN + " = ?"; } Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, columns, @@ -842,6 +850,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { } private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { + storeIdentityKey(account, name, own, fingerprint, base64Serialized, AxolotlService.SQLiteAxolotlStore.Trust.UNDECIDED); + } + + private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, AxolotlService.SQLiteAxolotlStore.Trust trusted) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); @@ -849,11 +861,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0); values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint); values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.ordinal()); db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } - public AxolotlService.SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String name, String fingerprint) { - Cursor cursor = getIdentityKeyCursor(account, name, false, fingerprint); + public AxolotlService.SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String fingerprint) { + Cursor cursor = getIdentityKeyCursor(account, fingerprint); AxolotlService.SQLiteAxolotlStore.Trust trust = null; if (cursor.getCount() > 0) { cursor.moveToFirst(); @@ -864,18 +877,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { return trust; } - public boolean setIdentityKeyTrust(Account account, String name, String fingerprint, AxolotlService.SQLiteAxolotlStore.Trust trust) { + public boolean setIdentityKeyTrust(Account account, String fingerprint, AxolotlService.SQLiteAxolotlStore.Trust trust) { SQLiteDatabase db = this.getWritableDatabase(); String[] selectionArgs = { account.getUuid(), - name, fingerprint }; ContentValues values = new ContentValues(); values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal()); int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", selectionArgs); return rows == 1; @@ -886,7 +897,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { - storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT)); + storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED); } public void recreateAxolotlDb() { -- cgit v1.2.3 From 14010bf5a6198e4e53ba3f86328d061cf20b8da1 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sun, 19 Jul 2015 18:36:28 +0200 Subject: Ask for key trust when sending messages If the contact (or the own account) has keys that have UNDECIDED trust, we now drop the user into the new TrustKeysActivity, where they have to decide for each new key whether it should be TRUSTED or UNTRUSTED. --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 39ef5d36..a2c62a8c 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -834,10 +834,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public Set loadIdentityKeys(Account account, String name) { + return loadIdentityKeys(account, name, null); + } + + public Set loadIdentityKeys(Account account, String name, AxolotlService.SQLiteAxolotlStore.Trust trust) { Set identityKeys = new HashSet<>(); Cursor cursor = getIdentityKeyCursor(account, name, false); while(cursor.moveToNext()) { + if ( trust != null && + cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)) + != trust.ordinal()) { + continue; + } try { identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); } catch (InvalidKeyException e) { -- cgit v1.2.3 From dd964077b97f4d8ca68cf4863a12e3eab0ce7771 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 13:15:49 +0200 Subject: Fix axolotl database migration Can't call getWritableDatabase in recreateAxolotlDb() --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index a2c62a8c..8168b1a6 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -289,7 +289,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { cursor.close(); } if (oldVersion < 15 && newVersion >= 15) { - recreateAxolotlDb(); + recreateAxolotlDb(db); db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.FINGERPRINT + " TEXT"); } @@ -910,8 +910,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void recreateAxolotlDb() { + recreateAxolotlDb(getWritableDatabase()); + } + + public void recreateAxolotlDb(SQLiteDatabase db) { Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+">>> (RE)CREATING AXOLOTL DATABASE <<<"); - SQLiteDatabase db = this.getWritableDatabase(); db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); db.execSQL(CREATE_SESSIONS_STATEMENT); db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME); -- cgit v1.2.3 From 19a0ae42d667644ee3400c92c53ad0ad093c52fe Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 14:56:41 +0200 Subject: Lock TrustKeys if no trusted keys are available --- .../siacs/conversations/persistance/DatabaseBackend.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 8168b1a6..71b4cba9 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -3,6 +3,7 @@ package eu.siacs.conversations.persistance; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; +import android.database.DatabaseUtils; import android.database.sqlite.SQLiteCantOpenDatabaseException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; @@ -858,6 +859,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { return identityKeys; } + public long numTrustedKeys(Account account, String name) { + SQLiteDatabase db = getReadableDatabase(); + String[] args = { + account.getUuid(), + name + }; + return DatabaseUtils.queryNumEntries(db, AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?" + + " AND " + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", + args + ); + } + private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { storeIdentityKey(account, name, own, fingerprint, base64Serialized, AxolotlService.SQLiteAxolotlStore.Trust.UNDECIDED); } -- cgit v1.2.3 From 0ee64124fe317f6959d1ff61cc9e70b272bf8eb5 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Mon, 20 Jul 2015 22:02:54 +0200 Subject: Fix getNumTrustedKeys --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 71b4cba9..6091b352 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -863,11 +863,13 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = getReadableDatabase(); String[] args = { account.getUuid(), - name + name, + String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.ordinal()) }; return DatabaseUtils.queryNumEntries(db, AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?" - + " AND " + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", + + " AND " + AxolotlService.SQLiteAxolotlStore.NAME + " = ?" + + " AND " + AxolotlService.SQLiteAxolotlStore.TRUSTED + " = ?", args ); } -- cgit v1.2.3 From b7ff2c34614a92f3893732338f75cb0f7fe77d32 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 21 Jul 2015 01:52:22 +0200 Subject: Use properly fixed numeral values in Trust enum Why, oh God, why?! #thanksjamesgosling --- .../eu/siacs/conversations/persistance/DatabaseBackend.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 6091b352..3120c008 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -845,7 +845,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { while(cursor.moveToNext()) { if ( trust != null && cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)) - != trust.ordinal()) { + != trust.getCode()) { continue; } try { @@ -864,7 +864,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid(), name, - String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.ordinal()) + String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.getCode()) }; return DatabaseUtils.queryNumEntries(db, AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?" @@ -886,7 +886,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0); values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint); values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.ordinal()); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.getCode()); db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } @@ -896,7 +896,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (cursor.getCount() > 0) { cursor.moveToFirst(); int trustValue = cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)); - trust = AxolotlService.SQLiteAxolotlStore.Trust.values()[trustValue]; + trust = AxolotlService.SQLiteAxolotlStore.Trust.fromCode(trustValue); } cursor.close(); return trust; @@ -909,7 +909,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { fingerprint }; ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.ordinal()); + values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.getCode()); int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", -- cgit v1.2.3 From efcefc2e6301f6255ebcb3e11f0f0a51731bacca Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Tue, 28 Jul 2015 22:00:54 +0200 Subject: Refactor out inner classes, cache trust store Moves SQLiteAxolotlStore and XmppAxolotlSession into proper classes. IdentityKeys trust statuses are now cached in an LruCache to prevent hammering the database when rendering the UI. --- .../conversations/persistance/DatabaseBackend.java | 261 +++++++++++---------- 1 file changed, 131 insertions(+), 130 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 3120c008..99dbcf34 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -27,6 +27,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; +import eu.siacs.conversations.crypto.axolotl.SQLiteAxolotlStore; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -55,56 +56,56 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Contact.JID + ") ON CONFLICT REPLACE);"; private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE " - + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME + "(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + SQLiteAxolotlStore.PREKEY_TABLENAME + "(" + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.ID + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.ID + ") ON CONFLICT REPLACE" +");"; private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE " - + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "(" + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.ID + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.ID + ") ON CONFLICT REPLACE"+ ");"; private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE " - + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME + "(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + SQLiteAxolotlStore.SESSION_TABLENAME + "(" + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.NAME + " TEXT, " + + SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.NAME + ", " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.NAME + ", " + + SQLiteAxolotlStore.DEVICE_ID + ") ON CONFLICT REPLACE" +");"; private static String CREATE_IDENTITIES_STATEMENT = "CREATE TABLE " - + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME + "(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.NAME + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.OWN + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " TEXT, " - + AxolotlService.SQLiteAxolotlStore.TRUSTED + " INTEGER, " - + AxolotlService.SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + AxolotlService.SQLiteAxolotlStore.ACCOUNT + + SQLiteAxolotlStore.IDENTITIES_TABLENAME + "(" + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.NAME + " TEXT, " + + SQLiteAxolotlStore.OWN + " INTEGER, " + + SQLiteAxolotlStore.FINGERPRINT + " TEXT, " + + SQLiteAxolotlStore.TRUSTED + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + AxolotlService.SQLiteAxolotlStore.ACCOUNT + ", " - + AxolotlService.SQLiteAxolotlStore.NAME + ", " - + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.NAME + ", " + + SQLiteAxolotlStore.FINGERPRINT + ") ON CONFLICT IGNORE" +");"; @@ -567,11 +568,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] selectionArgs = {account.getUuid(), contact.getName(), Integer.toString(contact.getDeviceId())}; - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.SESSION_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " = ? ", + SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + SQLiteAxolotlStore.NAME + " = ? AND " + + SQLiteAxolotlStore.DEVICE_ID + " = ? ", selectionArgs, null, null, null); @@ -584,7 +585,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e) { cursor.close(); throw new AssertionError(e); @@ -597,19 +598,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { public List getSubDeviceSessions(Account account, AxolotlAddress contact) { List devices = new ArrayList<>(); final SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.DEVICE_ID}; + String[] columns = {SQLiteAxolotlStore.DEVICE_ID}; String[] selectionArgs = {account.getUuid(), contact.getName()}; - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.SESSION_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", + SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + SQLiteAxolotlStore.NAME + " = ?", selectionArgs, null, null, null); while(cursor.moveToNext()) { devices.add(cursor.getInt( - cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.DEVICE_ID))); + cursor.getColumnIndex(SQLiteAxolotlStore.DEVICE_ID))); } cursor.close(); @@ -626,11 +627,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void storeSession(Account account, AxolotlAddress contact, SessionRecord session) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.NAME, contact.getName()); - values.put(AxolotlService.SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(),Base64.DEFAULT)); - values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); - db.insert(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, null, values); + values.put(SQLiteAxolotlStore.NAME, contact.getName()); + values.put(SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(SQLiteAxolotlStore.SESSION_TABLENAME, null, values); } public void deleteSession(Account account, AxolotlAddress contact) { @@ -638,30 +639,30 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = {account.getUuid(), contact.getName(), Integer.toString(contact.getDeviceId())}; - db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.DEVICE_ID + " = ? ", + db.delete(SQLiteAxolotlStore.SESSION_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + SQLiteAxolotlStore.NAME + " = ? AND " + + SQLiteAxolotlStore.DEVICE_ID + " = ? ", args); } public void deleteAllSessions(Account account, AxolotlAddress contact) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = {account.getUuid(), contact.getName()}; - db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " - + AxolotlService.SQLiteAxolotlStore.NAME + " = ?", + db.delete(SQLiteAxolotlStore.SESSION_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + "=? AND " + + SQLiteAxolotlStore.NAME + " = ?", args); } private Cursor getCursorForPreKey(Account account, int preKeyId) { SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] columns = {SQLiteAxolotlStore.KEY}; String[] selectionArgs = {account.getUuid(), Integer.toString(preKeyId)}; - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.PREKEY_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " - + AxolotlService.SQLiteAxolotlStore.ID + "=?", + SQLiteAxolotlStore.ACCOUNT + "=? AND " + + SQLiteAxolotlStore.ID + "=?", selectionArgs, null, null, null); @@ -674,7 +675,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e ) { throw new AssertionError(e); } @@ -693,28 +694,28 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void storePreKey(Account account, PreKeyRecord record) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); - values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); - db.insert(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, null, values); + values.put(SQLiteAxolotlStore.ID, record.getId()); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(SQLiteAxolotlStore.PREKEY_TABLENAME, null, values); } public void deletePreKey(Account account, int preKeyId) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = {account.getUuid(), Integer.toString(preKeyId)}; - db.delete(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " - + AxolotlService.SQLiteAxolotlStore.ID + "=?", + db.delete(SQLiteAxolotlStore.PREKEY_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + "=? AND " + + SQLiteAxolotlStore.ID + "=?", args); } private Cursor getCursorForSignedPreKey(Account account, int signedPreKeyId) { SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] columns = {SQLiteAxolotlStore.KEY}; String[] selectionArgs = {account.getUuid(), Integer.toString(signedPreKeyId)}; - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " + AxolotlService.SQLiteAxolotlStore.ID + "=?", + SQLiteAxolotlStore.ACCOUNT + "=? AND " + SQLiteAxolotlStore.ID + "=?", selectionArgs, null, null, null); @@ -727,7 +728,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (IOException e ) { throw new AssertionError(e); } @@ -739,17 +740,17 @@ public class DatabaseBackend extends SQLiteOpenHelper { public List loadSignedPreKeys(Account account) { List prekeys = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.KEY}; + String[] columns = {SQLiteAxolotlStore.KEY}; String[] selectionArgs = {account.getUuid()}; - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, columns, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=?", + SQLiteAxolotlStore.ACCOUNT + "=?", selectionArgs, null, null, null); while(cursor.moveToNext()) { try { - prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)), Base64.DEFAULT))); + prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT))); } catch (IOException ignored) { } } @@ -767,18 +768,18 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void storeSignedPreKey(Account account, SignedPreKeyRecord record) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.ID, record.getId()); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); - values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); - db.insert(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values); + values.put(SQLiteAxolotlStore.ID, record.getId()); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + db.insert(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values); } public void deleteSignedPreKey(Account account, int signedPreKeyId) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = {account.getUuid(), Integer.toString(signedPreKeyId)}; - db.delete(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + "=? AND " - + AxolotlService.SQLiteAxolotlStore.ID + "=?", + db.delete(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + "=? AND " + + SQLiteAxolotlStore.ID + "=?", args); } @@ -792,24 +793,24 @@ public class DatabaseBackend extends SQLiteOpenHelper { private Cursor getIdentityKeyCursor(Account account, String name, Boolean own, String fingerprint) { final SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {AxolotlService.SQLiteAxolotlStore.TRUSTED, - AxolotlService.SQLiteAxolotlStore.KEY}; + String[] columns = {SQLiteAxolotlStore.TRUSTED, + SQLiteAxolotlStore.KEY}; ArrayList selectionArgs = new ArrayList<>(4); selectionArgs.add(account.getUuid()); - String selectionString = AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?"; + String selectionString = SQLiteAxolotlStore.ACCOUNT + " = ?"; if (name != null){ selectionArgs.add(name); - selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.NAME + " = ?"; + selectionString += " AND " + SQLiteAxolotlStore.NAME + " = ?"; } if (fingerprint != null){ selectionArgs.add(fingerprint); - selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ?"; + selectionString += " AND " + SQLiteAxolotlStore.FINGERPRINT + " = ?"; } if (own != null){ selectionArgs.add(own?"1":"0"); - selectionString += " AND " +AxolotlService.SQLiteAxolotlStore.OWN + " = ?"; + selectionString += " AND " + SQLiteAxolotlStore.OWN + " = ?"; } - Cursor cursor = db.query(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, + Cursor cursor = db.query(SQLiteAxolotlStore.IDENTITIES_TABLENAME, columns, selectionString, selectionArgs.toArray(new String[selectionArgs.size()]), @@ -824,7 +825,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { if(cursor.getCount() != 0) { cursor.moveToFirst(); try { - identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); } catch (InvalidKeyException e) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); } @@ -838,18 +839,18 @@ public class DatabaseBackend extends SQLiteOpenHelper { return loadIdentityKeys(account, name, null); } - public Set loadIdentityKeys(Account account, String name, AxolotlService.SQLiteAxolotlStore.Trust trust) { + public Set loadIdentityKeys(Account account, String name, SQLiteAxolotlStore.Trust trust) { Set identityKeys = new HashSet<>(); Cursor cursor = getIdentityKeyCursor(account, name, false); while(cursor.moveToNext()) { if ( trust != null && - cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)) + cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)) != trust.getCode()) { continue; } try { - identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); + identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); } catch (InvalidKeyException e) { Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name); } @@ -864,55 +865,55 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid(), name, - String.valueOf(AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED.getCode()) + String.valueOf(SQLiteAxolotlStore.Trust.TRUSTED.getCode()) }; - return DatabaseUtils.queryNumEntries(db, AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?" - + " AND " + AxolotlService.SQLiteAxolotlStore.NAME + " = ?" - + " AND " + AxolotlService.SQLiteAxolotlStore.TRUSTED + " = ?", + return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ?" + + " AND " + SQLiteAxolotlStore.NAME + " = ?" + + " AND " + SQLiteAxolotlStore.TRUSTED + " = ?", args ); } private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { - storeIdentityKey(account, name, own, fingerprint, base64Serialized, AxolotlService.SQLiteAxolotlStore.Trust.UNDECIDED); + storeIdentityKey(account, name, own, fingerprint, base64Serialized, SQLiteAxolotlStore.Trust.UNDECIDED); } - private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, AxolotlService.SQLiteAxolotlStore.Trust trusted) { + private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, SQLiteAxolotlStore.Trust trusted) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.ACCOUNT, account.getUuid()); - values.put(AxolotlService.SQLiteAxolotlStore.NAME, name); - values.put(AxolotlService.SQLiteAxolotlStore.OWN, own ? 1 : 0); - values.put(AxolotlService.SQLiteAxolotlStore.FINGERPRINT, fingerprint); - values.put(AxolotlService.SQLiteAxolotlStore.KEY, base64Serialized); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trusted.getCode()); - db.insert(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); + values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); + values.put(SQLiteAxolotlStore.NAME, name); + values.put(SQLiteAxolotlStore.OWN, own ? 1 : 0); + values.put(SQLiteAxolotlStore.FINGERPRINT, fingerprint); + values.put(SQLiteAxolotlStore.KEY, base64Serialized); + values.put(SQLiteAxolotlStore.TRUSTED, trusted.getCode()); + db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } - public AxolotlService.SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String fingerprint) { + public SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String fingerprint) { Cursor cursor = getIdentityKeyCursor(account, fingerprint); - AxolotlService.SQLiteAxolotlStore.Trust trust = null; + SQLiteAxolotlStore.Trust trust = null; if (cursor.getCount() > 0) { cursor.moveToFirst(); - int trustValue = cursor.getInt(cursor.getColumnIndex(AxolotlService.SQLiteAxolotlStore.TRUSTED)); - trust = AxolotlService.SQLiteAxolotlStore.Trust.fromCode(trustValue); + int trustValue = cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)); + trust = SQLiteAxolotlStore.Trust.fromCode(trustValue); } cursor.close(); return trust; } - public boolean setIdentityKeyTrust(Account account, String fingerprint, AxolotlService.SQLiteAxolotlStore.Trust trust) { + public boolean setIdentityKeyTrust(Account account, String fingerprint, SQLiteAxolotlStore.Trust trust) { SQLiteDatabase db = this.getWritableDatabase(); String[] selectionArgs = { account.getUuid(), fingerprint }; ContentValues values = new ContentValues(); - values.put(AxolotlService.SQLiteAxolotlStore.TRUSTED, trust.getCode()); - int rows = db.update(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + AxolotlService.SQLiteAxolotlStore.FINGERPRINT + " = ? ", + values.put(SQLiteAxolotlStore.TRUSTED, trust.getCode()); + int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, + SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + SQLiteAxolotlStore.FINGERPRINT + " = ? ", selectionArgs); return rows == 1; } @@ -922,7 +923,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { - storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), AxolotlService.SQLiteAxolotlStore.Trust.TRUSTED); + storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), SQLiteAxolotlStore.Trust.TRUSTED); } public void recreateAxolotlDb() { @@ -931,13 +932,13 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void recreateAxolotlDb(SQLiteDatabase db) { Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+">>> (RE)CREATING AXOLOTL DATABASE <<<"); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME); + db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.SESSION_TABLENAME); db.execSQL(CREATE_SESSIONS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME); + db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.PREKEY_TABLENAME); db.execSQL(CREATE_PREKEYS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); + db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME); db.execSQL(CREATE_SIGNED_PREKEYS_STATEMENT); - db.execSQL("DROP TABLE IF EXISTS " + AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME); + db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.IDENTITIES_TABLENAME); db.execSQL(CREATE_IDENTITIES_STATEMENT); } @@ -948,17 +949,17 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] deleteArgs= { accountName }; - db.delete(AxolotlService.SQLiteAxolotlStore.SESSION_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + db.delete(SQLiteAxolotlStore.SESSION_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ?", deleteArgs); - db.delete(AxolotlService.SQLiteAxolotlStore.PREKEY_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + db.delete(SQLiteAxolotlStore.PREKEY_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ?", deleteArgs); - db.delete(AxolotlService.SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + db.delete(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ?", deleteArgs); - db.delete(AxolotlService.SQLiteAxolotlStore.IDENTITIES_TABLENAME, - AxolotlService.SQLiteAxolotlStore.ACCOUNT + " = ?", + db.delete(SQLiteAxolotlStore.IDENTITIES_TABLENAME, + SQLiteAxolotlStore.ACCOUNT + " = ?", deleteArgs); } } -- cgit v1.2.3 From e6df4d81d23e4b7c0c3798f114714dd3caebfe8c Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Wed, 29 Jul 2015 16:41:58 +0200 Subject: Tag carbon messages in parser, adapt session logic Messages sent from another device of the own account are now explicitly tagged as carboned message. The session detection logic now uses this tag to find "session borders". --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 99dbcf34..b3fce845 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -41,7 +41,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 15; + private static final int DATABASE_VERSION = 16; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -295,6 +295,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.FINGERPRINT + " TEXT"); } + if (oldVersion < 16 && newVersion >= 16) { + db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + + Message.CARBON + " INTEGER"); + } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From 26ac7c90306a566850139a3038a45402a964fcfd Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 31 Jul 2015 13:08:35 +0200 Subject: added missing carbon column message table create statement fixes #1310 --- src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 1 + 1 file changed, 1 insertion(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index b3fce845..8ac2884e 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -140,6 +140,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Message.RELATIVE_FILE_PATH + " TEXT, " + Message.SERVER_MSG_ID + " TEXT, " + Message.FINGERPRINT + " TEXT, " + + Message.CARBON + " INTEGER, " + Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY(" + Message.CONVERSATION + ") REFERENCES " + Conversation.TABLENAME + "(" + Conversation.UUID -- cgit v1.2.3 From 6cd9383e53900e03d324b227c0f01b1537881148 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sat, 1 Aug 2015 18:27:52 +0200 Subject: Let UNTRUSTED/UNDECIDED keys become INACTIVE --- .../conversations/persistance/DatabaseBackend.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 8ac2884e..9fe47512 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -28,6 +28,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import eu.siacs.conversations.Config; import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.SQLiteAxolotlStore; +import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Contact; import eu.siacs.conversations.entities.Conversation; @@ -844,7 +845,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { return loadIdentityKeys(account, name, null); } - public Set loadIdentityKeys(Account account, String name, SQLiteAxolotlStore.Trust trust) { + public Set loadIdentityKeys(Account account, String name, XmppAxolotlSession.Trust trust) { Set identityKeys = new HashSet<>(); Cursor cursor = getIdentityKeyCursor(account, name, false); @@ -870,7 +871,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid(), name, - String.valueOf(SQLiteAxolotlStore.Trust.TRUSTED.getCode()) + String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode()) }; return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, SQLiteAxolotlStore.ACCOUNT + " = ?" @@ -881,10 +882,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { } private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized) { - storeIdentityKey(account, name, own, fingerprint, base64Serialized, SQLiteAxolotlStore.Trust.UNDECIDED); + storeIdentityKey(account, name, own, fingerprint, base64Serialized, XmppAxolotlSession.Trust.UNDECIDED); } - private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, SQLiteAxolotlStore.Trust trusted) { + private void storeIdentityKey(Account account, String name, boolean own, String fingerprint, String base64Serialized, XmppAxolotlSession.Trust trusted) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); @@ -896,19 +897,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.insert(SQLiteAxolotlStore.IDENTITIES_TABLENAME, null, values); } - public SQLiteAxolotlStore.Trust isIdentityKeyTrusted(Account account, String fingerprint) { + public XmppAxolotlSession.Trust isIdentityKeyTrusted(Account account, String fingerprint) { Cursor cursor = getIdentityKeyCursor(account, fingerprint); - SQLiteAxolotlStore.Trust trust = null; + XmppAxolotlSession.Trust trust = null; if (cursor.getCount() > 0) { cursor.moveToFirst(); int trustValue = cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)); - trust = SQLiteAxolotlStore.Trust.fromCode(trustValue); + trust = XmppAxolotlSession.Trust.fromCode(trustValue); } cursor.close(); return trust; } - public boolean setIdentityKeyTrust(Account account, String fingerprint, SQLiteAxolotlStore.Trust trust) { + public boolean setIdentityKeyTrust(Account account, String fingerprint, XmppAxolotlSession.Trust trust) { SQLiteDatabase db = this.getWritableDatabase(); String[] selectionArgs = { account.getUuid(), @@ -928,7 +929,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { - storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), SQLiteAxolotlStore.Trust.TRUSTED); + storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED); } public void recreateAxolotlDb() { -- cgit v1.2.3 From e2d506c96a0a72b7a903d28d9b3a858430700266 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Sat, 5 Sep 2015 17:25:46 +0200 Subject: Never build a session with oneself If we detect our own ID is not in our own devicelist on receiving an update, we reannounce ourselves. This used to have the side effect of modifying the list of devices we thought were in the update set, causing us to accidentally build a session with ourselves. This lead to our own key being set to TRUSTED_INACTIVE, resulting in red lock icons on messages sent by the own device. We fix this by having publishOwnDeviceId() operate on a copy of the original set. This commit also includes a db migration which deletes sessions with oneself and sets own keys back to TRUSTED. --- .../conversations/persistance/DatabaseBackend.java | 67 ++++++++++++++++++---- 1 file changed, 56 insertions(+), 11 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 9fe47512..44063a54 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -42,7 +42,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 16; + private static final int DATABASE_VERSION = 17; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -301,6 +301,20 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.CARBON + " INTEGER"); } + if (oldVersion < 17 && newVersion >= 17) { + List accounts = getAccounts(db); + for (Account account : accounts) { + String ownDeviceIdString = account.getKey(SQLiteAxolotlStore.JSONKEY_REGISTRATION_ID); + if ( ownDeviceIdString == null ) { + continue; + } + int ownDeviceId = Integer.valueOf(ownDeviceIdString); + AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), ownDeviceId); + deleteSession(db, account, ownAddress); + IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account); + setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED ); + } + } } public static synchronized DatabaseBackend getInstance(Context context) { @@ -414,8 +428,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public List getAccounts() { - List list = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); + return getAccounts(db); + } + + private List getAccounts(SQLiteDatabase db) { + List list = new ArrayList<>(); Cursor cursor = db.query(Account.TABLENAME, null, null, null, null, null, null); while (cursor.moveToNext()) { @@ -602,8 +620,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public List getSubDeviceSessions(Account account, AxolotlAddress contact) { - List devices = new ArrayList<>(); final SQLiteDatabase db = this.getReadableDatabase(); + return getSubDeviceSessions(db, account, contact); + } + + private List getSubDeviceSessions(SQLiteDatabase db, Account account, AxolotlAddress contact) { + List devices = new ArrayList<>(); String[] columns = {SQLiteAxolotlStore.DEVICE_ID}; String[] selectionArgs = {account.getUuid(), contact.getName()}; @@ -642,6 +664,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void deleteSession(Account account, AxolotlAddress contact) { SQLiteDatabase db = this.getWritableDatabase(); + deleteSession(db, account, contact); + } + + private void deleteSession(SQLiteDatabase db, Account account, AxolotlAddress contact) { String[] args = {account.getUuid(), contact.getName(), Integer.toString(contact.getDeviceId())}; @@ -790,15 +816,24 @@ public class DatabaseBackend extends SQLiteOpenHelper { } private Cursor getIdentityKeyCursor(Account account, String name, boolean own) { - return getIdentityKeyCursor(account, name, own, null); + final SQLiteDatabase db = this.getReadableDatabase(); + return getIdentityKeyCursor(db, account, name, own); } - private Cursor getIdentityKeyCursor(Account account, String fingerprint) { - return getIdentityKeyCursor(account, null, null, fingerprint); + private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, boolean own) { + return getIdentityKeyCursor(db, account, name, own, null); } - private Cursor getIdentityKeyCursor(Account account, String name, Boolean own, String fingerprint) { + private Cursor getIdentityKeyCursor(Account account, String fingerprint) { final SQLiteDatabase db = this.getReadableDatabase(); + return getIdentityKeyCursor(db, account, fingerprint); + } + + private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String fingerprint) { + return getIdentityKeyCursor(db, account, null, null, fingerprint); + } + + private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, Boolean own, String fingerprint) { String[] columns = {SQLiteAxolotlStore.TRUSTED, SQLiteAxolotlStore.KEY}; ArrayList selectionArgs = new ArrayList<>(4); @@ -825,9 +860,15 @@ public class DatabaseBackend extends SQLiteOpenHelper { return cursor; } - public IdentityKeyPair loadOwnIdentityKeyPair(Account account, String name) { + public IdentityKeyPair loadOwnIdentityKeyPair(Account account) { + SQLiteDatabase db = getReadableDatabase(); + return loadOwnIdentityKeyPair(db, account); + } + + private IdentityKeyPair loadOwnIdentityKeyPair(SQLiteDatabase db, Account account) { + String name = account.getJid().toBareJid().toString(); IdentityKeyPair identityKeyPair = null; - Cursor cursor = getIdentityKeyCursor(account, name, true); + Cursor cursor = getIdentityKeyCursor(db, account, name, true); if(cursor.getCount() != 0) { cursor.moveToFirst(); try { @@ -911,6 +952,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { public boolean setIdentityKeyTrust(Account account, String fingerprint, XmppAxolotlSession.Trust trust) { SQLiteDatabase db = this.getWritableDatabase(); + return setIdentityKeyTrust(db, account, fingerprint, trust); + } + + private boolean setIdentityKeyTrust(SQLiteDatabase db, Account account, String fingerprint, XmppAxolotlSession.Trust trust) { String[] selectionArgs = { account.getUuid(), fingerprint @@ -928,8 +973,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); } - public void storeOwnIdentityKeyPair(Account account, String name, IdentityKeyPair identityKeyPair) { - storeIdentityKey(account, name, true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED); + public void storeOwnIdentityKeyPair(Account account, IdentityKeyPair identityKeyPair) { + storeIdentityKey(account, account.getJid().toBareJid().toString(), true, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKeyPair.serialize(), Base64.DEFAULT), XmppAxolotlSession.Trust.TRUSTED); } public void recreateAxolotlDb() { -- cgit v1.2.3 From 2c4a6b09127c8e6776020cd90c782ab950a70324 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 5 Sep 2015 18:47:37 +0200 Subject: add null pointer check to db migration --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 44063a54..d420c1cd 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -312,7 +312,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { AxolotlAddress ownAddress = new AxolotlAddress(account.getJid().toBareJid().toString(), ownDeviceId); deleteSession(db, account, ownAddress); IdentityKeyPair identityKeyPair = loadOwnIdentityKeyPair(db, account); - setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED ); + if (identityKeyPair != null) { + setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED); + } else { + Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not load own identity key pair"); + } } } } -- cgit v1.2.3 From 024e697cee47955019d842faa440381e814487b0 Mon Sep 17 00:00:00 2001 From: fiaxh Date: Sun, 20 Sep 2015 22:17:32 +0100 Subject: Iterator to go through all messages of a conversation --- .../conversations/persistance/DatabaseBackend.java | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index d420c1cd..be827929 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -21,6 +21,7 @@ import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; @@ -407,6 +408,43 @@ public class DatabaseBackend extends SQLiteOpenHelper { return list; } + public Iterable getMessagesIterable(final Conversation conversation){ + return new Iterable() { + @Override + public Iterator iterator() { + class MessageIterator implements Iterator{ + SQLiteDatabase db = getReadableDatabase(); + String[] selectionArgs = { conversation.getUuid() }; + Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION + + "=?", selectionArgs, null, null, Message.TIME_SENT + + " ASC", null); + + public MessageIterator() { + cursor.moveToFirst(); + } + + @Override + public boolean hasNext() { + return !cursor.isAfterLast(); + } + + @Override + public Message next() { + Message message = Message.fromCursor(cursor); + cursor.moveToNext(); + return message; + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } + return new MessageIterator(); + } + }; + } + public Conversation findConversation(final Account account, final Jid contactJid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = { account.getUuid(), -- cgit v1.2.3 From 5f9476448f54113e27f04f38fd64959b13bcd97b Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 14 Oct 2015 21:18:34 +0200 Subject: make unread status and notifications presistent across restarts --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index be827929..07071323 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 17; + private static final int DATABASE_VERSION = 18; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -143,6 +143,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Message.SERVER_MSG_ID + " TEXT, " + Message.FINGERPRINT + " TEXT, " + Message.CARBON + " INTEGER, " + + Message.READ + " NUMBER DEFAULT 1, " + Message.REMOTE_MSG_ID + " TEXT, FOREIGN KEY(" + Message.CONVERSATION + ") REFERENCES " + Conversation.TABLENAME + "(" + Conversation.UUID @@ -320,6 +321,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { } } } + if (oldVersion < 18 && newVersion >= 18) { + db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1"); + } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From c7ff196f58b5576ca1aeb5fd6d51bbe500754f06 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Thu, 29 Oct 2015 13:41:08 +0100 Subject: push CN into nick pep node when uploading certificate. subscribe to nick node --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 07071323..707237a1 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 18; + private static final int DATABASE_VERSION = 19; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -121,6 +121,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("create table " + Account.TABLENAME + "(" + Account.UUID + " TEXT PRIMARY KEY," + Account.USERNAME + " TEXT," + Account.SERVER + " TEXT," + Account.PASSWORD + " TEXT," + + Account.DISPLAY_NAME + " TEXT, " + Account.ROSTERVERSION + " TEXT," + Account.OPTIONS + " NUMBER, " + Account.AVATAR + " TEXT, " + Account.KEYS + " TEXT)"); @@ -324,6 +325,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 18 && newVersion >= 18) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1"); } + if (oldVersion < 19 && newVersion >= 19) { + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN "+ Account.DISPLAY_NAME+ " TEXT"); + } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From bca29cf7fd6fcf7438f39d81833cda18a94eefd9 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 31 Oct 2015 10:57:57 +0100 Subject: explicitly mark verified omemo keys in UI --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 707237a1..fdbfe4fe 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -962,12 +962,13 @@ public class DatabaseBackend extends SQLiteOpenHelper { String[] args = { account.getUuid(), name, - String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode()) + String.valueOf(XmppAxolotlSession.Trust.TRUSTED.getCode()), + String.valueOf(XmppAxolotlSession.Trust.TRUSTED_X509.getCode()) }; return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, SQLiteAxolotlStore.ACCOUNT + " = ?" + " AND " + SQLiteAxolotlStore.NAME + " = ?" - + " AND " + SQLiteAxolotlStore.TRUSTED + " = ?", + + " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR "+SQLiteAxolotlStore.TRUSTED+ " = ?)", args ); } -- cgit v1.2.3 From c6e54e7e5a3e402553d2f57e2997fb80d029d559 Mon Sep 17 00:00:00 2001 From: Andreas Straub Date: Fri, 6 Nov 2015 14:50:55 +0100 Subject: Move migration 19 before 17 Migration 17 depends on Account deserialization, so any migrations that touch the accounts table need to be applied beforehand. Re-writing the migration to work directly on the database would lead to a lot of code duplication, so it's not worth it at this time, but might become necessary later on to avoid dependency cycles. --- .../java/eu/siacs/conversations/persistance/DatabaseBackend.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index fdbfe4fe..0e133d19 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -304,6 +304,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.CARBON + " INTEGER"); } + if (oldVersion < 19 && newVersion >= 19) { + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN "+ Account.DISPLAY_NAME+ " TEXT"); + } + /* Any migrations that alter the Account table need to happen BEFORE this migration, as it + * depends on account de-serialization. + */ if (oldVersion < 17 && newVersion >= 17) { List accounts = getAccounts(db); for (Account account : accounts) { @@ -325,9 +331,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 18 && newVersion >= 18) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1"); } - if (oldVersion < 19 && newVersion >= 19) { - db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN "+ Account.DISPLAY_NAME+ " TEXT"); - } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From f0b1761ec3826b72fe3b20032b532dc5b1adfc1c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 28 Nov 2015 20:11:38 +0100 Subject: initial tor support --- .../conversations/persistance/DatabaseBackend.java | 222 +++++++++++---------- 1 file changed, 113 insertions(+), 109 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 0e133d19..8b74581c 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 19; + private static final int DATABASE_VERSION = 20; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -59,41 +59,41 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static String CREATE_PREKEYS_STATEMENT = "CREATE TABLE " + SQLiteAxolotlStore.PREKEY_TABLENAME + "(" - + SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + SQLiteAxolotlStore.ID + " INTEGER, " - + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + SQLiteAxolotlStore.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " - + SQLiteAxolotlStore.ID - + ") ON CONFLICT REPLACE" - +");"; + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.ID + + ") ON CONFLICT REPLACE" + + ");"; private static String CREATE_SIGNED_PREKEYS_STATEMENT = "CREATE TABLE " + SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME + "(" - + SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + SQLiteAxolotlStore.ID + " INTEGER, " - + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + SQLiteAxolotlStore.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " - + SQLiteAxolotlStore.ID - + ") ON CONFLICT REPLACE"+ + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.ID + + ") ON CONFLICT REPLACE" + ");"; private static String CREATE_SESSIONS_STATEMENT = "CREATE TABLE " + SQLiteAxolotlStore.SESSION_TABLENAME + "(" - + SQLiteAxolotlStore.ACCOUNT + " TEXT, " - + SQLiteAxolotlStore.NAME + " TEXT, " - + SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " - + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" - + SQLiteAxolotlStore.ACCOUNT - + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " - + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " - + SQLiteAxolotlStore.NAME + ", " - + SQLiteAxolotlStore.DEVICE_ID - + ") ON CONFLICT REPLACE" - +");"; + + SQLiteAxolotlStore.ACCOUNT + " TEXT, " + + SQLiteAxolotlStore.NAME + " TEXT, " + + SQLiteAxolotlStore.DEVICE_ID + " INTEGER, " + + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + + SQLiteAxolotlStore.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " + + SQLiteAxolotlStore.NAME + ", " + + SQLiteAxolotlStore.DEVICE_ID + + ") ON CONFLICT REPLACE" + + ");"; private static String CREATE_IDENTITIES_STATEMENT = "CREATE TABLE " + SQLiteAxolotlStore.IDENTITIES_TABLENAME + "(" @@ -106,10 +106,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { + SQLiteAxolotlStore.ACCOUNT + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + ") ON DELETE CASCADE, " + "UNIQUE( " + SQLiteAxolotlStore.ACCOUNT + ", " - + SQLiteAxolotlStore.NAME + ", " - + SQLiteAxolotlStore.FINGERPRINT + + SQLiteAxolotlStore.NAME + ", " + + SQLiteAxolotlStore.FINGERPRINT + ") ON CONFLICT IGNORE" - +");"; + + ");"; private DatabaseBackend(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); @@ -124,7 +124,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Account.DISPLAY_NAME + " TEXT, " + Account.ROSTERVERSION + " TEXT," + Account.OPTIONS + " NUMBER, " + Account.AVATAR + " TEXT, " + Account.KEYS - + " TEXT)"); + + " TEXT, " + Account.HOSTNAME + " TEXT, " + Account.PORT + " NUMBER DEFAULT 5222)"); db.execSQL("create table " + Conversation.TABLENAME + " (" + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME + " TEXT, " + Conversation.CONTACT + " TEXT, " @@ -202,23 +202,23 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 11 && newVersion >= 11) { db.execSQL("ALTER TABLE " + Contact.TABLENAME + " ADD COLUMN " + Contact.GROUPS + " TEXT"); - db.execSQL("delete from "+Contact.TABLENAME); - db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); + db.execSQL("delete from " + Contact.TABLENAME); + db.execSQL("update " + Account.TABLENAME + " set " + Account.ROSTERVERSION + " = NULL"); } if (oldVersion < 12 && newVersion >= 12) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.SERVER_MSG_ID + " TEXT"); } if (oldVersion < 13 && newVersion >= 13) { - db.execSQL("delete from "+Contact.TABLENAME); - db.execSQL("update "+Account.TABLENAME+" set "+Account.ROSTERVERSION+" = NULL"); + db.execSQL("delete from " + Contact.TABLENAME); + db.execSQL("update " + Account.TABLENAME + " set " + Account.ROSTERVERSION + " = NULL"); } if (oldVersion < 14 && newVersion >= 14) { // migrate db to new, canonicalized JID domainpart representation // Conversation table Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME, new String[0]); - while(cursor.moveToNext()) { + while (cursor.moveToNext()) { String newJid; try { newJid = Jid.fromString( @@ -226,8 +226,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { ).toString(); } catch (InvalidJidException ignored) { Log.e(Config.LOGTAG, "Failed to migrate Conversation CONTACTJID " - +cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) - +": " + ignored +". Skipping..."); + + cursor.getString(cursor.getColumnIndex(Conversation.CONTACTJID)) + + ": " + ignored + ". Skipping..."); continue; } @@ -236,14 +236,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { cursor.getString(cursor.getColumnIndex(Conversation.UUID)), }; db.execSQL("update " + Conversation.TABLENAME - + " set " + Conversation.CONTACTJID + " = ? " + + " set " + Conversation.CONTACTJID + " = ? " + " where " + Conversation.UUID + " = ?", updateArgs); } cursor.close(); // Contact table cursor = db.rawQuery("select * from " + Contact.TABLENAME, new String[0]); - while(cursor.moveToNext()) { + while (cursor.moveToNext()) { String newJid; try { newJid = Jid.fromString( @@ -251,8 +251,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { ).toString(); } catch (InvalidJidException ignored) { Log.e(Config.LOGTAG, "Failed to migrate Contact JID " - +cursor.getString(cursor.getColumnIndex(Contact.JID)) - +": " + ignored +". Skipping..."); + + cursor.getString(cursor.getColumnIndex(Contact.JID)) + + ": " + ignored + ". Skipping..."); continue; } @@ -270,7 +270,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { // Account table cursor = db.rawQuery("select * from " + Account.TABLENAME, new String[0]); - while(cursor.moveToNext()) { + while (cursor.moveToNext()) { String newServer; try { newServer = Jid.fromParts( @@ -280,8 +280,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { ).getDomainpart(); } catch (InvalidJidException ignored) { Log.e(Config.LOGTAG, "Failed to migrate Account SERVER " - +cursor.getString(cursor.getColumnIndex(Account.SERVER)) - +": " + ignored +". Skipping..."); + + cursor.getString(cursor.getColumnIndex(Account.SERVER)) + + ": " + ignored + ". Skipping..."); continue; } @@ -295,7 +295,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } cursor.close(); } - if (oldVersion < 15 && newVersion >= 15) { + if (oldVersion < 15 && newVersion >= 15) { recreateAxolotlDb(db); db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.FINGERPRINT + " TEXT"); @@ -305,7 +305,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { + Message.CARBON + " INTEGER"); } if (oldVersion < 19 && newVersion >= 19) { - db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN "+ Account.DISPLAY_NAME+ " TEXT"); + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.DISPLAY_NAME + " TEXT"); + } + if (oldVersion < 20 && newVersion >= 20) { + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.HOSTNAME + " TEXT"); + db.execSQL("ALTER TABLE " + Account.TABLENAME + " ADD COLUMN " + Account.PORT + " NUMBER DEFAULT 5222"); } /* Any migrations that alter the Account table need to happen BEFORE this migration, as it * depends on account de-serialization. @@ -314,7 +318,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { List accounts = getAccounts(db); for (Account account : accounts) { String ownDeviceIdString = account.getKey(SQLiteAxolotlStore.JSONKEY_REGISTRATION_ID); - if ( ownDeviceIdString == null ) { + if (ownDeviceIdString == null) { continue; } int ownDeviceId = Integer.valueOf(ownDeviceIdString); @@ -324,12 +328,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (identityKeyPair != null) { setIdentityKeyTrust(db, account, identityKeyPair.getPublicKey().getFingerprint().replaceAll("\\s", ""), XmppAxolotlSession.Trust.TRUSTED); } else { - Log.d(Config.LOGTAG,account.getJid().toBareJid()+": could not load own identity key pair"); + Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": could not load own identity key pair"); } } } if (oldVersion < 18 && newVersion >= 18) { - db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN "+ Message.READ+ " NUMBER DEFAULT 1"); + db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.READ + " NUMBER DEFAULT 1"); } } @@ -374,7 +378,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public CopyOnWriteArrayList getConversations(int status) { CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { Integer.toString(status) }; + String[] selectionArgs = {Integer.toString(status)}; Cursor cursor = db.rawQuery("select * from " + Conversation.TABLENAME + " where " + Conversation.STATUS + " = ? order by " + Conversation.CREATED + " desc", selectionArgs); @@ -390,20 +394,20 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public ArrayList getMessages(Conversation conversation, int limit, - long timestamp) { + long timestamp) { ArrayList list = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; if (timestamp == -1) { - String[] selectionArgs = { conversation.getUuid() }; + String[] selectionArgs = {conversation.getUuid()}; cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION + "=?", selectionArgs, null, null, Message.TIME_SENT + " DESC", String.valueOf(limit)); } else { - String[] selectionArgs = { conversation.getUuid(), - Long.toString(timestamp) }; + String[] selectionArgs = {conversation.getUuid(), + Long.toString(timestamp)}; cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=? and " + Message.TIME_SENT + " getMessagesIterable(final Conversation conversation){ + public Iterable getMessagesIterable(final Conversation conversation) { return new Iterable() { @Override public Iterator iterator() { - class MessageIterator implements Iterator{ + class MessageIterator implements Iterator { SQLiteDatabase db = getReadableDatabase(); - String[] selectionArgs = { conversation.getUuid() }; + String[] selectionArgs = {conversation.getUuid()}; Cursor cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION + "=?", selectionArgs, null, null, Message.TIME_SENT + " ASC", null); @@ -458,10 +462,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Conversation findConversation(final Account account, final Jid contactJid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { account.getUuid(), + String[] selectionArgs = {account.getUuid(), contactJid.toBareJid().toString() + "/%", contactJid.toBareJid().toString() - }; + }; Cursor cursor = db.query(Conversation.TABLENAME, null, Conversation.ACCOUNT + "=? AND (" + Conversation.CONTACTJID + " like ? OR " + Conversation.CONTACTJID + "=?)", selectionArgs, null, null, null); @@ -475,7 +479,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void updateConversation(final Conversation conversation) { final SQLiteDatabase db = this.getWritableDatabase(); - final String[] args = { conversation.getUuid() }; + final String[] args = {conversation.getUuid()}; db.update(Conversation.TABLENAME, conversation.getContentValues(), Conversation.UUID + "=?", args); } @@ -498,14 +502,14 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void updateAccount(Account account) { SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; + String[] args = {account.getUuid()}; db.update(Account.TABLENAME, account.getContentValues(), Account.UUID + "=?", args); } public void deleteAccount(Account account) { SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { account.getUuid() }; + String[] args = {account.getUuid()}; db.delete(Account.TABLENAME, Account.UUID + "=?", args); } @@ -534,7 +538,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void updateMessage(Message message) { SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; + String[] args = {message.getUuid()}; db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args); } @@ -542,7 +546,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void readRoster(Roster roster) { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; - String args[] = { roster.getAccount().getUuid() }; + String args[] = {roster.getAccount().getUuid()}; cursor = db.query(Contact.TABLENAME, null, Contact.ACCOUNT + "=?", args, null, null, null); while (cursor.moveToNext()) { roster.initContact(Contact.fromCursor(cursor)); @@ -558,7 +562,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.insert(Contact.TABLENAME, null, contact.getContentValues()); } else { String where = Contact.ACCOUNT + "=? AND " + Contact.JID + "=?"; - String[] whereArgs = { account.getUuid(), contact.getJid().toString() }; + String[] whereArgs = {account.getUuid(), contact.getJid().toString()}; db.delete(Contact.TABLENAME, where, whereArgs); } } @@ -568,19 +572,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void deleteMessage(Message message) { SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { message.getUuid() }; + String[] args = {message.getUuid()}; db.delete(Message.TABLENAME, Message.UUID + "=?", args); } public void deleteMessagesInConversation(Conversation conversation) { SQLiteDatabase db = this.getWritableDatabase(); - String[] args = { conversation.getUuid() }; + String[] args = {conversation.getUuid()}; db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args); } public Conversation findConversationByUuid(String conversationUuid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { conversationUuid }; + String[] selectionArgs = {conversationUuid}; Cursor cursor = db.query(Conversation.TABLENAME, null, Conversation.UUID + "=?", selectionArgs, null, null, null); if (cursor.getCount() == 0) { @@ -594,7 +598,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Message findMessageByUuid(String messageUuid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { messageUuid }; + String[] selectionArgs = {messageUuid}; Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?", selectionArgs, null, null, null); if (cursor.getCount() == 0) { @@ -608,7 +612,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public Account findAccountByUuid(String accountUuid) { SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = { accountUuid }; + String[] selectionArgs = {accountUuid}; Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?", selectionArgs, null, null, null); if (cursor.getCount() == 0) { @@ -624,9 +628,9 @@ public class DatabaseBackend extends SQLiteOpenHelper { ArrayList list = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor; - String[] selectionArgs = { conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE) }; - cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=? AND "+Message.TYPE+"=?", selectionArgs, null, null,null); + String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE)}; + cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION + + "=? AND " + Message.TYPE + "=?", selectionArgs, null, null, null); if (cursor.getCount() > 0) { cursor.moveToLast(); do { @@ -659,10 +663,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { public SessionRecord loadSession(Account account, AxolotlAddress contact) { SessionRecord session = null; Cursor cursor = getCursorForSession(account, contact); - if(cursor.getCount() != 0) { + if (cursor.getCount() != 0) { cursor.moveToFirst(); try { - session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + session = new SessionRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)); } catch (IOException e) { cursor.close(); throw new AssertionError(e); @@ -689,7 +693,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { selectionArgs, null, null, null); - while(cursor.moveToNext()) { + while (cursor.moveToNext()) { devices.add(cursor.getInt( cursor.getColumnIndex(SQLiteAxolotlStore.DEVICE_ID))); } @@ -710,7 +714,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { ContentValues values = new ContentValues(); values.put(SQLiteAxolotlStore.NAME, contact.getName()); values.put(SQLiteAxolotlStore.DEVICE_ID, contact.getDeviceId()); - values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(session.serialize(), Base64.DEFAULT)); values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(SQLiteAxolotlStore.SESSION_TABLENAME, null, values); } @@ -757,11 +761,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { public PreKeyRecord loadPreKey(Account account, int preKeyId) { PreKeyRecord record = null; Cursor cursor = getCursorForPreKey(account, preKeyId); - if(cursor.getCount() != 0) { + if (cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); - } catch (IOException e ) { + record = new PreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)); + } catch (IOException e) { throw new AssertionError(e); } } @@ -780,7 +784,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(SQLiteAxolotlStore.ID, record.getId()); - values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(), Base64.DEFAULT)); values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(SQLiteAxolotlStore.PREKEY_TABLENAME, null, values); } @@ -810,11 +814,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { public SignedPreKeyRecord loadSignedPreKey(Account account, int signedPreKeyId) { SignedPreKeyRecord record = null; Cursor cursor = getCursorForSignedPreKey(account, signedPreKeyId); - if(cursor.getCount() != 0) { + if (cursor.getCount() != 0) { cursor.moveToFirst(); try { - record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); - } catch (IOException e ) { + record = new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)); + } catch (IOException e) { throw new AssertionError(e); } } @@ -833,7 +837,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { selectionArgs, null, null, null); - while(cursor.moveToNext()) { + while (cursor.moveToNext()) { try { prekeys.add(new SignedPreKeyRecord(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT))); } catch (IOException ignored) { @@ -854,7 +858,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(SQLiteAxolotlStore.ID, record.getId()); - values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(),Base64.DEFAULT)); + values.put(SQLiteAxolotlStore.KEY, Base64.encodeToString(record.serialize(), Base64.DEFAULT)); values.put(SQLiteAxolotlStore.ACCOUNT, account.getUuid()); db.insert(SQLiteAxolotlStore.SIGNED_PREKEY_TABLENAME, null, values); } @@ -874,7 +878,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } private Cursor getIdentityKeyCursor(SQLiteDatabase db, Account account, String name, boolean own) { - return getIdentityKeyCursor(db, account, name, own, null); + return getIdentityKeyCursor(db, account, name, own, null); } private Cursor getIdentityKeyCursor(Account account, String fingerprint) { @@ -892,16 +896,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { ArrayList selectionArgs = new ArrayList<>(4); selectionArgs.add(account.getUuid()); String selectionString = SQLiteAxolotlStore.ACCOUNT + " = ?"; - if (name != null){ + if (name != null) { selectionArgs.add(name); selectionString += " AND " + SQLiteAxolotlStore.NAME + " = ?"; } - if (fingerprint != null){ + if (fingerprint != null) { selectionArgs.add(fingerprint); selectionString += " AND " + SQLiteAxolotlStore.FINGERPRINT + " = ?"; } - if (own != null){ - selectionArgs.add(own?"1":"0"); + if (own != null) { + selectionArgs.add(own ? "1" : "0"); selectionString += " AND " + SQLiteAxolotlStore.OWN + " = ?"; } Cursor cursor = db.query(SQLiteAxolotlStore.IDENTITIES_TABLENAME, @@ -922,12 +926,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { String name = account.getJid().toBareJid().toString(); IdentityKeyPair identityKeyPair = null; Cursor cursor = getIdentityKeyCursor(db, account, name, true); - if(cursor.getCount() != 0) { + if (cursor.getCount() != 0) { cursor.moveToFirst(); try { - identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT)); + identityKeyPair = new IdentityKeyPair(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT)); } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); } } cursor.close(); @@ -943,16 +947,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { Set identityKeys = new HashSet<>(); Cursor cursor = getIdentityKeyCursor(account, name, false); - while(cursor.moveToNext()) { - if ( trust != null && + while (cursor.moveToNext()) { + if (trust != null && cursor.getInt(cursor.getColumnIndex(SQLiteAxolotlStore.TRUSTED)) != trust.getCode()) { continue; } try { - identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)),Base64.DEFAULT),0)); + identityKeys.add(new IdentityKey(Base64.decode(cursor.getString(cursor.getColumnIndex(SQLiteAxolotlStore.KEY)), Base64.DEFAULT), 0)); } catch (InvalidKeyException e) { - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+"Encountered invalid IdentityKey in database for account"+account.getJid().toBareJid()+", address: "+name); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Encountered invalid IdentityKey in database for account" + account.getJid().toBareJid() + ", address: " + name); } } cursor.close(); @@ -970,8 +974,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { }; return DatabaseUtils.queryNumEntries(db, SQLiteAxolotlStore.IDENTITIES_TABLENAME, SQLiteAxolotlStore.ACCOUNT + " = ?" - + " AND " + SQLiteAxolotlStore.NAME + " = ?" - + " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR "+SQLiteAxolotlStore.TRUSTED+ " = ?)", + + " AND " + SQLiteAxolotlStore.NAME + " = ?" + + " AND (" + SQLiteAxolotlStore.TRUSTED + " = ? OR " + SQLiteAxolotlStore.TRUSTED + " = ?)", args ); } @@ -1018,7 +1022,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { values.put(SQLiteAxolotlStore.TRUSTED, trust.getCode()); int rows = db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, SQLiteAxolotlStore.ACCOUNT + " = ? AND " - + SQLiteAxolotlStore.FINGERPRINT + " = ? ", + + SQLiteAxolotlStore.FINGERPRINT + " = ? ", selectionArgs); return rows == 1; } @@ -1036,7 +1040,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public void recreateAxolotlDb(SQLiteDatabase db) { - Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX+" : "+">>> (RE)CREATING AXOLOTL DATABASE <<<"); + Log.d(Config.LOGTAG, AxolotlService.LOGPREFIX + " : " + ">>> (RE)CREATING AXOLOTL DATABASE <<<"); db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.SESSION_TABLENAME); db.execSQL(CREATE_SESSIONS_STATEMENT); db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.PREKEY_TABLENAME); @@ -1046,12 +1050,12 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.execSQL("DROP TABLE IF EXISTS " + SQLiteAxolotlStore.IDENTITIES_TABLENAME); db.execSQL(CREATE_IDENTITIES_STATEMENT); } - + public void wipeAxolotlDb(Account account) { String accountName = account.getUuid(); - Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account)+">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<"); + Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + ">>> WIPING AXOLOTL DATABASE FOR ACCOUNT " + accountName + " <<<"); SQLiteDatabase db = this.getWritableDatabase(); - String[] deleteArgs= { + String[] deleteArgs = { accountName }; db.delete(SQLiteAxolotlStore.SESSION_TABLENAME, -- cgit v1.2.3 From e5f154316cbfa1d701947fae8bc31239df37531a Mon Sep 17 00:00:00 2001 From: fiaxh Date: Wed, 2 Dec 2015 15:43:55 +0000 Subject: Unset all PGP signatures once ... so they will be redone to match the changed status. --- .../eu/siacs/conversations/persistance/DatabaseBackend.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 8b74581c..2347c318 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -43,7 +43,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 20; + private static final int DATABASE_VERSION = 21; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -335,6 +335,15 @@ public class DatabaseBackend extends SQLiteOpenHelper { if (oldVersion < 18 && newVersion >= 18) { db.execSQL("ALTER TABLE " + Message.TABLENAME + " ADD COLUMN " + Message.READ + " NUMBER DEFAULT 1"); } + + if (oldVersion < 21 && newVersion >= 21) { + List accounts = getAccounts(db); + for (Account account : accounts) { + account.unsetPgpSignature(); + db.update(Account.TABLENAME, account.getContentValues(), Account.UUID + + "=?", new String[]{account.getUuid()}); + } + } } public static synchronized DatabaseBackend getInstance(Context context) { -- cgit v1.2.3 From 293e820a5857ffff5301babc43fc08120a35385c Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 11 Dec 2015 13:52:04 +0100 Subject: get rid of lastMessageTransmitted in favor of db query --- .../siacs/conversations/persistance/DatabaseBackend.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 2347c318..e482f0f8 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -9,6 +9,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Base64; import android.util.Log; +import android.util.Pair; import org.whispersystems.libaxolotl.AxolotlAddress; import org.whispersystems.libaxolotl.IdentityKey; @@ -591,6 +592,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args); } + public Pair getLastMessageReceived(Account account) { + SQLiteDatabase db = this.getReadableDatabase(); + String sql = "select messages.timeSent,messages.serverMsgId from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and (messages.status=0 or messages.carbon=1 or messages.serverMsgId not null) order by messages.timesent desc limit 1"; + String[] args = {account.getUuid()}; + Cursor cursor = db.rawQuery(sql,args); + if (cursor.getCount() ==0) { + return null; + } else { + cursor.moveToFirst(); + return new Pair<>(cursor.getLong(0),cursor.getString(1)); + } + } + public Conversation findConversationByUuid(String conversationUuid) { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = {conversationUuid}; -- cgit v1.2.3 From d0bad09f13886c7d8ee20c0205293cb0250d9c2f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 23 Dec 2015 17:41:26 +0100 Subject: save certificate when verifying with x509 --- .../conversations/persistance/DatabaseBackend.java | 31 ++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index e482f0f8..4882d72b 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -15,11 +15,14 @@ import org.whispersystems.libaxolotl.AxolotlAddress; import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.InvalidKeyException; +import org.whispersystems.libaxolotl.state.AxolotlStore; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; import java.io.IOException; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -44,7 +47,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { private static DatabaseBackend instance = null; private static final String DATABASE_NAME = "history"; - private static final int DATABASE_VERSION = 21; + private static final int DATABASE_VERSION = 22; private static String CREATE_CONTATCS_STATEMENT = "create table " + Contact.TABLENAME + "(" + Contact.ACCOUNT + " TEXT, " @@ -102,6 +105,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { + SQLiteAxolotlStore.NAME + " TEXT, " + SQLiteAxolotlStore.OWN + " INTEGER, " + SQLiteAxolotlStore.FINGERPRINT + " TEXT, " + + SQLiteAxolotlStore.CERTIFICATE + " BLOB, " + SQLiteAxolotlStore.TRUSTED + " INTEGER, " + SQLiteAxolotlStore.KEY + " TEXT, FOREIGN KEY(" + SQLiteAxolotlStore.ACCOUNT @@ -345,6 +349,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { + "=?", new String[]{account.getUuid()}); } } + + if (oldVersion < 22 && newVersion >= 22) { + db.execSQL("ALTER TABLE " + SQLiteAxolotlStore.IDENTITIES_TABLENAME + " ADD COLUMN " + SQLiteAxolotlStore.CERTIFICATE); + } } public static synchronized DatabaseBackend getInstance(Context context) { @@ -596,7 +604,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getReadableDatabase(); String sql = "select messages.timeSent,messages.serverMsgId from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and (messages.status=0 or messages.carbon=1 or messages.serverMsgId not null) order by messages.timesent desc limit 1"; String[] args = {account.getUuid()}; - Cursor cursor = db.rawQuery(sql,args); + Cursor cursor = db.rawQuery(sql, args); if (cursor.getCount() ==0) { return null; } else { @@ -1050,6 +1058,25 @@ public class DatabaseBackend extends SQLiteOpenHelper { return rows == 1; } + public boolean setIdentityKeyCertificate(Account account, String fingerprint, X509Certificate x509Certificate) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] selectionArgs = { + account.getUuid(), + fingerprint + }; + try { + ContentValues values = new ContentValues(); + values.put(SQLiteAxolotlStore.CERTIFICATE, x509Certificate.getEncoded()); + return db.update(SQLiteAxolotlStore.IDENTITIES_TABLENAME, values, + SQLiteAxolotlStore.ACCOUNT + " = ? AND " + + SQLiteAxolotlStore.FINGERPRINT + " = ? ", + selectionArgs) == 1; + } catch (CertificateEncodingException e) { + Log.d(Config.LOGTAG,"could not encode certificate"); + return false; + } + } + public void storeIdentityKey(Account account, String name, IdentityKey identityKey) { storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); } -- cgit v1.2.3 From f46cbb38a92ff5281a974ecc0932ba5459c7334e Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 23 Dec 2015 19:18:53 +0100 Subject: show certificate information --- .../conversations/persistance/DatabaseBackend.java | 39 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 4882d72b..3077c488 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -15,13 +15,15 @@ import org.whispersystems.libaxolotl.AxolotlAddress; import org.whispersystems.libaxolotl.IdentityKey; import org.whispersystems.libaxolotl.IdentityKeyPair; import org.whispersystems.libaxolotl.InvalidKeyException; -import org.whispersystems.libaxolotl.state.AxolotlStore; import org.whispersystems.libaxolotl.state.PreKeyRecord; import org.whispersystems.libaxolotl.state.SessionRecord; import org.whispersystems.libaxolotl.state.SignedPreKeyRecord; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.HashSet; @@ -600,16 +602,16 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.delete(Message.TABLENAME, Message.CONVERSATION + "=?", args); } - public Pair getLastMessageReceived(Account account) { + public Pair getLastMessageReceived(Account account) { SQLiteDatabase db = this.getReadableDatabase(); String sql = "select messages.timeSent,messages.serverMsgId from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and (messages.status=0 or messages.carbon=1 or messages.serverMsgId not null) order by messages.timesent desc limit 1"; String[] args = {account.getUuid()}; Cursor cursor = db.rawQuery(sql, args); - if (cursor.getCount() ==0) { + if (cursor.getCount() == 0) { return null; } else { cursor.moveToFirst(); - return new Pair<>(cursor.getLong(0),cursor.getString(1)); + return new Pair<>(cursor.getLong(0), cursor.getString(1)); } } @@ -1072,11 +1074,38 @@ public class DatabaseBackend extends SQLiteOpenHelper { + SQLiteAxolotlStore.FINGERPRINT + " = ? ", selectionArgs) == 1; } catch (CertificateEncodingException e) { - Log.d(Config.LOGTAG,"could not encode certificate"); + Log.d(Config.LOGTAG, "could not encode certificate"); return false; } } + public X509Certificate getIdentityKeyCertifcate(Account account, String fingerprint) { + SQLiteDatabase db = this.getReadableDatabase(); + String[] selectionArgs = { + account.getUuid(), + fingerprint + }; + String[] colums = {SQLiteAxolotlStore.CERTIFICATE}; + String selection = SQLiteAxolotlStore.ACCOUNT + " = ? AND " + SQLiteAxolotlStore.FINGERPRINT + " = ? "; + Cursor cursor = db.query(SQLiteAxolotlStore.IDENTITIES_TABLENAME, colums, selection, selectionArgs, null, null, null); + if (cursor.getCount() < 1) { + return null; + } else { + cursor.moveToFirst(); + byte[] certificate = cursor.getBlob(cursor.getColumnIndex(SQLiteAxolotlStore.CERTIFICATE)); + if (certificate == null || certificate.length == 0) { + return null; + } + try { + CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); + return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(certificate)); + } catch (CertificateException e) { + Log.d(Config.LOGTAG,"certificate exception "+e.getMessage()); + return null; + } + } + } + public void storeIdentityKey(Account account, String name, IdentityKey identityKey) { storeIdentityKey(account, name, false, identityKey.getFingerprint().replaceAll("\\s", ""), Base64.encodeToString(identityKey.serialize(), Base64.DEFAULT)); } -- cgit v1.2.3 From ffb49c72177d71f1efaff944a52ca43a1fb63428 Mon Sep 17 00:00:00 2001 From: Dheeraj CVR Date: Wed, 13 Jan 2016 11:55:46 +0400 Subject: use batch transactions when writing roster Fixes https://github.com/siacs/Conversations/issues/1648 --- src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index 3077c488..c73a0564 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -577,6 +577,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { public void writeRoster(final Roster roster) { final Account account = roster.getAccount(); final SQLiteDatabase db = this.getWritableDatabase(); + db.beginTransaction(); for (Contact contact : roster.getContacts()) { if (contact.getOption(Contact.Options.IN_ROSTER)) { db.insert(Contact.TABLENAME, null, contact.getContentValues()); @@ -586,6 +587,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.delete(Contact.TABLENAME, where, whereArgs); } } + db.setTransactionSuccessful(); + db.endTransaction(); account.setRosterVersion(roster.getVersion()); updateAccount(account); } -- cgit v1.2.3 From 943d0391d44596090cb100a749b461f75b5615dc Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 15 Jan 2016 23:46:52 +0100 Subject: catch exception when reading message id from database --- .../conversations/persistance/DatabaseBackend.java | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index c73a0564..d6e580df 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -606,15 +606,19 @@ public class DatabaseBackend extends SQLiteOpenHelper { } public Pair getLastMessageReceived(Account account) { - SQLiteDatabase db = this.getReadableDatabase(); - String sql = "select messages.timeSent,messages.serverMsgId from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and (messages.status=0 or messages.carbon=1 or messages.serverMsgId not null) order by messages.timesent desc limit 1"; - String[] args = {account.getUuid()}; - Cursor cursor = db.rawQuery(sql, args); - if (cursor.getCount() == 0) { + try { + SQLiteDatabase db = this.getReadableDatabase(); + String sql = "select messages.timeSent,messages.serverMsgId from accounts join conversations on accounts.uuid=conversations.accountUuid join messages on conversations.uuid=messages.conversationUuid where accounts.uuid=? and (messages.status=0 or messages.carbon=1 or messages.serverMsgId not null) order by messages.timesent desc limit 1"; + String[] args = {account.getUuid()}; + Cursor cursor = db.rawQuery(sql, args); + if (cursor.getCount() == 0) { + return null; + } else { + cursor.moveToFirst(); + return new Pair<>(cursor.getLong(0), cursor.getString(1)); + } + } catch (Exception e) { return null; - } else { - cursor.moveToFirst(); - return new Pair<>(cursor.getLong(0), cursor.getString(1)); } } -- cgit v1.2.3 From ad5bcb7d43494dd90d555cee42b9c69ec7326f1f Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Sat, 16 Jan 2016 18:57:19 +0100 Subject: removed some unused methods from db backend --- .../conversations/persistance/DatabaseBackend.java | 83 ---------------------- 1 file changed, 83 deletions(-) (limited to 'src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java') diff --git a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java index d6e580df..77c16f25 100644 --- a/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java +++ b/src/main/java/eu/siacs/conversations/persistance/DatabaseBackend.java @@ -379,22 +379,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.insert(Account.TABLENAME, null, account.getContentValues()); } - public void createContact(Contact contact) { - SQLiteDatabase db = this.getWritableDatabase(); - db.insert(Contact.TABLENAME, null, contact.getContentValues()); - } - - public int getConversationCount() { - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor = db.rawQuery("select count(uuid) as count from " - + Conversation.TABLENAME + " where " + Conversation.STATUS - + "=" + Conversation.STATUS_AVAILABLE, null); - cursor.moveToFirst(); - int count = cursor.getInt(0); - cursor.close(); - return count; - } - public CopyOnWriteArrayList getConversations(int status) { CopyOnWriteArrayList list = new CopyOnWriteArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); @@ -593,12 +577,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { updateAccount(account); } - public void deleteMessage(Message message) { - SQLiteDatabase db = this.getWritableDatabase(); - String[] args = {message.getUuid()}; - db.delete(Message.TABLENAME, Message.UUID + "=?", args); - } - public void deleteMessagesInConversation(Conversation conversation) { SQLiteDatabase db = this.getWritableDatabase(); String[] args = {conversation.getUuid()}; @@ -622,67 +600,6 @@ public class DatabaseBackend extends SQLiteOpenHelper { } } - public Conversation findConversationByUuid(String conversationUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = {conversationUuid}; - Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.UUID + "=?", selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - Conversation conversation = Conversation.fromCursor(cursor); - cursor.close(); - return conversation; - } - - public Message findMessageByUuid(String messageUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = {messageUuid}; - Cursor cursor = db.query(Message.TABLENAME, null, Message.UUID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - Message message = Message.fromCursor(cursor); - cursor.close(); - return message; - } - - public Account findAccountByUuid(String accountUuid) { - SQLiteDatabase db = this.getReadableDatabase(); - String[] selectionArgs = {accountUuid}; - Cursor cursor = db.query(Account.TABLENAME, null, Account.UUID + "=?", - selectionArgs, null, null, null); - if (cursor.getCount() == 0) { - return null; - } - cursor.moveToFirst(); - Account account = Account.fromCursor(cursor); - cursor.close(); - return account; - } - - public List getImageMessages(Conversation conversation) { - ArrayList list = new ArrayList<>(); - SQLiteDatabase db = this.getReadableDatabase(); - Cursor cursor; - String[] selectionArgs = {conversation.getUuid(), String.valueOf(Message.TYPE_IMAGE)}; - cursor = db.query(Message.TABLENAME, null, Message.CONVERSATION - + "=? AND " + Message.TYPE + "=?", selectionArgs, null, null, null); - if (cursor.getCount() > 0) { - cursor.moveToLast(); - do { - Message message = Message.fromCursor(cursor); - message.setConversation(conversation); - list.add(message); - } while (cursor.moveToPrevious()); - } - cursor.close(); - return list; - } - private Cursor getCursorForSession(Account account, AxolotlAddress contact) { final SQLiteDatabase db = this.getReadableDatabase(); String[] columns = null; -- cgit v1.2.3