OpenHarmony分布式调度详解|dmslite_permission.c

62 阅读3分钟

前言

本部分分析的代码位于foundation\distributedschedule\dmsfwk_lite\source\dmslite_permission.c。这个文件中的函数用于在任务调度过程中进行权限检查。其中CheckRemotePermission()执行主要的权限检查工作,GetBmsInterface()仅针对FOUNDATION用户,用于调出获取需要检查的包信息。

代码分析

获取bms接口
/**
 * 函数功能:该函数仅用于FOUNDATION用户,调用SAMGR获取Feature,从而获取包信息
 * 函数参数:
 *      bmsInterface:传入的BmsServerProxy结构体对象
 * 函数返回值:
 *      成功返回true,失败返回false
 */
static bool GetBmsInterface(struct BmsServerProxy **bmsInterface)
{
    IUnknown *iUnknown = SAMGR_GetInstance()->GetFeatureApi(BMS_SERVICE, BMS_FEATURE); // 使用SAMGR调用FeatureApi获取iUnknown对象
    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;
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。
`欢迎大家关注公众号<程序猿百晓生>,可以了解到一下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.【OpenHarmony】Uboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......
检查远程是否有与本地FAs交互的权限
/**
 * 函数功能:检查远程是否有与本地FAs交互的权限
 * 函数参数:
 *      permissionCheckInfo:检查远程权限所需的解析信息
 * 返回值:
 *      成功返回0,否则返回非零值
 * 说明:
 * 1.判断所检查的信息是否为空
 * 2.初始化包信息
 * 3.获取调用者的uid
 * 4.根据uid获取相应的包信息
 * 5.构造签名字符串,并进行签名比对
 */
int32_t CheckRemotePermission(const PermissionCheckInfo *permissionCheckInfo)
{
    if (permissionCheckInfo == NULL) { // 检查参数的有效性
        return DMS_EC_FAILURE;
    }
    BundleInfo bundleInfo; // 初始化一个包信息结构体对象,并为其填充为0
    if (memset_s(&bundleInfo, sizeof(BundleInfo), 0x00, sizeof(BundleInfo)) != EOK) {
        HILOGE("[bundleInfo memset failed]");
        return DMS_EC_FAILURE;
    }
    int32_t errCode;
#ifndef APP_PLATFORM_WATCHGT
    uid_t callerUid = getuid(); // 获取当前用户id
    if (callerUid == FOUNDATION_UID) { // 如果为FOUNDATION用户,则是进程内模式,属于进程间调用,否则属于跨进程调用
        /* inner-process mode */
        struct BmsServerProxy *bmsInterface = NULL; // 从BmsServerProxy对象中获取包信息
        if (!GetBmsInterface(&bmsInterface)) {
            HILOGE("[GetBmsInterface query null]");
            return DMS_EC_GET_BMS_FAILURE;
        }
        errCode = bmsInterface->GetBundleInfo(permissionCheckInfo->calleeBundleName,
            GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
    } else if (callerUid == SHELL_UID) { // 进程间模式,属于跨进程调用
        /* inter-process mode (mainly called in xts testsuit process started by shell) */
        errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
            GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
    } else {
        errCode = EC_FAILURE;
    }
#else
    errCode = GetBundleInfo(permissionCheckInfo->calleeBundleName,
        GET_BUNDLE_WITHOUT_ABILITIES, &bundleInfo);
#endif
    if (errCode != EC_SUCCESS) { // 如果errCode不为0,获取包信息失败
        HILOGE("[GetBundleInfo errCode = %d]", errCode);
        return DMS_EC_GET_BUNDLEINFO_FAILURE;
    }
    /* appId: bundleName + "_" + signature */
    // 签名格式为:bundleName + "_" + signature + 包名长度 + 1
    const char *calleeSignature = bundleInfo.appId + strlen(permissionCheckInfo->calleeBundleName)
        + DELIMITER_LENGTH;
    if ((permissionCheckInfo->callerSignature == NULL) || (calleeSignature == NULL)) { // 如果签名为空,返回失败错误码
        HILOGE("[Signature is null]");
        return DMS_EC_FAILURE;
    }
    if (strcmp(permissionCheckInfo->callerSignature, calleeSignature) != 0) { // 如果签名不一致,则权限检查不通过
        HILOGE("[Signature unmatched]");
        return DMS_EC_CHECK_PERMISSION_FAILURE;
    }
    return DMS_EC_SUCCESS;
}