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 "config_policy_loader.h"
16 
17 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
18 #include "accesstoken_log.h"
19 #include "config_policy_utils.h"
20 #include "json_parser.h"
21 #endif
22 
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 namespace {
27 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "ConfigPolicLoader"};
29 static constexpr const char* ACCESSTOKEN_CONFIG_FILE = "/etc/access_token/accesstoken_config.json";
30 
31 static constexpr const char* PERMISSION_MANAGER_BUNDLE_NAME_KEY = "permission_manager_bundle_name";
32 static constexpr const char* GRANT_ABILITY_NAME_KEY = "grant_ability_name";
33 static constexpr const char* GRANT_SERVICE_ABILITY_NAME_KEY = "grant_servicre_ability_name";
34 static constexpr const char* PERMISSION_STATE_SHEET_ABILITY_NAME_KEY = "permission_state_sheet_ability_name";
35 static constexpr const char* GLOBAL_SWITCH_SHEET_ABILITY_NAME_KEY = "global_switch_sheet_ability_name";
36 static constexpr const char* TEMP_PERM_CANCLE_TIME_KEY = "temp_perm_cencle_time";
37 
38 static constexpr const char* RECORD_SIZE_MAXIMUM_KEY = "permission_used_record_size_maximum";
39 static constexpr const char* RECORD_AGING_TIME_KEY = "permission_used_record_aging_time";
40 static constexpr const char* GLOBAL_DIALOG_BUNDLE_NAME_KEY = "global_dialog_bundle_name";
41 static constexpr const char* GLOBAL_DIALOG_ABILITY_NAME_KEY = "global_dialog_ability_name";
42 
43 static constexpr const char* SEND_REQUEST_REPEAT_TIMES_KEY = "send_request_repeat_times";
44 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
45 }
46 
47 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
GetConfigFilePathList(std::vector<std::string> & pathList)48 void ConfigPolicLoader::GetConfigFilePathList(std::vector<std::string>& pathList)
49 {
50     CfgDir *dirs = GetCfgDirList(); // malloc a CfgDir point, need to free later
51     if (dirs == nullptr) {
52         ACCESSTOKEN_LOG_ERROR(LABEL, "Can't get cfg file path.");
53         return;
54     }
55 
56     for (const auto& path : dirs->paths) {
57         if ((path == nullptr) || (!JsonParser::IsDirExsit(path))) {
58             continue;
59         }
60 
61         ACCESSTOKEN_LOG_INFO(LABEL, "Accesstoken cfg dir: %{public}s.", path);
62         pathList.emplace_back(path);
63     }
64 
65     FreeCfgDirList(dirs); // free
66 }
67 
from_json(const nlohmann::json & j,AccessTokenServiceConfig & a)68 void from_json(const nlohmann::json& j, AccessTokenServiceConfig& a)
69 {
70     if (!JsonParser::GetStringFromJson(j, PERMISSION_MANAGER_BUNDLE_NAME_KEY, a.grantBundleName)) {
71         return;
72     }
73 
74     if (!JsonParser::GetStringFromJson(j, GRANT_ABILITY_NAME_KEY, a.grantAbilityName)) {
75         return;
76     }
77 
78     if (!JsonParser::GetStringFromJson(j, GRANT_SERVICE_ABILITY_NAME_KEY, a.grantAbilityName)) {
79         return;
80     }
81 
82     if (!JsonParser::GetStringFromJson(j, PERMISSION_STATE_SHEET_ABILITY_NAME_KEY, a.permStateAbilityName)) {
83         return;
84     }
85 
86     if (!JsonParser::GetStringFromJson(j, GLOBAL_SWITCH_SHEET_ABILITY_NAME_KEY, a.globalSwitchAbilityName)) {
87         return;
88     }
89 
90     if (!JsonParser::GetIntFromJson(j, TEMP_PERM_CANCLE_TIME_KEY, a.cancleTime)) {
91         return;
92     }
93 }
94 
from_json(const nlohmann::json & j,PrivacyServiceConfig & p)95 void from_json(const nlohmann::json& j, PrivacyServiceConfig& p)
96 {
97     if (!JsonParser::GetIntFromJson(j, RECORD_SIZE_MAXIMUM_KEY, p.sizeMaxImum)) {
98         return;
99     }
100 
101     if (!JsonParser::GetIntFromJson(j, RECORD_AGING_TIME_KEY, p.agingTime)) {
102         return;
103     }
104 
105     if (!JsonParser::GetStringFromJson(j, GLOBAL_DIALOG_BUNDLE_NAME_KEY, p.globalDialogBundleName)) {
106         return;
107     }
108 
109     if (!JsonParser::GetStringFromJson(j, GLOBAL_DIALOG_ABILITY_NAME_KEY, p.globalDialogAbilityName)) {
110         return;
111     }
112 }
113 
from_json(const nlohmann::json & j,TokenSyncServiceConfig & t)114 void from_json(const nlohmann::json& j, TokenSyncServiceConfig& t)
115 {
116     if (!JsonParser::GetIntFromJson(j, SEND_REQUEST_REPEAT_TIMES_KEY, t.sendRequestRepeatTimes)) {
117         return;
118     }
119 }
120 
GetConfigValueFromFile(const ServiceType & type,const std::string & fileContent,AccessTokenConfigValue & config)121 bool ConfigPolicLoader::GetConfigValueFromFile(const ServiceType& type, const std::string& fileContent,
122     AccessTokenConfigValue& config)
123 {
124     nlohmann::json jsonRes = nlohmann::json::parse(fileContent, nullptr, false);
125     if (jsonRes.is_discarded()) {
126         ACCESSTOKEN_LOG_ERROR(LABEL, "JsonRes is invalid.");
127         return false;
128     }
129 
130     if (type == ServiceType::ACCESSTOKEN_SERVICE) {
131         if ((jsonRes.find("accesstoken") != jsonRes.end()) && (jsonRes.at("accesstoken").is_object())) {
132             config.atConfig = jsonRes.at("accesstoken").get<nlohmann::json>();
133             return true;
134         } else {
135             return false;
136         }
137     } else if (type == ServiceType::PRIVACY_SERVICE) {
138         if ((jsonRes.find("privacy") != jsonRes.end()) && (jsonRes.at("privacy").is_object())) {
139             config.pConfig = jsonRes.at("privacy").get<nlohmann::json>();
140             return true;
141         } else {
142             return false;
143         }
144     }
145 
146     if ((jsonRes.find("tokensync") != jsonRes.end()) && (jsonRes.at("tokensync").is_object())) {
147         config.tsConfig = jsonRes.at("tokensync").get<nlohmann::json>();
148         return true;
149     } else {
150         return false;
151     }
152 }
153 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
154 
GetConfigValue(const ServiceType & type,AccessTokenConfigValue & config)155 bool ConfigPolicLoader::GetConfigValue(const ServiceType& type, AccessTokenConfigValue& config)
156 {
157     bool successFlag = false;
158 #ifdef CUSTOMIZATION_CONFIG_POLICY_ENABLE
159     std::vector<std::string> pathList;
160     GetConfigFilePathList(pathList);
161 
162     for (const auto& path : pathList) {
163         std::string filePath = path + ACCESSTOKEN_CONFIG_FILE;
164         std::string fileContent;
165         int32_t res = JsonParser::ReadCfgFile(filePath, fileContent);
166         if (res != 0) {
167             ACCESSTOKEN_LOG_ERROR(LABEL, "Read Cfg file [%{public}s] failed, error(%{public}d).",
168                 filePath.c_str(), res);
169             continue;
170         }
171 
172         if (GetConfigValueFromFile(type, fileContent, config)) {
173             ACCESSTOKEN_LOG_INFO(LABEL, "Get valid config value!");
174             successFlag = true;
175             break; // once get the config value, break the loop
176         }
177     }
178 #endif // CUSTOMIZATION_CONFIG_POLICY_ENABLE
179     return successFlag;
180 }
181 
182 extern "C" {
Create()183 void* Create()
184 {
185     return reinterpret_cast<void*>(new ConfigPolicLoader);
186 }
187 
Destroy(void * loaderPtr)188 void Destroy(void* loaderPtr)
189 {
190     ConfigPolicyLoaderInterface* loader = reinterpret_cast<ConfigPolicyLoaderInterface*>(loaderPtr);
191     if (loader != nullptr) {
192         delete loader;
193     }
194 }
195 }
196 } // namespace AccessToken
197 } // namespace Security
198 } // namespace OHOS
199