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 "hiview_listener.h"
17
18 #include <unordered_set>
19
20 #include "database_manager.h"
21 #include "security_guard_log.h"
22 #include "security_guard_utils.h"
23
24 namespace OHOS::Security::SecurityGuard {
25 namespace {
26 constexpr int CONTENT_MAX_LEN = 900;
27 constexpr int64_t PASTEBOARD_EVENT_ID = 1011015000;
28 constexpr int64_t BUNDLE_INSTALL_EVENT_ID = 0x818800800;
29 constexpr int64_t BUNDLE_UPDATE_EVENT_ID = 0x818800801;
30 const std::unordered_set<std::string> HAP_INSTALL_UPDATE_STR = {"USERID", "BUNDLE_NAME",
31 "VERSION", "APP_DISTRIBUTION_TYPE", "INSTALL_TIME", "CALLING_UID", "CALLING_APPID",
32 "CALLING_BUNDLE_NAME", "FINGERPRINT", "HIDE_DESKTOP_ICON", "INSTALL_TYPE", "HASH_VALUE"};
33 }
34
OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)35 void HiviewListener::OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
36 {
37 if (sysEvent == nullptr) {
38 return;
39 }
40 SGLOGD("Hiview OnEvent: %{public}s", sysEvent->AsJson().c_str());
41 SecEvent event;
42 if (!GetSecEvent(sysEvent, event)) {
43 SGLOGE("Unknown event");
44 return;
45 }
46 DatabaseManager::GetInstance().InsertEvent(HIVIEW_SOURCE, event);
47 }
48
OnServiceDied()49 void HiviewListener::OnServiceDied()
50 {
51 SGLOGI("Hiview service disconnect");
52 }
53
GetSecEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent,SecEvent & event)54 bool HiviewListener::GetSecEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent, SecEvent& event)
55 {
56 std::unordered_map<std::string, int64_t> domainName2Id = {
57 {"PASTEBOARD-USE_BEHAVIOUR", PASTEBOARD_EVENT_ID},
58 {"BUNDLE_MANAGER-BUNDLE_INSTALL", BUNDLE_INSTALL_EVENT_ID},
59 {"BUNDLE_MANAGER-BUNDLE_UPDATE", BUNDLE_UPDATE_EVENT_ID}
60 };
61 std::string domainName = sysEvent->GetDomain() + "-" + sysEvent->GetEventName();
62 if (domainName2Id.count(domainName) == 0) {
63 SGLOGE("The eventId is not applied for");
64 return false;
65 }
66
67 std::string eventJsonStr = sysEvent->AsJson();
68 if (eventJsonStr.empty() || !nlohmann::json::accept(eventJsonStr)) {
69 SGLOGE("eventJsonStr err");
70 return false;
71 }
72 nlohmann::json eventJson = nlohmann::json::parse(eventJsonStr);
73 if (eventJson.is_discarded()) {
74 SGLOGE("json err");
75 return false;
76 }
77
78 int64_t sysEventId = domainName2Id[domainName];
79 filterInstallOrUpdateContent(sysEventId, eventJson);
80 if (eventJson.dump().size() >= CONTENT_MAX_LEN) {
81 SGLOGE("The JSON length is too long.");
82 return false;
83 }
84
85 event = {
86 .eventId = sysEventId,
87 .version = "1.0",
88 .date = SecurityGuardUtils::GetDate(),
89 .content = eventJson.dump()
90 };
91 return true;
92 }
93
filterInstallOrUpdateContent(int64_t eventId,nlohmann::json & jsonObj)94 void HiviewListener::filterInstallOrUpdateContent(int64_t eventId, nlohmann::json& jsonObj)
95 {
96 if ((eventId != BUNDLE_INSTALL_EVENT_ID) && (eventId != BUNDLE_UPDATE_EVENT_ID)) {
97 return;
98 }
99 if (!filterHashValue(jsonObj)) {
100 return;
101 }
102 for (auto it = jsonObj.begin(); it != jsonObj.end();) {
103 if (HAP_INSTALL_UPDATE_STR.find(it.key()) == HAP_INSTALL_UPDATE_STR.end()) {
104 it = jsonObj.erase(it);
105 } else {
106 ++it;
107 }
108 }
109 }
110
filterHashValue(nlohmann::json & jsonObj)111 bool HiviewListener::filterHashValue(nlohmann::json& jsonObj)
112 {
113 if (jsonObj.contains("FILE_PATH") && jsonObj.contains("HASH_VALUE")) {
114 bool isFindHap = false;
115 size_t index = 0;
116 const auto& filePath = jsonObj["FILE_PATH"];
117 for (size_t i = 0; i < filePath.size(); i++) {
118 const std::string& path = filePath[i];
119 if (path.find(".hap") != std::string::npos) {
120 isFindHap = true;
121 index = i;
122 break;
123 }
124 }
125 if (!isFindHap || (jsonObj["HASH_VALUE"].size() <= index)) {
126 SGLOGE("Failed to find the hash value of hap");
127 return false;
128 }
129 jsonObj["HASH_VALUE"] = jsonObj["HASH_VALUE"][index];
130 }
131 return true;
132 }
133 } // OHOS::Security::SecurityGuard