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
16 #include "config_subscriber.h"
17
18 #include <fstream>
19 #include <mutex>
20 #include <future>
21 #include "ffrt.h"
22 #include "directory_ex.h"
23 #include "string_ex.h"
24
25 #include "bigdata.h"
26 #include "event_config.h"
27 #include "config_define.h"
28 #include "config_manager.h"
29 #include "model_config.h"
30 #include "security_guard_log.h"
31 #include "security_guard_utils.h"
32 #include "i_model_info.h"
33 #include "file_util.h"
34 #include "json_util.h"
35 #include "sg_collect_client.h"
36
37 namespace OHOS::Security::SecurityGuard {
38 // LCOV_EXCL_START
GetUpdateFileDstPath(const std::string & fileName,std::string & dstPath)39 void ConfigSubscriber::GetUpdateFileDstPath(const std::string &fileName, std::string &dstPath)
40 {
41 std::ios::pos_type maxSize = 1 * 1024 * 1024; // byte
42 std::string jsonStr;
43 if (!FileUtil::ReadFileToStr("/system/etc/security_guard_update_config.json", maxSize, jsonStr)) {
44 SGLOGE("Read Update cfg file error.");
45 return;
46 }
47 cJSON *inJson = cJSON_Parse(jsonStr.c_str());
48 if (inJson == nullptr || !cJSON_IsArray(inJson)) {
49 SGLOGE("Json Parse Error: inJson is null or not a array.");
50 cJSON_Delete(inJson);
51 inJson = nullptr;
52 return;
53 }
54
55 int size = cJSON_GetArraySize(inJson);
56 for (int i = 0; i < size; i++) {
57 cJSON *item = cJSON_GetArrayItem(inJson, i);
58 std::string fileNameStr;
59 std::string dstPathStr;
60 if (!JsonUtil::GetString(item, "fileName", fileNameStr) || !JsonUtil::GetString(item, "dstPath", dstPathStr)) {
61 SGLOGE("Json Parse Error: fileName or dstPath not correct.");
62 continue;
63 }
64 if (fileName == fileNameStr) {
65 dstPath = dstPathStr;
66 break;
67 }
68 }
69 cJSON_Delete(inJson);
70 inJson = nullptr;
71 }
72 // LCOV_EXCL_STOP
73
UpdateConfig(const std::string & file)74 bool ConfigSubscriber::UpdateConfig(const std::string &file)
75 {
76 ConfigUpdateEvent event{};
77 bool isSuccess = false;
78 if (file == CONFIG_CACHE_FILES[EVENT_CFG_INDEX]) {
79 isSuccess = ConfigManager::UpdateConfig<EventConfig>();
80 } else if (file == CONFIG_CACHE_FILES[MODEL_CFG_INDEX]) {
81 isSuccess = ConfigManager::UpdateConfig<ModelConfig>();
82 }
83
84 std::string dstPath = file;
85 if (file != CONFIG_CACHE_FILES[EVENT_CFG_INDEX] && file != CONFIG_CACHE_FILES[MODEL_CFG_INDEX]) {
86 GetUpdateFileDstPath(file, dstPath);
87 if (!dstPath.empty()) {
88 SGLOGI("UpdateConfig, tmp path=%{public}s, dstPath=%{public}s.", file.c_str(), dstPath.c_str());
89 isSuccess = SecurityGuardUtils::CopyFile(file, dstPath);
90 }
91 }
92
93 event.path = file;
94 event.time = SecurityGuardUtils::GetDate();
95 event.ret = isSuccess ? SUCCESS : FAILED;
96 SGLOGD("file path=%{public}s, TIME=%{public}s, ret=%{public}d", event.path.c_str(), event.time.c_str(), event.ret);
97 BigData::ReportConfigUpdateEvent(event);
98 if (isSuccess) {
99 std::string name;
100 size_t lastSlashPos = dstPath.find_last_of('/');
101 if (lastSlashPos != std::string::npos) {
102 name = dstPath.substr(lastSlashPos + 1);
103 }
104 std::string content = R"({"path":")" + dstPath + R"(", "name":")" + name + R"("})";
105 auto task = [content] {
106 auto info = std::make_shared<EventInfo>(0xAB000004, "1.0", content);
107 int32_t ret = SecurityGuard::NativeDataCollectKit::ReportSecurityInfo(info);
108 if (ret != SUCCESS) {
109 SGLOGE("ReportSecurityEvent Error %{public}d", ret);
110 }
111 };
112 auto thread = std::thread(task);
113 thread.join();
114 }
115 if (!RemoveFile(file)) {
116 SGLOGE("remove file error, %{public}s", strerror(errno));
117 }
118 return isSuccess;
119 }
120 } // namespace OHOS::Security::SecurityGuard
121