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_info_helper.h"
16
17 #include "accesstoken_kit.h"
18 #include "display.h"
19 #include "display_info.h"
20 #include "display_manager.h"
21 #include "location_button.h"
22 #include "paste_button.h"
23 #include "save_button.h"
24 #include "sec_comp_err.h"
25 #include "sec_comp_log.h"
26 #include "sec_comp_service.h"
27 #include "sec_comp_tool.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, "SecCompInfoHelper"};
35 static constexpr double MAX_RECT_PERCENT = 0.1F; // 10%
36 static constexpr double ZERO_OFFSET = 0.0F;
37 static std::mutex g_renderLock;
38 }
39
AdjustSecCompRect(SecCompBase * comp,float scale)40 void SecCompInfoHelper::AdjustSecCompRect(SecCompBase* comp, float scale)
41 {
42 comp->rect_.width_ *= scale;
43 comp->rect_.height_ *= scale;
44 comp->rect_.x_ = comp->windowRect_.x_ + (comp->rect_.x_ - comp->windowRect_.x_) * scale;
45 comp->rect_.y_ = comp->windowRect_.y_ + (comp->rect_.y_ - comp->windowRect_.y_) * scale;
46
47 SC_LOG_DEBUG(LABEL, "After adjust x %{public}f, y %{public}f, width %{public}f, height %{public}f",
48 comp->rect_.x_, comp->rect_.y_, comp->rect_.width_, comp->rect_.height_);
49 }
50
ParseComponent(SecCompType type,const nlohmann::json & jsonComponent)51 SecCompBase* SecCompInfoHelper::ParseComponent(SecCompType type, const nlohmann::json& jsonComponent)
52 {
53 SecCompBase* comp = nullptr;
54 switch (type) {
55 case LOCATION_COMPONENT:
56 comp = ConstructComponent<LocationButton>(jsonComponent);
57 break;
58 case PASTE_COMPONENT:
59 comp = ConstructComponent<PasteButton>(jsonComponent);
60 break;
61 case SAVE_COMPONENT:
62 comp = ConstructComponent<SaveButton>(jsonComponent);
63 break;
64 default:
65 SC_LOG_ERROR(LABEL, "Parse component type unknown");
66 break;
67 }
68 if (comp == nullptr) {
69 SC_LOG_ERROR(LABEL, "Parse component failed");
70 return comp;
71 }
72
73 comp->SetValid(CheckComponentValid(comp));
74 return comp;
75 }
76
GetScreenSize(double & width,double & height)77 static bool GetScreenSize(double& width, double& height)
78 {
79 sptr<OHOS::Rosen::Display> display =
80 OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplaySync();
81 if (display == nullptr) {
82 SC_LOG_ERROR(LABEL, "Get display manager failed");
83 return false;
84 }
85
86 auto info = display->GetDisplayInfo();
87 if (info == nullptr) {
88 SC_LOG_ERROR(LABEL, "Get display info failed");
89 return false;
90 }
91
92 width = static_cast<double>(info->GetWidth());
93 height = static_cast<double>(info->GetHeight());
94 SC_LOG_DEBUG(LABEL, "display manager Screen width %{public}f height %{public}f",
95 width, height);
96 return true;
97 }
98
CheckRectValid(const SecCompRect & rect,const SecCompRect & windowRect)99 bool SecCompInfoHelper::CheckRectValid(const SecCompRect& rect, const SecCompRect& windowRect)
100 {
101 double curScreenWidth = 0.0F;
102 double curScreenHeight = 0.0F;
103 if (!GetScreenSize(curScreenWidth, curScreenHeight)) {
104 SC_LOG_ERROR(LABEL, "Get screen size is invalid");
105 return false;
106 }
107
108 if (GreatOrEqual(0.0, rect.width_) || GreatOrEqual(0.0, rect.height_)) {
109 SC_LOG_ERROR(LABEL, "width or height is <= 0");
110 return false;
111 }
112
113 if (GreatNotEqual(ZERO_OFFSET, rect.x_) || GreatNotEqual(ZERO_OFFSET, rect.y_) ||
114 GreatNotEqual(rect.x_, curScreenWidth) || GreatNotEqual(rect.y_, curScreenHeight)) {
115 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of screen");
116 return false;
117 }
118
119 if (GreatOrEqual((rect.x_ + rect.width_), curScreenWidth) ||
120 GreatOrEqual((rect.y_ + rect.height_), curScreenHeight)) {
121 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of screen");
122 return false;
123 }
124
125 if (GreatNotEqual(windowRect.x_, rect.x_) || GreatNotEqual(windowRect.y_, rect.y_) ||
126 GreatNotEqual(rect.x_ + rect.width_, windowRect.x_ + windowRect.width_) ||
127 GreatNotEqual(rect.y_ + rect.height_, windowRect.y_ + windowRect.height_)) {
128 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is out of window");
129 return false;
130 }
131
132 // check rect > 10%
133 if (GreatOrEqual((rect.width_ * rect.height_), (curScreenWidth * curScreenHeight * MAX_RECT_PERCENT))) {
134 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: security component is larger than 10 percent of screen");
135 return false;
136 }
137 SC_LOG_DEBUG(LABEL, "check component rect success.");
138 return true;
139 }
140
CheckSecCompBaseButton(const SecCompBase * comp)141 static bool CheckSecCompBaseButton(const SecCompBase* comp)
142 {
143 if ((comp->text_ < 0) && (comp->icon_ < 0)) {
144 SC_LOG_INFO(LABEL, "both text and icon do not exist.");
145 return false;
146 }
147 if (comp->text_ >= 0) {
148 DimensionT minFontSize;
149 if (comp->icon_ >= 0) {
150 minFontSize = MIN_FONT_SIZE_WITH_ICON;
151 } else {
152 minFontSize = MIN_FONT_SIZE_WITHOUT_ICON;
153 }
154
155 if (comp->fontSize_ < minFontSize) {
156 SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: fontSize is too small.");
157 return false;
158 }
159 }
160 if ((comp->icon_ >= 0) && comp->iconSize_ < MIN_ICON_SIZE) {
161 SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: iconSize is too small.");
162 return false;
163 }
164
165 if ((comp->bg_ != SecCompBackground::NO_BG_TYPE) && !IsColorFullTransparent(comp->bgColor_) &&
166 (((comp->text_ != NO_TEXT) && (IsColorSimilar(comp->fontColor_, comp->bgColor_))) ||
167 ((comp->icon_ != NO_ICON) && (IsColorSimilar(comp->iconColor_, comp->bgColor_))))) {
168 SC_LOG_INFO(LABEL, "SecurityComponentCheckFail: fontColor or iconColor is similar with backgroundColor.");
169 return false;
170 }
171
172 if (comp->bg_ == SecCompBackground::NO_BG_TYPE &&
173 ((comp->padding_.top != MIN_PADDING_WITHOUT_BG) || (comp->padding_.right != MIN_PADDING_WITHOUT_BG) ||
174 (comp->padding_.bottom != MIN_PADDING_WITHOUT_BG) || (comp->padding_.left != MIN_PADDING_WITHOUT_BG))) {
175 SC_LOG_INFO(LABEL, "padding can not change without background.");
176 return false;
177 }
178
179 return true;
180 }
181
CheckSecCompBase(const SecCompBase * comp)182 static bool CheckSecCompBase(const SecCompBase* comp)
183 {
184 if (comp->parentEffect_) {
185 SC_LOG_ERROR(LABEL,
186 "SecurityComponentCheckFail: the parents of security component have invalid effect.");
187 return false;
188 }
189
190 if ((comp->padding_.top < MIN_PADDING_SIZE) || (comp->padding_.right < MIN_PADDING_SIZE) ||
191 (comp->padding_.bottom < MIN_PADDING_SIZE) || (comp->padding_.left < MIN_PADDING_SIZE) ||
192 (comp->textIconSpace_ < MIN_PADDING_SIZE)) {
193 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: padding or textIconSpace is too small.");
194 return false;
195 }
196
197 if (((comp->text_ != NO_TEXT) && (IsColorTransparent(comp->fontColor_))) ||
198 ((comp->icon_ != NO_ICON) && (IsColorTransparent(comp->iconColor_)))) {
199 SC_LOG_ERROR(LABEL, "SecurityComponentCheckFail: fontColor or iconColor is too transparent.");
200 return false;
201 }
202 if (!CheckSecCompBaseButton(comp)) {
203 return false;
204 }
205 return true;
206 }
207
CheckComponentValid(SecCompBase * comp)208 bool SecCompInfoHelper::CheckComponentValid(SecCompBase* comp)
209 {
210 if ((comp == nullptr) || !IsComponentTypeValid(comp->type_)) {
211 SC_LOG_INFO(LABEL, "comp is null or type is invalid.");
212 return false;
213 }
214
215 float scale = WindowInfoHelper::GetWindowScale(comp->windowId_);
216 SC_LOG_DEBUG(LABEL, "WindowScale = %{public}f", scale);
217 if (!IsEqual(scale, WindowInfoHelper::FULL_SCREEN_SCALE) && !IsEqual(scale, 0.0)) {
218 AdjustSecCompRect(comp, scale);
219 }
220
221 if (!CheckSecCompBase(comp)) {
222 SC_LOG_INFO(LABEL, "SecComp base is invalid.");
223 return false;
224 }
225
226 return true;
227 }
228
GrantTempPermission(AccessToken::AccessTokenID tokenId,const std::shared_ptr<SecCompBase> & componentInfo)229 int32_t SecCompInfoHelper::GrantTempPermission(AccessToken::AccessTokenID tokenId,
230 const std::shared_ptr<SecCompBase>& componentInfo)
231 {
232 if ((tokenId <= 0) || (componentInfo == nullptr)) {
233 SC_LOG_ERROR(LABEL, "Grant component is null");
234 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
235 }
236
237 SecCompType type = componentInfo->type_;
238 int32_t res;
239 switch (type) {
240 case LOCATION_COMPONENT:
241 {
242 res = SecCompPermManager::GetInstance().GrantAppPermission(tokenId,
243 "ohos.permission.APPROXIMATELY_LOCATION");
244 if (res != SC_OK) {
245 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
246 }
247 res = SecCompPermManager::GetInstance().GrantAppPermission(tokenId, "ohos.permission.LOCATION");
248 if (res != SC_OK) {
249 SecCompPermManager::GetInstance().RevokeAppPermission(
250 tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
251 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
252 }
253 SC_LOG_INFO(LABEL, "Grant location permission, scid = %{public}d.", componentInfo->nodeId_);
254 return SC_OK;
255 }
256 case PASTE_COMPONENT:
257 res = SecCompPermManager::GetInstance().GrantAppPermission(tokenId, "ohos.permission.SECURE_PASTE");
258 if (res != SC_OK) {
259 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
260 }
261 SC_LOG_INFO(LABEL, "Grant paste permission, scid = %{public}d.", componentInfo->nodeId_);
262 return SC_OK;
263 case SAVE_COMPONENT:
264 if (IsDlpSandboxCalling(tokenId)) {
265 SC_LOG_INFO(LABEL, "Dlp sandbox app are not allowed to use save component.");
266 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
267 }
268 SC_LOG_INFO(LABEL, "Grant save permission, scid = %{public}d.", componentInfo->nodeId_);
269 return SecCompPermManager::GetInstance().GrantTempSavePermission(tokenId);
270 default:
271 SC_LOG_ERROR(LABEL, "Parse component type unknown");
272 break;
273 }
274 return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
275 }
276
IsDlpSandboxCalling(AccessToken::AccessTokenID tokenId)277 inline bool SecCompInfoHelper::IsDlpSandboxCalling(AccessToken::AccessTokenID tokenId)
278 {
279 return AccessToken::AccessTokenKit::GetHapDlpFlag(tokenId) != 0;
280 }
281 } // namespace SecurityComponent
282 } // namespace Security
283 } // namespace OHOS
284