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