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
16 #include <accesstoken_kit.h>
17 #include <app_mgr_client.h>
18 #include <app_mgr_interface.h>
19 #include <bundle_constants.h>
20 #include <ipc_skeleton.h>
21 #include <bundle_mgr_proxy.h>
22 #include <bundle_mgr_interface.h>
23 #include <system_ability_definition.h>
24 #include <iservice_registry.h>
25 #include <tokenid_kit.h>
26 #ifdef IMF_ENABLE
27 #include <input_method_controller.h>
28 #endif // IMF_ENABLE
29 #include <singleton.h>
30 #include <singleton_container.h>
31 #include <pwd.h>
32 #include "common/include/session_permission.h"
33 #include "parameters.h"
34 #include "window_manager_hilog.h"
35
36 namespace OHOS {
37 namespace Rosen {
38 namespace {
39 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionPermission"};
40 constexpr int32_t FOUNDATION_UID = 5523;
41
GetBundleManagerProxy()42 sptr<AppExecFwk::IBundleMgr> GetBundleManagerProxy()
43 {
44 sptr<ISystemAbilityManager> systemAbilityManager =
45 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
46 if (!systemAbilityManager) {
47 WLOGFE("Failed to get system ability mgr.");
48 return nullptr;
49 }
50 sptr<IRemoteObject> remoteObject
51 = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
52 if (!remoteObject) {
53 WLOGFE("Failed to get bundle manager service.");
54 return nullptr;
55 }
56 auto bundleManagerServiceProxy = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
57 if (!bundleManagerServiceProxy || !bundleManagerServiceProxy->AsObject()) {
58 WLOGFE("Failed to get bundle manager proxy.");
59 return nullptr;
60 }
61 return bundleManagerServiceProxy;
62 }
63 }
64
IsSystemServiceCalling(bool needPrintLog)65 bool SessionPermission::IsSystemServiceCalling(bool needPrintLog)
66 {
67 const auto tokenId = IPCSkeleton::GetCallingTokenID();
68 if (IsTokenNativeOrShellType(tokenId)) {
69 TLOGD(WmsLogTag::DEFAULT, "system service calling");
70 return true;
71 }
72 if (needPrintLog) {
73 TLOGE(WmsLogTag::DEFAULT, "Not system service calling");
74 }
75 return false;
76 }
77
IsSystemCalling()78 bool SessionPermission::IsSystemCalling()
79 {
80 const auto tokenId = IPCSkeleton::GetCallingTokenID();
81 if (IsTokenNativeOrShellType(tokenId)) {
82 return true;
83 }
84 return IsSystemAppCall();
85 }
86
IsSystemAppCall()87 bool SessionPermission::IsSystemAppCall()
88 {
89 uint64_t callingTokenId = IPCSkeleton::GetCallingFullTokenID();
90 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callingTokenId);
91 }
92
IsSystemAppCallByCallingTokenID(uint32_t callingTokenId)93 bool SessionPermission::IsSystemAppCallByCallingTokenID(uint32_t callingTokenId)
94 {
95 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(callingTokenId);
96 }
97
IsSACalling()98 bool SessionPermission::IsSACalling()
99 {
100 const auto tokenId = IPCSkeleton::GetCallingTokenID();
101 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
102 if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
103 TLOGD(WmsLogTag::DEFAULT, "SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
104 return true;
105 }
106 TLOGD(WmsLogTag::DEFAULT, "Not SA called, tokenId:%{private}u, flag:%{public}u", tokenId, flag);
107 return false;
108 }
109
VerifyCallingPermission(const std::string & permissionName)110 bool SessionPermission::VerifyCallingPermission(const std::string& permissionName)
111 {
112 auto callerToken = IPCSkeleton::GetCallingTokenID();
113 TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u",
114 permissionName.c_str(), callerToken);
115 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
116 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
117 TLOGE(WmsLogTag::DEFAULT,
118 "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d",
119 permissionName.c_str(), callerToken, ret);
120 return false;
121 }
122 TLOGD(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u",
123 permissionName.c_str(), callerToken);
124 return true;
125 }
126
VerifyPermissionByCallerToken(const uint32_t callerToken,const std::string & permissionName)127 bool SessionPermission::VerifyPermissionByCallerToken(const uint32_t callerToken, const std::string& permissionName)
128 {
129 TLOGD(WmsLogTag::DEFAULT, "permission %{public}s, callingTokenID:%{private}u",
130 permissionName.c_str(), callerToken);
131 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
132 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
133 TLOGE(WmsLogTag::DEFAULT,
134 "permission %{public}s: PERMISSION_DENIED, callingTokenID:%{private}u, ret:%{public}d",
135 permissionName.c_str(), callerToken, ret);
136 return false;
137 }
138 TLOGD(WmsLogTag::DEFAULT, "Verify AccessToken success. permission %{public}s, callingTokenID:%{private}u",
139 permissionName.c_str(), callerToken);
140 return true;
141 }
142
VerifySessionPermission()143 bool SessionPermission::VerifySessionPermission()
144 {
145 if (IsSACalling()) {
146 TLOGD(WmsLogTag::DEFAULT, "Is SA Call, Permission verified success.");
147 return true;
148 }
149 if (VerifyCallingPermission(PermissionConstants::PERMISSION_MANAGE_MISSION)) {
150 TLOGD(WmsLogTag::DEFAULT, "MANAGE permission verified success.");
151 return true;
152 }
153 WLOGFW("Permission verified failed.");
154 return false;
155 }
156
JudgeCallerIsAllowedToUseSystemAPI()157 bool SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()
158 {
159 if (IsSACalling() || IsShellCall()) {
160 return true;
161 }
162 return IsSystemAppCall();
163 }
164
IsShellCall()165 bool SessionPermission::IsShellCall()
166 {
167 auto callerToken = IPCSkeleton::GetCallingTokenID();
168 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
169 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
170 TLOGD(WmsLogTag::DEFAULT, "TokenType is Shell, verify success");
171 return true;
172 }
173 TLOGD(WmsLogTag::DEFAULT, "Not Shell called. tokenId:%{private}u, type:%{public}u", callerToken, tokenType);
174 return false;
175 }
176
IsStartByHdcd()177 bool SessionPermission::IsStartByHdcd()
178 {
179 OHOS::Security::AccessToken::NativeTokenInfo info;
180 uint32_t tokenId = IPCSkeleton::GetCallingTokenID();
181 if (!IsTokenNativeOrShellType(tokenId)) {
182 return false;
183 }
184 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, info) != 0) {
185 return false;
186 }
187 if (info.processName.compare("hdcd") == 0) {
188 return true;
189 }
190 return false;
191 }
192
IsStartedByInputMethod()193 bool SessionPermission::IsStartedByInputMethod()
194 {
195 #ifdef IMF_ENABLE
196 auto imc = MiscServices::InputMethodController::GetInstance();
197 if (!imc) {
198 TLOGE(WmsLogTag::DEFAULT, "InputMethodController is nullptr");
199 return false;
200 }
201 int pid = IPCSkeleton::GetCallingPid();
202 return imc->IsCurrentImeByPid(pid);
203 #else
204 return false;
205 #endif // IMF_ENABLE
206 }
207
IsSameBundleNameAsCalling(const std::string & bundleName)208 bool SessionPermission::IsSameBundleNameAsCalling(const std::string& bundleName)
209 {
210 if (bundleName == "") {
211 return false;
212 }
213 auto bundleManagerServiceProxy_ = GetBundleManagerProxy();
214 if (!bundleManagerServiceProxy_) {
215 WLOGFE("failed to get BundleManagerServiceProxy");
216 return false;
217 }
218 int uid = IPCSkeleton::GetCallingUid();
219 // reset ipc identity
220 std::string identity = IPCSkeleton::ResetCallingIdentity();
221 std::string callingBundleName;
222 bundleManagerServiceProxy_->GetNameForUid(uid, callingBundleName);
223 IPCSkeleton::SetCallingIdentity(identity);
224 if (callingBundleName == bundleName) {
225 WLOGFD("verify bundle name success");
226 return true;
227 } else {
228 WLOGFE("verify bundle name failed, calling bundle name %{public}s, but window bundle name %{public}s.",
229 callingBundleName.c_str(), bundleName.c_str());
230 return false;
231 }
232 }
233
IsSameAppAsCalling(const std::string & bundleName,const std::string & appIdentifier)234 bool SessionPermission::IsSameAppAsCalling(const std::string& bundleName, const std::string& appIdentifier)
235 {
236 if (bundleName == "" || appIdentifier == "") {
237 return false;
238 }
239 auto bundleManagerServiceProxy = GetBundleManagerProxy();
240 if (!bundleManagerServiceProxy) {
241 TLOGE(WmsLogTag::DEFAULT, "failed to get BundleManagerServiceProxy");
242 return false;
243 }
244 int uid = IPCSkeleton::GetCallingUid();
245 // reset ipc identity
246 std::string identity = IPCSkeleton::ResetCallingIdentity();
247 std::string callingBundleName;
248 bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName);
249 if (callingBundleName != bundleName) {
250 TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.",
251 callingBundleName.c_str(), bundleName.c_str());
252 IPCSkeleton::SetCallingIdentity(identity);
253 return false;
254 }
255 AppExecFwk::BundleInfo bundleInfo;
256 int userId = uid / 200000; // 200000 use uid to caculate userId
257 bool ret = bundleManagerServiceProxy->GetBundleInfoV9(
258 callingBundleName, static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO),
259 bundleInfo, userId);
260 IPCSkeleton::SetCallingIdentity(identity);
261
262 if (ret != ERR_OK) {
263 TLOGE(WmsLogTag::DEFAULT, "failed to query app info, callingBundleName:%{public}s, userId:%{public}d",
264 callingBundleName.c_str(), userId);
265 return false;
266 }
267
268 if (bundleInfo.signatureInfo.appIdentifier == appIdentifier) {
269 TLOGD(WmsLogTag::DEFAULT, "verify app success");
270 return true;
271 }
272
273 TLOGE(WmsLogTag::DEFAULT, "verify app failed, callingBundleName %{public}s, bundleName %{public}s.",
274 callingBundleName.c_str(), bundleName.c_str());
275 return false;
276 }
277
IsStartedByUIExtension()278 bool SessionPermission::IsStartedByUIExtension()
279 {
280 auto bundleManagerServiceProxy = GetBundleManagerProxy();
281 if (!bundleManagerServiceProxy) {
282 WLOGFE("failed to get BundleManagerServiceProxy");
283 return false;
284 }
285
286 int uid = IPCSkeleton::GetCallingUid();
287 // reset ipc identity
288 std::string identity = IPCSkeleton::ResetCallingIdentity();
289 std::string bundleName;
290 bundleManagerServiceProxy->GetNameForUid(uid, bundleName);
291 AppExecFwk::BundleInfo bundleInfo;
292 int userId = uid / 200000; // 200000 use uid to caculate userId
293 bool result = bundleManagerServiceProxy->GetBundleInfo(bundleName,
294 AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
295 // set ipc identity to raw
296 IPCSkeleton::SetCallingIdentity(identity);
297 if (!result) {
298 WLOGFE("failed to query extension ability info, bundleName:%{public}s, userId:%{public}d",
299 bundleName.c_str(), userId);
300 return false;
301 }
302
303 auto extensionInfo = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(),
304 [](AppExecFwk::ExtensionAbilityInfo extensionInfo) {
305 return (extensionInfo.type == AppExecFwk::ExtensionAbilityType::SYS_COMMON_UI);
306 });
307 return extensionInfo != bundleInfo.extensionInfos.end();
308 }
309
CheckCallingIsUserTestMode(pid_t pid)310 bool SessionPermission::CheckCallingIsUserTestMode(pid_t pid)
311 {
312 TLOGD(WmsLogTag::DEFAULT, "Calling proxy func");
313 bool isUserTestMode = false;
314 auto appMgrClient = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
315 if (appMgrClient == nullptr) {
316 TLOGE(WmsLogTag::DEFAULT, "AppMgeClient is null!");
317 return false;
318 }
319 // reset ipc identity
320 std::string identity = IPCSkeleton::ResetCallingIdentity();
321 int32_t ret = appMgrClient->CheckCallingIsUserTestMode(pid, isUserTestMode);
322 // set ipc identity to raw
323 IPCSkeleton::SetCallingIdentity(identity);
324 if (ret != ERR_OK) {
325 TLOGE(WmsLogTag::DEFAULT, "Permission denied! ret=%{public}d", ret);
326 return false;
327 }
328 return isUserTestMode;
329 }
330
IsBetaVersion()331 bool SessionPermission::IsBetaVersion()
332 {
333 std::string betaName = OHOS::system::GetParameter("const.logsystem.versiontype", "");
334 return betaName.find("beta") != std::string::npos;
335 }
336
IsFoundationCall()337 bool SessionPermission::IsFoundationCall()
338 {
339 return IPCSkeleton::GetCallingUid() == FOUNDATION_UID;
340 }
341
GetCallingBundleName()342 std::string SessionPermission::GetCallingBundleName()
343 {
344 auto bundleManagerServiceProxy = GetBundleManagerProxy();
345 if (!bundleManagerServiceProxy) {
346 WLOGFE("failed to get BundleManagerServiceProxy");
347 return "";
348 }
349 int uid = IPCSkeleton::GetCallingUid();
350 // reset ipc identity
351 std::string identity = IPCSkeleton::ResetCallingIdentity();
352 std::string callingBundleName;
353 bundleManagerServiceProxy->GetNameForUid(uid, callingBundleName);
354 // if bundlename is empty, fill in pw_name
355 if (callingBundleName.empty()) {
356 if (struct passwd* user = getpwuid(uid)) {
357 callingBundleName = user->pw_name;
358 }
359 }
360 IPCSkeleton::SetCallingIdentity(identity);
361 return callingBundleName;
362 }
363
VerifyPermissionByBundleName(const std::string & permissionName,const std::string & bundleName,uint32_t userId)364 bool SessionPermission::VerifyPermissionByBundleName(
365 const std::string& permissionName, const std::string& bundleName, uint32_t userId)
366 {
367 auto bundleManagerServiceProxy = GetBundleManagerProxy();
368 if (!bundleManagerServiceProxy) {
369 TLOGW(WmsLogTag::DEFAULT, "failed to get BundleManagerServiceProxy");
370 return false;
371 }
372 std::string identity = IPCSkeleton::ResetCallingIdentity();
373 AppExecFwk::BundleInfo bundleInfo;
374 bool result = bundleManagerServiceProxy->GetBundleInfo(bundleName,
375 AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId);
376 IPCSkeleton::SetCallingIdentity(identity);
377 if (!result) {
378 TLOGW(WmsLogTag::DEFAULT, "get bundle info failed!");
379 return false;
380 }
381 return VerifyPermissionByCallerToken(bundleInfo.applicationInfo.accessTokenId, permissionName);
382 }
383
IsTokenNativeOrShellType(uint32_t tokenId)384 bool SessionPermission::IsTokenNativeOrShellType(uint32_t tokenId)
385 {
386 const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
387 TLOGD(WmsLogTag::DEFAULT, "tokenId:%{private}u, flag:%{public}u", tokenId, flag);
388 if (flag != Security::AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE &&
389 flag != Security::AccessToken::TypeATokenTypeEnum::TOKEN_SHELL) {
390 return false;
391 }
392 return true;
393 }
394 } // namespace Rosen
395 } // namespace OHOS