What I'm trying to do: implement lightweight, secure IPC protocol between two applications installed on the device. Client app should be able to send commands and queries to Service
running in a service app, and receive back results of computations.
Apps relationship: source code of both apps is under my control, but the apps will have different signatures (non-negotiable).
Security requirements: service app should provide its services to a single client. Client's application ID (package name) is known and constant.
What I tried: I tried to implement IPC with two-way Messenger
communication scheme (similar to this blog post). This approach works fine, but I encountered one major issue - I can't find a way to obtain UID
of the client, therefore I can't satisfy security requirements.
Consider this code found in Service
of the service application:
// This messenger will be used by the clients of this service in order to send commands
private Messenger inboxMessenger = new Messenger(new Handler() {
@Override
public void handleMessage(Message msg)
// TODO: verify the identity of the client
switch (msg.what) {
case MSG_GET_DATA:
returnDataToClient(msg.replyTo);
break;
}
}
});
The idea here is that when the client app sends a message to this Service
, it puts its local "callback" Messenger
into replyTo
member of the sent Message
. Documentation for Messenger
states that:
Note: the implementation underneath is just a simple wrapper around a Binder that is used to perform the communication.
so I thought that I could somehow map the Binder returned by Messenger#getBinder()
to client's UID
, but I'm now having troubles:
Messenger#getBinder()
returns IBinder which can't be cast toBinder
- Even if I do manage to get a reference to client's
Binder
, the methodBinder#getCallingUid()
isstatic
and does not accept arguments...
So, in order to make this particular implementation work securely, I need to find a way to obtain caller's UID
based on the contents of Message
or based on a particular Messenger
which was created by the client. Since Android's security architecture is built around Binders
, it seems strange that there is no straightforward approach to mapping Binders
to UIDs
(or package names)... So, how can I do this?
Bonus question: except for AIDL, is there any other IPC technique on Android that fulfills the requirements stated above?