• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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