• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sec_comp_entity.h"
16 
17 #include <chrono>
18 #include "bundle_mgr_client.h"
19 #include "datashare_helper.h"
20 #include "hisysevent.h"
21 #include "ipc_skeleton.h"
22 #include "iservice_registry.h"
23 #include "i_sec_comp_service.h"
24 #include "sec_comp_err.h"
25 #include "sec_comp_enhance_adapter.h"
26 #include "sec_comp_info_helper.h"
27 #include "sec_comp_log.h"
28 #include "window_info_helper.h"
29 
30 namespace OHOS {
31 namespace Security {
32 namespace SecurityComponent {
33 namespace {
34 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompEntity"};
35 static constexpr uint64_t MAX_TOUCH_INTERVAL = 1000000L; // 1000ms
36 static constexpr uint64_t TIME_CONVERSION_UNIT = 1000;
37 static constexpr uint32_t FOLD_VIRTUAL_DISPLAY_ID = 999;
38 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
39 constexpr const char *SETTINGS_DATASHARE_URI =
40     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
41 constexpr const char *SETTINGS_DATASHARE_SEARCH_URI =
42     "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?" \
43     "Proxy=true&key=accessibility_screenreader_enabled";
44 constexpr const char *ADVANCED_DATA_COLUMN_KEYWORD = "KEYWORD";
45 constexpr const char *ADVANCED_DATA_COLUMN_VALUE = "VALUE";
46 constexpr const char *QUERY_KEYWORD = "accessibility_screenreader_enabled";
47 static bool IsScreenReadMode();
48 }
49 
GrantTempPermission()50 int32_t SecCompEntity::GrantTempPermission()
51 {
52     isGrant_ = true;
53     return SecCompPermManager::GetInstance().GrantTempPermission(tokenId_, componentInfo_);
54 }
55 
CompareComponentBasicInfo(SecCompBase * other,bool isRectCheck) const56 bool SecCompEntity::CompareComponentBasicInfo(SecCompBase* other, bool isRectCheck) const
57 {
58     return componentInfo_->CompareComponentBasicInfo(other, isRectCheck);
59 }
60 
CheckPointEvent(SecCompClickEvent & clickInfo,int32_t superFoldOffsetY,const CrossAxisState crossAxisState) const61 int32_t SecCompEntity::CheckPointEvent(SecCompClickEvent& clickInfo, int32_t superFoldOffsetY,
62     const CrossAxisState crossAxisState) const
63 {
64     auto current = static_cast<uint64_t>(
65         std::chrono::high_resolution_clock::now().time_since_epoch().count()) / TIME_CONVERSION_UNIT;
66     if (clickInfo.point.timestamp < current - MAX_TOUCH_INTERVAL || clickInfo.point.timestamp > current) {
67         SC_LOG_ERROR(LABEL, "touch timestamp invalid clickInfo. timestamp: %{public}llu, current: %{public}llu",
68             static_cast<unsigned long long>(clickInfo.point.timestamp), static_cast<unsigned long long>(current));
69         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
70     }
71 
72     if (!componentInfo_->rect_.IsInRect(clickInfo.point.touchX, clickInfo.point.touchY)) {
73         if ((crossAxisState == CrossAxisState::STATE_CROSS) &&
74             componentInfo_->rect_.IsInRect(clickInfo.point.touchX, clickInfo.point.touchY + superFoldOffsetY)) {
75             clickInfo.point.touchY += superFoldOffsetY;
76             SC_LOG_INFO(LABEL, "Fold PC cross state and component is in PC virtual screen.");
77             return SC_OK;
78         }
79         SC_LOG_ERROR(LABEL, "touch point is not in component rect = (%{public}f, %{public}f)" \
80             "left top point of component rect = (%{public}f, %{public}f)" \
81             "right bottom point of component rect = (%{public}f, %{public}f)",
82             clickInfo.point.touchX, clickInfo.point.touchY, componentInfo_->rect_.x_, componentInfo_->rect_.y_,
83             componentInfo_->rect_.x_ + componentInfo_->rect_.width_,
84             componentInfo_->rect_.y_ + componentInfo_->rect_.height_);
85         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
86     }
87     return SC_OK;
88 }
89 
CheckKeyEvent(const SecCompClickEvent & clickInfo) const90 int32_t SecCompEntity::CheckKeyEvent(const SecCompClickEvent& clickInfo) const
91 {
92     auto current = static_cast<uint64_t>(
93         std::chrono::high_resolution_clock::now().time_since_epoch().count()) / TIME_CONVERSION_UNIT;
94     if (clickInfo.key.timestamp < current - MAX_TOUCH_INTERVAL || clickInfo.key.timestamp > current) {
95         SC_LOG_ERROR(LABEL, "keyboard timestamp invalid clickInfo. timestamp: %{public}llu, current: %{public}llu",
96             static_cast<unsigned long long>(clickInfo.key.timestamp), static_cast<unsigned long long>(current));
97         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
98     }
99     if ((clickInfo.key.keyCode != KEY_SPACE) && (clickInfo.key.keyCode != KEY_ENTER) &&
100         (clickInfo.key.keyCode != KEY_NUMPAD_ENTER)) {
101         SC_LOG_ERROR(LABEL, "keyboard keyCode invalid. keyCode: %{public}d", clickInfo.key.keyCode);
102         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
103     }
104 
105     return SC_OK;
106 }
107 
IsInPCVirtualScreen(const CrossAxisState crossAxisState) const108 bool SecCompEntity::IsInPCVirtualScreen(const CrossAxisState crossAxisState) const
109 {
110     bool isInPCVirtualScreen = false;
111     if (componentInfo_->displayId_ == FOLD_VIRTUAL_DISPLAY_ID) {
112         if (crossAxisState == CrossAxisState::STATE_NO_CROSS) {
113             isInPCVirtualScreen = true;
114         } else {
115             SC_LOG_WARN(LABEL, "Security component maybe in PC virtual screen, the cross axis state is %{public}d",
116                 static_cast<int32_t>(crossAxisState));
117         }
118     }
119     return isInPCVirtualScreen;
120 }
121 
CheckClickInfo(SecCompClickEvent & clickInfo,int32_t superFoldOffsetY,const CrossAxisState crossAxisState) const122 int32_t SecCompEntity::CheckClickInfo(SecCompClickEvent& clickInfo, int32_t superFoldOffsetY,
123     const CrossAxisState crossAxisState) const
124 {
125     bool isInPCVirtualScreen = IsInPCVirtualScreen(crossAxisState);
126     SC_LOG_INFO(LABEL, "The cross axis state: %{public}d, the fold offset y: %{public}d.",
127         static_cast<int32_t>(crossAxisState), superFoldOffsetY);
128     if (isInPCVirtualScreen) {
129         clickInfo.point.touchY += superFoldOffsetY;
130         componentInfo_->rect_.y_ += superFoldOffsetY;
131     }
132     if (!WindowInfoHelper::CheckOtherWindowCoverComp(componentInfo_->windowId_,
133         componentInfo_->rect_)) {
134         SC_LOG_ERROR(LABEL, "Component may be covered by other window");
135         return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
136     }
137 
138     int32_t res = SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
139     bool isScreenReadMode = IsScreenReadMode();
140     if (clickInfo.type == ClickEventType::POINT_EVENT_TYPE && !isScreenReadMode) {
141         res = CheckPointEvent(clickInfo, superFoldOffsetY, crossAxisState);
142     } else if (clickInfo.type == ClickEventType::POINT_EVENT_TYPE && isScreenReadMode) {
143         SC_LOG_WARN(LABEL, "Device is in screen read mode, skip event check.");
144         return SC_OK;
145     } else if (clickInfo.type == ClickEventType::KEY_EVENT_TYPE) {
146         res = CheckKeyEvent(clickInfo);
147     }
148     if (res != SC_OK) {
149         return res;
150     }
151 
152     res = SecCompEnhanceAdapter::CheckExtraInfo(clickInfo);
153     if (res == SC_SERVICE_ERROR_CLICK_EVENT_INVALID) {
154         SC_LOG_ERROR(LABEL, "Click ExtraInfo is invalid");
155         return res;
156     }
157 
158     if ((res != SC_OK) && (res != SC_ENHANCE_ERROR_NOT_EXIST_ENHANCE)) {
159         SC_LOG_ERROR(LABEL, "HMAC checkout failed");
160         int32_t uid = IPCSkeleton::GetCallingUid();
161         OHOS::AppExecFwk::BundleMgrClient bmsClient;
162         std::string bundleName = "";
163         bmsClient.GetNameForUid(uid, bundleName);
164         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CLICK_INFO_CHECK_FAILED",
165             HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
166             "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId_, "SC_TYPE", componentInfo_->type_);
167         return SC_ENHANCE_ERROR_CLICK_EXTRA_CHECK_FAIL;
168     }
169     return SC_OK;
170 }
171 
172 namespace {
IsScreenReadMode()173 static bool IsScreenReadMode()
174 {
175     auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
176     if (saManager == nullptr) {
177         SC_LOG_ERROR(LABEL, "Get sa manager is nullptr.");
178         return false;
179     }
180     auto remoteObj = saManager->GetSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
181     if (remoteObj == nullptr) {
182         SC_LOG_ERROR(LABEL, "Get remoteObj is nullptr.");
183         return false;
184     }
185     std::shared_ptr<DataShare::DataShareHelper> dataShareHelper =
186         DataShare::DataShareHelper::Creator(remoteObj, SETTINGS_DATASHARE_URI, SETTINGS_DATA_EXT_URI);
187     if (dataShareHelper == nullptr) {
188         SC_LOG_ERROR(LABEL, "Get dataShareHelper is nullptr.");
189         return false;
190     }
191     DataShare::DataSharePredicates predicates;
192     std::vector<std::string> columns;
193     predicates.EqualTo(ADVANCED_DATA_COLUMN_KEYWORD, QUERY_KEYWORD);
194     OHOS::Uri uri(SETTINGS_DATASHARE_SEARCH_URI);
195     auto result = dataShareHelper->Query(uri, predicates, columns);
196     if (result == nullptr) {
197         SC_LOG_ERROR(LABEL, "Query result is nullptr.");
198         dataShareHelper->Release();
199         return false;
200     }
201     if (result->GoToFirstRow() != DataShare::E_OK) {
202         SC_LOG_ERROR(LABEL, "Query failed, GoToFirstRow error.");
203         result->Close();
204         dataShareHelper->Release();
205         return false;
206     }
207     int32_t columnIndex;
208     result->GetColumnIndex(ADVANCED_DATA_COLUMN_VALUE, columnIndex);
209     std::string value;
210     result->GetString(columnIndex, value);
211     result->Close();
212     dataShareHelper->Release();
213     return value == "1";
214 }
215 }
216 }  // namespace SecurityComponent
217 }  // namespace Security
218 }  // namespace OHOS
219