1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci
16e0dac50fSopenharmony_ci#include "permission.h"
17e0dac50fSopenharmony_ci
18e0dac50fSopenharmony_ci#include <accesstoken_kit.h>
19e0dac50fSopenharmony_ci#include <bundle_constants.h>
20e0dac50fSopenharmony_ci#include <ipc_skeleton.h>
21e0dac50fSopenharmony_ci#include <bundle_mgr_proxy.h>
22e0dac50fSopenharmony_ci#include <bundle_mgr_interface.h>
23e0dac50fSopenharmony_ci#include <system_ability_definition.h>
24e0dac50fSopenharmony_ci#include <iservice_registry.h>
25e0dac50fSopenharmony_ci#include <tokenid_kit.h>
26e0dac50fSopenharmony_ci
27e0dac50fSopenharmony_ci#include "window_manager_hilog.h"
28e0dac50fSopenharmony_ci
29e0dac50fSopenharmony_cinamespace OHOS {
30e0dac50fSopenharmony_cinamespace Rosen {
31e0dac50fSopenharmony_cinamespace {
32e0dac50fSopenharmony_ciconstexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "Permission"};
33e0dac50fSopenharmony_ci}
34e0dac50fSopenharmony_ci
35e0dac50fSopenharmony_cibool Permission::IsSystemServiceCalling(bool needPrintLog, bool isLocalSysCalling)
36e0dac50fSopenharmony_ci{
37e0dac50fSopenharmony_ci    uint32_t tokenId = isLocalSysCalling ?
38e0dac50fSopenharmony_ci        static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID()) :
39e0dac50fSopenharmony_ci        IPCSkeleton::GetCallingTokenID();
40e0dac50fSopenharmony_ci    const auto flag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
41e0dac50fSopenharmony_ci    if (flag == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
42e0dac50fSopenharmony_ci        flag == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
43e0dac50fSopenharmony_ci        TLOGD(WmsLogTag::DEFAULT, "system service calling, tokenId: %{private}u, flag: %{public}u", tokenId, flag);
44e0dac50fSopenharmony_ci        return true;
45e0dac50fSopenharmony_ci    }
46e0dac50fSopenharmony_ci    if (needPrintLog) {
47e0dac50fSopenharmony_ci        TLOGE(WmsLogTag::DEFAULT, "not system service calling, tokenId: %{private}u, flag: %{public}u", tokenId, flag);
48e0dac50fSopenharmony_ci    }
49e0dac50fSopenharmony_ci    return false;
50e0dac50fSopenharmony_ci}
51e0dac50fSopenharmony_ci
52e0dac50fSopenharmony_cibool Permission::IsSystemCallingOrStartByHdcd(bool isLocalSysCalling)
53e0dac50fSopenharmony_ci{
54e0dac50fSopenharmony_ci    if (!IsSystemCalling(isLocalSysCalling) && !IsStartByHdcd(isLocalSysCalling)) {
55e0dac50fSopenharmony_ci        TLOGE(WmsLogTag::DEFAULT, "not system calling, not start by hdcd");
56e0dac50fSopenharmony_ci        return false;
57e0dac50fSopenharmony_ci    }
58e0dac50fSopenharmony_ci    return true;
59e0dac50fSopenharmony_ci}
60e0dac50fSopenharmony_ci
61e0dac50fSopenharmony_cibool Permission::IsSystemCalling(bool isLocalSysCalling)
62e0dac50fSopenharmony_ci{
63e0dac50fSopenharmony_ci    if (IsSystemServiceCalling(false, isLocalSysCalling)) {
64e0dac50fSopenharmony_ci        return true;
65e0dac50fSopenharmony_ci    }
66e0dac50fSopenharmony_ci    uint64_t tokenId = isLocalSysCalling ?
67e0dac50fSopenharmony_ci        IPCSkeleton::GetSelfTokenID() : IPCSkeleton::GetCallingFullTokenID();
68e0dac50fSopenharmony_ci    return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
69e0dac50fSopenharmony_ci}
70e0dac50fSopenharmony_ci
71e0dac50fSopenharmony_cibool Permission::CheckCallingPermission(const std::string& permission)
72e0dac50fSopenharmony_ci{
73e0dac50fSopenharmony_ci    WLOGFD("permission:%{public}s", permission.c_str());
74e0dac50fSopenharmony_ci
75e0dac50fSopenharmony_ci    if (Security::AccessToken::AccessTokenKit::VerifyAccessToken(IPCSkeleton::GetCallingTokenID(), permission) !=
76e0dac50fSopenharmony_ci        AppExecFwk::Constants::PERMISSION_GRANTED) {
77e0dac50fSopenharmony_ci        WLOGW("permission denied!");
78e0dac50fSopenharmony_ci        return false;
79e0dac50fSopenharmony_ci    }
80e0dac50fSopenharmony_ci    WLOGFD("permission ok!");
81e0dac50fSopenharmony_ci    return true;
82e0dac50fSopenharmony_ci}
83e0dac50fSopenharmony_ci
84e0dac50fSopenharmony_cibool Permission::IsStartByHdcd(bool isLocalSysCalling)
85e0dac50fSopenharmony_ci{
86e0dac50fSopenharmony_ci    uint32_t tokenId = isLocalSysCalling ?
87e0dac50fSopenharmony_ci        static_cast<uint32_t>(IPCSkeleton::GetSelfTokenID()) :
88e0dac50fSopenharmony_ci        IPCSkeleton::GetCallingTokenID();
89e0dac50fSopenharmony_ci    OHOS::Security::AccessToken::NativeTokenInfo info;
90e0dac50fSopenharmony_ci    if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, info) != 0) {
91e0dac50fSopenharmony_ci        return false;
92e0dac50fSopenharmony_ci    }
93e0dac50fSopenharmony_ci    if (info.processName.compare("hdcd") == 0) {
94e0dac50fSopenharmony_ci        return true;
95e0dac50fSopenharmony_ci    }
96e0dac50fSopenharmony_ci    return false;
97e0dac50fSopenharmony_ci}
98e0dac50fSopenharmony_ci
99e0dac50fSopenharmony_cibool Permission::IsStartByInputMethod()
100e0dac50fSopenharmony_ci{
101e0dac50fSopenharmony_ci    sptr<ISystemAbilityManager> systemAbilityManager =
102e0dac50fSopenharmony_ci            SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
103e0dac50fSopenharmony_ci    if (!systemAbilityManager) {
104e0dac50fSopenharmony_ci        WLOGFE("Failed to get system ability mgr.");
105e0dac50fSopenharmony_ci        return false;
106e0dac50fSopenharmony_ci    }
107e0dac50fSopenharmony_ci    sptr<IRemoteObject> remoteObject
108e0dac50fSopenharmony_ci        = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
109e0dac50fSopenharmony_ci    if (!remoteObject) {
110e0dac50fSopenharmony_ci        WLOGFE("Failed to get display manager service.");
111e0dac50fSopenharmony_ci        return false;
112e0dac50fSopenharmony_ci    }
113e0dac50fSopenharmony_ci    auto bundleManagerServiceProxy_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
114e0dac50fSopenharmony_ci    if ((!bundleManagerServiceProxy_) || (!bundleManagerServiceProxy_->AsObject())) {
115e0dac50fSopenharmony_ci        WLOGFE("Failed to get system display manager services");
116e0dac50fSopenharmony_ci        return false;
117e0dac50fSopenharmony_ci    }
118e0dac50fSopenharmony_ci
119e0dac50fSopenharmony_ci    int uid = IPCSkeleton::GetCallingUid();
120e0dac50fSopenharmony_ci    // reset ipc identity
121e0dac50fSopenharmony_ci    std::string identity = IPCSkeleton::ResetCallingIdentity();
122e0dac50fSopenharmony_ci    std::string bundleName;
123e0dac50fSopenharmony_ci    bundleManagerServiceProxy_->GetNameForUid(uid, bundleName);
124e0dac50fSopenharmony_ci    AppExecFwk::BundleInfo bundleInfo;
125e0dac50fSopenharmony_ci    // 200000 use uid to caculate userId
126e0dac50fSopenharmony_ci    int userId = uid / 200000;
127e0dac50fSopenharmony_ci    bool result = bundleManagerServiceProxy_->GetBundleInfo(bundleName,
128e0dac50fSopenharmony_ci        AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, userId);
129e0dac50fSopenharmony_ci    // set ipc identity to raw
130e0dac50fSopenharmony_ci    IPCSkeleton::SetCallingIdentity(identity);
131e0dac50fSopenharmony_ci    if (!result) {
132e0dac50fSopenharmony_ci        WLOGFE("failed to query extension ability info");
133e0dac50fSopenharmony_ci        return false;
134e0dac50fSopenharmony_ci    }
135e0dac50fSopenharmony_ci
136e0dac50fSopenharmony_ci    auto extensionInfo = std::find_if(bundleInfo.extensionInfos.begin(), bundleInfo.extensionInfos.end(),
137e0dac50fSopenharmony_ci        [](AppExecFwk::ExtensionAbilityInfo extensionInfo) {
138e0dac50fSopenharmony_ci            return (extensionInfo.type == AppExecFwk::ExtensionAbilityType::INPUTMETHOD);
139e0dac50fSopenharmony_ci        });
140e0dac50fSopenharmony_ci    if (extensionInfo != bundleInfo.extensionInfos.end()) {
141e0dac50fSopenharmony_ci        return true;
142e0dac50fSopenharmony_ci    } else {
143e0dac50fSopenharmony_ci        return false;
144e0dac50fSopenharmony_ci    }
145e0dac50fSopenharmony_ci}
146e0dac50fSopenharmony_ci
147e0dac50fSopenharmony_cibool Permission::CheckIsCallingBundleName(const std::string name)
148e0dac50fSopenharmony_ci{
149e0dac50fSopenharmony_ci    sptr<ISystemAbilityManager> systemAbilityManager =
150e0dac50fSopenharmony_ci            SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
151e0dac50fSopenharmony_ci    if (!systemAbilityManager) {
152e0dac50fSopenharmony_ci        WLOGFE("Failed to get system ability mgr.");
153e0dac50fSopenharmony_ci        return false;
154e0dac50fSopenharmony_ci    }
155e0dac50fSopenharmony_ci    sptr<IRemoteObject> remoteObject
156e0dac50fSopenharmony_ci        = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
157e0dac50fSopenharmony_ci    if (!remoteObject) {
158e0dac50fSopenharmony_ci        WLOGFE("Failed to get display manager service.");
159e0dac50fSopenharmony_ci        return false;
160e0dac50fSopenharmony_ci    }
161e0dac50fSopenharmony_ci    auto bundleManagerServiceProxy_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
162e0dac50fSopenharmony_ci    if ((!bundleManagerServiceProxy_) || (!bundleManagerServiceProxy_->AsObject())) {
163e0dac50fSopenharmony_ci        WLOGFE("Failed to get system display manager services");
164e0dac50fSopenharmony_ci        return false;
165e0dac50fSopenharmony_ci    }
166e0dac50fSopenharmony_ci    int uid = IPCSkeleton::GetCallingUid();
167e0dac50fSopenharmony_ci    // reset ipc identity
168e0dac50fSopenharmony_ci    std::string identity = IPCSkeleton::ResetCallingIdentity();
169e0dac50fSopenharmony_ci    WLOGFI("resetCallingIdentity:%{public}s", identity.c_str());
170e0dac50fSopenharmony_ci    std::string callingBundleName;
171e0dac50fSopenharmony_ci    bundleManagerServiceProxy_->GetNameForUid(uid, callingBundleName);
172e0dac50fSopenharmony_ci    WLOGFI("get the bundle name:%{public}s", callingBundleName.c_str());
173e0dac50fSopenharmony_ci    IPCSkeleton::SetCallingIdentity(identity);
174e0dac50fSopenharmony_ci    std::string::size_type idx = callingBundleName.find(name);
175e0dac50fSopenharmony_ci    if (idx != std::string::npos) {
176e0dac50fSopenharmony_ci        return true;
177e0dac50fSopenharmony_ci    }
178e0dac50fSopenharmony_ci    return false;
179e0dac50fSopenharmony_ci}
180e0dac50fSopenharmony_ci} // namespace Rosen
181e0dac50fSopenharmony_ci} // namespace OHOS