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 constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
38 constexpr const char *SETTINGS_DATASHARE_URI =
39 "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
40 constexpr const char *SETTINGS_DATASHARE_SEARCH_URI =
41 "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?" \
42 "Proxy=true&key=accessibility_screenreader_enabled";
43 constexpr const char *ADVANCED_DATA_COLUMN_KEYWORD = "KEYWORD";
44 constexpr const char *ADVANCED_DATA_COLUMN_VALUE = "VALUE";
45 constexpr const char *QUERY_KEYWORD = "accessibility_screenreader_enabled";
46 static bool IsScreenReadMode();
47 }
48
GrantTempPermission()49 int32_t SecCompEntity::GrantTempPermission()
50 {
51 isGrant_ = true;
52 return SecCompInfoHelper::GrantTempPermission(tokenId_, componentInfo_);
53 }
54
CompareComponentBasicInfo(SecCompBase * other,bool isRectCheck) const55 bool SecCompEntity::CompareComponentBasicInfo(SecCompBase* other, bool isRectCheck) const
56 {
57 return componentInfo_->CompareComponentBasicInfo(other, isRectCheck);
58 }
59
CheckPointEvent(const SecCompClickEvent & clickInfo) const60 int32_t SecCompEntity::CheckPointEvent(const SecCompClickEvent& clickInfo) const
61 {
62 auto current = static_cast<uint64_t>(
63 std::chrono::high_resolution_clock::now().time_since_epoch().count()) / TIME_CONVERSION_UNIT;
64 if (clickInfo.point.timestamp < current - MAX_TOUCH_INTERVAL || clickInfo.point.timestamp > current) {
65 SC_LOG_ERROR(LABEL, "touch timestamp invalid clickInfo. timestamp: %{public}llu, current: %{public}llu",
66 static_cast<unsigned long long>(clickInfo.point.timestamp), static_cast<unsigned long long>(current));
67 return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
68 }
69
70 if (!componentInfo_->rect_.IsInRect(clickInfo.point.touchX, clickInfo.point.touchY)) {
71 SC_LOG_ERROR(LABEL, "touch point is not in component rect = (%{public}f, %{public}f)" \
72 "left top point of component rect = (%{public}f, %{public}f)" \
73 "right bottom point of component rect = (%{public}f, %{public}f)",
74 clickInfo.point.touchX, clickInfo.point.touchY, componentInfo_->rect_.x_, componentInfo_->rect_.y_,
75 componentInfo_->rect_.x_ + componentInfo_->rect_.width_,
76 componentInfo_->rect_.y_ + componentInfo_->rect_.height_);
77 return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
78 }
79 return SC_OK;
80 }
81
CheckKeyEvent(const SecCompClickEvent & clickInfo) const82 int32_t SecCompEntity::CheckKeyEvent(const SecCompClickEvent& clickInfo) const
83 {
84 auto current = static_cast<uint64_t>(
85 std::chrono::high_resolution_clock::now().time_since_epoch().count()) / TIME_CONVERSION_UNIT;
86 if (clickInfo.key.timestamp < current - MAX_TOUCH_INTERVAL || clickInfo.key.timestamp > current) {
87 SC_LOG_ERROR(LABEL, "keyboard timestamp invalid clickInfo. timestamp: %{public}llu, current: %{public}llu",
88 static_cast<unsigned long long>(clickInfo.key.timestamp), static_cast<unsigned long long>(current));
89 return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
90 }
91 if ((clickInfo.key.keyCode != KEY_SPACE) && (clickInfo.key.keyCode != KEY_ENTER) &&
92 (clickInfo.key.keyCode != KEY_NUMPAD_ENTER)) {
93 SC_LOG_ERROR(LABEL, "keyboard keyCode invalid. keyCode: %{public}d", clickInfo.key.keyCode);
94 return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
95 }
96
97 return SC_OK;
98 }
99
CheckClickInfo(const SecCompClickEvent & clickInfo) const100 int32_t SecCompEntity::CheckClickInfo(const SecCompClickEvent& clickInfo) const
101 {
102 if (!WindowInfoHelper::CheckOtherWindowCoverComp(componentInfo_->windowId_,
103 componentInfo_->rect_)) {
104 SC_LOG_ERROR(LABEL, "Component may be covered by other window");
105 return SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
106 }
107
108 int32_t res = SC_SERVICE_ERROR_CLICK_EVENT_INVALID;
109 bool isScreenReadMode = IsScreenReadMode();
110 if (clickInfo.type == ClickEventType::POINT_EVENT_TYPE && !isScreenReadMode) {
111 res = CheckPointEvent(clickInfo);
112 } else if (clickInfo.type == ClickEventType::POINT_EVENT_TYPE && isScreenReadMode) {
113 SC_LOG_WARN(LABEL, "Device is in screen read mode, skip event check.");
114 return SC_OK;
115 } else if (clickInfo.type == ClickEventType::KEY_EVENT_TYPE) {
116 res = CheckKeyEvent(clickInfo);
117 }
118 if (res != SC_OK) {
119 return res;
120 }
121
122 res = SecCompEnhanceAdapter::CheckExtraInfo(clickInfo);
123 if (res == SC_SERVICE_ERROR_CLICK_EVENT_INVALID) {
124 SC_LOG_ERROR(LABEL, "Click ExtraInfo is invalid");
125 return res;
126 }
127
128 if ((res != SC_OK) && (res != SC_ENHANCE_ERROR_NOT_EXIST_ENHANCE)) {
129 SC_LOG_ERROR(LABEL, "HMAC checkout failed");
130 int32_t uid = IPCSkeleton::GetCallingUid();
131 OHOS::AppExecFwk::BundleMgrClient bmsClient;
132 std::string bundleName = "";
133 bmsClient.GetNameForUid(uid, bundleName);
134 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SEC_COMPONENT, "CLICK_INFO_CHECK_FAILED",
135 HiviewDFX::HiSysEvent::EventType::SECURITY, "CALLER_UID", uid, "CALLER_BUNDLE_NAME", bundleName,
136 "CALLER_PID", IPCSkeleton::GetCallingPid(), "SC_ID", scId_, "SC_TYPE", componentInfo_->type_);
137 return SC_ENHANCE_ERROR_CLICK_EXTRA_CHECK_FAIL;
138 }
139 return SC_OK;
140 }
141
142 namespace {
IsScreenReadMode()143 static bool IsScreenReadMode()
144 {
145 auto saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
146 if (saManager == nullptr) {
147 SC_LOG_ERROR(LABEL, "Get sa manager is nullptr.");
148 return false;
149 }
150 auto remoteObj = saManager->GetSystemAbility(SA_ID_SECURITY_COMPONENT_SERVICE);
151 if (remoteObj == nullptr) {
152 SC_LOG_ERROR(LABEL, "Get remoteObj is nullptr.");
153 return false;
154 }
155 std::shared_ptr<DataShare::DataShareHelper> dataShareHelper =
156 DataShare::DataShareHelper::Creator(remoteObj, SETTINGS_DATASHARE_URI, SETTINGS_DATA_EXT_URI);
157 if (dataShareHelper == nullptr) {
158 SC_LOG_ERROR(LABEL, "Get dataShareHelper is nullptr.");
159 return false;
160 }
161 DataShare::DataSharePredicates predicates;
162 std::vector<std::string> columns;
163 predicates.EqualTo(ADVANCED_DATA_COLUMN_KEYWORD, QUERY_KEYWORD);
164 OHOS::Uri uri(SETTINGS_DATASHARE_SEARCH_URI);
165 auto result = dataShareHelper->Query(uri, predicates, columns);
166 if (result == nullptr) {
167 SC_LOG_ERROR(LABEL, "Query result is nullptr.");
168 dataShareHelper->Release();
169 return false;
170 }
171 if (result->GoToFirstRow() != DataShare::E_OK) {
172 SC_LOG_ERROR(LABEL, "Query failed, GoToFirstRow error.");
173 result->Close();
174 dataShareHelper->Release();
175 return false;
176 }
177 int32_t columnIndex;
178 result->GetColumnIndex(ADVANCED_DATA_COLUMN_VALUE, columnIndex);
179 std::string value;
180 result->GetString(columnIndex, value);
181 result->Close();
182 dataShareHelper->Release();
183 return value == "1";
184 }
185 }
186 } // namespace SecurityComponent
187 } // namespace Security
188 } // namespace OHOS
189