1 /*
2 * Copyright (c) 2024 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 "json_parse_loader.h"
16
17 #include <cstdio>
18 #include <fcntl.h>
19 #include <memory>
20 #include <set>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include "access_token_error.h"
26 #include "accesstoken_common_log.h"
27 #include "cjson_utils.h"
28 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
29 #include "config_policy_utils.h"
30 #endif
31 #include "data_validator.h"
32 #include "permission_map.h"
33
34 namespace OHOS {
35 namespace Security {
36 namespace AccessToken {
37 namespace {
38 constexpr int32_t MAX_NATIVE_CONFIG_FILE_SIZE = 5 * 1024 * 1024; // 5M
39 constexpr size_t BUFFER_SIZE = 1024;
40 constexpr uint64_t FD_TAG = 0xD005A01;
41
42 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
43 static constexpr const char* ACCESSTOKEN_CONFIG_FILE = "/etc/access_token/accesstoken_config.json";
44 static constexpr const char* PERMISSION_MANAGER_BUNDLE_NAME_KEY = "permission_manager_bundle_name";
45 static constexpr const char* GRANT_ABILITY_NAME_KEY = "grant_ability_name";
46 static constexpr const char* GRANT_SERVICE_ABILITY_NAME_KEY = "grant_service_ability_name";
47 static constexpr const char* PERMISSION_STATE_SHEET_ABILITY_NAME_KEY = "permission_state_sheet_ability_name";
48 static constexpr const char* GLOBAL_SWITCH_SHEET_ABILITY_NAME_KEY = "global_switch_sheet_ability_name";
49 static constexpr const char* TEMP_PERM_CANCLE_TIME_KEY = "temp_perm_cencle_time";
50 static constexpr const char* APPLICATION_SETTING_ABILITY_NAME_KEY = "application_setting_ability_name";
51
52 static constexpr const char* RECORD_SIZE_MAXIMUM_KEY = "permission_used_record_size_maximum";
53 static constexpr const char* RECORD_AGING_TIME_KEY = "permission_used_record_aging_time";
54 static constexpr const char* GLOBAL_DIALOG_BUNDLE_NAME_KEY = "global_dialog_bundle_name";
55 static constexpr const char* GLOBAL_DIALOG_ABILITY_NAME_KEY = "global_dialog_ability_name";
56
57 static constexpr const char* SEND_REQUEST_REPEAT_TIMES_KEY = "send_request_repeat_times";
58 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
59
60 // native_token.json
61 static const char* NATIVE_TOKEN_CONFIG_FILE = "/data/service/el0/access_token/nativetoken.json";
62 static const char* JSON_PROCESS_NAME = "processName";
63 static const char* JSON_APL = "APL";
64 static const char* JSON_VERSION = "version";
65 static const char* JSON_TOKEN_ID = "tokenId";
66 static const char* JSON_TOKEN_ATTR = "tokenAttr";
67 static const char* JSON_DCAPS = "dcaps";
68 static const char* JSON_PERMS = "permissions";
69 static const char* JSON_ACLS = "nativeAcls";
70 static const int32_t MAX_DCAPS_NUM = 10 * 1024;
71 static const int32_t MAX_REQ_PERM_NUM = 10 * 1024;
72
73 // dlp json
74 static const char* CLONE_PERMISSION_CONFIG_FILE = "/system/etc/dlp_permission/clone_app_permission.json";
75 }
76
ReadCfgFile(const std::string & file,std::string & rawData)77 int32_t ConfigPolicLoader::ReadCfgFile(const std::string& file, std::string& rawData)
78 {
79 char filePath[PATH_MAX] = {0};
80 if (realpath(file.c_str(), filePath) == nullptr) {
81 return ERR_FILE_OPERATE_FAILED;
82 }
83 int32_t fd = open(filePath, O_RDONLY);
84 if (fd < 0) {
85 LOGE(ATM_DOMAIN, ATM_TAG, "Open failed errno %{public}d.", errno);
86 return ERR_FILE_OPERATE_FAILED;
87 }
88 fdsan_exchange_owner_tag(fd, 0, FD_TAG);
89 struct stat statBuffer;
90
91 if (fstat(fd, &statBuffer) != 0) {
92 LOGE(ATM_DOMAIN, ATM_TAG, "Fstat failed.");
93 (void)fdsan_close_with_tag(fd, FD_TAG);
94 return ERR_FILE_OPERATE_FAILED;
95 }
96
97 if (statBuffer.st_size == 0) {
98 LOGE(ATM_DOMAIN, ATM_TAG, "Config file size is invalid.");
99 (void)fdsan_close_with_tag(fd, FD_TAG);
100 return ERR_PARAM_INVALID;
101 }
102 if (statBuffer.st_size > MAX_NATIVE_CONFIG_FILE_SIZE) {
103 LOGE(ATM_DOMAIN, ATM_TAG, "Config file size is too large.");
104 (void)fdsan_close_with_tag(fd, FD_TAG);
105 return ERR_OVERSIZE;
106 }
107 rawData.reserve(statBuffer.st_size);
108
109 char buff[BUFFER_SIZE] = { 0 };
110 ssize_t readLen = 0;
111 while ((readLen = read(fd, buff, BUFFER_SIZE)) > 0) {
112 rawData.append(buff, readLen);
113 }
114 (void)fdsan_close_with_tag(fd, FD_TAG);
115 if (readLen == 0) {
116 return RET_SUCCESS;
117 }
118 return ERR_FILE_OPERATE_FAILED;
119 }
120
IsDirExsit(const std::string & file)121 bool ConfigPolicLoader::IsDirExsit(const std::string& file)
122 {
123 if (file.empty()) {
124 LOGE(ATM_DOMAIN, ATM_TAG, "File path is empty");
125 return false;
126 }
127
128 struct stat buf;
129 if (stat(file.c_str(), &buf) != 0) {
130 LOGE(ATM_DOMAIN, ATM_TAG, "Get file attributes failed, errno %{public}d.", errno);
131 return false;
132 }
133
134 if (!S_ISDIR(buf.st_mode)) {
135 LOGE(ATM_DOMAIN, ATM_TAG, "File mode is not directory.");
136 return false;
137 }
138
139 return true;
140 }
141
142 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
GetConfigFilePathList(std::vector<std::string> & pathList)143 void ConfigPolicLoader::GetConfigFilePathList(std::vector<std::string>& pathList)
144 {
145 CfgDir* dirs = GetCfgDirList(); // malloc a CfgDir point, need to free later
146 if (dirs == nullptr) {
147 LOGE(ATM_DOMAIN, ATM_TAG, "Can't get cfg file path.");
148 return;
149 }
150
151 for (const auto& path : dirs->paths) {
152 if ((path == nullptr) || (!IsDirExsit(path))) {
153 continue;
154 }
155
156 LOGI(ATM_DOMAIN, ATM_TAG, "Accesstoken cfg dir: %{public}s.", path);
157 pathList.emplace_back(path);
158 }
159
160 FreeCfgDirList(dirs); // free
161 }
162
GetAtCfgFromJson(const CJson * j,AccessTokenServiceConfig & a)163 bool GetAtCfgFromJson(const CJson* j, AccessTokenServiceConfig& a)
164 {
165 if (!GetStringFromJson(j, PERMISSION_MANAGER_BUNDLE_NAME_KEY, a.grantBundleName)) {
166 return false;
167 }
168
169 if (!GetStringFromJson(j, GRANT_ABILITY_NAME_KEY, a.grantAbilityName)) {
170 return false;
171 }
172
173 if (!GetStringFromJson(j, GRANT_SERVICE_ABILITY_NAME_KEY, a.grantServiceAbilityName)) {
174 return false;
175 }
176
177 if (!GetStringFromJson(j, PERMISSION_STATE_SHEET_ABILITY_NAME_KEY, a.permStateAbilityName)) {
178 return false;
179 }
180
181 if (!GetStringFromJson(j, GLOBAL_SWITCH_SHEET_ABILITY_NAME_KEY, a.globalSwitchAbilityName)) {
182 return false;
183 }
184
185 if (!GetIntFromJson(j, TEMP_PERM_CANCLE_TIME_KEY, a.cancelTime)) {
186 return false;
187 }
188
189 GetStringFromJson(j, APPLICATION_SETTING_ABILITY_NAME_KEY, a.applicationSettingAbilityName);
190 return true;
191 }
192
GetPrivacyCfgFromJson(const CJson * j,PrivacyServiceConfig & p)193 bool GetPrivacyCfgFromJson(const CJson* j, PrivacyServiceConfig& p)
194 {
195 if (!GetIntFromJson(j, RECORD_SIZE_MAXIMUM_KEY, p.sizeMaxImum)) {
196 return false;
197 }
198
199 if (!GetIntFromJson(j, RECORD_AGING_TIME_KEY, p.agingTime)) {
200 return false;
201 }
202
203 if (!GetStringFromJson(j, GLOBAL_DIALOG_BUNDLE_NAME_KEY, p.globalDialogBundleName)) {
204 return false;
205 }
206
207 if (!GetStringFromJson(j, GLOBAL_DIALOG_ABILITY_NAME_KEY, p.globalDialogAbilityName)) {
208 return false;
209 }
210 return true;
211 }
212
GetTokenSyncCfgFromJson(const CJson * j,TokenSyncServiceConfig & t)213 bool GetTokenSyncCfgFromJson(const CJson* j, TokenSyncServiceConfig& t)
214 {
215 if (!GetIntFromJson(j, SEND_REQUEST_REPEAT_TIMES_KEY, t.sendRequestRepeatTimes)) {
216 return false;
217 }
218 return true;
219 }
220
GetConfigValueFromFile(const ServiceType & type,const std::string & fileContent,AccessTokenConfigValue & config)221 bool ConfigPolicLoader::GetConfigValueFromFile(const ServiceType& type, const std::string& fileContent,
222 AccessTokenConfigValue& config)
223 {
224 CJsonUnique jsonRes = CreateJsonFromString(fileContent);
225 if (jsonRes == nullptr) {
226 LOGE(ATM_DOMAIN, ATM_TAG, "JsonRes is invalid.");
227 return false;
228 }
229
230 if (type == ServiceType::ACCESSTOKEN_SERVICE) {
231 CJson* atJson = GetObjFromJson(jsonRes, "accesstoken");
232 return GetAtCfgFromJson(atJson, config.atConfig);
233 } else if (type == ServiceType::PRIVACY_SERVICE) {
234 CJson* prJson = GetObjFromJson(jsonRes, "privacy");
235 return GetPrivacyCfgFromJson(prJson, config.pConfig);
236 }
237 CJson* toSyncJson = GetObjFromJson(jsonRes, "tokensync");
238 return GetTokenSyncCfgFromJson(toSyncJson, config.tsConfig);
239 }
240 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
241
GetConfigValue(const ServiceType & type,AccessTokenConfigValue & config)242 bool ConfigPolicLoader::GetConfigValue(const ServiceType& type, AccessTokenConfigValue& config)
243 {
244 bool successFlag = false;
245 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
246 std::vector<std::string> pathList;
247 GetConfigFilePathList(pathList);
248
249 for (const auto& path : pathList) {
250 std::string filePath = path + ACCESSTOKEN_CONFIG_FILE;
251 std::string fileContent;
252 int32_t res = ReadCfgFile(filePath, fileContent);
253 if (res != 0) {
254 continue;
255 }
256
257 if (GetConfigValueFromFile(type, fileContent, config)) {
258 LOGI(ATM_DOMAIN, ATM_TAG, "Get valid config value from file [%{public}s]!", filePath.c_str());
259 successFlag = true;
260 break; // once get the config value, break the loop
261 }
262 }
263 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
264 return successFlag;
265 }
266
NativeReqPermsGet(const CJson * j,std::vector<PermissionStatus> & permStateList)267 static int32_t NativeReqPermsGet(const CJson* j, std::vector<PermissionStatus>& permStateList)
268 {
269 CJson* permJson = GetArrayFromJson(j, JSON_PERMS);
270 if (permJson == nullptr) {
271 LOGE(ATM_DOMAIN, ATM_TAG, "JSON_PERMS is invalid.");
272 return ERR_PARAM_INVALID;
273 }
274 int32_t len = cJSON_GetArraySize(permJson);
275 if (len > MAX_REQ_PERM_NUM) {
276 LOGE(ATM_DOMAIN, ATM_TAG, "Permission num oversize.");
277 return ERR_OVERSIZE;
278 }
279 std::set<std::string> permRes;
280 for (int32_t i = 0; i < len; i++) {
281 std::string permReq = cJSON_GetStringValue(cJSON_GetArrayItem(permJson, i));
282 PermissionStatus permState;
283 if (permRes.count(permReq) != 0) {
284 continue;
285 }
286 permState.permissionName = permReq;
287 permState.grantStatus = PERMISSION_GRANTED;
288 permState.grantFlag = PERMISSION_SYSTEM_FIXED;
289 permStateList.push_back(permState);
290 permRes.insert(permReq);
291 }
292 return RET_SUCCESS;
293 }
294
GetTokenIdTypeEnum(AccessTokenID id)295 static ATokenTypeEnum GetTokenIdTypeEnum(AccessTokenID id)
296 {
297 AccessTokenIDInner* idInner = reinterpret_cast<AccessTokenIDInner* >(&id);
298 return static_cast<ATokenTypeEnum>(idInner->type);
299 }
300
GetSingleNativeTokenFromJson(const CJson * j,NativeTokenInfoBase & native)301 static void GetSingleNativeTokenFromJson(const CJson* j, NativeTokenInfoBase& native)
302 {
303 NativeTokenInfoBase info;
304 int32_t aplNum = 0;
305 if (!GetIntFromJson(j, JSON_APL, aplNum) || !DataValidator::IsAplNumValid(aplNum)) {
306 return;
307 }
308 info.apl = static_cast<ATokenAplEnum>(aplNum);
309 int32_t ver;
310 GetIntFromJson(j, JSON_VERSION, ver);
311 info.ver = (uint8_t)ver;
312 GetUnsignedIntFromJson(j, JSON_TOKEN_ID, info.tokenID);
313 if ((info.ver != DEFAULT_TOKEN_VERSION) || (info.tokenID == 0)) {
314 return;
315 }
316 ATokenTypeEnum type = GetTokenIdTypeEnum(info.tokenID);
317 if ((type != TOKEN_NATIVE) && (type != TOKEN_SHELL)) {
318 return;
319 }
320 if (!GetUnsignedIntFromJson(j, JSON_TOKEN_ATTR, info.tokenAttr)) {
321 return;
322 }
323 CJson* dcapsJson = GetArrayFromJson(j, JSON_DCAPS);
324 CJson* aclsJson = GetArrayFromJson(j, JSON_ACLS);
325 if ((dcapsJson == nullptr) || (aclsJson == nullptr)) {
326 return;
327 }
328 int32_t dcapLen = cJSON_GetArraySize(dcapsJson);
329 int32_t aclLen = cJSON_GetArraySize(aclsJson);
330 if ((dcapLen > MAX_DCAPS_NUM) || (aclLen > MAX_REQ_PERM_NUM)) {
331 LOGE(ATM_DOMAIN, ATM_TAG, "Native dcap oversize.");
332 return;
333 }
334 for (int32_t i = 0; i < dcapLen; i++) {
335 std::string item = cJSON_GetStringValue(cJSON_GetArrayItem(dcapsJson, i));
336 info.dcap.push_back(item);
337 }
338 for (int i = 0; i < aclLen; i++) {
339 std::string item = cJSON_GetStringValue(cJSON_GetArrayItem(aclsJson, i));
340 info.nativeAcls.push_back(item);
341 }
342
343 if (NativeReqPermsGet(j, info.permStateList) != RET_SUCCESS) {
344 return;
345 }
346
347 if (!GetStringFromJson(j, JSON_PROCESS_NAME, info.processName) ||
348 !DataValidator::IsProcessNameValid(info.processName)) {
349 return;
350 }
351 native = info;
352 }
353
ParserNativeRawData(const std::string & nativeRawData,std::vector<NativeTokenInfoBase> & tokenInfos)354 bool ConfigPolicLoader::ParserNativeRawData(
355 const std::string& nativeRawData, std::vector<NativeTokenInfoBase>& tokenInfos)
356 {
357 CJsonUnique jsonRes = CreateJsonFromString(nativeRawData);
358 if (jsonRes == nullptr) {
359 LOGE(ATM_DOMAIN, ATM_TAG, "JsonRes is invalid.");
360 return false;
361 }
362 int32_t len = cJSON_GetArraySize(jsonRes.get());
363 for (int32_t i = 0; i < len; i++) {
364 CJson* item = cJSON_GetArrayItem(jsonRes.get(), i);
365 NativeTokenInfoBase token;
366 GetSingleNativeTokenFromJson(item, token);
367 if (!token.processName.empty()) {
368 tokenInfos.emplace_back(token);
369 }
370 }
371 return true;
372 }
373
GetAllNativeTokenInfo(std::vector<NativeTokenInfoBase> & tokenInfos)374 int32_t ConfigPolicLoader::GetAllNativeTokenInfo(std::vector<NativeTokenInfoBase>& tokenInfos)
375 {
376 std::string nativeRawData;
377 int32_t ret = ReadCfgFile(NATIVE_TOKEN_CONFIG_FILE, nativeRawData);
378 if (ret != RET_SUCCESS) {
379 LOGE(ATM_DOMAIN, ATM_TAG,
380 "Read native token json file failed, err = %{public}d.", ret);
381 return ret;
382 }
383 if (!ParserNativeRawData(nativeRawData, tokenInfos)) {
384 LOGE(ATM_DOMAIN, ATM_TAG, "ParserNativeRawData failed.");
385 return ERR_PRASE_RAW_DATA_FAILED;
386 }
387 return RET_SUCCESS;
388 }
389
JsonFromPermissionDlpMode(const CJson * j,PermissionDlpMode & p)390 static void JsonFromPermissionDlpMode(const CJson* j, PermissionDlpMode& p)
391 {
392 if (!GetStringFromJson(j, "name", p.permissionName)) {
393 return;
394 }
395 if (!DataValidator::IsProcessNameValid(p.permissionName)) {
396 return;
397 }
398
399 std::string dlpModeStr;
400 if (!GetStringFromJson(j, "dlpGrantRange", dlpModeStr)) {
401 return;
402 }
403 if (dlpModeStr == "all") {
404 p.dlpMode = DLP_PERM_ALL;
405 return;
406 }
407 if (dlpModeStr == "full_control") {
408 p.dlpMode = DLP_PERM_FULL_CONTROL;
409 return;
410 }
411 p.dlpMode = DLP_PERM_NONE;
412 return;
413 }
414
ParserDlpPermsRawData(const std::string & dlpPermsRawData,std::vector<PermissionDlpMode> & dlpPerms)415 bool ConfigPolicLoader::ParserDlpPermsRawData(
416 const std::string& dlpPermsRawData, std::vector<PermissionDlpMode>& dlpPerms)
417 {
418 CJsonUnique jsonRes = CreateJsonFromString(dlpPermsRawData);
419 if (jsonRes == nullptr) {
420 LOGE(ATM_DOMAIN, ATM_TAG, "JsonRes is invalid.");
421 return false;
422 }
423
424 CJson* dlpPermTokenJson = GetArrayFromJson(jsonRes.get(), "dlpPermissions");
425 if ((dlpPermTokenJson != nullptr)) {
426 CJson* j = nullptr;
427 std::vector<PermissionDlpMode> dlpPermissions;
428 cJSON_ArrayForEach(j, dlpPermTokenJson) {
429 PermissionDlpMode p;
430 JsonFromPermissionDlpMode(j, p);
431 dlpPerms.emplace_back(p);
432 }
433 }
434 return true;
435 }
436
GetDlpPermissions(std::vector<PermissionDlpMode> & dlpPerms)437 int32_t ConfigPolicLoader::GetDlpPermissions(std::vector<PermissionDlpMode>& dlpPerms)
438 {
439 std::string dlpPermsRawData;
440 int32_t ret = ReadCfgFile(CLONE_PERMISSION_CONFIG_FILE, dlpPermsRawData);
441 if (ret != RET_SUCCESS) {
442 LOGE(ATM_DOMAIN, ATM_TAG,
443 "Read(%{public}s) failed, err = %{public}d.", CLONE_PERMISSION_CONFIG_FILE, ret);
444 return ret;
445 }
446 if (!ParserDlpPermsRawData(dlpPermsRawData, dlpPerms)) {
447 LOGE(ATM_DOMAIN, ATM_TAG, "ParserDlpPermsRawData failed.");
448 return ERR_PRASE_RAW_DATA_FAILED;
449 }
450 return RET_SUCCESS;
451 }
452
DumpHapTokenInfo(const HapTokenInfo & hapInfo,bool isRemote,bool isPermDialogForbidden,const std::vector<PermissionStatus> & permStateList)453 std::string ConfigPolicLoader::DumpHapTokenInfo(const HapTokenInfo& hapInfo, bool isRemote, bool isPermDialogForbidden,
454 const std::vector<PermissionStatus>& permStateList)
455 {
456 CJsonUnique j = CreateJson();
457 (void)AddUnsignedIntToJson(j, "tokenID", hapInfo.tokenID);
458 (void)AddUnsignedIntToJson(j, "tokenAttr", hapInfo.tokenAttr);
459 (void)AddIntToJson(j, "ver", static_cast<int>(hapInfo.ver));
460 (void)AddIntToJson(j, "userId", hapInfo.userID);
461 (void)AddStringToJson(j, "bundleName", hapInfo.bundleName);
462 (void)AddIntToJson(j, "instIndex", hapInfo.instIndex);
463 (void)AddIntToJson(j, "dlpType", hapInfo.dlpType);
464 (void)AddBoolToJson(j, "isRemote", isRemote);
465 (void)AddBoolToJson(j, "isPermDialogForbidden", isPermDialogForbidden);
466
467 CJsonUnique permStateListJson = CreateJsonArray();
468 for (auto iter = permStateList.begin(); iter != permStateList.end(); ++iter) {
469 CJsonUnique permStateJson = CreateJson();
470 (void)AddStringToJson(permStateJson, "permissionName", iter->permissionName);
471 (void)AddIntToJson(permStateJson, "grantStatus", iter->grantStatus);
472 (void)AddUnsignedIntToJson(permStateJson, "grantFlag", iter->grantFlag);
473 (void)AddObjToArray(permStateListJson, permStateJson);
474 }
475 (void)AddObjToJson(j, "permStateList", permStateListJson);
476 return JsonToStringFormatted(j.get());
477 }
478
IsPermissionReqValid(int32_t tokenApl,const std::string & permissionName,const std::vector<std::string> & nativeAcls)479 static bool IsPermissionReqValid(int32_t tokenApl, const std::string& permissionName,
480 const std::vector<std::string>& nativeAcls)
481 {
482 PermissionBriefDef briefDef;
483 if (!GetPermissionBriefDef(permissionName, briefDef)) {
484 return false;
485 }
486
487 if (tokenApl >= briefDef.availableLevel) {
488 return true;
489 }
490
491 auto iter = std::find(nativeAcls.begin(), nativeAcls.end(), permissionName);
492 if (iter != nativeAcls.end()) {
493 return true;
494 }
495 return false;
496 }
497
DumpNativeTokenInfo(const NativeTokenInfoBase & native)498 std::string ConfigPolicLoader::DumpNativeTokenInfo(const NativeTokenInfoBase& native)
499 {
500 CJsonUnique j = CreateJson();
501 (void)AddUnsignedIntToJson(j, "tokenID", native.tokenID);
502 (void)AddStringToJson(j, "processName", native.processName);
503 (void)AddIntToJson(j, "apl", native.apl);
504
505 CJsonUnique permStateListJson = CreateJsonArray();
506 CJsonUnique invalidPermStringJson = CreateJsonArray();
507 for (auto iter = native.permStateList.begin(); iter != native.permStateList.end(); ++iter) {
508 if (!IsPermissionReqValid(native.apl, iter->permissionName, native.nativeAcls)) {
509 CJsonUnique tmpJson = CreateJsonString(iter->permissionName);
510 (void)AddObjToArray(invalidPermStringJson, tmpJson);
511 continue;
512 }
513 CJsonUnique permStateJson = CreateJson();
514 (void)AddStringToJson(permStateJson, "permissionName", iter->permissionName);
515 (void)AddIntToJson(permStateJson, "grantStatus", iter->grantStatus);
516 (void)AddUnsignedIntToJson(permStateJson, "grantFlag", iter->grantFlag);
517 (void)AddObjToArray(permStateListJson, permStateJson);
518 }
519
520 (void)AddObjToJson(j, "permStateList", permStateListJson);
521 (void)AddObjToJson(j, "invalidPermList", invalidPermStringJson);
522 return JsonToStringFormatted(j.get());
523 }
524
525 extern "C" {
Create()526 void* Create()
527 {
528 return reinterpret_cast<void*>(new ConfigPolicLoader);
529 }
530
Destroy(void * loaderPtr)531 void Destroy(void* loaderPtr)
532 {
533 ConfigPolicyLoaderInterface* loader = reinterpret_cast<ConfigPolicyLoaderInterface*>(loaderPtr);
534 if (loader != nullptr) {
535 delete loader;
536 }
537 }
538 }
539 } // namespace AccessToken
540 } // namespace Security
541 } // namespace OHOS
542