私がやろうとしているのは、デバイスにインストールされた 2 つのアプリケーション間で軽量で安全なIPC プロトコルを実装することです。Service
クライアント アプリは、サービス アプリで実行されているコマンドとクエリを送信し、計算結果を受け取ることができる必要があります。
アプリの関係:両方のアプリのソース コードは私の管理下にありますが、アプリの署名は異なります (交渉不可)。
セキュリティ要件:サービス アプリは、そのサービスを単一のクライアントに提供する必要があります。クライアントのアプリケーション ID (パッケージ名) は既知で一定です。
試したこと:双方向Messenger
通信方式で IPC を実装しようとしました (このブログ投稿と同様)。このアプローチは問題なく機能しますが、大きな問題が 1 つUID
あります。クライアントを取得する方法が見つからないため、セキュリティ要件を満たすことができません。
Service
サービス アプリケーションの次のコードについて考えてみましょう。
// 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;
}
}
});
ここでの考え方は、クライアント アプリがメッセージを thisService
に送信するときに、ローカルの「コールバック」Messenger
をreplyTo
sent のメンバーに入れるというものMessage
です。次の状態のドキュメントMessenger
:
注: 下の実装は、通信を実行するために使用される Binder の単純なラッパーです。
だから私はどうにかして返されたBinderMessenger#getBinder()
をクライアントのUID
にマップできると思っていましたが、現在問題が発生しています:
Messenger#getBinder()
キャストできないIBinderを返しますBinder
- クライアントの への参照を取得できたとしても
Binder
、メソッドBinder#getCallingUid()
はstatic
引数を受け入れません...
したがって、この特定の実装を安全に機能させるには、クライアントによって作成された特定のコンテンツまたは特定UID
のコンテンツに基づいて呼び出し元を取得する方法を見つける必要があります。Android のセキュリティ アーキテクチャは を中心に構築されているため、(またはパッケージ名) へのマッピングへの直接的なアプローチがないのは奇妙に思えます...では、どうすればこれを行うことができますか?Message
Messenger
Binders
Binders
UIDs
おまけの質問: AIDL を除いて、Android で上記の要件を満たす IPC 手法は他にありますか?