mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
New broadcast on database change to inform other apps
This commit is contained in:
parent
d599d26bbd
commit
4177f7159c
@ -235,11 +235,18 @@ public class KeychainContentProviderHelper {
|
||||
* @param keyId
|
||||
* @return user id
|
||||
*/
|
||||
public String getUserId(long keyId) {
|
||||
public String getUserId(long keyId, boolean secretKeyrings) {
|
||||
String userId = null;
|
||||
try {
|
||||
Uri contentUri = ContentUris.withAppendedId(CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID,
|
||||
keyId);
|
||||
Uri contentUri = null;
|
||||
if (secretKeyrings) {
|
||||
contentUri = ContentUris.withAppendedId(CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID,
|
||||
keyId);
|
||||
} else {
|
||||
contentUri = ContentUris.withAppendedId(CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID,
|
||||
keyId);
|
||||
}
|
||||
|
||||
Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "user_id" },
|
||||
null, null, null);
|
||||
if (c != null && c.moveToFirst()) {
|
||||
|
@ -35,6 +35,7 @@ import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Intent;
|
||||
import android.content.UriMatcher;
|
||||
import android.database.Cursor;
|
||||
import android.database.DatabaseUtils;
|
||||
@ -47,6 +48,9 @@ import android.provider.BaseColumns;
|
||||
import android.text.TextUtils;
|
||||
|
||||
public class KeychainProvider extends ContentProvider {
|
||||
public static final String ACTION_BROADCAST_DATABASE_CHANGE = Constants.PACKAGE_NAME
|
||||
+ ".action.DATABASE_CHANGE";
|
||||
|
||||
private static final int PUBLIC_KEY_RING = 101;
|
||||
private static final int PUBLIC_KEY_RING_BY_ROW_ID = 102;
|
||||
private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID = 103;
|
||||
@ -104,22 +108,26 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/public/like_email/_
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC,
|
||||
PUBLIC_KEY_RING);
|
||||
matcher.addURI(authority,
|
||||
KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/#",
|
||||
PUBLIC_KEY_RING_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
|
||||
+ KeychainContract.PATH_BY_MASTER_KEY_ID + "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
|
||||
+ KeychainContract.PATH_BY_KEY_ID + "/*", PUBLIC_KEY_RING_BY_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
|
||||
+ KeychainContract.PATH_BY_EMAILS + "/*", PUBLIC_KEY_RING_BY_EMAILS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
|
||||
+ KeychainContract.PATH_BY_EMAILS, PUBLIC_KEY_RING_BY_EMAILS); // without emails
|
||||
// specified
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC + "/"
|
||||
+ KeychainContract.PATH_BY_LIKE_EMAIL + "/*", PUBLIC_KEY_RING_BY_LIKE_EMAIL);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC, PUBLIC_KEY_RING);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/#", PUBLIC_KEY_RING_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID
|
||||
+ "/*", PUBLIC_KEY_RING_BY_MASTER_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_KEY_ID + "/*",
|
||||
PUBLIC_KEY_RING_BY_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS + "/*",
|
||||
PUBLIC_KEY_RING_BY_EMAILS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_EMAILS,
|
||||
PUBLIC_KEY_RING_BY_EMAILS); // without emails
|
||||
// specified
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*",
|
||||
PUBLIC_KEY_RING_BY_LIKE_EMAIL);
|
||||
|
||||
/**
|
||||
* public keys
|
||||
@ -129,10 +137,12 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/public/#/keys/#
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
|
||||
+ "/#/" + KeychainContract.PATH_KEYS, PUBLIC_KEY_RING_KEY);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
|
||||
+ "/#/" + KeychainContract.PATH_KEYS + "/#", PUBLIC_KEY_RING_KEY_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS,
|
||||
PUBLIC_KEY_RING_KEY);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_KEYS + "/#",
|
||||
PUBLIC_KEY_RING_KEY_BY_ROW_ID);
|
||||
|
||||
/**
|
||||
* public user ids
|
||||
@ -142,10 +152,12 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/public/#/user_ids/#
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
|
||||
+ "/#/" + KeychainContract.PATH_USER_IDS, PUBLIC_KEY_RING_USER_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_PUBLIC
|
||||
+ "/#/" + KeychainContract.PATH_USER_IDS + "/#", PUBLIC_KEY_RING_USER_ID_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS,
|
||||
PUBLIC_KEY_RING_USER_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_PUBLIC + "/#/" + KeychainContract.PATH_USER_IDS + "/#",
|
||||
PUBLIC_KEY_RING_USER_ID_BY_ROW_ID);
|
||||
|
||||
/**
|
||||
* secret key rings
|
||||
@ -159,22 +171,26 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/secret/like_email/_
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET,
|
||||
SECRET_KEY_RING);
|
||||
matcher.addURI(authority,
|
||||
KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/#",
|
||||
SECRET_KEY_RING_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
|
||||
+ KeychainContract.PATH_BY_MASTER_KEY_ID + "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
|
||||
+ KeychainContract.PATH_BY_KEY_ID + "/*", SECRET_KEY_RING_BY_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
|
||||
+ KeychainContract.PATH_BY_EMAILS + "/*", SECRET_KEY_RING_BY_EMAILS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
|
||||
+ KeychainContract.PATH_BY_EMAILS, SECRET_KEY_RING_BY_EMAILS); // without emails
|
||||
// specified
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET + "/"
|
||||
+ KeychainContract.PATH_BY_LIKE_EMAIL + "/*", SECRET_KEY_RING_BY_LIKE_EMAIL);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET, SECRET_KEY_RING);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/#", SECRET_KEY_RING_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_MASTER_KEY_ID
|
||||
+ "/*", SECRET_KEY_RING_BY_MASTER_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_KEY_ID + "/*",
|
||||
SECRET_KEY_RING_BY_KEY_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS + "/*",
|
||||
SECRET_KEY_RING_BY_EMAILS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_EMAILS,
|
||||
SECRET_KEY_RING_BY_EMAILS); // without emails
|
||||
// specified
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/" + KeychainContract.PATH_BY_LIKE_EMAIL + "/*",
|
||||
SECRET_KEY_RING_BY_LIKE_EMAIL);
|
||||
|
||||
/**
|
||||
* secret keys
|
||||
@ -184,10 +200,12 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/secret/#/keys/#
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
|
||||
+ "/#/" + KeychainContract.PATH_KEYS, SECRET_KEY_RING_KEY);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
|
||||
+ "/#/" + KeychainContract.PATH_KEYS + "/#", SECRET_KEY_RING_KEY_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS,
|
||||
SECRET_KEY_RING_KEY);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_KEYS + "/#",
|
||||
SECRET_KEY_RING_KEY_BY_ROW_ID);
|
||||
|
||||
/**
|
||||
* secret user ids
|
||||
@ -197,10 +215,12 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/secret/#/user_ids/#
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
|
||||
+ "/#/" + KeychainContract.PATH_USER_IDS, SECRET_KEY_RING_USER_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + KeychainContract.PATH_SECRET
|
||||
+ "/#/" + KeychainContract.PATH_USER_IDS + "/#", SECRET_KEY_RING_USER_ID_BY_ROW_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS,
|
||||
SECRET_KEY_RING_USER_ID);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/"
|
||||
+ KeychainContract.PATH_SECRET + "/#/" + KeychainContract.PATH_USER_IDS + "/#",
|
||||
SECRET_KEY_RING_USER_ID_BY_ROW_ID);
|
||||
|
||||
/**
|
||||
* data stream
|
||||
@ -656,6 +676,7 @@ public class KeychainProvider extends ContentProvider {
|
||||
|
||||
// notify of changes in db
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
sendBroadcastDatabaseChange();
|
||||
|
||||
return rowUri;
|
||||
}
|
||||
@ -704,6 +725,7 @@ public class KeychainProvider extends ContentProvider {
|
||||
|
||||
// notify of changes in db
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
sendBroadcastDatabaseChange();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -761,6 +783,7 @@ public class KeychainProvider extends ContentProvider {
|
||||
|
||||
// notify of changes in db
|
||||
getContext().getContentResolver().notifyChange(uri, null);
|
||||
sendBroadcastDatabaseChange();
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -849,4 +872,14 @@ public class KeychainProvider extends ContentProvider {
|
||||
File file = new File(getContext().getFilesDir().getAbsolutePath(), fileName);
|
||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
* This broadcast is send system wide to inform other application that a keyring was inserted,
|
||||
* updated, or deleted
|
||||
*/
|
||||
private void sendBroadcastDatabaseChange() {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(ACTION_BROADCAST_DATABASE_CHANGE);
|
||||
getContext().sendBroadcast(intent, Constants.PERMISSION_ACCESS_API);
|
||||
}
|
||||
}
|
||||
|
27
README.md
27
README.md
@ -66,14 +66,15 @@ See http://docs.oseems.com/general/application/eclipse/fix-gc-overhead-limit-exc
|
||||
|
||||
Android primitives to exchange data: Intent, Intent with return values, Send (also an Intent), Content Provider, AIDL
|
||||
|
||||
## Permission
|
||||
## Possible Permissions
|
||||
|
||||
* ACCESS_API: Encrypt/Sign/Decrypt/Create keys without user interaction (intents, remote service), Read key information (not the actual keys)(content provider)
|
||||
* ACCESS_KEYS: get and import actual public and secret keys (remote service)
|
||||
|
||||
## Intents
|
||||
## Without Permissions
|
||||
|
||||
### Without permission
|
||||
### Intents
|
||||
All Intents start with org.sufficientlysecure.keychain.action.
|
||||
|
||||
* android.intent.action.VIEW connected to .gpg and .asc files: Import Key and Decrypt
|
||||
* android.intent.action.SEND connected to all mime types (text/plain and every binary data like files and images): Encrypt and Decrypt
|
||||
@ -92,7 +93,9 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
|
||||
* DECRYPT
|
||||
* DECRYPT_FILE
|
||||
|
||||
### With permission ACCESS_API
|
||||
## With permission ACCESS_API
|
||||
|
||||
### Intents
|
||||
|
||||
* CREATE_KEYRING
|
||||
* ENCRYPT_AND_RETURN
|
||||
@ -101,7 +104,11 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
|
||||
* DECRYPT_AND_RETURN
|
||||
* DECRYPT_STREAM_AND_RETURN
|
||||
|
||||
## Content Provider
|
||||
### Broadcast Receiver
|
||||
On change of database the following broadcast is send.
|
||||
* DATABASE_CHANGE
|
||||
|
||||
### Content Provider
|
||||
|
||||
* The whole content provider requires a permission (only read)
|
||||
* Don't give out blobs (keys can be accessed by ACCESS_KEYS via remote service)
|
||||
@ -109,11 +116,13 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
|
||||
* Look at android:grantUriPermissions especially for ApgServiceBlobProvider
|
||||
* Only give out android:readPermission
|
||||
|
||||
## ApgApiService (Remote Service)
|
||||
* ACCESS_API
|
||||
### ApgApiService (Remote Service)
|
||||
AIDL service
|
||||
|
||||
## ApgKeyService (Remote Service)
|
||||
* ACCESS_KEYS
|
||||
## With permission ACCESS_KEYS
|
||||
|
||||
### ApgKeyService (Remote Service)
|
||||
AIDL service to access actual private keyring objects
|
||||
|
||||
# Licenses
|
||||
OpenPGP Kechain is licensed under Apache License v2.
|
||||
|
Loading…
Reference in New Issue
Block a user