• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 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 "token_modify_notifier.h"
17 
18 #include "accesstoken_callback_proxys.h"
19 #include "accesstoken_id_manager.h"
20 #include "accesstoken_info_manager.h"
21 #include "accesstoken_common_log.h"
22 #include "access_token_error.h"
23 #include "hap_token_info.h"
24 #include "hap_token_info_inner.h"
25 #include "libraryloader.h"
26 #include "token_sync_kit_loader.h"
27 
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 namespace {
32 std::recursive_mutex g_instanceMutex;
33 }
34 
TokenModifyNotifier()35 TokenModifyNotifier::TokenModifyNotifier() : hasInited_(false), notifyTokenWorker_("TokenModify") {}
36 
~TokenModifyNotifier()37 TokenModifyNotifier::~TokenModifyNotifier()
38 {
39     if (!hasInited_) {
40         return;
41     }
42     this->notifyTokenWorker_.Stop();
43     this->hasInited_ = false;
44 }
45 
AddHapTokenObservation(AccessTokenID tokenID)46 void TokenModifyNotifier::AddHapTokenObservation(AccessTokenID tokenID)
47 {
48     if (AccessTokenIDManager::GetInstance().GetTokenIdType(tokenID) != TOKEN_HAP) {
49         LOGI(ATM_DOMAIN, ATM_TAG, "Observation token is not hap token");
50         return;
51     }
52     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->listLock_);
53     if (observationSet_.count(tokenID) <= 0) {
54         observationSet_.insert(tokenID);
55     }
56 }
57 
NotifyTokenDelete(AccessTokenID tokenID)58 void TokenModifyNotifier::NotifyTokenDelete(AccessTokenID tokenID)
59 {
60     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->listLock_);
61     if (observationSet_.count(tokenID) <= 0) {
62         LOGD(ATM_DOMAIN, ATM_TAG, "Hap token is not observed");
63         return;
64     }
65     observationSet_.erase(tokenID);
66     deleteTokenList_.emplace_back(tokenID);
67     NotifyTokenChangedIfNeed();
68 }
69 
NotifyTokenModify(AccessTokenID tokenID)70 void TokenModifyNotifier::NotifyTokenModify(AccessTokenID tokenID)
71 {
72     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->listLock_);
73     if (observationSet_.count(tokenID) <= 0) {
74         LOGD(ATM_DOMAIN, ATM_TAG, "Hap token is not observed");
75         return;
76     }
77     modifiedTokenList_.emplace_back(tokenID);
78     NotifyTokenChangedIfNeed();
79 }
80 
GetInstance()81 TokenModifyNotifier& TokenModifyNotifier::GetInstance()
82 {
83     static TokenModifyNotifier* instance = nullptr;
84     if (instance == nullptr) {
85         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
86         if (instance == nullptr) {
87             TokenModifyNotifier* tmp = new (std::nothrow) TokenModifyNotifier();
88             instance = std::move(tmp);
89         }
90     }
91 
92     if (!instance->hasInited_) {
93         Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(instance->initLock_);
94         if (!instance->hasInited_) {
95             instance->notifyTokenWorker_.Start(1);
96             instance->hasInited_ = true;
97         }
98     }
99 
100     return *instance;
101 }
102 
NotifyTokenSyncTask()103 void TokenModifyNotifier::NotifyTokenSyncTask()
104 {
105     LOGI(ATM_DOMAIN, ATM_TAG, "Called!");
106 
107     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->notifyLock_);
108     LOGI(ATM_DOMAIN, ATM_TAG, "Start execution!");
109     LibraryLoader loader(TOKEN_SYNC_LIBPATH);
110     TokenSyncKitInterface* tokenSyncKit = loader.GetObject<TokenSyncKitInterface>();
111     if (tokenSyncKit == nullptr) {
112         LOGE(ATM_DOMAIN, ATM_TAG, "Dlopen libtokensync_sdk failed.");
113         return;
114     }
115 
116     std::vector<AccessTokenID> deleteList;
117     std::vector<AccessTokenID> modifiedList;
118     {
119         Utils::UniqueWriteGuard<Utils::RWLock> listGuard(this->listLock_);
120         deleteList = deleteTokenList_;
121         modifiedList = modifiedTokenList_;
122         deleteTokenList_.clear();
123         modifiedTokenList_.clear();
124     }
125 
126     for (AccessTokenID deleteToken : deleteList) {
127         int ret = TOKEN_SYNC_SUCCESS;
128         if (tokenSyncCallbackObject_ != nullptr) {
129             ret = tokenSyncCallbackObject_->DeleteRemoteHapTokenInfo(deleteToken);
130         }
131         ret = tokenSyncKit->DeleteRemoteHapTokenInfo(deleteToken);
132         if (ret != TOKEN_SYNC_SUCCESS) {
133             LOGE(ATM_DOMAIN, ATM_TAG, "Fail to delete remote haptoken info, ret is %{public}d", ret);
134         }
135     }
136 
137     for (AccessTokenID modifyToken : modifiedList) {
138         HapTokenInfoForSync hapSync;
139         int ret = AccessTokenInfoManager::GetInstance().GetHapTokenSync(modifyToken, hapSync);
140         if (ret != RET_SUCCESS) {
141             LOGE(ATM_DOMAIN, ATM_TAG, "The hap token 0x%{public}x need to sync is not found!", modifyToken);
142             continue;
143         }
144         if (tokenSyncCallbackObject_ != nullptr) {
145             ret = tokenSyncCallbackObject_->UpdateRemoteHapTokenInfo(hapSync);
146         }
147         ret = tokenSyncKit->UpdateRemoteHapTokenInfo(hapSync);
148         if (ret != TOKEN_SYNC_SUCCESS) {
149             LOGE(ATM_DOMAIN, ATM_TAG, "Fail to update remote haptoken info, ret is %{public}d", ret);
150         }
151     }
152 
153     LOGI(ATM_DOMAIN, ATM_TAG, "Over!");
154 }
155 
GetRemoteHapTokenInfo(const std::string & deviceID,AccessTokenID tokenID)156 int32_t TokenModifyNotifier::GetRemoteHapTokenInfo(const std::string& deviceID, AccessTokenID tokenID)
157 {
158     if (tokenSyncCallbackObject_ != nullptr) {
159         Utils::UniqueReadGuard<Utils::RWLock> infoGuard(this->notifyLock_);
160         int32_t ret = tokenSyncCallbackObject_->GetRemoteHapTokenInfo(deviceID, tokenID);
161         if (ret != TOKEN_SYNC_OPENSOURCE_DEVICE) {
162             return ret;
163         }
164     }
165 
166     LibraryLoader loader(TOKEN_SYNC_LIBPATH);
167     TokenSyncKitInterface* tokenSyncKit = loader.GetObject<TokenSyncKitInterface>();
168     if (tokenSyncKit == nullptr) {
169         LOGE(ATM_DOMAIN, ATM_TAG, "Dlopen libtokensync_sdk failed.");
170         return ERR_LOAD_SO_FAILED;
171     }
172     return tokenSyncKit->GetRemoteHapTokenInfo(deviceID, tokenID);
173 }
174 
RegisterTokenSyncCallback(const sptr<IRemoteObject> & callback)175 int32_t TokenModifyNotifier::RegisterTokenSyncCallback(const sptr<IRemoteObject>& callback)
176 {
177     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->notifyLock_);
178     tokenSyncCallbackObject_ = new (std::nothrow) TokenSyncCallbackProxy(callback);
179     tokenSyncCallbackDeathRecipient_ = sptr<TokenSyncCallbackDeathRecipient>::MakeSptr();
180     if (tokenSyncCallbackDeathRecipient_ == nullptr) {
181         return RET_FAILED;
182     }
183     callback->AddDeathRecipient(tokenSyncCallbackDeathRecipient_);
184     LOGI(ATM_DOMAIN, ATM_TAG, "Register token sync callback successful.");
185     return ERR_OK;
186 }
187 
UnRegisterTokenSyncCallback()188 void TokenModifyNotifier::UnRegisterTokenSyncCallback()
189 {
190     Utils::UniqueWriteGuard<Utils::RWLock> infoGuard(this->notifyLock_);
191     if (tokenSyncCallbackObject_ != nullptr && tokenSyncCallbackDeathRecipient_ != nullptr) {
192         tokenSyncCallbackObject_->AsObject()->RemoveDeathRecipient(tokenSyncCallbackDeathRecipient_);
193     }
194     tokenSyncCallbackObject_ = nullptr;
195     tokenSyncCallbackDeathRecipient_ = nullptr;
196     LOGI(ATM_DOMAIN, ATM_TAG, "Unregister token sync callback successful.");
197 }
198 
NotifyTokenChangedIfNeed()199 void TokenModifyNotifier::NotifyTokenChangedIfNeed()
200 {
201     if (notifyTokenWorker_.GetCurTaskNum() > 1) {
202         LOGI(ATM_DOMAIN, ATM_TAG, " has notify task! taskNum is %{public}zu.", notifyTokenWorker_.GetCurTaskNum());
203         return;
204     }
205 
206     notifyTokenWorker_.AddTask([]() {
207         TokenModifyNotifier::GetInstance().NotifyTokenSyncTask();
208     });
209 }
210 } // namespace AccessToken
211 } // namespace Security
212 } // namespace OHOS
213