1 /*
2  * Copyright (C) 2005 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "PermissionController"
18 
19 #include <binder/IPermissionController.h>
20 
21 #include <utils/Log.h>
22 #include <binder/Parcel.h>
23 #include <utils/String8.h>
24 
25 namespace android {
26 
27 // ----------------------------------------------------------------------
28 
29 class BpPermissionController : public BpInterface<IPermissionController>
30 {
31 public:
BpPermissionController(const sp<IBinder> & impl)32     explicit BpPermissionController(const sp<IBinder>& impl)
33         : BpInterface<IPermissionController>(impl)
34     {
35     }
36 
checkPermission(const String16 & permission,int32_t pid,int32_t uid)37     virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
38     {
39         Parcel data, reply;
40         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
41         data.writeString16(permission);
42         data.writeInt32(pid);
43         data.writeInt32(uid);
44         remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
45         // fail on exception
46         if (reply.readExceptionCode() != 0) return 0;
47         return reply.readInt32() != 0;
48     }
49 
noteOp(const String16 & op,int32_t uid,const String16 & packageName)50     virtual int32_t noteOp(const String16& op, int32_t uid, const String16& packageName)
51     {
52         Parcel data, reply;
53         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
54         data.writeString16(op);
55         data.writeInt32(uid);
56         data.writeString16(packageName);
57         remote()->transact(NOTE_OP_TRANSACTION, data, &reply);
58         // fail on exception
59         if (reply.readExceptionCode() != 0) return 2; // MODE_ERRORED
60         return reply.readInt32();
61     }
62 
getPackagesForUid(const uid_t uid,Vector<String16> & packages)63     virtual void getPackagesForUid(const uid_t uid, Vector<String16>& packages)
64     {
65         Parcel data, reply;
66         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
67         data.writeInt32(uid);
68         remote()->transact(GET_PACKAGES_FOR_UID_TRANSACTION, data, &reply);
69         // fail on exception
70         if (reply.readExceptionCode() != 0) {
71             return;
72         }
73         const int32_t size = reply.readInt32();
74         if (size <= 0) {
75             return;
76         }
77         for (int i = 0; i < size; i++) {
78             packages.push(reply.readString16());
79         }
80     }
81 
isRuntimePermission(const String16 & permission)82     virtual bool isRuntimePermission(const String16& permission)
83     {
84         Parcel data, reply;
85         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
86         data.writeString16(permission);
87         remote()->transact(IS_RUNTIME_PERMISSION_TRANSACTION, data, &reply);
88         // fail on exception
89         if (reply.readExceptionCode() != 0) return false;
90         return reply.readInt32() != 0;
91     }
92 
getPackageUid(const String16 & package,int flags)93     virtual int getPackageUid(const String16& package, int flags)
94     {
95         Parcel data, reply;
96         data.writeInterfaceToken(IPermissionController::getInterfaceDescriptor());
97         data.writeString16(package);
98         data.writeInt32(flags);
99         remote()->transact(GET_PACKAGE_UID_TRANSACTION, data, &reply);
100         // fail on exception
101         if (reply.readExceptionCode() != 0) return false;
102         return reply.readInt32();
103     }
104 };
105 
106 IMPLEMENT_META_INTERFACE(PermissionController, "android.os.IPermissionController")
107 
108 // ----------------------------------------------------------------------
109 
110 // NOLINTNEXTLINE(google-default-arguments)
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)111 status_t BnPermissionController::onTransact(
112     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
113 {
114     switch(code) {
115         case CHECK_PERMISSION_TRANSACTION: {
116             CHECK_INTERFACE(IPermissionController, data, reply);
117             String16 permission = data.readString16();
118             int32_t pid = data.readInt32();
119             int32_t uid = data.readInt32();
120             bool res = checkPermission(permission, pid, uid);
121             reply->writeNoException();
122             reply->writeInt32(res ? 1 : 0);
123             return NO_ERROR;
124         } break;
125 
126         case NOTE_OP_TRANSACTION: {
127             CHECK_INTERFACE(IPermissionController, data, reply);
128             String16 op = data.readString16();
129             int32_t uid = data.readInt32();
130             String16 packageName = data.readString16();
131             int32_t res = noteOp(op, uid, packageName);
132             reply->writeNoException();
133             reply->writeInt32(res);
134             return NO_ERROR;
135         } break;
136 
137         case GET_PACKAGES_FOR_UID_TRANSACTION: {
138             CHECK_INTERFACE(IPermissionController, data, reply);
139             int32_t uid = data.readInt32();
140             Vector<String16> packages;
141             getPackagesForUid(uid, packages);
142             reply->writeNoException();
143             size_t size = packages.size();
144             reply->writeInt32(size);
145             for (size_t i = 0; i < size; i++) {
146                 reply->writeString16(packages[i]);
147             }
148             return NO_ERROR;
149         } break;
150 
151         case IS_RUNTIME_PERMISSION_TRANSACTION: {
152             CHECK_INTERFACE(IPermissionController, data, reply);
153             String16 permission = data.readString16();
154             const bool res = isRuntimePermission(permission);
155             reply->writeNoException();
156             reply->writeInt32(res ? 1 : 0);
157             return NO_ERROR;
158         } break;
159 
160         case GET_PACKAGE_UID_TRANSACTION: {
161             CHECK_INTERFACE(IPermissionController, data, reply);
162             String16 package = data.readString16();
163             int flags = data.readInt32();
164             const int uid = getPackageUid(package, flags);
165             reply->writeNoException();
166             reply->writeInt32(uid);
167             return NO_ERROR;
168         } break;
169 
170         default:
171             return BBinder::onTransact(code, data, reply, flags);
172     }
173 }
174 
175 } // namespace android
176