mirror of
https://github.com/openharmony/ability_dmsfwk_lite.git
synced 2026-07-01 20:54:02 -04:00
5835905156
Signed-off-by: MisterE<smart_e@126.com> Co-Authored-By: Agent
255 lines
8.5 KiB
C
255 lines
8.5 KiB
C
/*
|
|
* Copyright (c) 2020 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "dmslite_permission.h"
|
|
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
|
|
#ifdef WEARABLE_PRODUCT
|
|
#include "bundle_manager.h"
|
|
#else
|
|
#include "bundle_inner_interface.h"
|
|
#include "bundle_manager.h"
|
|
#endif
|
|
#include "dmslite_log.h"
|
|
#include "dmslite_utils.h"
|
|
#include "samgr_lite.h"
|
|
#include "securec.h"
|
|
|
|
#define DELIMITER_LENGTH 1
|
|
#define GET_BUNDLE_WITHOUT_ABILITIES 0
|
|
#ifndef WEARABLE_PRODUCT
|
|
#define NATIVE_APPID_DIR "/system/native_appid/"
|
|
#define APPID_FILE_PREFIX "uid_"
|
|
#define APPID_FILE_SUFFIX "_appid"
|
|
#define MAX_FILE_PATH_LEN 64
|
|
#define MAX_NATIVE_SERVICE_UID 99
|
|
#endif
|
|
|
|
#ifndef WEARABLE_PRODUCT
|
|
static bool GetBmsInterface(struct BmsServerProxy **bmsInterface)
|
|
{
|
|
IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE);
|
|
if (iUnknown == NULL) {
|
|
HILOGE("[GetFeatureApi failed]");
|
|
return false;
|
|
}
|
|
|
|
int32_t errCode = iUnknown->QueryInterface(iUnknown, DEFAULT_VERSION, (void **) bmsInterface);
|
|
if (errCode != EC_SUCCESS) {
|
|
HILOGE("[QueryInterface failed]");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
static int32_t GetCalleeBundleInfo(const char *calleeBundleName, BundleInfo *bundleInfo)
|
|
{
|
|
int32_t errCode;
|
|
#ifndef WEARABLE_PRODUCT
|
|
uid_t callerUid = getuid();
|
|
if (callerUid == FOUNDATION_UID) {
|
|
struct BmsServerProxy *bmsInterface = NULL;
|
|
if (!GetBmsInterface(&bmsInterface)) {
|
|
HILOGE("[GetBmsInterface query null]");
|
|
return DMS_EC_GET_BMS_FAILURE;
|
|
}
|
|
if (calleeBundleName == NULL) {
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
errCode = bmsInterface->GetBundleInfo(calleeBundleName,
|
|
GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
} else if (callerUid == SHELL_UID) {
|
|
errCode = GetBundleInfo(calleeBundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
} else {
|
|
errCode = EC_FAILURE;
|
|
}
|
|
#else
|
|
errCode = GetBundleInfo(calleeBundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
#endif
|
|
if (errCode != EC_SUCCESS) {
|
|
HILOGE("[GetBundleInfo errCode = %d]", errCode);
|
|
return DMS_EC_GET_BUNDLEINFO_FAILURE;
|
|
}
|
|
return DMS_EC_SUCCESS;
|
|
}
|
|
|
|
static int32_t ExtractCalleeSignature(const BundleInfo *bundleInfo, const char *calleeBundleName,
|
|
const char **calleeSignature)
|
|
{
|
|
if (bundleInfo == NULL || bundleInfo->appId == NULL || calleeBundleName == NULL) {
|
|
HILOGE("[Invalid parameter]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
size_t bundleNameLen = strlen(calleeBundleName);
|
|
size_t appIdLen = strlen(bundleInfo->appId);
|
|
if (bundleNameLen + DELIMITER_LENGTH >= appIdLen) {
|
|
HILOGE("[Invalid appId format]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
if (strncmp(bundleInfo->appId, calleeBundleName, bundleNameLen) != 0 ||
|
|
bundleInfo->appId[bundleNameLen] != '_') {
|
|
HILOGE("[AppId does not start with calleeBundleName_]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
*calleeSignature = bundleInfo->appId + bundleNameLen + DELIMITER_LENGTH;
|
|
return DMS_EC_SUCCESS;
|
|
}
|
|
|
|
int32_t CheckRemotePermission(const PermissionCheckInfo *permissionCheckInfo)
|
|
{
|
|
if (permissionCheckInfo == NULL) {
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
BundleInfo bundleInfo;
|
|
if (memset_s(&bundleInfo, sizeof(BundleInfo), 0x00, sizeof(BundleInfo)) != EOK) {
|
|
HILOGE("[bundleInfo memset failed]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
int32_t ret = GetCalleeBundleInfo(permissionCheckInfo->calleeBundleName, &bundleInfo);
|
|
if (ret != DMS_EC_SUCCESS) {
|
|
return ret;
|
|
}
|
|
const char *calleeSignature = NULL;
|
|
ret = ExtractCalleeSignature(&bundleInfo, permissionCheckInfo->calleeBundleName, &calleeSignature);
|
|
if (ret != DMS_EC_SUCCESS) {
|
|
ClearBundleInfo(&bundleInfo);
|
|
return ret;
|
|
}
|
|
if (permissionCheckInfo->callerSignature == NULL || calleeSignature == NULL) {
|
|
HILOGE("[Signature is null]");
|
|
ClearBundleInfo(&bundleInfo);
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
if (strcmp(permissionCheckInfo->callerSignature, calleeSignature) != 0) {
|
|
HILOGE("[Signature unmatched]");
|
|
ClearBundleInfo(&bundleInfo);
|
|
return DMS_EC_CHECK_PERMISSION_FAILURE;
|
|
}
|
|
ClearBundleInfo(&bundleInfo);
|
|
return DMS_EC_SUCCESS;
|
|
}
|
|
|
|
static int32_t GetBundleInfoFromFile(const char *filePath, BundleInfo *bundleInfo)
|
|
{
|
|
int32_t fd = open(filePath, O_RDONLY, S_IRUSR);
|
|
if (fd < 0) {
|
|
HILOGE("[open file failed]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
int32_t fileLen = lseek(fd, 0, SEEK_END);
|
|
if (fileLen <= 0) {
|
|
HILOGE("[fileLen is invalid, fileLen=%d]", fileLen);
|
|
close(fd);
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
int32_t ret = lseek(fd, 0, SEEK_SET);
|
|
if (ret < 0) {
|
|
HILOGE("[lseek failed, ret=%d]", ret);
|
|
close(fd);
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
int32_t appIdLen = fileLen + 1;
|
|
char *appId = (char *)DMS_ALLOC(appIdLen);
|
|
if (appId == NULL) {
|
|
HILOGE("[DMS_ALLOC appId failed]");
|
|
close(fd);
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
(void)memset_s(appId, appIdLen, 0x00, appIdLen);
|
|
ret = read(fd, appId, fileLen);
|
|
if (ret < 0) {
|
|
HILOGE("[read appId failed, ret=%d]", ret);
|
|
DMS_FREE(appId);
|
|
close(fd);
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
for (; fileLen > 0; --fileLen) {
|
|
if (appId[fileLen - 1] != '\n') {
|
|
break;
|
|
}
|
|
}
|
|
appId[fileLen] = '\0';
|
|
bundleInfo->appId = appId;
|
|
close(fd);
|
|
return DMS_EC_SUCCESS;
|
|
}
|
|
|
|
static int32_t GetBundleInfoFromBms(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
|
|
{
|
|
int32_t errCode;
|
|
#ifndef WEARABLE_PRODUCT
|
|
char *bundleName = NULL;
|
|
uid_t callerUid = getuid();
|
|
if (callerUid == FOUNDATION_UID) {
|
|
/* inner-process mode */
|
|
struct BmsServerProxy *bmsServerProxy = NULL;
|
|
if (!GetBmsInterface(&bmsServerProxy)) {
|
|
HILOGE("[GetBmsInterface query null]");
|
|
return DMS_EC_GET_BMS_FAILURE;
|
|
}
|
|
if (bmsServerProxy->GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
|
|
HILOGE("[GetBundleNameForUid failed]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
errCode = bmsServerProxy->GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
} else if (callerUid == SHELL_UID) {
|
|
/* inter-process mode (mainly called in xts testsuit process started by shell) */
|
|
if (GetBundleNameForUid(callerInfo->uid, &bundleName) != EC_SUCCESS) {
|
|
HILOGE("[GetBundleNameForUid failed]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
errCode = GetBundleInfo(bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
} else {
|
|
errCode = DMS_EC_FAILURE;
|
|
}
|
|
DMS_FREE(bundleName);
|
|
#else
|
|
errCode = GetBundleInfo(callerInfo->bundleName, GET_BUNDLE_WITHOUT_ABILITIES, bundleInfo);
|
|
#endif
|
|
if (errCode != EC_SUCCESS) {
|
|
HILOGE("[GetBundleInfo failed]");
|
|
return DMS_EC_GET_BUNDLEINFO_FAILURE;
|
|
}
|
|
return DMS_EC_SUCCESS;
|
|
}
|
|
|
|
int32_t GetCallerBundleInfo(const CallerInfo *callerInfo, BundleInfo *bundleInfo)
|
|
{
|
|
if ((callerInfo == NULL) || (bundleInfo == NULL)) {
|
|
HILOGE("[invalid parameter]");
|
|
return DMS_EC_INVALID_PARAMETER;
|
|
}
|
|
#ifndef WEARABLE_PRODUCT
|
|
if (callerInfo->uid <= MAX_NATIVE_SERVICE_UID) {
|
|
char filePath[MAX_FILE_PATH_LEN] = {0};
|
|
int32_t ret = sprintf_s(filePath, MAX_FILE_PATH_LEN, "%s%s%d%s", NATIVE_APPID_DIR, APPID_FILE_PREFIX,
|
|
callerInfo->uid, APPID_FILE_SUFFIX);
|
|
if (ret < 0) {
|
|
HILOGE("[filePath sprintf failed]");
|
|
return DMS_EC_FAILURE;
|
|
}
|
|
bundleInfo->uid = callerInfo->uid;
|
|
return GetBundleInfoFromFile(filePath, bundleInfo);
|
|
}
|
|
#endif
|
|
return GetBundleInfoFromBms(callerInfo, bundleInfo);
|
|
}
|