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