diff options
author | Vincent Breitmoser <valodim@mugenguild.com> | 2015-01-31 18:49:54 +0100 |
---|---|---|
committer | Vincent Breitmoser <valodim@mugenguild.com> | 2015-01-31 18:49:54 +0100 |
commit | 0b6dc65c97b0fb5dae9bf1a06f9c7db0b65ea4ad (patch) | |
tree | 92954cab7f0aa299c2658a9f15586168ccf12e4f /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider | |
parent | 5466d1e9802815726d713bca2aeabaff2861519c (diff) | |
parent | e651a392795caa395b060946b0cfaca5a5b41ded (diff) | |
download | open-keychain-0b6dc65c97b0fb5dae9bf1a06f9c7db0b65ea4ad.tar.gz open-keychain-0b6dc65c97b0fb5dae9bf1a06f9c7db0b65ea4ad.tar.bz2 open-keychain-0b6dc65c97b0fb5dae9bf1a06f9c7db0b65ea4ad.zip |
Merge remote-tracking branch 'origin/development' into development
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider')
4 files changed, 127 insertions, 8 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index f4e00c36c..5856589c4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -85,6 +85,11 @@ public class KeychainContract { String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name } + interface ApiAppsAllowedKeysColumns { + String KEY_ID = "key_id"; // not a database id + String PACKAGE_NAME = "package_name"; // foreign key to api_apps.package_name + } + public static final String CONTENT_AUTHORITY = Constants.PACKAGE_NAME + ".provider"; private static final Uri BASE_CONTENT_URI_INTERNAL = Uri @@ -106,6 +111,7 @@ public class KeychainContract { public static final String BASE_API_APPS = "api_apps"; public static final String PATH_ACCOUNTS = "accounts"; + public static final String PATH_ALLOWED_KEYS = "allowed_keys"; public static class KeyRings implements BaseColumns, KeysColumns, UserPacketsColumns { public static final String MASTER_KEY_ID = KeysColumns.MASTER_KEY_ID; @@ -305,6 +311,22 @@ public class KeychainContract { } } + public static class ApiAllowedKeys implements ApiAppsAllowedKeysColumns, BaseColumns { + public static final Uri CONTENT_URI = BASE_CONTENT_URI_INTERNAL.buildUpon() + .appendPath(BASE_API_APPS).build(); + + /** + * Use if multiple items get returned + */ + public static final String CONTENT_TYPE + = "vnd.android.cursor.dir/vnd.org.sufficientlysecure.keychain.provider.api_apps.allowed_keys"; + + public static Uri buildBaseUri(String packageName) { + return CONTENT_URI.buildUpon().appendEncodedPath(packageName).appendPath(PATH_ALLOWED_KEYS) + .build(); + } + } + public static class Certs implements CertsColumns, BaseColumns { public static final String USER_ID = UserPacketsColumns.USER_ID; public static final String SIGNER_UID = "signer_user_id"; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java index 5ce5eec17..d34cc74a3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainDatabase.java @@ -28,6 +28,7 @@ import android.provider.BaseColumns; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAllowedKeysColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsAccountsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAppsColumns; import org.sufficientlysecure.keychain.provider.KeychainContract.CertsColumns; @@ -52,7 +53,7 @@ import java.io.IOException; */ public class KeychainDatabase extends SQLiteOpenHelper { private static final String DATABASE_NAME = "openkeychain.db"; - private static final int DATABASE_VERSION = 7; + private static final int DATABASE_VERSION = 8; static Boolean apgHack = false; private Context mContext; @@ -64,6 +65,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { String CERTS = "certs"; String API_APPS = "api_apps"; String API_ACCOUNTS = "api_accounts"; + String API_ALLOWED_KEYS = "api_allowed_keys"; } private static final String CREATE_KEYRINGS_PUBLIC = @@ -166,6 +168,18 @@ public class KeychainDatabase extends SQLiteOpenHelper { + Tables.API_APPS + "(" + ApiAppsColumns.PACKAGE_NAME + ") ON DELETE CASCADE" + ")"; + private static final String CREATE_API_APPS_ALLOWED_KEYS = + "CREATE TABLE IF NOT EXISTS " + Tables.API_ALLOWED_KEYS + " (" + + BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + ApiAppsAllowedKeysColumns.KEY_ID + " INTEGER, " + + ApiAppsAllowedKeysColumns.PACKAGE_NAME + " TEXT NOT NULL, " + + + "UNIQUE(" + ApiAppsAllowedKeysColumns.KEY_ID + ", " + + ApiAppsAllowedKeysColumns.PACKAGE_NAME + "), " + + "FOREIGN KEY(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") REFERENCES " + + Tables.API_APPS + "(" + ApiAppsAllowedKeysColumns.PACKAGE_NAME + ") ON DELETE CASCADE" + + ")"; + KeychainDatabase(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); mContext = context; @@ -195,6 +209,7 @@ public class KeychainDatabase extends SQLiteOpenHelper { db.execSQL(CREATE_CERTS); db.execSQL(CREATE_API_APPS); db.execSQL(CREATE_API_APPS_ACCOUNTS); + db.execSQL(CREATE_API_APPS_ALLOWED_KEYS); } @Override @@ -243,6 +258,15 @@ public class KeychainDatabase extends SQLiteOpenHelper { case 6: db.execSQL("ALTER TABLE user_ids ADD COLUMN type INTEGER"); db.execSQL("ALTER TABLE user_ids ADD COLUMN attribute_data BLOB"); + case 7: + // consolidate + case 8: + // new table for allowed key ids in API + try { + db.execSQL(CREATE_API_APPS_ALLOWED_KEYS); + } catch (Exception e) { + // never mind, the column probably already existed + } } // always do consolidate after upgrade diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 72475472e..2ffc8c2ca 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -31,6 +31,7 @@ import android.net.Uri; import android.text.TextUtils; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; @@ -63,9 +64,10 @@ public class KeychainProvider extends ContentProvider { private static final int KEY_RING_CERTS_SPECIFIC = 206; private static final int API_APPS = 301; - private static final int API_APPS_BY_PACKAGE_NAME = 303; - private static final int API_ACCOUNTS = 304; - private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 306; + private static final int API_APPS_BY_PACKAGE_NAME = 302; + private static final int API_ACCOUNTS = 303; + private static final int API_ACCOUNTS_BY_ACCOUNT_NAME = 304; + private static final int API_ALLOWED_KEYS = 305; private static final int KEY_RINGS_FIND_BY_EMAIL = 400; private static final int KEY_RINGS_FIND_BY_SUBKEY = 401; @@ -162,6 +164,8 @@ public class KeychainProvider extends ContentProvider { * * api_apps/_/accounts * api_apps/_/accounts/_ (account name) + * + * api_apps/_/allowed_keys * </pre> */ matcher.addURI(authority, KeychainContract.BASE_API_APPS, API_APPS); @@ -172,6 +176,9 @@ public class KeychainProvider extends ContentProvider { matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + KeychainContract.PATH_ACCOUNTS + "/*", API_ACCOUNTS_BY_ACCOUNT_NAME); + matcher.addURI(authority, KeychainContract.BASE_API_APPS + "/*/" + + KeychainContract.PATH_ALLOWED_KEYS, API_ALLOWED_KEYS); + return matcher; } @@ -223,6 +230,9 @@ public class KeychainProvider extends ContentProvider { case API_ACCOUNTS_BY_ACCOUNT_NAME: return ApiAccounts.CONTENT_ITEM_TYPE; + case API_ALLOWED_KEYS: + return ApiAllowedKeys.CONTENT_TYPE; + default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -614,6 +624,12 @@ public class KeychainProvider extends ContentProvider { qb.appendWhereEscapeString(uri.getLastPathSegment()); break; + case API_ALLOWED_KEYS: + qb.setTables(Tables.API_ALLOWED_KEYS); + qb.appendWhere(Tables.API_ALLOWED_KEYS + "." + ApiAccounts.PACKAGE_NAME + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(1)); + + break; default: throw new IllegalArgumentException("Unknown URI " + uri + " (" + match + ")"); @@ -683,7 +699,7 @@ public class KeychainProvider extends ContentProvider { )) { throw new AssertionError("Incorrect type for user packet! This is a bug!"); } - if (values.get(UserPacketsColumns.RANK) == 0 && values.get(UserPacketsColumns.USER_ID) == null) { + if (((Number)values.get(UserPacketsColumns.RANK)).intValue() == 0 && values.get(UserPacketsColumns.USER_ID) == null) { throw new AssertionError("Rank 0 user packet must be a user id!"); } db.insertOrThrow(Tables.USER_PACKETS, null, values); @@ -701,7 +717,7 @@ public class KeychainProvider extends ContentProvider { db.insertOrThrow(Tables.API_APPS, null, values); break; - case API_ACCOUNTS: + case API_ACCOUNTS: { // set foreign key automatically based on given uri // e.g., api_apps/com.example.app/accounts/ String packageName = uri.getPathSegments().get(1); @@ -709,12 +725,21 @@ public class KeychainProvider extends ContentProvider { db.insertOrThrow(Tables.API_ACCOUNTS, null, values); break; + } + case API_ALLOWED_KEYS: { + // set foreign key automatically based on given uri + // e.g., api_apps/com.example.app/allowed_keys/ + String packageName = uri.getPathSegments().get(1); + values.put(ApiAllowedKeys.PACKAGE_NAME, packageName); + db.insertOrThrow(Tables.API_ALLOWED_KEYS, null, values); + break; + } default: throw new UnsupportedOperationException("Unknown uri: " + uri); } - if(keyId != null) { + if (keyId != null) { uri = KeyRings.buildGenericKeyRingUri(keyId); rowUri = uri; } @@ -777,6 +802,10 @@ public class KeychainProvider extends ContentProvider { count = db.delete(Tables.API_ACCOUNTS, buildDefaultApiAccountsSelection(uri, additionalSelection), selectionArgs); break; + case API_ALLOWED_KEYS: + count = db.delete(Tables.API_ALLOWED_KEYS, buildDefaultApiAllowedKeysSelection(uri, additionalSelection), + selectionArgs); + break; default: throw new UnsupportedOperationException("Unknown uri: " + uri); } @@ -869,4 +898,15 @@ public class KeychainProvider extends ContentProvider { + andSelection; } + private String buildDefaultApiAllowedKeysSelection(Uri uri, String selection) { + String packageName = DatabaseUtils.sqlEscapeString(uri.getPathSegments().get(1)); + + String andSelection = ""; + if (!TextUtils.isEmpty(selection)) { + andSelection = " AND (" + selection + ")"; + } + + return ApiAllowedKeys.PACKAGE_NAME + "=" + packageName + andSelection; + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index f23006a94..2ba7a19dc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -50,6 +50,7 @@ import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedPublicKey; import org.sufficientlysecure.keychain.pgp.WrappedSignature; import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException; +import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys; import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps; import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; @@ -1312,7 +1313,6 @@ public class ProviderHelper { progress.setProgress(100, 100); log.add(LogType.MSG_CON_SUCCESS, indent); - indent -= 1; return new ConsolidateResult(ConsolidateResult.RESULT_OK, log); @@ -1508,6 +1508,39 @@ public class ProviderHelper { return keyIds; } + public Set<Long> getAllowedKeyIdsForApp(Uri uri) { + Set<Long> keyIds = new HashSet<>(); + + Cursor cursor = mContentResolver.query(uri, null, null, null, null); + try { + if (cursor != null) { + int keyIdColumn = cursor.getColumnIndex(KeychainContract.ApiAllowedKeys.KEY_ID); + while (cursor.moveToNext()) { + keyIds.add(cursor.getLong(keyIdColumn)); + } + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return keyIds; + } + + public void saveAllowedKeyIdsForApp(Uri uri, Set<Long> allowedKeyIds) + throws RemoteException, OperationApplicationException { + // wipe whole table of allowed keys for this account + mContentResolver.delete(uri, null, null); + + // re-insert allowed key ids + for (Long keyId : allowedKeyIds) { + ContentValues values = new ContentValues(); + values.put(ApiAllowedKeys.KEY_ID, keyId); + mContentResolver.insert(uri, values); + } + } + public Set<String> getAllFingerprints(Uri uri) { Set<String> fingerprints = new HashSet<>(); String[] projection = new String[]{KeyRings.FINGERPRINT}; |