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
29using namespace OHOS;
30using namespace AppExecFwk;
31using namespace Security::AccessToken;
32
33namespace {
34int32_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
70int32_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
91int32_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}