• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "static_subscriber_manager.h"
17 
18 #include <fstream>
19 
20 #include "ability_manager_helper.h"
21 #include "access_token_helper.h"
22 #include "bundle_manager_helper.h"
23 #include "common_event_constant.h"
24 #include "common_event_support.h"
25 #include "event_log_wrapper.h"
26 #include "event_report.h"
27 #include "hitrace_meter.h"
28 #include "os_account_manager_helper.h"
29 
30 namespace OHOS {
31 namespace EventFwk {
32 namespace {
33 const std::string STATIC_SUBSCRIBER_CONFIG_FILE = "/system/etc/static_subscriber_config.json";
34 const std::string CONFIG_APPS = "apps";
35 constexpr static char JSON_KEY_COMMON_EVENTS[] = "commonEvents";
36 constexpr static char JSON_KEY_NAME[] = "name";
37 constexpr static char JSON_KEY_PERMISSION[] = "permission";
38 constexpr static char JSON_KEY_EVENTS[] = "events";
39 }
40 
StaticSubscriberManager()41 StaticSubscriberManager::StaticSubscriberManager() {}
42 
~StaticSubscriberManager()43 StaticSubscriberManager::~StaticSubscriberManager() {}
44 
InitAllowList()45 bool StaticSubscriberManager::InitAllowList()
46 {
47     EVENT_LOGI("enter");
48 
49     nlohmann::json jsonObj;
50     std::ifstream jfile(STATIC_SUBSCRIBER_CONFIG_FILE);
51     if (!jfile.is_open()) {
52         EVENT_LOGI("json file can not open");
53         hasInitAllowList_ = false;
54         return false;
55     }
56     jfile >> jsonObj;
57     jfile.close();
58 
59     for (auto j : jsonObj[CONFIG_APPS]) {
60         subscriberList_.emplace_back(j.get<std::string>());
61     }
62     hasInitAllowList_ = true;
63     return true;
64 }
65 
InitValidSubscribers()66 bool StaticSubscriberManager::InitValidSubscribers()
67 {
68     EVENT_LOGI("enter");
69 
70     if (!validSubscribers_.empty()) {
71         validSubscribers_.clear();
72     }
73     std::vector<AppExecFwk::ExtensionAbilityInfo> extensions;
74     // get all static subscriber type extensions
75     if (!DelayedSingleton<BundleManagerHelper>::GetInstance()->QueryExtensionInfos(extensions)) {
76         EVENT_LOGE("QueryExtensionInfos failed");
77         return false;
78     }
79     // filter legal extensions and add them to valid map
80     for (auto extension : extensions) {
81         if (find(subscriberList_.begin(), subscriberList_.end(), extension.bundleName) == subscriberList_.end()) {
82             continue;
83         }
84         EVENT_LOGI("find legal extension, bundlename = %{public}s", extension.bundleName.c_str());
85         AddSubscriber(extension);
86     }
87     hasInitValidSubscribers_ = true;
88     return true;
89 }
90 
PublishCommonEvent(const CommonEventData & data,const CommonEventPublishInfo & publishInfo,const Security::AccessToken::AccessTokenID & callerToken,const int32_t & userId,const sptr<IRemoteObject> & service,const std::string & bundleName)91 void StaticSubscriberManager::PublishCommonEvent(const CommonEventData &data,
92     const CommonEventPublishInfo &publishInfo, const Security::AccessToken::AccessTokenID &callerToken,
93     const int32_t &userId, const sptr<IRemoteObject> &service, const std::string &bundleName)
94 {
95     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
96     EVENT_LOGI("enter, event = %{public}s, userId = %{public}d", data.GetWant().GetAction().c_str(), userId);
97 
98     std::lock_guard<std::mutex> lock(subscriberMutex_);
99     if (!hasInitAllowList_ && !InitAllowList()) {
100         EVENT_LOGE("failed to init subscriber list");
101         return;
102     }
103 
104     if ((!hasInitValidSubscribers_ ||
105         data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_BOOT_COMPLETED ||
106         data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_LOCKED_BOOT_COMPLETED ||
107         data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_USER_SWITCHED ||
108         data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_UID_REMOVED ||
109         data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_USER_STARTED) &&
110         !InitValidSubscribers()) {
111         EVENT_LOGE("failed to init Init valid subscribers map!");
112         return;
113     }
114 
115     UpdateSubscriber(data);
116 
117     auto targetSubscribers = validSubscribers_.find(data.GetWant().GetAction());
118     if (targetSubscribers != validSubscribers_.end()) {
119         for (auto subscriber : targetSubscribers->second) {
120             EVENT_LOGW("subscriber.userId = %{public}d, userId = %{public}d", subscriber.userId, userId);
121             if (subscriber.userId < SUBSCRIBE_USER_SYSTEM_BEGIN) {
122                 EVENT_LOGW("subscriber userId is invalid, subscriber.userId = %{public}d", subscriber.userId);
123                 SendStaticEventProcErrHiSysEvent(userId, bundleName, subscriber.bundleName, data.GetWant().GetAction());
124                 continue;
125             }
126             if ((subscriber.userId > SUBSCRIBE_USER_SYSTEM_END) && (userId != ALL_USER)
127                 && (subscriber.userId != userId)) {
128                 EVENT_LOGW("subscriber userId is not match, subscriber.userId = %{public}d, userId = %{public}d",
129                     subscriber.userId, userId);
130                 SendStaticEventProcErrHiSysEvent(userId, bundleName, subscriber.bundleName, data.GetWant().GetAction());
131                 continue;
132             }
133             // judge if app is system app.
134             if (!DelayedSingleton<BundleManagerHelper>::GetInstance()->
135                 CheckIsSystemAppByBundleName(subscriber.bundleName, subscriber.userId)) {
136                 EVENT_LOGW("subscriber is not system app, not allow.");
137                 continue;
138             }
139             if (!VerifyPublisherPermission(callerToken, subscriber.permission)) {
140                 EVENT_LOGW("publisher does not have required permission %{public}s", subscriber.permission.c_str());
141                 SendStaticEventProcErrHiSysEvent(userId, bundleName, subscriber.bundleName, data.GetWant().GetAction());
142                 continue;
143             }
144             if (!VerifySubscriberPermission(subscriber.bundleName, subscriber.userId,
145                 publishInfo.GetSubscriberPermissions())) {
146                 EVENT_LOGW("subscriber does not have required permissions");
147                 SendStaticEventProcErrHiSysEvent(userId, bundleName, subscriber.bundleName, data.GetWant().GetAction());
148                 continue;
149             }
150             if (!publishInfo.GetBundleName().empty() && subscriber.bundleName != publishInfo.GetBundleName()) {
151                 EVENT_LOGW("subscriber bundleName is not match, subscriber.bundleName = %{public}s, "
152                     "bundleName = %{public}s", subscriber.bundleName.c_str(), publishInfo.GetBundleName().c_str());
153                 continue;
154             }
155             AAFwk::Want want;
156             want.SetElementName(subscriber.bundleName, subscriber.name);
157             EVENT_LOGI("Ready to connect to subscriber %{public}s in bundle %{public}s",
158                 subscriber.name.c_str(), subscriber.bundleName.c_str());
159             DelayedSingleton<AbilityManagerHelper>::GetInstance()->
160                 ConnectAbility(want, data, service, subscriber.userId);
161         }
162     }
163 }
164 
VerifyPublisherPermission(const Security::AccessToken::AccessTokenID & callerToken,const std::string & permission)165 bool StaticSubscriberManager::VerifyPublisherPermission(const Security::AccessToken::AccessTokenID &callerToken,
166     const std::string &permission)
167 {
168     EVENT_LOGI("enter");
169     if (permission.empty()) {
170         EVENT_LOGI("no need permission");
171         return true;
172     }
173     return AccessTokenHelper::VerifyAccessToken(callerToken, permission);
174 }
175 
VerifySubscriberPermission(const std::string & bundleName,const int32_t & userId,const std::vector<std::string> & permissions)176 bool StaticSubscriberManager::VerifySubscriberPermission(const std::string &bundleName, const int32_t &userId,
177     const std::vector<std::string> &permissions)
178 {
179     // get hap tokenid with default instindex(0), this should be modified later.
180     Security::AccessToken::AccessTokenID tokenId = AccessTokenHelper::GetHapTokenID(userId, bundleName, 0);
181     for (auto permission : permissions) {
182         if (permission.empty()) {
183             continue;
184         }
185         if (!AccessTokenHelper::VerifyAccessToken(tokenId, permission)) {
186             EVENT_LOGW("subscriber does not have required permission : %{public}s", permission.c_str());
187             return false;
188         }
189     }
190     return true;
191 }
192 
ParseEvents(const std::string & extensionName,const std::string & extensionBundleName,const int32_t & extensionUserId,const std::string & profile)193 void StaticSubscriberManager::ParseEvents(const std::string &extensionName, const std::string &extensionBundleName,
194     const int32_t &extensionUserId, const std::string &profile)
195 {
196     EVENT_LOGI("enter, subscriber name = %{public}s, bundle name = %{public}s, userId = %{public}d",
197         extensionName.c_str(), extensionBundleName.c_str(), extensionUserId);
198 
199     if (profile.empty()) {
200         EVENT_LOGE("invalid profile");
201         return;
202     }
203     if (!nlohmann::json::accept(profile.c_str())) {
204         EVENT_LOGE("invalid format profile");
205         return;
206     }
207 
208     nlohmann::json jsonObj = nlohmann::json::parse(profile, nullptr, false);
209     if (jsonObj.is_null() || jsonObj.empty()) {
210         EVENT_LOGE("invalid jsonObj");
211         return;
212     }
213     nlohmann::json commonEventsObj = jsonObj[JSON_KEY_COMMON_EVENTS];
214     if (commonEventsObj.is_null() || !commonEventsObj.is_array() || commonEventsObj.empty()) {
215         EVENT_LOGE("invalid common event obj size");
216         return;
217     }
218     for (auto commonEventObj : commonEventsObj) {
219         if (commonEventObj.is_null() || !commonEventObj.is_object()) {
220             EVENT_LOGW("invalid common event obj");
221             continue;
222         }
223         if (commonEventObj[JSON_KEY_NAME].is_null() || !commonEventObj[JSON_KEY_NAME].is_string()) {
224             EVENT_LOGW("invalid common event ability name obj");
225             continue;
226         }
227         if (commonEventObj[JSON_KEY_NAME].get<std::string>() != extensionName) {
228             EVENT_LOGW("extensionName is not match");
229             continue;
230         }
231         if (commonEventObj[JSON_KEY_PERMISSION].is_null() || !commonEventObj[JSON_KEY_PERMISSION].is_string()) {
232             EVENT_LOGW("invalid permission obj");
233             continue;
234         }
235         if (commonEventObj[JSON_KEY_EVENTS].is_null() || !commonEventObj[JSON_KEY_EVENTS].is_array() ||
236             commonEventObj[JSON_KEY_EVENTS].empty()) {
237             EVENT_LOGW("invalid events obj");
238             continue;
239         }
240 
241         for (auto e : commonEventObj[JSON_KEY_EVENTS]) {
242             if (e.is_null() || !e.is_string()) {
243                 EVENT_LOGW("invalid event obj");
244                 continue;
245             }
246             StaticSubscriberInfo subscriber = { .name = extensionName, .bundleName = extensionBundleName,
247                 .userId = extensionUserId, .permission = commonEventObj[JSON_KEY_PERMISSION].get<std::string>() };
248             AddToValidSubscribers(e.get<std::string>(), subscriber);
249         }
250     }
251 }
252 
AddSubscriber(const AppExecFwk::ExtensionAbilityInfo & extension)253 void StaticSubscriberManager::AddSubscriber(const AppExecFwk::ExtensionAbilityInfo &extension)
254 {
255     EVENT_LOGI("enter, subscriber bundlename = %{public}s", extension.bundleName.c_str());
256 
257     std::vector<std::string> profileInfos;
258     if (!DelayedSingleton<BundleManagerHelper>::GetInstance()->GetResConfigFile(extension, profileInfos)) {
259         EVENT_LOGE("GetProfile failed");
260         return;
261     }
262     for (auto profile : profileInfos) {
263         int32_t userId = -1;
264         if (DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(
265             extension.applicationInfo.uid, userId) != ERR_OK) {
266             EVENT_LOGE("GetOsAccountLocalIdFromUid failed, uid = %{public}d", extension.applicationInfo.uid);
267             return;
268         }
269         ParseEvents(extension.name, extension.bundleName, userId, profile);
270     }
271 }
272 
AddToValidSubscribers(const std::string & eventName,const StaticSubscriberInfo & subscriber)273 void StaticSubscriberManager::AddToValidSubscribers(const std::string &eventName,
274     const StaticSubscriberInfo &subscriber)
275 {
276     if (validSubscribers_.find(eventName) != validSubscribers_.end()) {
277         for (auto sub : validSubscribers_[eventName]) {
278             if ((sub.name == subscriber.name) &&
279                 (sub.bundleName == subscriber.bundleName) &&
280                 (sub.userId == subscriber.userId)) {
281                 EVENT_LOGI("subscriber already exist, event = %{public}s, bundlename = %{public}s, name = %{public}s,"
282                     "userId = %{public}d", eventName.c_str(), subscriber.bundleName.c_str(), subscriber.name.c_str(),
283                     subscriber.userId);
284                 return;
285             }
286         }
287     }
288     validSubscribers_[eventName].emplace_back(subscriber);
289     EVENT_LOGI("subscriber added, event = %{public}s, bundlename = %{public}s, name = %{public}s, userId = %{public}d",
290         eventName.c_str(), subscriber.bundleName.c_str(), subscriber.name.c_str(), subscriber.userId);
291 }
292 
AddSubscriberWithBundleName(const std::string & bundleName,const int32_t & userId)293 void StaticSubscriberManager::AddSubscriberWithBundleName(const std::string &bundleName, const int32_t &userId)
294 {
295     EVENT_LOGI("enter, bundleName = %{public}s, userId = %{public}d", bundleName.c_str(), userId);
296 
297     std::vector<AppExecFwk::ExtensionAbilityInfo> extensions;
298     if (!DelayedSingleton<BundleManagerHelper>::GetInstance()->QueryExtensionInfos(extensions, userId)) {
299         EVENT_LOGE("QueryExtensionInfos failed");
300         return;
301     }
302 
303     for (auto extension : extensions) {
304         if ((extension.bundleName == bundleName) &&
305             find(subscriberList_.begin(), subscriberList_.end(), extension.bundleName) != subscriberList_.end()) {
306             AddSubscriber(extension);
307         }
308     }
309 }
310 
RemoveSubscriberWithBundleName(const std::string & bundleName,const int32_t & userId)311 void StaticSubscriberManager::RemoveSubscriberWithBundleName(const std::string &bundleName, const int32_t &userId)
312 {
313     EVENT_LOGI("enter, bundleName = %{public}s, userId = %{public}d", bundleName.c_str(), userId);
314 
315     for (auto it = validSubscribers_.begin(); it != validSubscribers_.end();) {
316         auto subIt = it->second.begin();
317         while (subIt != it->second.end()) {
318             if ((subIt->bundleName == bundleName) && (subIt->userId == userId)) {
319                 EVENT_LOGI("remove subscriber, event = %{public}s, bundlename = %{public}s, userId = %{public}d",
320                     it->first.c_str(), bundleName.c_str(), userId);
321                 subIt = it->second.erase(subIt);
322             } else {
323                 subIt++;
324             }
325         }
326         if (it->second.empty()) {
327             validSubscribers_.erase(it++);
328         } else {
329             it++;
330         }
331     }
332 }
333 
UpdateSubscriber(const CommonEventData & data)334 void StaticSubscriberManager::UpdateSubscriber(const CommonEventData &data)
335 {
336     HITRACE_METER_NAME(HITRACE_TAG_NOTIFICATION, __PRETTY_FUNCTION__);
337     EVENT_LOGI("enter");
338 
339     if ((data.GetWant().GetAction() != CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) &&
340         (data.GetWant().GetAction() != CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED) &&
341         (data.GetWant().GetAction() != CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED)) {
342         EVENT_LOGI("no need to update map");
343         return;
344     }
345 
346     std::string bundleName = data.GetWant().GetElement().GetBundleName();
347     int32_t uid = data.GetWant().GetIntParam(AppExecFwk::Constants::UID, -1);
348     int32_t userId = -1;
349     if (DelayedSingleton<OsAccountManagerHelper>::GetInstance()->GetOsAccountLocalIdFromUid(uid, userId) != ERR_OK) {
350         EVENT_LOGW("GetOsAccountLocalIdFromUid failed, uid = %{public}d", uid);
351         return;
352     }
353     std::vector<int> osAccountIds;
354     if (DelayedSingleton<OsAccountManagerHelper>::GetInstance()->QueryActiveOsAccountIds(osAccountIds) != ERR_OK) {
355         EVENT_LOGW("failed to QueryActiveOsAccountIds!");
356         return;
357     }
358     if (find(osAccountIds.begin(), osAccountIds.end(), userId) == osAccountIds.end()) {
359         EVENT_LOGW("userId is not active, no need to update.");
360         return;
361     }
362     EVENT_LOGI("active uid = %{public}d, userId = %{public}d", uid, userId);
363     if (data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED) {
364         EVENT_LOGI("UpdateSubscribersMap bundle %{public}s ready to add", bundleName.c_str());
365         AddSubscriberWithBundleName(bundleName, userId);
366     } else if (data.GetWant().GetAction() == CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
367         EVENT_LOGI("UpdateSubscribersMap bundle %{public}s ready to remove", bundleName.c_str());
368         RemoveSubscriberWithBundleName(bundleName, userId);
369     } else {
370         EVENT_LOGI("UpdateSubscribersMap bundle %{public}s ready to update", bundleName.c_str());
371         RemoveSubscriberWithBundleName(bundleName, userId);
372         AddSubscriberWithBundleName(bundleName, userId);
373     }
374 }
375 
SendStaticEventProcErrHiSysEvent(int32_t userId,const std::string & publisherName,const std::string & subscriberName,const std::string & eventName)376 void StaticSubscriberManager::SendStaticEventProcErrHiSysEvent(int32_t userId, const std::string &publisherName,
377     const std::string &subscriberName, const std::string &eventName)
378 {
379     EventInfo eventInfo;
380     eventInfo.userId = userId;
381     eventInfo.publisherName = publisherName;
382     eventInfo.subscriberName = subscriberName;
383     eventInfo.eventName = eventName;
384     EventReport::SendHiSysEvent(STATIC_EVENT_PROC_ERROR, eventInfo);
385 }
386 }  // namespace EventFwk
387 }  // namespace OHOS
388