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 "global_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
24 namespace OHOS::Security::SecurityGuard {
25 namespace {
26 const char* APPS = "apps";
27 const char* NAME = "name";
28 const char* FINGERPRINTER = "fingerprint";
29 const char* ATTRIBUTE = "attribute";
30 constexpr uint32_t HASHLENGTH = 64;
31 constexpr uint32_t MAXAPPNAMELENGTH = 256;
32 }
Load(int mode)33 bool GlobalAppConfig::Load(int mode)
34 {
35 std::string path;
36 if (mode == INIT_MODE) {
37 if (FileExists(CONFIG_CACHE_FILES[GLOBAL_APP_CFG_INDEX])) {
38 path = CONFIG_CACHE_FILES[GLOBAL_APP_CFG_INDEX];
39 } else {
40 return true;
41 }
42 }
43 if (mode == UPDATE_MODE) {
44 if (FileExists(CONFIG_CACHE_FILES[GLOBAL_APP_CFG_INDEX])) {
45 path = CONFIG_CACHE_FILES[GLOBAL_APP_CFG_INDEX];
46 }
47 }
48 SGLOGD("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 GlobalAppConfig::Parse()
61 {
62 return true;
63 }
Update()64 bool GlobalAppConfig::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 GlobalAppConfig json error");
74 return false;
75 }
76 std::vector<AppInfo> configs;
77 if (!ParseAppListConfig(configs, jsonObj)) {
78 SGLOGE("parse GlobalAppConfig 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 (AppInfoRdbHelper::GetInstance().DeleteAppInfoByIsGlobalApp(1) != SUCCESS) {
90 SGLOGE("DeleteAppInfoByIsGlobalApp error");
91 return false;
92 }
93 if (AppInfoRdbHelper::GetInstance().InsertAllAppInfo(configs)) {
94 SGLOGE("InsertAllAppInfo error");
95 return false;
96 }
97 SecurityGuardUtils::CopyFile(CONFIG_CACHE_FILES[GLOBAL_APP_CFG_INDEX], CONFIG_UPTATE_FILES[GLOBAL_APP_CFG_INDEX]);
98 return true;
99 }
100
ParseAppListConfig(std::vector<AppInfo> & configs,const nlohmann::json & json)101 bool GlobalAppConfig::ParseAppListConfig(std::vector<AppInfo>& configs, const nlohmann::json& json)
102 {
103 if (json.find(APPS) == json.end() || !json.at(APPS).is_array()) {
104 SGLOGE("check %{public}s error", APPS);
105 return false;
106 }
107 for (auto it : json.at(APPS)) {
108 AppInfo config {};
109 config.isGlobalApp = 1;
110 if (!JsonCfg::Unmarshal(config.appHash, it, FINGERPRINTER) || config.appHash.size() != HASHLENGTH) {
111 SGLOGE("parse %{public}s error", FINGERPRINTER);
112 return false;
113 }
114 if (!JsonCfg::Unmarshal(config.appName, it, NAME) || config.appName.size() > MAXAPPNAMELENGTH ||
115 config.appName.empty()) {
116 SGLOGE("parse %{public}s error", NAME);
117 return false;
118 }
119 std::unordered_set<std::string> tmp = {"monitoring", "payment", "malicious"};
120 if (!JsonCfg::Unmarshal(config.attrs, it, ATTRIBUTE) || config.attrs.size() >= ATTRMAX) {
121 SGLOGE("parse %{public}s error", ATTRIBUTE);
122 return false;
123 }
124 for (auto iter : config.attrs) {
125 if (tmp.count(iter) == 0) {
126 SGLOGE("check %{public}s error", ATTRIBUTE);
127 return false;
128 }
129 }
130 configs.emplace_back(config);
131 }
132 return true;
133 }
134 }
135