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