往期知识点记录:
- 鸿蒙(HarmonyOS)应用层开发(北向)知识点汇总
- OpenHarmony轻量系统服务管理|samgr_server功能详解(一)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(二)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(三)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(四)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(五)
- OpenHarmony轻量系统服务管理|samgr_server功能详解(六)
- OpenHarmony分布式调度详解|dmslite.c
- OpenHarmony分布式调度详解|dmslite_feature.c 源码阅读
- OpenHarmony分布式调度详解|dmslite_session.c
- OpenHarmony分布式调度详解|dmslite_tlv_common.c
- OpenHarmony分布式调度详解|dmslite_famgr.c
- OpenHarmony分布式调度详解|dmslite_msg_handler.c
- OpenHarmony分布式调度详解|dmslite_pack.c
- OpenHarmony分布式调度详解|dmslite_permission.c
- 持续更新中……
前言
本部分分析的代码位于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;
}
检查远程是否有与本地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;
}
写在最后
如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:
- 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力。
- 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识。
- 想要获取更多完整鸿蒙最新学习资源,请看下图提示: