• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <ohos_errno.h>
17 #include <pthread.h>
18 #include <securec.h>
19 
20 #include "cJSON.h"
21 #include "iproxy_client.h"
22 #include "liteipc_adapter.h"
23 #include "log.h"
24 #include "pms_interface.h"
25 #include "pms_types.h"
26 #include "registry.h"
27 #include "samgr_lite.h"
28 
29 #define PERMISSION_SERVICE "permissionms"
30 #define PERM_FEATURE "PmsFeature"
31 #define PERM_INNER_FEATURE "PmsInnerFeature"
32 #define MAX_DATA_LEN 0x100
33 #define FIELD_PERMISSION "permissions"
34 #define FIELD_NAME "name"
35 #define FIELD_DESC "desc"
36 #define FIELD_IS_GRANTED "isGranted"
37 #define FIELD_FLAGS "flags"
38 #define SYS_SVC_UID_MAX 99
39 #define SYS_APP_UID_MIN 100
40 #define SYS_APP_UID_MAX 999
41 #define PERMISSION_NUM_MAX 1000
42 
43 enum FUNCID {
44     ID_CHECK_SELF = 0,
45     ID_QUERY,
46     ID_CHECK = 10,
47     ID_GRANT,
48     ID_REVOKE,
49     ID_GRANT_RUNTIME,
50     ID_REVOKE_RUNTIME,
51     ID_UPDATE_PERMS_FLAGS,
52 };
53 
54 typedef struct ClientApi {
55     INHERIT_CLIENT_IPROXY;
56     int (*CheckSelfPermission)(const char *permissionName);
57     int (*QueryPermission)(const char *identifier, PermissionSaved **permissions, int *permNum);
58 } ClientApi;
59 
60 typedef struct ClientEntry {
61     INHERIT_IUNKNOWNENTRY(ClientApi);
62 } ClientEntry;
63 
64 typedef struct InnerClientApi {
65     INHERIT_CLIENT_IPROXY;
66     int (*CheckPermission)(int uid, const char *permissionName);
67     int (*GrantPermission)(const char *identifier, const char *permName);
68     int (*RevokePermission)(const char *identifier, const char *permName);
69     int (*GrantRuntimePermission)(int uid, const char *permissionName);
70     int (*RevokeRuntimePermission)(int uid, const char *permissionName);
71     int (*UpdatePermissionFlags)(const char *identifier, const char *permissionName, int flags);
72 } InnerClientApi;
73 
74 typedef struct ClientInnerEntry {
75     INHERIT_IUNKNOWNENTRY(InnerClientApi);
76 } ClientInnerEntry;
77 
78 typedef struct RetOfQueryPerms {
79     int resultCode;
80     int length;
81     PermissionSaved *permission;
82 } RetOfQueryPerms;
83 
84 typedef struct RetOfGetDevUdid {
85     unsigned char *udid;
86     int size;
87     int result;
88 } RetOfGetDevUdid;
89 
CreatClient(const char * service,const char * feature,uint32 size)90 void *CreatClient(const char *service, const char *feature, uint32 size)
91 {
92     (void)service;
93     (void)feature;
94     uint32 len = size + sizeof(ClientEntry);
95     if ((len < size) || (len < sizeof(ClientEntry))) {
96         return NULL;
97     }
98     uint8 *client = malloc(len);
99     if (client == NULL) {
100         return NULL;
101     }
102     (void)memset_s(client, len, 0, len);
103     ClientEntry *entry = (ClientEntry *)&client[size];
104     entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
105     entry->ref = 1;
106     entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
107     entry->iUnknown.AddRef = IUNKNOWN_AddRef;
108     entry->iUnknown.Release = IUNKNOWN_Release;
109     entry->iUnknown.Invoke = NULL;
110     entry->iUnknown.CheckSelfPermission = CheckSelfPermission;
111     entry->iUnknown.QueryPermission = QueryPermission;
112     return client;
113 }
114 
DestroyClient(const char * service,const char * feature,void * iproxy)115 void DestroyClient(const char *service, const char *feature, void *iproxy)
116 {
117     (void)service;
118     (void)feature;
119     free(iproxy);
120 }
121 
GetClientApi(void)122 static ClientApi *GetClientApi(void)
123 {
124     SAMGR_RegisterFactory(PERMISSION_SERVICE, PERM_FEATURE, CreatClient, DestroyClient);
125     ClientApi *clientApi = NULL;
126     HILOG_INFO(HILOG_MODULE_APP, "[GetFeatureApi S:%s F:%s]: BEGIN\n", PERMISSION_SERVICE, PERM_FEATURE);
127     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(PERMISSION_SERVICE, PERM_FEATURE);
128     if (iUnknown == NULL) {
129         HILOG_INFO(HILOG_MODULE_APP, "[GetFeatureApi S:%s F:%s]: error is NULL\n", PERMISSION_SERVICE, PERM_FEATURE);
130         return NULL;
131     }
132 
133     (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&clientApi);
134     HILOG_INFO(HILOG_MODULE_APP, "[QueryInterface CLIENT_PROXY_VER S:%s, F:%s]\n",
135                PERMISSION_SERVICE, PERM_FEATURE);
136     return clientApi;
137 }
138 
ReleaseClientApi(ClientApi * clientApi)139 static void ReleaseClientApi(ClientApi *clientApi)
140 {
141     if (clientApi == NULL) {
142         return;
143     }
144     int32 ref = clientApi->Release((IUnknown *)clientApi);
145     HILOG_INFO(HILOG_MODULE_APP, "[Release api S:%s, F:%s]: ref:%d\n",
146                PERMISSION_SERVICE, PERM_FEATURE, ref);
147 }
148 
CreatInnerClient(const char * service,const char * feature,uint32 size)149 void *CreatInnerClient(const char *service, const char *feature, uint32 size)
150 {
151     (void)service;
152     (void)feature;
153     uint32 len = size + sizeof(ClientInnerEntry);
154     if ((len < size) || (len < sizeof(ClientInnerEntry))) {
155         return NULL;
156     }
157     uint8 *client = malloc(len);
158     if (client == NULL) {
159         return NULL;
160     }
161     (void)memset_s(client, len, 0, len);
162     ClientInnerEntry *entry = (ClientInnerEntry *)&client[size];
163     entry->ver = ((uint16)CLIENT_PROXY_VER | (uint16)DEFAULT_VERSION);
164     entry->ref = 1;
165     entry->iUnknown.QueryInterface = IUNKNOWN_QueryInterface;
166     entry->iUnknown.AddRef = IUNKNOWN_AddRef;
167     entry->iUnknown.Release = IUNKNOWN_Release;
168     entry->iUnknown.Invoke = NULL;
169     entry->iUnknown.CheckPermission = CheckPermission;
170     entry->iUnknown.GrantPermission = GrantPermission;
171     entry->iUnknown.RevokePermission = RevokePermission;
172     entry->iUnknown.GrantRuntimePermission = GrantRuntimePermission;
173     entry->iUnknown.RevokeRuntimePermission = RevokeRuntimePermission;
174     entry->iUnknown.UpdatePermissionFlags = UpdatePermissionFlags;
175     return client;
176 }
177 
DestroyInnerClient(const char * service,const char * feature,void * iproxy)178 void DestroyInnerClient(const char *service, const char *feature, void *iproxy)
179 {
180     (void)service;
181     (void)feature;
182     free(iproxy);
183 }
184 
GetInnerClientApi(void)185 static InnerClientApi *GetInnerClientApi(void)
186 {
187     SAMGR_RegisterFactory(PERMISSION_SERVICE, PERM_INNER_FEATURE, CreatInnerClient, DestroyInnerClient);
188     InnerClientApi *clientApi = NULL;
189     HILOG_INFO(HILOG_MODULE_APP, "[GetFeatureApi S:%s F:%s]: BEGIN\n", PERMISSION_SERVICE, PERM_INNER_FEATURE);
190     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(PERMISSION_SERVICE, PERM_INNER_FEATURE);
191     if (iUnknown == NULL) {
192         HILOG_INFO(HILOG_MODULE_APP, "[GetFeatureApi S:%s F:%s]: error is NULL\n", PERMISSION_SERVICE,
193             PERM_INNER_FEATURE);
194         return NULL;
195     }
196     (void)iUnknown->QueryInterface(iUnknown, CLIENT_PROXY_VER, (void **)&clientApi);
197     HILOG_INFO(HILOG_MODULE_APP, "[QueryInterface CLIENT_PROXY_VER S:%s, F:%s]\n",
198                PERMISSION_SERVICE, PERM_INNER_FEATURE);
199     return clientApi;
200 }
201 
ReleaseInnerClientApi(InnerClientApi * clientApi)202 static void ReleaseInnerClientApi(InnerClientApi *clientApi)
203 {
204     if (clientApi == NULL) {
205         return;
206     }
207     int32 ref = clientApi->Release((IUnknown *)clientApi);
208     HILOG_INFO(HILOG_MODULE_APP, "[Release api S:%s, F:%s]: ref:%d\n",
209                PERMISSION_SERVICE, PERM_INNER_FEATURE, ref);
210 }
211 
ParsePermissions(const char * jsonStr,PermissionSaved ** perms,int * permNum)212 static int ParsePermissions(const char *jsonStr, PermissionSaved **perms, int *permNum)
213 {
214     cJSON *root = cJSON_Parse(jsonStr);
215     if (root == NULL) {
216         return PERM_ERRORCODE_JSONPARSE_FAIL;
217     }
218     cJSON *array = cJSON_GetObjectItem(root, FIELD_PERMISSION);
219     int pSize = cJSON_GetArraySize(array);
220     if (pSize > PERMISSION_NUM_MAX) {
221         return PERM_ERRORCODE_JSONPARSE_FAIL;
222     }
223 
224     int allocSize = sizeof(PermissionSaved) * pSize;
225     if (allocSize == 0) {
226         cJSON_Delete(root);
227         return PERM_ERRORCODE_SUCCESS;
228     }
229 
230     *perms = (PermissionSaved *) malloc(allocSize);
231     if (*perms == NULL) {
232         cJSON_Delete(root);
233         return PERM_ERRORCODE_MALLOC_FAIL;
234     }
235     for (int i = 0; i < pSize; i++) {
236         cJSON *object = cJSON_GetArrayItem(array, i);
237         cJSON *itemName = cJSON_GetObjectItem(object, FIELD_NAME);
238         cJSON *itemDesc = cJSON_GetObjectItem(object, FIELD_DESC);
239         cJSON *itemGranted = cJSON_GetObjectItem(object, FIELD_IS_GRANTED);
240         if (itemName == NULL || itemDesc == NULL || itemGranted == NULL || !cJSON_IsString(itemName)
241             || itemName->valuestring == NULL || !cJSON_IsString(itemDesc) || itemDesc->valuestring == NULL) {
242             cJSON_Delete(root);
243             free(*perms);
244             *perms = NULL;
245             return PERM_ERRORCODE_JSONPARSE_FAIL;
246         }
247         if (strcpy_s((*perms + i)->name, PERM_NAME_LEN, itemName->valuestring) != EOK) {
248             cJSON_Delete(root);
249             free(*perms);
250             *perms = NULL;
251             return PERM_ERRORCODE_COPY_ERROR;
252         }
253         if (strcpy_s((*perms + i)->desc, PERM_DESC_LEN, itemDesc->valuestring) != EOK) {
254             cJSON_Delete(root);
255             free(*perms);
256             *perms = NULL;
257             return PERM_ERRORCODE_COPY_ERROR;
258         }
259         (*perms + i)->granted = (enum IsGranted) itemGranted->valueint;
260     }
261     *permNum = pSize;
262     cJSON_Delete(root);
263     return PERM_ERRORCODE_SUCCESS;
264 }
265 
Notify(IOwner owner,int code,IpcIo * reply)266 static int Notify(IOwner owner, int code, IpcIo *reply)
267 {
268     if ((reply == NULL) || (owner == NULL)) {
269         HILOG_ERROR(HILOG_MODULE_APP, "Lite Ipc reply or owner is NULL");
270         return OHOS_FAILURE;
271     }
272 
273     int32_t *ret = (int32_t *)owner;
274     *ret = IpcIoPopInt32(reply);
275 
276     return EC_SUCCESS;
277 }
278 
DealQueryReply(IOwner owner,int code,IpcIo * reply)279 static int DealQueryReply(IOwner owner, int code, IpcIo *reply)
280 {
281     if ((reply == NULL) || (owner == NULL)) {
282         return OHOS_FAILURE;
283     }
284     int resultCode = IpcIoPopInt32(reply);
285     RetOfQueryPerms *ret = (RetOfQueryPerms *)(owner);
286     if (resultCode != PERM_ERRORCODE_SUCCESS) {
287         ret->resultCode = resultCode;
288         return resultCode;
289     }
290 #ifndef __LINUX__
291     BuffPtr *buff = IpcIoPopDataBuff(reply);
292     if (buff == NULL) {
293         ret->resultCode = OHOS_FAILURE;
294         HILOG_ERROR(HILOG_MODULE_APP, "Permission string popped is empty!");
295         return OHOS_FAILURE;
296     }
297     char *jsonStr = (char *)(buff->buff);
298 #else
299     char *jsonStr = (char *)IpcIoPopString(reply, NULL);
300 #endif
301     HILOG_INFO(HILOG_MODULE_APP, "[perms: %s]", jsonStr);
302     int retCode = ParsePermissions(jsonStr, &(ret->permission), &(ret->length));
303 #ifndef __LINUX__
304     FreeBuffer(NULL, buff->buff);
305 #endif
306     ret->resultCode = retCode;
307     return retCode;
308 }
309 
CheckSelfPermission(const char * permissionName)310 int CheckSelfPermission(const char *permissionName)
311 {
312     uid_t callingUid = getuid();
313     if (callingUid <= SYS_APP_UID_MAX) {
314         return GRANTED;
315     }
316     ClientApi *proxy = GetClientApi();
317     if (proxy == NULL) {
318         return OHOS_FAILURE;
319     }
320     IpcIo request;
321     char data[MAX_DATA_LEN];
322     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
323     IpcIoPushString(&request, permissionName);
324     int32_t ret = -1;
325     proxy->Invoke((IClientProxy *)proxy, ID_CHECK_SELF, &request, &ret, Notify);
326     ReleaseClientApi(proxy);
327     return ret;
328 }
329 
CheckPermission(int uid,const char * permissionName)330 int CheckPermission(int uid, const char *permissionName)
331 {
332     uid_t callingUid = getuid();
333     if (callingUid <= SYS_APP_UID_MAX) {
334         return GRANTED;
335     }
336     InnerClientApi *proxy = GetInnerClientApi();
337     if (proxy == NULL) {
338         return OHOS_FAILURE;
339     }
340     IpcIo request;
341     char data[MAX_DATA_LEN];
342     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
343     IpcIoPushInt64(&request, uid);
344     IpcIoPushString(&request, permissionName);
345     int32_t ret = -1;
346     proxy->Invoke((IClientProxy *)proxy, ID_CHECK, &request, &ret, Notify);
347     ReleaseInnerClientApi(proxy);
348     return ret;
349 }
350 
QueryPermission(const char * identifier,PermissionSaved ** permissions,int * permNum)351 int QueryPermission(const char *identifier, PermissionSaved **permissions, int *permNum)
352 {
353     ClientApi *proxy = GetClientApi();
354     if (proxy == NULL) {
355         return OHOS_FAILURE;
356     }
357     if (permissions == NULL || permNum == NULL) {
358         return OHOS_FAILURE;
359     }
360     IpcIo request;
361     char data[MAX_DATA_LEN];
362     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
363     IpcIoPushString(&request, identifier);
364     RetOfQueryPerms ret = {
365         .resultCode = 0,
366         .length = 0,
367         .permission = NULL
368     };
369     proxy->Invoke((IClientProxy *)proxy, ID_QUERY, &request, &ret, DealQueryReply);
370     *permissions = ret.permission;
371     *permNum = ret.length;
372     ReleaseClientApi(proxy);
373     return ret.resultCode;
374 }
375 
GrantPermission(const char * identifier,const char * permName)376 int GrantPermission(const char *identifier, const char *permName)
377 {
378     InnerClientApi *proxy = GetInnerClientApi();
379     if (proxy == NULL) {
380         return OHOS_FAILURE;
381     }
382     IpcIo request;
383     char data[MAX_DATA_LEN];
384     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
385     IpcIoPushString(&request, identifier);
386     IpcIoPushString(&request, permName);
387     int32_t ret = -1;
388     proxy->Invoke((IClientProxy *)proxy, ID_GRANT, &request, &ret, Notify);
389     ReleaseInnerClientApi(proxy);
390     HILOG_INFO(HILOG_MODULE_APP, "client grant[ret: %d]", ret);
391     return ret;
392 }
393 
RevokePermission(const char * identifier,const char * permName)394 int RevokePermission(const char *identifier, const char *permName)
395 {
396     InnerClientApi *proxy = GetInnerClientApi();
397     if (proxy == NULL) {
398         return OHOS_FAILURE;
399     }
400     IpcIo request;
401     char data[MAX_DATA_LEN];
402     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
403     IpcIoPushString(&request, identifier);
404     IpcIoPushString(&request, permName);
405     int32_t ret = -1;
406     proxy->Invoke((IClientProxy *)proxy, ID_REVOKE, &request, &ret, Notify);
407     ReleaseInnerClientApi(proxy);
408     HILOG_INFO(HILOG_MODULE_APP, "client revoke[ret: %d]", ret);
409     return ret;
410 }
411 
GrantRuntimePermission(int uid,const char * permissionName)412 int GrantRuntimePermission(int uid, const char *permissionName)
413 {
414     InnerClientApi *proxy = GetInnerClientApi();
415     if (proxy == NULL) {
416         return OHOS_FAILURE;
417     }
418     IpcIo request;
419     char data[MAX_DATA_LEN];
420     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
421     IpcIoPushInt64(&request, uid);
422     IpcIoPushString(&request, permissionName);
423     int32_t ret = -1;
424     proxy->Invoke((IClientProxy *)proxy, ID_GRANT_RUNTIME, &request, &ret, Notify);
425     ReleaseInnerClientApi(proxy);
426     return ret;
427 }
428 
RevokeRuntimePermission(int uid,const char * permissionName)429 int RevokeRuntimePermission(int uid, const char *permissionName)
430 {
431     InnerClientApi *proxy = GetInnerClientApi();
432     if (proxy == NULL) {
433         return OHOS_FAILURE;
434     }
435     IpcIo request;
436     char data[MAX_DATA_LEN];
437     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
438     IpcIoPushInt64(&request, uid);
439     IpcIoPushString(&request, permissionName);
440     int32_t ret = -1;
441     proxy->Invoke((IClientProxy *)proxy, ID_REVOKE_RUNTIME, &request, &ret, Notify);
442     ReleaseInnerClientApi(proxy);
443     return ret;
444 }
445 
UpdatePermissionFlags(const char * identifier,const char * permissionName,const int flags)446 int UpdatePermissionFlags(const char *identifier, const char *permissionName, const int flags)
447 {
448     InnerClientApi *proxy = GetInnerClientApi();
449     if (proxy == NULL) {
450         return OHOS_FAILURE;
451     }
452     IpcIo request;
453     char data[MAX_DATA_LEN];
454     IpcIoInit(&request, data, MAX_DATA_LEN, 0);
455     IpcIoPushString(&request, identifier);
456     IpcIoPushString(&request, permissionName);
457     IpcIoPushInt32(&request, flags);
458     int32_t ret = -1;
459     proxy->Invoke((IClientProxy *)proxy, ID_UPDATE_PERMS_FLAGS, &request, &ret, Notify);
460     ReleaseInnerClientApi(proxy);
461     return ret;
462 }
463 
464