private void decryptCredentials(DatabaseEntry entry, JSONObject jDatabase) { String databaseUsername, databasePassword = null; // if no encryption key or both username and password are empty, skip encryption if (!SettingsManager.getSyncSetting(SettingsManager.SyncKey.sync_credentials) || TextUtils.isEmpty(SettingsManager.getEc()) || (TextUtils.isEmpty(databaseUsername = jDatabase.optString("database_username")) && TextUtils.isEmpty(databasePassword = jDatabase.optString("database_password")))) return; try { AesCbcWithIntegrity.SecretKeys keys = AesCbcWithIntegrity.keys(SettingsManager.getEc()); if (!TextUtils.isEmpty(databaseUsername)) { AesCbcWithIntegrity.CipherTextIvMac cipherTextIvMac = new AesCbcWithIntegrity.CipherTextIvMac(databaseUsername); entry.databaseUsername = AesCbcWithIntegrity.decryptString(cipherTextIvMac, keys); } if (!TextUtils.isEmpty(databasePassword)) { AesCbcWithIntegrity.CipherTextIvMac cipherTextIvMac = new AesCbcWithIntegrity.CipherTextIvMac(databasePassword); entry.databasePassword = AesCbcWithIntegrity.decryptString(cipherTextIvMac, keys); } } catch (GeneralSecurityException | UnsupportedEncodingException e) { if (SettingsManager.DEBUG()) e.printStackTrace(); // fail silently on any kind of error // user will see warning on database entry when restored without username/password } }
public void parseSyncResponse() { if (SettingsManager.DEBUG()) Log.d("sync", "parse sync response"); if (jsonObject == null) return; JSONObject jData = jsonObject.optJSONObject("data"); if (jData != null) { // query history if (SettingsManager.getSyncSetting(SettingsManager.SyncKey.sync_query_history)) { JSONArray jQueryHistory = jData.optJSONArray("query_history"); if (jQueryHistory != null) { List<String> queryHistory = new ArrayList<>(); for (int i = 0; i < jQueryHistory.length(); i++) { queryHistory.add(jQueryHistory.optString(i)); } DatabaseManager.getInstance().insertQueryHistory(queryHistory); } } // databases if (SettingsManager.getSyncSetting(SettingsManager.SyncKey.sync_databases)) { JSONArray jDatabases = jData.optJSONArray("databases"); if (jDatabases != null) { List<DatabaseEntry> entries = new ArrayList<>(); for (int i = 0; i < jDatabases.length(); i++) { JSONObject jDatabase = jDatabases.optJSONObject(i); DatabaseEntry databaseEntry = new DatabaseEntry(); databaseEntry.id = jDatabase.optString("_id"); databaseEntry.type = jDatabase.optString("type"); databaseEntry.databaseUri = jDatabase.optString("database_uri"); databaseEntry.databaseName = jDatabase.optString("database_name"); if (TextUtils.isEmpty(databaseEntry.id) || TextUtils.isEmpty(databaseEntry.type) || TextUtils.isEmpty(databaseEntry.databaseUri)) { continue; } databaseEntry.databasePort = jDatabase.optInt("database_port"); decryptCredentials(databaseEntry, jDatabase); databaseEntry.isFavorite = jDatabase.optBoolean("is_favorite"); databaseEntry.created = jDatabase.optLong("created"); databaseEntry.accessed = jDatabase.optLong("accessed"); entries.add(databaseEntry); } DatabaseManager.getInstance().insertDatabaseEntry(entries); DatabaseManager.getInstance() .rawQueryNoResult("DELETE FROM _database WHERE deleted = 1", null); } } // settings if (SettingsManager.getSyncSetting(SettingsManager.SyncKey.sync_settings)) { JSONObject jSettings = jData.optJSONObject("settings"); if (jSettings != null) { for (SettingsManager.SyncKey key : SettingsManager.SyncKey.values()) { if (!key.isSyncable() || !jSettings.has(key.toString())) continue; boolean enabled = jSettings.optBoolean(key.toString()); SettingsManager.setSyncSetting(key, enabled); } for (SettingsManager.Key key : SettingsManager.Key.values()) { if (!key.isSyncable() || !jSettings.has(key.toString())) continue; if (key.getKeyClass() == long.class) { SettingsManager.setSetting(key, jSettings.optLong(key.toString())); } else { SettingsManager.setSetting(key, jSettings.opt(key.toString())); } } } } } }