• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 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 "upms_udmf_utils.h"
17 
18 #include "ability_manager_errors.h"
19 #include "hilog_tag_wrapper.h"
20 #include "hitrace_meter.h"
21 #include "in_process_call_wrapper.h"
22 #include "udmf_client.h"
23 #include "uri_permission_utils.h"
24 #include "uri.h"
25 
26 namespace OHOS {
27 namespace AAFwk {
28 namespace {
29 constexpr const char *UDMF_FILE_URI_ENTRY = "general.file-uri";
30 constexpr const char *UDMF_ORI_URI = "oriUri";
31 constexpr const char *FILE_SCHEME = "file";
32 }
33 
GetBatchData(const std::string & key,std::vector<std::string> & uris)34 int32_t UDMFUtils::GetBatchData(const std::string &key, std::vector<std::string> &uris)
35 {
36     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
37     TAG_LOGI(AAFwkTag::URIPERMMGR, "GetBatchData call");
38     uris.clear();
39     UDMF::QueryOption query = { .key = key };
40     std::vector<UDMF::UnifiedData> unifiedDataset;
41     auto ret = IN_PROCESS_CALL(UDMF::UdmfClient::GetInstance().GetBatchData(query, unifiedDataset));
42     if (ret != ERR_OK) {
43         TAG_LOGE(AAFwkTag::URIPERMMGR, "GetBatchData failed:%{public}d", ret);
44         return ret;
45     }
46     for (size_t i = 0; i < unifiedDataset.size(); i++) {
47         std::vector<std::shared_ptr<UDMF::UnifiedRecord>> records = unifiedDataset[i].GetRecords();
48         for (const auto &record : records) {
49             auto fileEntry = record->GetEntry(UDMF_FILE_URI_ENTRY);
50             std::shared_ptr<UDMF::Object> fileEntryObj = std::get<std::shared_ptr<UDMF::Object>>(fileEntry);
51             if (fileEntryObj == nullptr) {
52                 TAG_LOGE(AAFwkTag::URIPERMMGR, "file entry obj null");
53                 return ERR_UPMS_GET_ORI_URI_FAILED;
54             }
55             std::string oriUri;
56             fileEntryObj->GetValue(UDMF_ORI_URI, oriUri);
57             if (oriUri.empty()) {
58                 TAG_LOGE(AAFwkTag::URIPERMMGR, "get oriUri failed");
59                 return ERR_UPMS_GET_ORI_URI_FAILED;
60             }
61             Uri uri(oriUri);
62             if (uri.GetScheme() != FILE_SCHEME) {
63                 TAG_LOGE(AAFwkTag::URIPERMMGR, "not file uri:%{public}s", uri.GetScheme().c_str());
64                 return ERR_UPMS_NOT_FILE_URI;
65             }
66             uris.emplace_back(oriUri);
67         }
68     }
69     if (uris.empty()) {
70         TAG_LOGE(AAFwkTag::URIPERMMGR, "uris empty");
71         return ERR_UPMS_GET_FILE_URIS_BY_KEY_FAILED;
72     }
73     return ERR_OK;
74 }
75 
AddPrivilege(const std::string & key,uint32_t tokenId,const std::string & readPermission)76 int32_t UDMFUtils::AddPrivilege(const std::string &key, uint32_t tokenId, const std::string &readPermission)
77 {
78     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
79     TAG_LOGI(AAFwkTag::URIPERMMGR, "AddPrivilege call");
80     UDMF::QueryOption query = { .key = key };
81     UDMF::Privilege privilege = { .tokenId = tokenId, .readPermission = readPermission };
82     auto ret = IN_PROCESS_CALL(UDMF::UdmfClient::GetInstance().AddPrivilege(query, privilege));
83     if (ret != ERR_OK) {
84         TAG_LOGE(AAFwkTag::URIPERMMGR, "AddPrivilege failed:%{public}d", ret);
85     }
86     return ret;
87 }
88 
IsUdKeyCreateByCaller(uint32_t callerTokenId,const std::string & key)89 bool UDMFUtils::IsUdKeyCreateByCaller(uint32_t callerTokenId, const std::string &key)
90 {
91     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
92     auto keyAuthority =  IN_PROCESS_CALL(UDMF::UdmfClient::GetInstance().GetBundleNameByUdKey(key));
93     std::string callerAuthority;
94     UPMSUtils::GetAlterableBundleNameByTokenId(callerTokenId, callerAuthority);
95     if (callerAuthority != keyAuthority) {
96         TAG_LOGE(AAFwkTag::URIPERMMGR, "Authority: %{public}s-%{public}s",
97             keyAuthority.c_str(), callerAuthority.c_str());
98         return false;
99     }
100     return true;
101 }
102 
ProcessUdmfKey(const std::string & key,uint32_t callerTokenId,uint32_t targetTokenId,std::vector<std::string> & uris)103 int32_t UDMFUtils::ProcessUdmfKey(const std::string &key, uint32_t callerTokenId, uint32_t targetTokenId,
104     std::vector<std::string> &uris)
105 {
106     // To check if the key belong to callerTokenId
107     if (!IsUdKeyCreateByCaller(callerTokenId, key)) {
108         TAG_LOGE(AAFwkTag::URIPERMMGR, "Key is not create by caller");
109         return ERR_UPMS_KEY_IS_NOT_CREATE_BY_CALLER;
110     }
111     auto ret = AddPrivilege(key, targetTokenId, "");
112     if (ret != ERR_OK) {
113         TAG_LOGE(AAFwkTag::URIPERMMGR, "AddPrivilege failed:%{public}d", ret);
114         return ERR_UPMS_ADD_PRIVILEGED_FAILED;
115     }
116     uint32_t selfToken = IPCSkeleton::GetSelfTokenID();
117     ret = AddPrivilege(key, selfToken, "readAndKeep");
118     if (ret != ERR_OK) {
119         TAG_LOGE(AAFwkTag::URIPERMMGR, "AddPrivilege self failed:%{public}d", ret);
120         return ERR_UPMS_ADD_PRIVILEGED_FAILED;
121     }
122     ret = GetBatchData(key, uris);
123     if (ret != ERR_OK) {
124         TAG_LOGE(AAFwkTag::URIPERMMGR, "GetBatchData failed:%{public}d", ret);
125         return ERR_UPMS_GET_FILE_URIS_BY_KEY_FAILED;
126     }
127     return ERR_OK;
128 }
129 } // OHOS
130 } // AAFwk