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