1 /*
2 * Copyright (c) 2023 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 "local_app_config.h"
16 #include <unordered_set>
17 #include "app_info_rdb_helper.h"
18 #include "security_guard_log.h"
19 #include "security_guard_utils.h"
20 #include "security_guard_define.h"
21 #include "file_ex.h"
22 #include "json_cfg.h"
23 namespace OHOS::Security::SecurityGuard {
24 namespace {
25 const char* APPS = "apps";
26 const char* NAME = "name";
27 const char* FINGERPRINTER = "fingerprint";
28 const char* ATTRIBUTE = "attribute";
29 const char* ISUPDATE = "isUpdate";
30 constexpr uint32_t HASHLENGTH = 64;
31 constexpr uint32_t MAXAPPNAMELENGTH = 256;
32 }
Load(int mode)33 bool LocalAppConfig::Load(int mode)
34 {
35 std::string path;
36 if (mode == INIT_MODE) {
37 if (FileExists(CONFIG_CACHE_FILES[LOCAL_APP_CFG_INDEX])) {
38 path = CONFIG_CACHE_FILES[LOCAL_APP_CFG_INDEX];
39 } else {
40 return true;
41 }
42 }
43 if (mode == UPDATE_MODE) {
44 if (FileExists(CONFIG_CACHE_FILES[LOCAL_APP_CFG_INDEX])) {
45 path = CONFIG_CACHE_FILES[LOCAL_APP_CFG_INDEX];
46 }
47 }
48 SGLOGI("path=%{public}s", path.c_str());
49 if (path.empty()) {
50 SGLOGE("path is empty");
51 return false;
52 }
53 stream_ = std::ifstream(path, std::ios::in);
54 if (!stream_.is_open() || !stream_) {
55 SGLOGE("stream error, %{public}s", strerror(errno));
56 return false;
57 }
58 return true;
59 }
Parse()60 bool LocalAppConfig::Parse()
61 {
62 return true;
63 }
Update()64 bool LocalAppConfig::Update()
65 {
66 if (!stream_.is_open() || !stream_) {
67 SGLOGE("stream error");
68 return false;
69 }
70 nlohmann::json jsonObj = nlohmann::json::parse(stream_, nullptr, false);
71 stream_.close();
72 if (jsonObj.is_discarded()) {
73 SGLOGE("Parse LocalAppConfig json error");
74 return false;
75 }
76 std::vector<AppInfo> configs;
77 if (!ParseAppListConfig(configs, jsonObj)) {
78 SGLOGE("Parse LocalAppConfig error");
79 return false;
80 }
81 for (size_t i = 0; i < configs.size(); i++) {
82 for (size_t j = i + 1; j < configs.size(); j++) {
83 if (configs[i].appName == configs[j].appName) {
84 SGLOGE("app%{public}s name repeate", configs[i].appName.c_str());
85 return false;
86 }
87 }
88 }
89 if (!UpdateInfoToDb(configs)) {
90 SGLOGE("UpdateInfoToDb error");
91 return false;
92 }
93
94 SecurityGuardUtils::CopyFile(CONFIG_CACHE_FILES[LOCAL_APP_CFG_INDEX], CONFIG_UPTATE_FILES[LOCAL_APP_CFG_INDEX]);
95 return true;
96 }
97
ParseAppListConfig(std::vector<AppInfo> & configs,const nlohmann::json & json)98 bool LocalAppConfig::ParseAppListConfig(std::vector<AppInfo>& configs, const nlohmann::json& json)
99 {
100 if (json.find(APPS) == json.end() || !json.at(APPS).is_array()) {
101 SGLOGE("check %{public}s error", APPS);
102 return false;
103 }
104 for (auto it : json.at(APPS)) {
105 AppInfo config {};
106 if (!JsonCfg::Unmarshal(config.appHash, it, FINGERPRINTER) || config.appHash.size() != HASHLENGTH) {
107 SGLOGE("parse %{public}s error", FINGERPRINTER);
108 return false;
109 }
110 if (!JsonCfg::Unmarshal(config.appName, it, NAME) || config.appName.size() > MAXAPPNAMELENGTH ||
111 config.appName.empty()) {
112 SGLOGE("parse %{public}s error", NAME);
113 return false;
114 }
115 std::unordered_set<std::string> tmp = {"monitoring", "payment", "malicious"};
116 if (!JsonCfg::Unmarshal(config.attrs, it, ATTRIBUTE) || config.attrs.size() >= ATTRMAX) {
117 SGLOGE("parse %{public}s error", ATTRIBUTE);
118 return false;
119 }
120 for (auto iter : config.attrs) {
121 if (tmp.count(iter) == 0) {
122 SGLOGE("check %{public}s error", ATTRIBUTE);
123 return false;
124 }
125 }
126 if (!JsonCfg::Unmarshal(config.isUpdate, it, ISUPDATE) || (config.isUpdate != 0 && config.isUpdate != 1)) {
127 SGLOGE("parse %{public}s error", ISUPDATE);
128 return false;
129 }
130 configs.emplace_back(config);
131 }
132 return true;
133 }
134
IsNeedUpdate(const AppInfo & config,const AppInfo & dbConfig,bool & isFind)135 bool LocalAppConfig::IsNeedUpdate(const AppInfo &config, const AppInfo &dbConfig, bool &isFind)
136 {
137 if (config.appName == dbConfig.appName) {
138 isFind = true;
139 if (config.isUpdate == 1) {
140 AppInfoRdbHelper::GetInstance().DeleteAppInfoByNameAndGlobbalFlag(config.appName, 0);
141 if (AppInfoRdbHelper::GetInstance().InsertAppInfo(config) != SUCCESS) {
142 SGLOGE("InsertAppInfo error");
143 return false;
144 }
145 }
146 }
147 return true;
148 }
149
UpdateInfoToDb(const std::vector<AppInfo> & configs)150 bool LocalAppConfig::UpdateInfoToDb(const std::vector<AppInfo> &configs)
151 {
152 SGLOGI("UpdateInfoToDb ..................");
153 std::vector<AppInfo> dbConfigs;
154 if (AppInfoRdbHelper::GetInstance().QueryAllAppInfo(dbConfigs) != SUCCESS) {
155 SGLOGE("QueryAllAppInfo error");
156 return false;
157 }
158 for (auto iter : dbConfigs) {
159 bool isFind = false;
160 SGLOGI("appName %{public}s isGlobalApp %{public}d", iter.appName.c_str(), iter.isGlobalApp);
161 if (iter.isGlobalApp == 1) {
162 continue;
163 }
164 for (auto it : configs) {
165 if (!IsNeedUpdate(it, iter, isFind)) {
166 return false;
167 }
168 }
169 if (!isFind) {
170 AppInfoRdbHelper::GetInstance().DeleteAppInfoByNameAndGlobbalFlag(iter.appName, 0);
171 }
172 }
173 for (auto iter : configs) {
174 bool isFind = false;
175 for (auto it : dbConfigs) {
176 if (it.appName == iter.appName && it.isGlobalApp == 0) {
177 isFind = true;
178 break;
179 }
180 }
181 if (!isFind && (iter.isUpdate == 1)) {
182 if (AppInfoRdbHelper::GetInstance().InsertAppInfo(iter) != SUCCESS) {
183 SGLOGE("InsertAppInfo error");
184 return false;
185 }
186 }
187 }
188 return true;
189 }
190 }