1 /*
2  * Copyright (c) 2023-2024 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 "bms_wrapper.h"
17 #include "bundle_mgr_interface.h"
18 #include "iservice_registry.h"
19 
20 #include <cstring>
21 #include "securec.h"
22 
23 #include "accesstoken_kit.h"
24 #include "bundle_mgr_client.h"
25 #include "hap_token_info.h"
26 #include "ipc_skeleton.h"
27 
28 #include "asset_type.h"
29 #include "asset_log.h"
30 
31 using namespace OHOS;
32 using namespace AppExecFwk;
33 using namespace Security::AccessToken;
34 
35 namespace {
36 constexpr int BUNDLE_MGR_SERVICE_SYS_ABILITY_ID = 401;
37 
GetBundleMgr()38 sptr<IBundleMgr> GetBundleMgr()
39 {
40     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
41     if (systemAbilityManager == nullptr) {
42         LOGE("[FATAL]systemAbilityManager is nullptr, please check.");
43         return nullptr;
44     }
45     auto bundleMgrRemoteObj = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
46     if (bundleMgrRemoteObj == nullptr) {
47         LOGE("[FATAL]bundleMgrRemoteObj is nullptr, please check.");
48         return nullptr;
49     }
50     return iface_cast<IBundleMgr>(bundleMgrRemoteObj);
51 }
52 
GetHapProcessInfo(int32_t userId,uint64_t uid,ProcessInfo * processInfo)53 int32_t GetHapProcessInfo(int32_t userId, uint64_t uid, ProcessInfo *processInfo)
54 {
55     auto bundleMgr = GetBundleMgr();
56     if (bundleMgr == nullptr) {
57         LOGE("[FATAL]bundleMgr is nullptr, please check.");
58         return ASSET_BMS_ERROR;
59     }
60     int32_t appIndex = 0;
61     std::string bundleName;
62     int32_t ret = bundleMgr->GetNameAndIndexForUid(uid, bundleName, appIndex);
63     if (ret != RET_SUCCESS) {
64         LOGE("[FATAL]GetNameAndIndexForUid get bundleName and appIndex failed. ret:%{public}d", ret);
65         return ASSET_BMS_ERROR;
66     }
67     processInfo->hapInfo.appIndex = appIndex;
68 
69     if (memcpy_s(processInfo->processName, processInfo->processNameLen, bundleName.c_str(),
70         bundleName.size()) != EOK) {
71         LOGE("[FATAL]The processName buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
72             bundleName.size(), processInfo->processNameLen);
73         return ASSET_OUT_OF_MEMORY;
74     }
75     processInfo->processNameLen = bundleName.size();
76 
77     AppExecFwk::BundleMgrClient bmsClient;
78     AppExecFwk::BundleInfo bundleInfo;
79     if (!bmsClient.GetBundleInfo(bundleName, BundleFlag::GET_BUNDLE_WITH_HASH_VALUE,
80         bundleInfo, userId)) {
81         LOGE("[FATAL]Get bundle info failed!");
82         return ASSET_BMS_ERROR;
83     }
84 
85     if (memcpy_s(processInfo->hapInfo.appId, processInfo->hapInfo.appIdLen, bundleInfo.appId.c_str(),
86         bundleInfo.appId.size()) != EOK) {
87         LOGE("[FATAL]The app id buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
88             bundleInfo.appId.size(), processInfo->hapInfo.appIdLen);
89         return ASSET_OUT_OF_MEMORY;
90     }
91     processInfo->hapInfo.appIdLen = bundleInfo.appId.size();
92 
93     return ASSET_SUCCESS;
94 }
95 
GetNativeProcessInfo(uint32_t tokenId,uint64_t uid,ProcessInfo * processInfo)96 int32_t GetNativeProcessInfo(uint32_t tokenId, uint64_t uid, ProcessInfo *processInfo)
97 {
98     NativeTokenInfo nativeTokenInfo;
99     int32_t ret = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
100     if (ret != RET_SUCCESS) {
101         LOGE("[FATAL]Get native token info failed, ret = %{public}d", ret);
102         return ASSET_ACCESS_TOKEN_ERROR;
103     }
104 
105     if (memcpy_s(processInfo->processName, processInfo->processNameLen, nativeTokenInfo.processName.c_str(),
106         nativeTokenInfo.processName.size()) != EOK) {
107         LOGE("[FATAL]The processName buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
108             nativeTokenInfo.processName.size(), processInfo->processNameLen);
109         return ASSET_OUT_OF_MEMORY;
110     }
111     processInfo->processNameLen = nativeTokenInfo.processName.size();
112     processInfo->nativeInfo.uid = uid;
113     return ASSET_SUCCESS;
114 }
115 } // namespace
116 
GetCallingProcessInfo(uint32_t userId,uint64_t uid,ProcessInfo * processInfo)117 int32_t GetCallingProcessInfo(uint32_t userId, uint64_t uid, ProcessInfo *processInfo)
118 {
119     processInfo->userId = userId;
120     auto tokenId = IPCSkeleton::GetCallingTokenID();
121     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
122     int32_t res = ASSET_SUCCESS;
123     switch (tokenType) {
124         case ATokenTypeEnum::TOKEN_HAP:
125             processInfo->ownerType = HAP;
126             res = GetHapProcessInfo(userId, uid, processInfo);
127             break;
128         case ATokenTypeEnum::TOKEN_NATIVE:
129         case ATokenTypeEnum::TOKEN_SHELL:
130             processInfo->ownerType = NATIVE;
131             res = GetNativeProcessInfo(tokenId, uid, processInfo);
132             break;
133         default:
134             LOGE("[FATAL]Invalid calling type: %{public}d", tokenType);
135             res = ASSET_INVALID_ARGUMENT;
136     }
137     return res;
138 }