• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "appspawn_utils.h"
17 #include "cJSON.h"
18 #include "config_policy_utils.h"
19 #include "dec_api.h"
20 #include "hilog/log.h"
21 #include "json_utils.h"
22 
InitDecConfig(void)23 static std::vector<cJSON *> InitDecConfig(void)
24 {
25     std::vector<cJSON *> sandboxConfig = {};
26     CfgFiles *files = GetCfgFiles("etc/sandbox");
27     for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) {
28         if (files->paths[i] == nullptr) {
29             continue;
30         }
31         std::string path = files->paths[i];
32         std::string appPath = path + "/appdata-sandbox.json";
33         APPSPAWN_LOGV("Init sandbox dec config %{public}s", appPath.c_str());
34         cJSON *config = GetJsonObjFromFile(appPath.c_str());
35         APPSPAWN_CHECK((config != nullptr && cJSON_IsObject(config)), continue,
36             "Failed to init sandbox dec config %{public}s", appPath.c_str());
37         sandboxConfig.push_back(config);
38     }
39     FreeCfgFiles(files);
40     return sandboxConfig;
41 }
42 
DestroyDecConfig(std::vector<cJSON * > & sandboxConfig)43 static void DestroyDecConfig(std::vector<cJSON *> &sandboxConfig)
44 {
45     for (auto& config : sandboxConfig) {
46         APPSPAWN_CHECK_ONLY_EXPER(config != nullptr, continue);
47         cJSON_Delete(config);
48         config = nullptr;
49     }
50     sandboxConfig.clear();
51 }
52 
ConvertDecPath(std::string path)53 static std::string ConvertDecPath(std::string path)
54 {
55     std::vector<std::pair<std::string, std::string>> replacements = {
56         {"<currentUserId>", "currentUser"},
57         {"<PackageName>", "com.ohos.dlpmanager"}
58     };
59 
60     for (const auto& [from, to] : replacements) {
61         size_t pos = 0;
62         while ((pos = path.find(from, pos)) != std::string::npos) {
63             path.replace(pos, from.length(), to);
64             pos += to.length();
65         }
66     }
67     return path;
68 }
69 
AddDecPathsByPermission(std::map<std::string,std::vector<std::string>> & decMap,const std::string permission,const cJSON * permItem)70 static void AddDecPathsByPermission(std::map<std::string, std::vector<std::string>> &decMap,
71                                     const std::string permission, const cJSON *permItem)
72 {
73     cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(permItem, "mount-paths");
74     APPSPAWN_CHECK(mountPoints != nullptr && cJSON_IsArray(mountPoints), return,
75         "Don't get mountPoints json from permission");
76 
77     std::vector<std::string> decPaths = {};
78     int arraySize = cJSON_GetArraySize(mountPoints);
79     for (int i = 0; i < arraySize; ++i) {
80         cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i);
81         APPSPAWN_CHECK(mntPoint != nullptr && cJSON_IsObject(mntPoint), continue,
82             "Don't get mntPoint json from mountPoints");
83 
84         cJSON *decPathJson = cJSON_GetObjectItemCaseSensitive(mntPoint, "dec-paths");
85         if (decPathJson == nullptr || !cJSON_IsArray(decPathJson)) {
86             APPSPAWN_LOGV("Don't get decPath json from mntPoint");
87             continue;
88         }
89 
90         int count = cJSON_GetArraySize(decPathJson);
91         for (int j = 0; j < count; ++j) {
92             cJSON *item = cJSON_GetArrayItem(decPathJson, j);
93             APPSPAWN_CHECK(item != nullptr && cJSON_IsString(item), continue, "Don't get decPath item");
94             const char *strValue = cJSON_GetStringValue(item);
95             APPSPAWN_CHECK_ONLY_EXPER(strValue != nullptr, continue);
96 
97             std::string decPath = ConvertDecPath(strValue);
98             APPSPAWN_LOGI("Get decPath %{public}s from %{public}s", decPath.c_str(), permission.c_str());
99             decPaths.push_back(decPath);
100         }
101     }
102 
103     if (!decPaths.empty()) {
104         auto it = decMap.find(permission);
105         if (it == decMap.end()) {
106             decMap[permission] = decPaths;
107         } else {
108             for (const auto& path : decPaths) {
109                 it->second.push_back(path);
110             }
111         }
112     }
113 }
114 
ProcessConfig(const cJSON * config,std::map<std::string,std::vector<std::string>> & decMap)115 static void ProcessConfig(const cJSON *config, std::map<std::string, std::vector<std::string>> &decMap)
116 {
117     cJSON *permission = cJSON_GetObjectItemCaseSensitive(config, "permission");
118     APPSPAWN_CHECK(permission != nullptr && cJSON_IsArray(permission), return,
119         "Don't get permission json from config");
120 
121     int arraySize = cJSON_GetArraySize(permission);
122     for (int i = 0; i < arraySize; ++i) {
123         cJSON *item = cJSON_GetArrayItem(permission, i);
124         cJSON *permissionChild = item->child;
125         while (permissionChild != nullptr && cJSON_IsArray(permissionChild)) {
126             cJSON *permItem = cJSON_GetArrayItem(permissionChild, 0);
127             APPSPAWN_CHECK(permItem != nullptr && cJSON_IsObject(permItem), permissionChild = permissionChild->next;
128                 continue, "Don't get permission item");
129             APPSPAWN_LOGV("AddDecPathsByPermission %{public}s", permissionChild->string);
130             AddDecPathsByPermission(decMap, permissionChild->string, permItem);
131             permissionChild = permissionChild->next;
132         }
133     }
134 }
135 
GetDecPathMap(void)136 std::map<std::string, std::vector<std::string>> GetDecPathMap(void)
137 {
138     std::vector<cJSON *> sandboxConfig = InitDecConfig();
139     APPSPAWN_CHECK(!sandboxConfig.empty(), return {}, "Sandbox dec config is empty");
140 
141     std::map<std::string, std::vector<std::string>> decMap = {};
142     for (auto& config : sandboxConfig) {
143         ProcessConfig(config, decMap);
144     }
145 
146     DestroyDecConfig(sandboxConfig);
147     return decMap;
148 }
149