1 /*
2 * Copyright (c) 2022 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 "uri_permission_manager_stub_impl.h"
17
18 #include "accesstoken_kit.h"
19 #include "hilog_wrapper.h"
20 #include "if_system_ability_manager.h"
21 #include "in_process_call_wrapper.h"
22 #include "ipc_skeleton.h"
23 #include "iservice_registry.h"
24 #include "os_account_manager_wrapper.h"
25 #include "singleton.h"
26 #include "system_ability_definition.h"
27 #include "want.h"
28
29 namespace OHOS {
30 namespace AAFwk {
31 const int32_t DEFAULT_USER_ID = 0;
32 using TokenId = Security::AccessToken::AccessTokenID;
33
GrantUriPermission(const Uri & uri,unsigned int flag,const TokenId fromTokenId,const TokenId targetTokenId)34 bool UriPermissionManagerStubImpl::GrantUriPermission(const Uri &uri, unsigned int flag,
35 const TokenId fromTokenId, const TokenId targetTokenId)
36 {
37 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(IPCSkeleton::GetCallingTokenID());
38 if (tokenType != Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
39 HILOG_DEBUG("caller tokenType is not native, verify failure.");
40 return false;
41 }
42
43 if ((flag & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
44 HILOG_WARN("UriPermissionManagerStubImpl::GrantUriPermission: The param flag is invalid.");
45 return false;
46 }
47 unsigned int tmpFlag = 0;
48 if (flag & Want::FLAG_AUTH_WRITE_URI_PERMISSION) {
49 tmpFlag = Want::FLAG_AUTH_WRITE_URI_PERMISSION;
50 } else {
51 tmpFlag = Want::FLAG_AUTH_READ_URI_PERMISSION;
52 }
53
54 auto storageMgrProxy = ConnectStorageManager();
55 if (storageMgrProxy == nullptr) {
56 HILOG_ERROR("ConnectStorageManager failed");
57 return false;
58 }
59 auto uriStr = uri.ToString();
60 auto ret = storageMgrProxy->CreateShareFile(uriStr, targetTokenId, tmpFlag);
61 if (ret != 0 && ret != -EEXIST) {
62 HILOG_ERROR("storageMgrProxy failed to CreateShareFile.");
63 return false;
64 }
65 std::lock_guard<std::mutex> guard(mutex_);
66 auto search = uriMap_.find(uriStr);
67 GrantInfo info = { tmpFlag, fromTokenId, targetTokenId };
68 if (search == uriMap_.end()) {
69 std::list<GrantInfo> infoList = { info };
70 uriMap_.emplace(uriStr, infoList);
71 return true;
72 }
73 auto& infoList = search->second;
74 for (auto& item : infoList) {
75 if (item.fromTokenId == fromTokenId && item.targetTokenId == targetTokenId) {
76 if ((tmpFlag & item.flag) == 0) {
77 HILOG_INFO("Update uri r/w permission.");
78 item.flag = tmpFlag;
79 }
80 HILOG_INFO("uri permission has granted, not to grant again.");
81 return true;
82 }
83 }
84 infoList.emplace_back(info);
85 return true;
86 }
87
VerifyUriPermission(const Uri & uri,unsigned int flag,const Security::AccessToken::AccessTokenID tokenId)88 bool UriPermissionManagerStubImpl::VerifyUriPermission(const Uri &uri, unsigned int flag,
89 const Security::AccessToken::AccessTokenID tokenId)
90 {
91 if ((flag & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
92 HILOG_WARN("UriPermissionManagerStubImpl:::VerifyUriPermission: The param flag is invalid.");
93 return false;
94 }
95
96 auto bms = ConnectBundleManager();
97 auto uriStr = uri.ToString();
98 if (bms) {
99 AppExecFwk::ExtensionAbilityInfo info;
100 if (!IN_PROCESS_CALL(bms->QueryExtensionAbilityInfoByUri(uriStr, GetCurrentAccountId(), info))) {
101 HILOG_DEBUG("%{public}s, Fail to get extension info from bundle manager.", __func__);
102 return false;
103 }
104 if (info.type != AppExecFwk::ExtensionAbilityType::FILESHARE) {
105 HILOG_DEBUG("%{public}s, The upms only open to FILESHARE. The type is %{public}u.", __func__, info.type);
106 return false;
107 }
108
109 if (tokenId == info.applicationInfo.accessTokenId) {
110 HILOG_DEBUG("The uri belongs to this application.");
111 return true;
112 }
113 }
114
115 std::lock_guard<std::mutex> guard(mutex_);
116 auto search = uriMap_.find(uriStr);
117 if (search == uriMap_.end()) {
118 HILOG_DEBUG("This tokenID does not have permission for this uri.");
119 return false;
120 }
121
122 unsigned int tmpFlag = 0;
123 if (flag & Want::FLAG_AUTH_WRITE_URI_PERMISSION) {
124 tmpFlag = Want::FLAG_AUTH_WRITE_URI_PERMISSION;
125 } else {
126 tmpFlag = Want::FLAG_AUTH_READ_URI_PERMISSION;
127 }
128
129 for (const auto& item : search->second) {
130 if (item.targetTokenId == tokenId &&
131 (item.flag == Want::FLAG_AUTH_WRITE_URI_PERMISSION || item.flag == tmpFlag)) {
132 HILOG_DEBUG("This tokenID have permission for this uri.");
133 return true;
134 }
135 }
136
137 HILOG_DEBUG("The application does not have permission for this URI.");
138 return false;
139 }
140
RemoveUriPermission(const TokenId tokenId)141 void UriPermissionManagerStubImpl::RemoveUriPermission(const TokenId tokenId)
142 {
143 HILOG_DEBUG("Start to remove uri permission.");
144 std::vector<std::string> uriList;
145 {
146 std::lock_guard<std::mutex> guard(mutex_);
147 for (auto iter = uriMap_.begin(); iter != uriMap_.end();) {
148 auto& list = iter->second;
149 for (auto it = list.begin(); it != list.end(); it++) {
150 if (it->targetTokenId == tokenId) {
151 HILOG_INFO("Erase an info form list.");
152 list.erase(it);
153 uriList.emplace_back(iter->first);
154 break;
155 }
156 }
157 if (list.size() == 0) {
158 uriMap_.erase(iter++);
159 } else {
160 iter++;
161 }
162 }
163 }
164
165 auto storageMgrProxy = ConnectStorageManager();
166 if (storageMgrProxy == nullptr) {
167 HILOG_ERROR("ConnectStorageManager failed");
168 return;
169 }
170
171 if (!uriList.empty()) {
172 storageMgrProxy->DeleteShareFile(tokenId, uriList);
173 }
174 }
175
ConnectBundleManager()176 sptr<AppExecFwk::IBundleMgr> UriPermissionManagerStubImpl::ConnectBundleManager()
177 {
178 HILOG_DEBUG("%{public}s is called.", __func__);
179 std::lock_guard<std::mutex> lock(bmsMutex_);
180 if (bundleManager_ == nullptr) {
181 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
182 if (!systemAbilityMgr) {
183 HILOG_ERROR("Failed to get SystemAbilityManager.");
184 return nullptr;
185 }
186
187 auto remoteObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
188 if (!remoteObj || (bundleManager_ = iface_cast<AppExecFwk::IBundleMgr>(remoteObj)) == nullptr) {
189 HILOG_ERROR("Failed to get bms.");
190 return nullptr;
191 }
192 auto self = weak_from_this();
193 const auto& onClearProxyCallback = [self](const wptr<IRemoteObject>& remote) {
194 auto impl = self.lock();
195 if (impl && impl->bundleManager_ == remote) {
196 impl->ClearBMSProxy();
197 }
198 };
199 sptr<BMSOrSMDeathRecipient> recipient(new BMSOrSMDeathRecipient(onClearProxyCallback));
200 bundleManager_->AsObject()->AddDeathRecipient(recipient);
201 }
202 HILOG_DEBUG("%{public}s end.", __func__);
203 return bundleManager_;
204 }
205
ConnectStorageManager()206 sptr<StorageManager::IStorageManager> UriPermissionManagerStubImpl::ConnectStorageManager()
207 {
208 std::lock_guard<std::mutex> lock(storageMutex_);
209 if (storageManager_ == nullptr) {
210 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
211 if (!systemAbilityMgr) {
212 HILOG_ERROR("Failed to get SystemAbilityManager.");
213 return nullptr;
214 }
215
216 auto remoteObj = systemAbilityMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
217 if (!remoteObj || (storageManager_ = iface_cast<StorageManager::IStorageManager>(remoteObj)) == nullptr) {
218 HILOG_ERROR("Failed to get storage manager.");
219 return nullptr;
220 }
221 auto self = weak_from_this();
222 const auto& onClearProxyCallback = [self](const wptr<IRemoteObject>& remote) {
223 auto impl = self.lock();
224 if (impl && impl->storageManager_ == remote) {
225 impl->ClearSMProxy();
226 }
227 };
228 sptr<BMSOrSMDeathRecipient> recipient(new BMSOrSMDeathRecipient(onClearProxyCallback));
229 storageManager_->AsObject()->AddDeathRecipient(recipient);
230 }
231 HILOG_DEBUG("%{public}s end.", __func__);
232 return storageManager_;
233 }
234
ClearBMSProxy()235 void UriPermissionManagerStubImpl::ClearBMSProxy()
236 {
237 HILOG_DEBUG("%{public}s is called.", __func__);
238 std::lock_guard<std::mutex> lock(bmsMutex_);
239 bundleManager_ = nullptr;
240 }
241
ClearSMProxy()242 void UriPermissionManagerStubImpl::ClearSMProxy()
243 {
244 HILOG_DEBUG("%{public}s is called.", __func__);
245 std::lock_guard<std::mutex> lock(bmsMutex_);
246 storageManager_ = nullptr;
247 }
248
OnRemoteDied(const wptr<IRemoteObject> & remote)249 void UriPermissionManagerStubImpl::BMSOrSMDeathRecipient::OnRemoteDied(
250 [[maybe_unused]] const wptr<IRemoteObject>& remote)
251 {
252 if (proxy_) {
253 HILOG_DEBUG("%{public}s, bms stub died.", __func__);
254 proxy_(remote);
255 }
256 }
257
GetCurrentAccountId()258 int UriPermissionManagerStubImpl::GetCurrentAccountId()
259 {
260 std::vector<int32_t> osActiveAccountIds;
261 ErrCode ret = DelayedSingleton<AppExecFwk::OsAccountManagerWrapper>::GetInstance()->
262 QueryActiveOsAccountIds(osActiveAccountIds);
263 if (ret != ERR_OK) {
264 HILOG_ERROR("QueryActiveOsAccountIds failed.");
265 return DEFAULT_USER_ID;
266 }
267 if (osActiveAccountIds.empty()) {
268 HILOG_ERROR("%{public}s, QueryActiveOsAccountIds is empty, no accounts.", __func__);
269 return DEFAULT_USER_ID;
270 }
271
272 return osActiveAccountIds.front();
273 }
274 } // namespace AAFwk
275 } // namespace OHOS
276