1 /*
2  * Copyright (c) 2020 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 #include "samgr_server.h"
16 #include <fcntl.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20 
21 #include <ohos_init.h>
22 #include <ohos_types.h>
23 #include <ohos_errno.h>
24 #include <liteipc.h>
25 #include <liteipc_adapter.h>
26 #include <log.h>
27 
28 #include "cJSON.h"
29 #include "default_client.h"
30 #include "policy_define.h"
31 #include "samgr_lite.h"
32 #include "securec.h"
33 #include "thread_adapter.h"
34 #include "memory_adapter.h"
35 
36 #undef LOG_TAG
37 #undef LOG_DOMAIN
38 #define LOG_TAG "Samgr"
39 #define LOG_DOMAIN 0xD001800
40 
41 typedef int(*ProcFunc)(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
42 #define MAX_SA_SIZE 0x100
43 #define RETRY_TIMES 3
44 #define RETRY_INTERVAL 1
45 #define UID_HAP 10000
46 #define MAX_SYSCAP_NUM_PER_REPLY 118
47 
48 static const char *GetName(Service *service);
49 static BOOL Initialize(Service *service, Identity identity);
50 static TaskConfig GetTaskConfig(Service *service);
51 static BOOL MessageHandle(Service *service, Request *request);
52 static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply);
53 static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data, void* argv);
54 static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
55 static int32 ProcPutFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity);
56 static int32 ProcGetFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity);
57 static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
58 static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity);
59 static void TransmitPolicy(int ret, const SvcIdentity* identity, IpcIo *reply,
60                            const PolicyTrans *policy, uint32 policyNum);
61 static void TransmitFixedPolicy(IpcIo *reply, PolicyTrans policy);
62 static IpcAuthInterface *GetIpcAuthInterface(void);
63 static int ProcSysCap(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply);
64 static void ParseSysCap(void);
65 
66 static SamgrServer g_server = {
67     .GetName = GetName,
68     .Initialize = Initialize,
69     .GetTaskConfig = GetTaskConfig,
70     .MessageHandle = MessageHandle,
71     SERVER_IPROXY_IMPL_BEGIN,
72     .Invoke = Invoke,
73     IPROXY_END,
74 };
75 
76 static ProcFunc g_functions[] = {
77     [RES_ENDPOINT] = ProcEndpoint,
78     [RES_FEATURE] = ProcFeature,
79     [RES_SYSCAP] = ProcSysCap,
80 };
81 
GetSysCapName(const SysCapImpl * serviceImpl)82 static const char *GetSysCapName(const SysCapImpl *serviceImpl)
83 {
84     if (serviceImpl == NULL) {
85         return NULL;
86     }
87     return serviceImpl->name;
88 }
89 
InitializeRegistry(void)90 static void InitializeRegistry(void)
91 {
92     HILOG_INFO(HILOG_MODULE_SAMGR, "Initialize Registry!");
93     g_server.mtx = MUTEX_InitValue();
94     SASTORA_Init(&g_server.store);
95     g_server.samgr = SAMGR_CreateEndpoint("samgr", RegisterSamgrEndpoint);
96     SAMGR_GetInstance()->RegisterService((Service *)&g_server);
97     g_server.sysCapMtx = MUTEX_InitValue();
98     g_server.sysCapabilitys = VECTOR_Make((VECTOR_Key)GetSysCapName, (VECTOR_Compare)strcmp);
99     ParseSysCap();
100     HILOG_INFO(HILOG_MODULE_SAMGR, "InitializeRegistry ParseSysCap size: %d", VECTOR_Size(&(g_server.sysCapabilitys)));
101 }
102 SYS_SERVICE_INIT(InitializeRegistry);
103 
CanRequest(const void * origin)104 static BOOL CanRequest(const void *origin)
105 {
106     pid_t uid = GetCallingUid(origin);
107     return uid < UID_HAP;
108 }
109 
GetName(Service * service)110 static const char *GetName(Service *service)
111 {
112     (void)service;
113     return SAMGR_SERVICE;
114 }
115 
Initialize(Service * service,Identity identity)116 static BOOL Initialize(Service *service, Identity identity)
117 {
118     SamgrServer *server = (SamgrServer *)service;
119     server->identity = identity;
120     SaName saName = {SAMGR_SERVICE, NULL};
121     SAMGR_AddRouter(server->samgr, &saName, &server->identity, GET_IUNKNOWN(*server));
122     return TRUE;
123 }
124 
MessageHandle(Service * service,Request * request)125 static BOOL MessageHandle(Service *service, Request *request)
126 {
127     SamgrServer *server = (SamgrServer *)service;
128     switch (request->msgId) {
129         case MSG_CLEAN:
130             MUTEX_Lock(server->mtx);
131             SASTORA_ClearByPid(&server->store, request->msgValue);
132             MUTEX_Unlock(server->mtx);
133             break;
134         default:
135             break;
136     }
137     return TRUE;
138 }
139 
GetTaskConfig(Service * service)140 static TaskConfig GetTaskConfig(Service *service)
141 {
142     (void)service;
143     TaskConfig config = {LEVEL_HIGH, PRI_BUTT - 1, 0x400, 20, SINGLE_TASK}; // Cannot use PRI_BUTT directly, so minus 1
144     return config;
145 }
146 
Invoke(IServerProxy * iProxy,int funcId,void * origin,IpcIo * req,IpcIo * reply)147 static int32 Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, IpcIo *reply)
148 {
149     SamgrServer *server = GET_OBJECT(iProxy, SamgrServer, iUnknown);
150     uint32_t resource = IpcIoPopUint32(req);
151     uint32_t option = IpcIoPopUint32(req);
152     if (server == NULL || resource >= RES_BUTT || g_functions[resource] == NULL) {
153         HILOG_ERROR(HILOG_MODULE_SAMGR, "Invalid Msg<%d, %u, %d>", resource, option, funcId);
154         return EC_INVALID;
155     }
156     return g_functions[resource](server, option, origin, req, reply);
157 }
158 
ProcEndpoint(SamgrServer * server,int32 option,void * origin,IpcIo * req,IpcIo * reply)159 static int ProcEndpoint(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
160 {
161     if (option != OP_POST) {
162         IpcIoPushUint32(reply, (uint32)INVALID_INDEX);
163         return EC_FAILURE;
164     }
165 
166     pid_t pid = GetCallingPid(origin);
167     PidHandle handle;
168     MUTEX_Lock(server->mtx);
169     int index = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
170     if (index == INVALID_INDEX) {
171         SvcIdentity identity = {(uint32)INVALID_INDEX, (uint32)INVALID_INDEX, (uint32)INVALID_INDEX};
172         (void)GenServiceHandle(&identity, GetCallingTid(origin));
173 #ifdef __LINUX__
174         IpcMsg* data = (IpcMsg*)origin;
175         if (data == NULL) {
176             HILOG_ERROR(HILOG_MODULE_SAMGR, "Register Endpoint origin null pointer!");
177             return EC_FAILURE;
178         }
179         identity.handle = data->target.handle;
180         BinderAcquire(g_server.samgr->context, identity.handle);
181 #endif
182 
183         handle.pid = pid;
184         handle.uid = GetCallingUid(origin);
185         handle.handle = identity.handle;
186         handle.deadId = INVALID_INDEX;
187         (void)SASTORA_SaveHandleByPid(&server->store, handle);
188         (void)UnregisterDeathCallback(identity, handle.deadId);
189         (void)RegisterDeathCallback(server->samgr->context, identity, OnEndpointExit, (void*)((uintptr_t)pid),
190                                     &handle.deadId);
191     }
192     MUTEX_Unlock(server->mtx);
193     IpcIoPushUint32(reply, handle.handle);
194     HILOG_INFO(HILOG_MODULE_SAMGR, "Register Endpoint<%d, %u, %u>", handle.pid, handle.handle, handle.deadId);
195     return EC_SUCCESS;
196 }
197 
ProcPutFeature(SamgrServer * server,const void * origin,IpcIo * req,IpcIo * reply,SvcIdentity * identity)198 static int32 ProcPutFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity)
199 {
200     size_t len = 0;
201     char *service = (char *)IpcIoPopString(req, &len);
202     if (service == NULL || len == 0) {
203         IpcIoPushInt32(reply, EC_INVALID);
204         return EC_INVALID;
205     }
206     pid_t pid = GetCallingPid(origin);
207     uid_t uid = GetCallingUid(origin);
208     char *feature = IpcIoPopBool(req) ? NULL : (char *)IpcIoPopString(req, &len);
209     MUTEX_Lock(server->mtx);
210     PidHandle handle;
211     int index = SASTORA_FindHandleByUidPid(&server->store, uid, pid, &handle);
212     if (index == INVALID_INDEX) {
213         MUTEX_Unlock(server->mtx);
214         HILOG_ERROR(HILOG_MODULE_SAMGR, "Endpoint[%d] is not register", pid);
215         IpcIoPushInt32(reply, EC_NOSERVICE);
216         return EC_NOSERVICE;
217     }
218     *identity = SASTORA_Find(&server->store, service, feature);
219     if (identity->handle != INVALID_INDEX && identity->handle != handle.handle) {
220         MUTEX_Unlock(server->mtx);
221         IpcIoPushInt32(reply, EC_INVALID);
222         return EC_INVALID;
223     }
224     identity->token = IpcIoPopUint32(req);
225     identity->handle = handle.handle;
226 
227     PolicyTrans *policy = NULL;
228     RegParams regParams = {service, feature, handle.uid, handle.pid};
229     uint32 policyNum = 0;
230     int ret = g_server.ipcAuth->GetCommunicationStrategy(regParams, &policy, &policyNum);
231     if (ret != EC_SUCCESS || policy == NULL) {
232         MUTEX_Unlock(server->mtx);
233         SAMGR_Free(policy);
234         HILOG_DEBUG(HILOG_MODULE_SAMGR, "Remote Get Communication Strategy<%s, %s> No Permission<%d>!",
235                     service, feature, ret);
236         IpcIoPushInt32(reply, EC_PERMISSION);
237         return EC_PERMISSION;
238     }
239 
240     ret = SASTORA_Save(&server->store, service, feature, identity);
241     MUTEX_Unlock(server->mtx);
242     HILOG_DEBUG(HILOG_MODULE_SAMGR, "Register Feature<%s, %s> pid<%d>, id<%u, %u> ret:%d",
243                 service, feature, pid, identity->handle, identity->token, ret);
244     TransmitPolicy(ret, identity, reply, policy, policyNum);
245     SAMGR_Free(policy);
246     return ret;
247 }
248 
TransmitPolicy(int ret,const SvcIdentity * identity,IpcIo * reply,const PolicyTrans * policy,uint32 policyNum)249 static void TransmitPolicy(int ret, const SvcIdentity* identity, IpcIo *reply,
250                            const PolicyTrans *policy, uint32 policyNum)
251 {
252     if (identity == NULL || reply == NULL || policy == NULL) {
253         IpcIoPushInt32(reply, EC_INVALID);
254         return;
255     }
256     if (ret != EC_SUCCESS) {
257         IpcIoPushInt32(reply, ret);
258         return;
259     }
260     IpcIoPushInt32(reply, ret);
261     IpcIoPushSvc(reply, identity);
262     IpcIoPushUint32(reply, policyNum);
263     uint32 i;
264     for (i = 0; i < policyNum; i++) {
265         IpcIoPushInt32(reply, policy[i].type);
266         switch (policy[i].type) {
267             case RANGE:
268                 IpcIoPushInt32(reply, policy[i].uidMin);
269                 IpcIoPushInt32(reply, policy[i].uidMax);
270                 break;
271             case FIXED:
272                 TransmitFixedPolicy(reply, policy[i]);
273                 break;
274             case BUNDLENAME:
275                 IpcIoPushInt32(reply, policy[i].fixedUid[0]);
276                 break;
277             default:
278                 break;
279         }
280     }
281 }
282 
TransmitFixedPolicy(IpcIo * reply,PolicyTrans policy)283 static void TransmitFixedPolicy(IpcIo *reply, PolicyTrans policy)
284 {
285     if (reply == NULL) {
286         return;
287     }
288     uint32 i;
289     for (i = 0; i < UID_SIZE; i++) {
290         IpcIoPushInt32(reply, policy.fixedUid[i]);
291     }
292 }
293 
ProcGetFeature(SamgrServer * server,const void * origin,IpcIo * req,IpcIo * reply,SvcIdentity * identity)294 static int32 ProcGetFeature(SamgrServer *server, const void *origin, IpcIo *req, IpcIo *reply, SvcIdentity *identity)
295 {
296     size_t len = 0;
297     char *service = (char *)IpcIoPopString(req, &len);
298     if (service == NULL || len == 0) {
299         IpcIoPushInt32(reply, EC_INVALID);
300         return EC_INVALID;
301     }
302     char *feature = IpcIoPopBool(req) ? NULL : (char *)IpcIoPopString(req, &len);
303     MUTEX_Lock(server->mtx);
304     *identity = SASTORA_Find(&server->store, service, feature);
305     if (identity->handle == INVALID_INDEX) {
306         MUTEX_Unlock(server->mtx);
307         HILOG_DEBUG(HILOG_MODULE_SAMGR, "Cannot Find Feature<%s, %s> id<%u, %u> ret:%d",
308                     service, feature, identity->handle, identity->token, EC_NOSERVICE);
309         return EC_NOSERVICE;
310     }
311 
312     PidHandle providerPid = SASTORA_FindPidHandleByIpcHandle(&server->store, identity->handle);
313     MUTEX_Unlock(server->mtx);
314     if (providerPid.pid == INVALID_INDEX || providerPid.uid == INVALID_INDEX) {
315         HILOG_DEBUG(HILOG_MODULE_SAMGR, "Cannot Find PidHandle<%s, %s> id<%d, %d> ret:%d",
316                     service, feature, identity->handle, identity->token, EC_FAILURE);
317         return EC_FAILURE;
318     }
319     AuthParams authParams = {
320         .providerService = service,
321         .providerfeature = feature,
322         .consumerPid = GetCallingPid(origin),
323         .consumerUid = GetCallingUid(origin),
324         .providerPid = providerPid.pid,
325         .providerUid = providerPid.uid
326     };
327     int isAuth = g_server.ipcAuth->IsCommunicationAllowed(authParams);
328     HILOG_DEBUG(HILOG_MODULE_SAMGR, "Judge Auth<%s, %s> ret:%d", service, feature, isAuth);
329 
330     int32 ret = (isAuth == EC_SUCCESS) ? AddServiceAccess(*identity, GetCallingTid(origin)) : EC_PERMISSION;
331     HILOG_DEBUG(HILOG_MODULE_SAMGR, "Find Feature<%s, %s> id<%d, %d> ret:%d",
332                 service, feature, identity->handle, identity->token, ret);
333     return ret;
334 }
335 
ProcFeature(SamgrServer * server,int32 option,void * origin,IpcIo * req,IpcIo * reply)336 static int ProcFeature(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
337 {
338     if (option != OP_PUT && option != OP_GET) {
339         IpcIoPushInt32(reply, EC_INVALID);
340         return EC_INVALID;
341     }
342 
343     if (g_server.ipcAuth == NULL) {
344         g_server.ipcAuth = GetIpcAuthInterface();
345     }
346     if (g_server.ipcAuth == NULL) {
347         IpcIoPushInt32(reply, EC_NOINIT);
348         return EC_NOINIT;
349     }
350 
351     int ret = EC_SUCCESS;
352     SvcIdentity identity = {INVALID_INDEX, INVALID_INDEX, INVALID_INDEX};
353     if (option == OP_PUT) {
354         ret = ProcPutFeature(server, origin, req, reply, &identity);
355     }
356     if (ret != EC_SUCCESS) {
357         return ret;
358     }
359 
360     if (option == OP_GET) {
361         ret = ProcGetFeature(server, origin, req, reply, &identity);
362         IpcIoPushInt32(reply, ret);
363         if (ret == EC_SUCCESS) {
364             IpcIoPushSvc(reply, &identity);
365         }
366     }
367     return ret;
368 }
369 
ProcAddSysCap(SamgrServer * server,IpcIo * req)370 static int32 ProcAddSysCap(SamgrServer *server, IpcIo *req)
371 {
372     size_t len = 0;
373     char *sysCap = (char *)IpcIoPopString(req, &len);
374     if (sysCap == NULL || len == 0 || len > MAX_SYSCAP_NAME_LEN) {
375         HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcAddSysCap sysCap invalid");
376         return EC_INVALID;
377     }
378     MUTEX_Lock(server->sysCapMtx);
379     Vector *sysCapablitys = &(server->sysCapabilitys);
380     int16 pos = VECTOR_FindByKey(sysCapablitys, (void *)sysCap);
381     if (pos < 0) {
382         MUTEX_Unlock(server->sysCapMtx);
383         return EC_FAILURE;
384     }
385     SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, pos);
386     if (serviceImpl == NULL) {
387         MUTEX_Unlock(server->sysCapMtx);
388         return EC_FAILURE;
389     }
390     serviceImpl->isRegister = TRUE;
391     MUTEX_Unlock(server->sysCapMtx);
392     return EC_SUCCESS;
393 }
394 
ProcGetSysCap(SamgrServer * server,IpcIo * req)395 static BOOL ProcGetSysCap(SamgrServer *server, IpcIo *req)
396 {
397     size_t len = 0;
398     char *sysCap = (char *)IpcIoPopString(req, &len);
399     if (sysCap == NULL || len == 0 || len > MAX_SYSCAP_NAME_LEN) {
400         HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcGetSysCap sysCap invalid");
401         return FALSE;
402     }
403     MUTEX_Lock(server->sysCapMtx);
404     Vector *sysCapablitys = &(server->sysCapabilitys);
405     int16 pos = VECTOR_FindByKey(sysCapablitys, (void *)sysCap);
406     if (pos < 0) {
407         MUTEX_Unlock(server->sysCapMtx);
408         return FALSE;
409     }
410     SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, pos);
411     if (serviceImpl == NULL) {
412         MUTEX_Unlock(server->sysCapMtx);
413         return FALSE;
414     }
415 
416     BOOL res = (serviceImpl->isRegister == TRUE);
417     MUTEX_Unlock(server->sysCapMtx);
418     return res;
419 }
420 
GetReplyNumAndNextReqIdx(Vector * sysCapablitys,int32 startIdx,int32 * nextRequestIdx)421 static int32 GetReplyNumAndNextReqIdx(Vector *sysCapablitys, int32 startIdx, int32 *nextRequestIdx)
422 {
423     int32 registerNum = 0;
424     int32 size = VECTOR_Num(sysCapablitys);
425     int32 i = startIdx;
426     for (; i < size && registerNum < MAX_SYSCAP_NUM_PER_REPLY; i++) {
427         SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
428         if (serviceImpl->isRegister == FALSE) {
429             continue;
430         }
431         registerNum++;
432     }
433     *nextRequestIdx = i;
434     return registerNum;
435 }
436 
ProcGetAllSysCap(SamgrServer * server,IpcIo * req,IpcIo * reply)437 void ProcGetAllSysCap(SamgrServer *server, IpcIo *req, IpcIo *reply)
438 {
439     uint32_t startIdx = IpcIoPopUint32(req);
440     MUTEX_Lock(server->sysCapMtx);
441     Vector *sysCapablitys = &(server->sysCapabilitys);
442     int32 size = VECTOR_Num(sysCapablitys);
443     if (size == INVALID_INDEX) {
444         IpcIoPushInt32(reply, EC_FAILURE);
445         IpcIoPushBool(reply, TRUE);
446         IpcIoPushUint32(reply, startIdx);
447         IpcIoPushUint32(reply, 0);
448         MUTEX_Unlock(server->sysCapMtx);
449         return;
450     }
451     int32 nextRequestIdx = startIdx;
452     int32 replyNum = GetReplyNumAndNextReqIdx(sysCapablitys, startIdx, &nextRequestIdx);
453     HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcGetAllSysCap replyNum: %d, size: %d, startIdx: %u, nextRequestIdx: %d",
454                 replyNum, size, startIdx, nextRequestIdx);
455     IpcIoPushInt32(reply, EC_SUCCESS);
456     // indicate is the last reply
457     IpcIoPushBool(reply, nextRequestIdx == size);
458     // indicate is the next start idx
459     IpcIoPushUint32(reply, nextRequestIdx);
460     IpcIoPushUint32(reply, replyNum);
461     int32 cnt = 0;
462     int32 i = startIdx;
463     for (; i < size && cnt < replyNum; i++) {
464         SysCapImpl *serviceImpl = (SysCapImpl *)VECTOR_At(sysCapablitys, i);
465         if (serviceImpl->isRegister == FALSE) {
466             continue;
467         }
468         IpcIoPushString(reply, serviceImpl->name);
469         cnt++;
470     }
471     MUTEX_Unlock(server->sysCapMtx);
472 }
473 
ProcSysCap(SamgrServer * server,int32 option,void * origin,IpcIo * req,IpcIo * reply)474 static int ProcSysCap(SamgrServer *server, int32 option, void *origin, IpcIo *req, IpcIo *reply)
475 {
476     if (CanRequest(origin) == FALSE) {
477         HILOG_ERROR(HILOG_MODULE_SAMGR, "ProcSysCap no permission");
478         IpcIoPushInt32(reply, EC_PERMISSION);
479         return EC_PERMISSION;
480     }
481     if (option != OP_PUT && option != OP_GET && option != OP_ALL) {
482         IpcIoPushInt32(reply, EC_INVALID);
483         return EC_INVALID;
484     }
485     HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcSysCap option: %d begin", option);
486     if (option == OP_PUT) {
487         int32 ret = ProcAddSysCap(server, req);
488         IpcIoPushInt32(reply, ret);
489     } else if (option == OP_GET) {
490         BOOL ret = ProcGetSysCap(server, req);
491         IpcIoPushInt32(reply, EC_SUCCESS);
492         IpcIoPushBool(reply, ret);
493     } else if (option == OP_ALL) {
494         ProcGetAllSysCap(server, req, reply);
495     } else {
496         HILOG_WARN(HILOG_MODULE_SAMGR, "ProcSysCap error option: %d", option);
497         IpcIoPushInt32(reply, EC_INVALID);
498         return EC_INVALID;
499     }
500     HILOG_DEBUG(HILOG_MODULE_SAMGR, "ProcSysCap end");
501     return EC_SUCCESS;
502 }
503 
RegisterSamgrEndpoint(const IpcContext * context,SvcIdentity * identity)504 static int RegisterSamgrEndpoint(const IpcContext* context, SvcIdentity* identity)
505 {
506     int ret = SetSaManager(context, MAX_SA_SIZE);
507     if (ret != LITEIPC_OK) {
508         HILOG_FATAL(HILOG_MODULE_SAMGR, "Set sa manager<%d> failed!", ret);
509         // Set sa manager failed! We need restart to recover
510         exit(-ret);
511     }
512     identity->handle = SAMGR_HANDLE;
513     identity->token = SAMGR_TOKEN;
514     identity->cookie = SAMGR_COOKIE;
515     return EC_SUCCESS;
516 }
517 
OnEndpointExit(const IpcContext * context,void * ipcMsg,IpcIo * data,void * argv)518 static int OnEndpointExit(const IpcContext *context, void* ipcMsg, IpcIo* data, void* argv)
519 {
520     (void)data;
521     if (ipcMsg != NULL) {
522         FreeBuffer(context, ipcMsg);
523     }
524     pid_t pid = (pid_t)((uintptr_t)argv);
525     Request request = {0};
526     request.msgId = MSG_CLEAN;
527     request.msgValue = pid;
528     int retry = RETRY_TIMES;
529     int ret = EC_INVALID;
530     while (retry > 0) {
531         ret = SAMGR_SendRequest(&g_server.identity, &request, NULL);
532         if (ret == EC_SUCCESS) {
533             break;
534         }
535         sleep(RETRY_INTERVAL);
536         --retry;
537     }
538 #ifdef __LINUX__
539     PidHandle handle;
540     int err = SASTORA_FindHandleByPid(&g_server.store, pid, &handle);
541     if (err != INVALID_INDEX) {
542         BinderRelease(context, handle.handle);
543     }
544 #endif
545     HILOG_ERROR(HILOG_MODULE_SAMGR, "IPC pid<%d> exit! send clean request retry(%d), ret(%d)!", pid, retry, ret);
546     return EC_SUCCESS;
547 }
548 
GetIpcAuthInterface(void)549 static IpcAuthInterface *GetIpcAuthInterface(void)
550 {
551     IpcAuthInterface *ipcAuth = NULL;
552     IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(PERMISSION_SERVICE, IPCAUTH);
553     if (iUnknown == NULL) {
554         HILOG_ERROR(HILOG_MODULE_SAMGR, "Get IpcAuthInterface: IUnknown NULL");
555         return NULL;
556     }
557     (void)iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **)&ipcAuth);
558     return ipcAuth;
559 }
560 
GetJsonStream()561 static cJSON *GetJsonStream()
562 {
563     const char *path = "/etc/system_capability.json";
564     struct stat fileInfo;
565     int32_t size = 0;
566 
567     if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) == 0) {
568         return NULL;
569     }
570 
571     int32_t fp = open(path, O_RDONLY, S_IRUSR);
572     if (fp < 0) {
573         return NULL;
574     }
575 
576     char *json = (char *)SAMGR_Malloc(size * sizeof(char));
577     if (json == NULL) {
578         close(fp);
579         return NULL;
580     }
581     if (read(fp, json, size * sizeof(char)) != size * sizeof(char)) {
582         SAMGR_Free(json);
583         close(fp);
584         return NULL;
585     }
586     close(fp);
587 
588     cJSON *root = cJSON_Parse(json);
589     SAMGR_Free(json);
590     json = NULL;
591     return root;
592 }
593 
ParseSysCap(void)594 static void ParseSysCap(void)
595 {
596     cJSON *root = GetJsonStream();
597     if (root == NULL) {
598         HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap GetJsonStream failed!");
599         return;
600     }
601     cJSON *sysCaps = cJSON_GetObjectItem(root, "systemCapability");
602     if (!cJSON_IsArray(sysCaps)) {
603         cJSON_Delete(root);
604         HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSysCap format failed!");
605         return;
606     }
607     int32_t size = cJSON_GetArraySize(sysCaps);
608     int32_t sysCapNum = 0;
609     for (int32_t i = 0; i < size; i++) {
610         if (sysCapNum >= MAX_SYSCAP_NUM) {
611             HILOG_ERROR(HILOG_MODULE_SAMGR, "ParseSycCapMap system capability exceed");
612             break;
613         }
614         cJSON *item = cJSON_GetArrayItem(sysCaps, i);
615         if (!cJSON_IsObject(item)) {
616             continue;
617         }
618         cJSON *name = cJSON_GetObjectItem(item, "name");
619         cJSON *isRegister = cJSON_GetObjectItem(item, "register-on-startup");
620         if (!cJSON_IsString(name) || !cJSON_IsBool(isRegister)) {
621             continue;
622         }
623         char *nameStr = cJSON_GetStringValue(name);
624         if (VECTOR_FindByKey(&(g_server.sysCapabilitys), nameStr) != INVALID_INDEX) {
625             HILOG_WARN(HILOG_MODULE_SAMGR, "Duplicate system capability %s register!", nameStr);
626             continue;
627         }
628         SysCapImpl *impl = (SysCapImpl *)SAMGR_Malloc(sizeof(SysCapImpl));
629         if (impl == NULL) {
630             continue;
631         }
632         if (strcpy_s(impl->name, sizeof(impl->name), cJSON_GetStringValue(name)) != EC_SUCCESS) {
633             SAMGR_Free(impl);
634             continue;
635         }
636         impl->isRegister = cJSON_IsTrue(isRegister);
637         if (VECTOR_Add(&(g_server.sysCapabilitys), impl) == INVALID_INDEX) {
638             SAMGR_Free(impl);
639             HILOG_ERROR(HILOG_MODULE_SAMGR, "system capability %s register failed!", impl->name);
640             continue;
641         }
642         sysCapNum++;
643     }
644     cJSON_Delete(root);
645 }
646