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 
18 #include <cstring>
19 #include "securec.h"
20 
21 #include "accesstoken_kit.h"
22 #include "bundle_mgr_client.h"
23 #include "hap_token_info.h"
24 #include "ipc_skeleton.h"
25 
26 #include "asset_type.h"
27 #include "asset_log.h"
28 
29 using namespace OHOS;
30 using namespace AppExecFwk;
31 using namespace Security::AccessToken;
32 
33 namespace {
GetHapProcessInfo(int32_t userId, uint32_t tokenId, ProcessInfo *processInfo)34 int32_t GetHapProcessInfo(int32_t userId, uint32_t tokenId, ProcessInfo *processInfo)
35 {
36     HapTokenInfo hapTokenInfo;
37     int32_t ret = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
38     if (ret != RET_SUCCESS) {
39         LOGE("[FATAL]Get hap token info failed, ret = %{public}d", ret);
40         return ASSET_ACCESS_TOKEN_ERROR;
41     }
42     if (memcpy_s(processInfo->processName, processInfo->processNameLen, hapTokenInfo.bundleName.c_str(),
43         hapTokenInfo.bundleName.size()) != EOK) {
44         LOGE("[FATAL]The processName buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
45             hapTokenInfo.bundleName.size(), processInfo->processNameLen);
46         return ASSET_OUT_OF_MEMORY;
47     }
48     processInfo->processNameLen = hapTokenInfo.bundleName.size();
49 
50     AppExecFwk::BundleMgrClient bmsClient;
51     AppExecFwk::BundleInfo bundleInfo;
52     if (!bmsClient.GetBundleInfo(hapTokenInfo.bundleName, BundleFlag::GET_BUNDLE_WITH_HASH_VALUE,
53         bundleInfo, userId)) {
54         LOGE("[FATAL]Get bundle info failed!");
55         return ASSET_BMS_ERROR;
56     }
57     processInfo->hapInfo.appIndex = bundleInfo.appIndex;
58 
59     if (memcpy_s(processInfo->hapInfo.appId, processInfo->hapInfo.appIdLen, bundleInfo.appId.c_str(),
60         bundleInfo.appId.size()) != EOK) {
61         LOGE("[FATAL]The app id buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
62             bundleInfo.appId.size(), processInfo->hapInfo.appIdLen);
63         return ASSET_OUT_OF_MEMORY;
64     }
65     processInfo->hapInfo.appIdLen = bundleInfo.appId.size();
66 
67     return ASSET_SUCCESS;
68 }
69 
GetNativeProcessInfo(uint32_t tokenId, uint64_t uid, ProcessInfo *processInfo)70 int32_t GetNativeProcessInfo(uint32_t tokenId, uint64_t uid, ProcessInfo *processInfo)
71 {
72     NativeTokenInfo nativeTokenInfo;
73     int32_t ret = AccessTokenKit::GetNativeTokenInfo(tokenId, nativeTokenInfo);
74     if (ret != RET_SUCCESS) {
75         LOGE("[FATAL]Get native token info failed, ret = %{public}d", ret);
76         return ASSET_ACCESS_TOKEN_ERROR;
77     }
78 
79     if (memcpy_s(processInfo->processName, processInfo->processNameLen, nativeTokenInfo.processName.c_str(),
80         nativeTokenInfo.processName.size()) != EOK) {
81         LOGE("[FATAL]The processName buffer is too small. Expect size: %{public}zu, actual size: %{public}u",
82             nativeTokenInfo.processName.size(), processInfo->processNameLen);
83         return ASSET_OUT_OF_MEMORY;
84     }
85     processInfo->processNameLen = nativeTokenInfo.processName.size();
86     processInfo->nativeInfo.uid = uid;
87     return ASSET_SUCCESS;
88 }
89 } // namespace
90 
GetCallingProcessInfo(uint32_t userId, uint64_t uid, ProcessInfo *processInfo)91 int32_t GetCallingProcessInfo(uint32_t userId, uint64_t uid, ProcessInfo *processInfo)
92 {
93     processInfo->userId = userId;
94     auto tokenId = IPCSkeleton::GetCallingTokenID();
95     ATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
96     int32_t res = ASSET_SUCCESS;
97     switch (tokenType) {
98         case ATokenTypeEnum::TOKEN_HAP:
99             processInfo->ownerType = HAP;
100             res = GetHapProcessInfo(userId, tokenId, processInfo);
101             break;
102         case ATokenTypeEnum::TOKEN_NATIVE:
103         case ATokenTypeEnum::TOKEN_SHELL:
104             processInfo->ownerType = NATIVE;
105             res = GetNativeProcessInfo(tokenId, uid, processInfo);
106             break;
107         default:
108             LOGE("[FATAL]Invalid calling type: %{public}d", tokenType);
109             res = ASSET_INVALID_ARGUMENT;
110     }
111     return res;
112 }