• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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