2

I have main application A that uses other apps as plugins, lets say B, C and D. I have no control over what app will be installed first.

How do I define signature level permission so only main app A can start plugin apps B, C and D?

Plugins don't have UI so user can't start them manually but I need to make sure only my main app can launch them. I tried defining the permission in plugins like so:

<permission
    android:name="my.custom.permission.START_PLUGIN"
    android:protectionLevel="signature"/>

And then in my main app:

<uses-permission android:name="my.custom.permission.START_PLUGIN" />

This doesn't seem to be correct approach. Can anyone tell me the correct way to achieve what I described above? Thanks.

EDIT: My plugins are implemented as bound services with AIDL interface.

lsrom
  • 608
  • 8
  • 22
  • how are your plugins implemented? as bound services, content providers, anything else? – pskink Jul 27 '17 at 06:26
  • Bound services. Updating question. – lsrom Jul 27 '17 at 06:37
  • so use `Binder#getCallingUid()` either in your custom `Binder#onTransact` method or Stub methods implementation – pskink Jul 27 '17 at 06:40
  • I would like to solve this problem using permissions. I will check out your suggestion but I would preffer solving it with signature level permission. – lsrom Jul 27 '17 at 06:47
  • Well, the Android system should handle this by itself... However I can't seem to find the correct way to do it. – lsrom Jul 27 '17 at 06:54
  • Well, I got it working with both custom permission and sharedUserId like you suggested @pskink but now I wonder. What's the difference between the two? What is better for my intended purpose? Can you explain it to me or point me to good source? Thanks. – lsrom Aug 01 '17 at 07:33
  • you dont need `custom permission`, just use `sharedUserId` and `exported=false` that way A B C and D will be seen by a system as one component – pskink Aug 01 '17 at 07:38
  • Yes, I now know that I don't need it, but I want to better understand the difference between the two. Can you point me in the right dirrection? – lsrom Aug 01 '17 at 07:40
  • To be more clear, I'm interested in difference between using sharedUserId, and custom permission with signature level protection. Both are granted based on app's signature and both seemed to do the same thing. I would like to know what is the difference between them and what are their (dis)advantages. – lsrom Aug 01 '17 at 07:48
  • so whats wrong it those words: `This doesn't seem to be correct approach. Can anyone tell me the correct way to achieve what I described above?` does custom permission seem to be correct approach or not? – pskink Aug 01 '17 at 08:53
  • Well, yes. They would allow to choose what parts of application to protect. Permission itself would be given to any application with the same signature, same as sharedUserId. As far as I can tell, the only difference is that sharedUserId couples apps much closely (can access each others SharedPrefs) and can't be used for only some parts of app. Is that correct? – lsrom Aug 01 '17 at 08:59
  • I checked this and only way to obtain custom permission is if the signatures checks out. User cannot grant this permission. If permission is not automatically granted, action requiring this permission throws java.lang.SecurityException. – lsrom Aug 01 '17 at 10:20
  • by using `sharedUserId` you can access the same components like files, databases etc and also make A B C and D to be run in the same physical process eliminating any slow IPC calls, if you dont care about the speed and resource sharing use custom permission – pskink Aug 01 '17 at 14:07

1 Answers1

3

To answer my original question, to make my example work, all you have to do is add permission attribute to your application components you want to protect. This is done in Manifest.xml file.

Let's say you have activity called MyActivity that you want only your apps with START_PLUGIN permission to be able to launch. So in your plugin, you do:

<permission
    android:name="my.custom.permission.START_PLUGIN"
    android:protectionLevel="signature"/>

and:

<activity
    android:name=".MyActivity"
    android:permission="my.custom.permission.START_PLUGIN"/>

The last one will ensure that only apps with START_PLUGIN permission can access that activity. So all you need to do is in app that should start this plugin use the permission like so:

<uses-permission android:name="my.custom.permission.START_PLUGIN" />

To decide if you want to use permission with signature level protection, or sharedUserId as suggested by @pskink in comments, consider following:

  • sharedUserId tightly couples both (or more) apps, enables them to access not only specific activities but their files (even SharedPreferences) and views and basically removes any level of separation
  • custom permission enables to to specify which parts of your app are to be protected, leaving you with more control but also with the need for IPC like AIDL

Links:

sharedUserId Android Reference

How to access data of app with sharedUserId

AIDL Reference

Android permission protection levels

lsrom
  • 608
  • 8
  • 22