• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #define LOG_TAG "KvStoreDataService"
17 
18 #include "kvstore_data_service.h"
19 
20 #include <directory_ex.h>
21 #include <file_ex.h>
22 #include <ipc_skeleton.h>
23 #include <unistd.h>
24 
25 #include <chrono>
26 #include <thread>
27 
28 #include "auth/auth_delegate.h"
29 #include "auto_launch_export.h"
30 #include "bootstrap.h"
31 #include "checker/checker_manager.h"
32 #include "communication_provider.h"
33 #include "config_factory.h"
34 #include "constant.h"
35 #include "dds_trace.h"
36 #include "device_kvstore_impl.h"
37 #include "executor_factory.h"
38 #include "if_system_ability_manager.h"
39 #include "iservice_registry.h"
40 #include "kvstore_account_observer.h"
41 #include "kvstore_app_accessor.h"
42 #include "kvstore_device_listener.h"
43 #include "kvstore_meta_manager.h"
44 #include "kvstore_utils.h"
45 #include "log_print.h"
46 #include "permission/permission.h"
47 #include "permission/permission_kit.h"
48 #include "permission_validator.h"
49 #include "process_communicator_impl.h"
50 #include "rdb_service_impl.h"
51 #include "reporter.h"
52 #include "route_head_handler_impl.h"
53 #include "system_ability_definition.h"
54 #include "uninstaller/uninstaller.h"
55 #include "upgrade_manager.h"
56 #include "user_delegate.h"
57 #include "utils/block_integer.h"
58 #include "utils/crypto.h"
59 
60 namespace OHOS::DistributedKv {
61 using json = nlohmann::json;
62 using namespace std::chrono;
63 using namespace OHOS::Security::Permission;
64 using namespace OHOS::DistributedData;
65 using KvStoreDelegateManager = DistributedDB::KvStoreDelegateManager;
66 
67 REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true);
68 
69 constexpr size_t MAX_APP_ID_LENGTH = 256;
70 
KvStoreDataService(bool runOnCreate)71 KvStoreDataService::KvStoreDataService(bool runOnCreate)
72     : SystemAbility(runOnCreate),
73       accountMutex_(),
74       deviceAccountMap_(),
75       clientDeathObserverMutex_(),
76       clientDeathObserverMap_()
77 {
78     ZLOGI("begin.");
79 }
80 
KvStoreDataService(int32_t systemAbilityId,bool runOnCreate)81 KvStoreDataService::KvStoreDataService(int32_t systemAbilityId, bool runOnCreate)
82     : SystemAbility(systemAbilityId, runOnCreate),
83       accountMutex_(),
84       deviceAccountMap_(),
85       clientDeathObserverMutex_(),
86       clientDeathObserverMap_()
87 {
88     ZLOGI("begin");
89 }
90 
~KvStoreDataService()91 KvStoreDataService::~KvStoreDataService()
92 {
93     ZLOGI("begin.");
94     deviceAccountMap_.clear();
95 }
96 
Initialize()97 void KvStoreDataService::Initialize()
98 {
99     ZLOGI("begin.");
100 #ifndef UT_TEST
101     KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default");
102 #endif
103     auto communicator = std::make_shared<AppDistributedKv::ProcessCommunicatorImpl>(RouteHeadHandlerImpl::Create);
104     auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator);
105     ZLOGI("set communicator ret:%{public}d.", static_cast<int>(ret));
106     auto syncActivationCheck = [this](const std::string &userId, const std::string &appId,
107                                    const std::string &storeId) -> bool {
108         return CheckSyncActivation(userId, appId, storeId);
109     };
110     ret = DistributedDB::KvStoreDelegateManager::SetSyncActivationCheckCallback(syncActivationCheck);
111     ZLOGI("set sync activation check callback ret:%{public}d.", static_cast<int>(ret));
112 
113     InitSecurityAdapter();
114     KvStoreMetaManager::GetInstance().InitMetaParameter();
115     std::thread th = std::thread([]() {
116         if (KvStoreMetaManager::GetInstance().CheckRootKeyExist() == Status::SUCCESS) {
117             return;
118         }
119         constexpr int RETRY_MAX_TIMES = 100;
120         int retryCount = 0;
121         constexpr int RETRY_TIME_INTERVAL_MILLISECOND = 1 * 1000 * 1000; // retry after 1 second
122         while (retryCount < RETRY_MAX_TIMES) {
123             if (KvStoreMetaManager::GetInstance().GenerateRootKey() == Status::SUCCESS) {
124                 ZLOGI("GenerateRootKey success.");
125                 break;
126             }
127             retryCount++;
128             ZLOGE("GenerateRootKey failed.");
129             usleep(RETRY_TIME_INTERVAL_MILLISECOND);
130         }
131     });
132     th.detach();
133 
134     accountEventObserver_ = std::make_shared<KvStoreAccountObserver>(*this);
135     AccountDelegate::GetInstance()->Subscribe(accountEventObserver_);
136     deviceInnerListener_ = std::make_unique<KvStoreDeviceListener>(*this);
137     KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(deviceInnerListener_.get(), { "innerListener" });
138 }
139 
GetKvStore(const Options & options,const AppId & appId,const StoreId & storeId,std::function<void (sptr<IKvStoreImpl>)> callback)140 Status KvStoreDataService::GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId,
141                                       std::function<void(sptr<IKvStoreImpl>)> callback)
142 {
143     ZLOGI("begin.");
144     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
145     if (!appId.IsValid() || !storeId.IsValid() || options.kvStoreType != KvStoreType::MULTI_VERSION) {
146         ZLOGE("invalid argument type.");
147         return Status::INVALID_ARGUMENT;
148     }
149     KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING);
150     KvStoreParam param;
151     param.bundleName = appId.appId;
152     param.storeId = storeId.storeId;
153     const int32_t uid = IPCSkeleton::GetCallingUid();
154     param.trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid);
155     if (param.trueAppId.empty()) {
156         ZLOGW("appId:%{public}s, uid:%{public}d, PERMISSION_DENIED", appId.appId.c_str(), uid);
157         return Status::PERMISSION_DENIED;
158     }
159 
160     param.userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
161     SecretKeyPara keyPara;
162     Status status = KvStoreDataService::GetSecretKey(options, param, keyPara);
163     if (status != Status::SUCCESS) {
164         callback(nullptr);
165         return status;
166     }
167 
168     auto it = deviceAccountMap_.find(param.userId);
169     if (it == deviceAccountMap_.end()) {
170         auto result = deviceAccountMap_.emplace(std::piecewise_construct,
171             std::forward_as_tuple(param.userId), std::forward_as_tuple(param.userId));
172         if (!result.second) {
173             ZLOGE("emplace failed.");
174             FaultMsg msg = {FaultType::RUNTIME_FAULT, "user", __FUNCTION__, Fault::RF_GET_DB};
175             Reporter::GetInstance()->ServiceFault()->Report(msg);
176             callback(nullptr);
177             return Status::ERROR;
178         }
179         it = result.first;
180     }
181 
182     sptr<KvStoreImpl> store;
183     param.status = (it->second).GetKvStore(options, param.bundleName, param.storeId, uid, keyPara.secretKey, store);
184     if (keyPara.outdated) {
185         KvStoreMetaManager::GetInstance().ReKey(param.userId, param.bundleName, param.storeId,
186             KvStoreAppManager::ConvertPathType(param.uid, param.bundleName, options.securityLevel), store);
187     }
188 
189     ZLOGD("get kvstore return status:%d, userId:[%s], bundleName:[%s].",
190         param.status, KvStoreUtils::ToBeAnonymous(param.userId).c_str(),  appId.appId.c_str());
191     if (param.status == Status::SUCCESS) {
192         callback(std::move(store));
193         return UpdateMetaData(options, param, keyPara.metaKey, it->second);
194     }
195     param.status = GetKvStoreFailDo(options, param, keyPara, it->second, store);
196     callback(std::move(store));
197     return param.status;
198 }
199 
GetSingleKvStore(const Options & options,const AppId & appId,const StoreId & storeId,std::function<void (sptr<ISingleKvStore>)> callback)200 Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId &appId, const StoreId &storeId,
201                                             std::function<void(sptr<ISingleKvStore>)> callback)
202 {
203     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
204     ZLOGI("begin.");
205     KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING);
206     KvStoreParam param;
207     Status status = FillStoreParam(options, appId, storeId, param);
208     if (status != Status::SUCCESS) {
209         callback(nullptr);
210         return status;
211     }
212 
213     SecretKeyPara keyPara;
214     status = KvStoreDataService::GetSecretKey(options, param, keyPara);
215     if (status != Status::SUCCESS) {
216         callback(nullptr);
217         return status;
218     }
219 
220     auto it = deviceAccountMap_.find(param.userId);
221     if (it == deviceAccountMap_.end()) {
222         auto result = deviceAccountMap_.emplace(std::piecewise_construct,
223             std::forward_as_tuple(param.userId), std::forward_as_tuple(param.userId));
224         if (!result.second) {
225             ZLOGE("emplace failed.");
226             callback(nullptr);
227             return Status::ERROR;
228         }
229         it = result.first;
230     }
231     sptr<SingleKvStoreImpl> store;
232     param.status =
233         (it->second).GetKvStore(options, param.bundleName, param.storeId, param.uid, keyPara.secretKey, store);
234     if (keyPara.outdated) {
235         KvStoreMetaManager::GetInstance().ReKey(param.userId, param.bundleName, param.storeId,
236             KvStoreAppManager::ConvertPathType(param.uid, param.bundleName, options.securityLevel), store);
237     }
238     if (param.status == Status::SUCCESS) {
239         status = UpdateMetaData(options, param, keyPara.metaKey, it->second);
240         if (status != Status::SUCCESS) {
241             ZLOGE("failed to write meta");
242             callback(nullptr);
243             return status;
244         }
245         callback(std::move(store));
246         return status;
247     }
248 
249     param.status =  GetSingleKvStoreFailDo(options, param, keyPara, it->second, store);
250     callback(std::move(store));
251     return param.status;
252 }
253 
FillStoreParam(const Options & options,const AppId & appId,const StoreId & storeId,KvStoreParam & param)254 Status KvStoreDataService::FillStoreParam(
255     const Options &options, const AppId &appId, const StoreId &storeId, KvStoreParam &param)
256 {
257     if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType()
258         || options.kvStoreType == KvStoreType::MULTI_VERSION) {
259         ZLOGE("invalid argument type.");
260         return Status::INVALID_ARGUMENT;
261     }
262     param.bundleName = appId.appId;
263     param.storeId = storeId.storeId;
264     param.uid = IPCSkeleton::GetCallingUid();
265     param.trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, param.uid);
266     ZLOGI("%{public}s, %{public}s", param.trueAppId.c_str(), param.bundleName.c_str());
267     if (param.trueAppId.empty()) {
268         ZLOGW("appId:%{public}s, uid:%{public}d, PERMISSION_DENIED", appId.appId.c_str(), param.uid);
269         return PERMISSION_DENIED;
270     }
271 
272     param.userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(param.uid);
273     return SUCCESS;
274 }
275 
GetSecretKey(const Options & options,const KvStoreParam & kvParas,SecretKeyPara & secretKeyParas)276 Status KvStoreDataService::GetSecretKey(const Options &options, const KvStoreParam &kvParas,
277     SecretKeyPara &secretKeyParas)
278 {
279     std::string bundleName = kvParas.bundleName;
280     std::string storeIdTmp = kvParas.storeId;
281     std::lock_guard<std::mutex> lg(accountMutex_);
282     auto metaKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp);
283     if (!CheckOptions(options, metaKey)) {
284         ZLOGE("encrypt type or kvStore type is not the same");
285         return Status::INVALID_ARGUMENT;
286     }
287     std::vector<uint8_t> secretKey;
288     std::unique_ptr<std::vector<uint8_t>, void (*)(std::vector<uint8_t> *)> cleanGuard(
289         &secretKey, [](std::vector<uint8_t> *ptr) { ptr->assign(ptr->size(), 0); });
290 
291     std::vector<uint8_t> metaSecretKey;
292     std::string secretKeyFile;
293     if (options.kvStoreType == KvStoreType::MULTI_VERSION) {
294         metaSecretKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp, "KEY");
295         secretKeyFile = KvStoreMetaManager::GetSecretKeyFile(kvParas.userId, bundleName, storeIdTmp,
296             KvStoreAppManager::ConvertPathType(kvParas.uid, bundleName, options.securityLevel));
297     } else {
298         metaSecretKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp, "SINGLE_KEY");
299         secretKeyFile = KvStoreMetaManager::GetSecretSingleKeyFile(kvParas.userId, bundleName, storeIdTmp,
300             KvStoreAppManager::ConvertPathType(kvParas.uid, bundleName, options.securityLevel));
301     }
302 
303     bool outdated = false;
304     Status alreadyCreated = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaSecretKey, CHECK_EXIST_LOCAL);
305     if (options.encrypt) {
306         ZLOGI("Getting secret key");
307         Status recStatus = RecoverSecretKey(alreadyCreated, outdated, metaSecretKey, secretKey, secretKeyFile);
308         if (recStatus != Status::SUCCESS) {
309             return recStatus;
310         }
311     } else {
312         if (alreadyCreated == Status::SUCCESS || FileExists(secretKeyFile)) {
313             ZLOGW("try to get an encrypted store with false option encrypt parameter");
314             return Status::CRYPT_ERROR;
315         }
316     }
317 
318     SecretKeyPara kvStoreSecretKey;
319     kvStoreSecretKey.metaKey = metaKey;
320     kvStoreSecretKey.secretKey = secretKey;
321     kvStoreSecretKey.metaSecretKey = metaSecretKey;
322     kvStoreSecretKey.secretKeyFile = secretKeyFile;
323     kvStoreSecretKey.alreadyCreated = alreadyCreated;
324     kvStoreSecretKey.outdated = outdated;
325     secretKeyParas = kvStoreSecretKey;
326 
327     return Status::SUCCESS;
328 }
329 
RecoverSecretKey(const Status & alreadyCreated,bool & outdated,const std::vector<uint8_t> & metaSecretKey,std::vector<uint8_t> & secretKey,const std::string & secretKeyFile)330 Status KvStoreDataService::RecoverSecretKey(const Status &alreadyCreated, bool &outdated,
331     const std::vector<uint8_t> &metaSecretKey, std::vector<uint8_t> &secretKey, const std::string &secretKeyFile)
332 {
333     if (alreadyCreated != Status::SUCCESS) {
334         KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile(
335             secretKeyFile, metaSecretKey, secretKey, outdated);
336         if (secretKey.empty()) {
337             ZLOGI("new secret key");
338             secretKey = Crypto::Random(32); // 32 is key length
339             KvStoreMetaManager::GetInstance().WriteSecretKeyToMeta(metaSecretKey, secretKey);
340             KvStoreMetaManager::GetInstance().WriteSecretKeyToFile(secretKeyFile, secretKey);
341         }
342     } else {
343         KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(metaSecretKey, secretKey, outdated);
344         if (secretKey.empty()) {
345             ZLOGW("get secret key from meta failed, try to recover");
346             KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile(
347                 secretKeyFile, metaSecretKey, secretKey, outdated);
348         }
349         if (secretKey.empty()) {
350             ZLOGW("recover failed");
351             return Status::CRYPT_ERROR;
352         }
353         KvStoreMetaManager::GetInstance().WriteSecretKeyToFile(secretKeyFile, secretKey);
354     }
355     return Status::SUCCESS;
356 }
357 
UpdateMetaData(const Options & options,const KvStoreParam & kvParas,const std::vector<uint8_t> & metaKey,KvStoreUserManager & kvStoreUserManager)358 Status KvStoreDataService::UpdateMetaData(const Options &options, const KvStoreParam &kvParas,
359     const std::vector<uint8_t> &metaKey, KvStoreUserManager &kvStoreUserManager)
360 {
361     auto localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId();
362     if (localDeviceId.empty()) {
363         ZLOGE("failed to get local device id");
364         return Status::ERROR;
365     }
366     KvStoreMetaData metaData;
367     metaData.appId = kvParas.trueAppId;
368     metaData.appType = "harmony";
369     metaData.bundleName = kvParas.bundleName;
370     metaData.deviceAccountId = kvParas.userId;
371     metaData.deviceId = localDeviceId;
372     metaData.isAutoSync = options.autoSync;
373     metaData.isBackup = options.backup;
374     metaData.isEncrypt = options.encrypt;
375     metaData.kvStoreType = options.kvStoreType;
376     metaData.schema = options.schema;
377     metaData.storeId = kvParas.storeId;
378     metaData.userId = AccountDelegate::GetInstance()->GetCurrentAccountId(kvParas.bundleName);
379     metaData.uid = IPCSkeleton::GetCallingUid();
380     metaData.version = STORE_VERSION;
381     metaData.securityLevel = options.securityLevel;
382     metaData.dataDir = kvStoreUserManager.GetDbDir(kvParas.bundleName, options);
383 
384     std::string jsonStr = metaData.Marshal();
385     std::vector<uint8_t> jsonVec(jsonStr.begin(), jsonStr.end());
386     return KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, UPDATE, jsonVec);
387 }
388 
GetKvStoreFailDo(const Options & options,const KvStoreParam & kvParas,SecretKeyPara & secKeyParas,KvStoreUserManager & kvUserManager,sptr<KvStoreImpl> & store)389 Status KvStoreDataService::GetKvStoreFailDo(const Options &options, const KvStoreParam &kvParas,
390     SecretKeyPara &secKeyParas, KvStoreUserManager &kvUserManager, sptr<KvStoreImpl> &store)
391 {
392     Status statusTmp = kvParas.status;
393     Status getKvStoreStatus = statusTmp;
394     int32_t path = KvStoreAppManager::ConvertPathType(kvParas.uid, kvParas.bundleName, options.securityLevel);
395     ZLOGW("getKvStore failed with status %d", static_cast<int>(getKvStoreStatus));
396     if (getKvStoreStatus == Status::CRYPT_ERROR && options.encrypt) {
397         if (secKeyParas.alreadyCreated != Status::SUCCESS) {
398             // create encrypted store failed, remove secret key
399             KvStoreMetaManager::GetInstance().RemoveSecretKey(kvParas.uid, kvParas.bundleName, kvParas.storeId);
400             return Status::ERROR;
401         }
402         // get existing encrypted store failed, retry with key stored in file
403         Status status = KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile(
404             secKeyParas.secretKeyFile, secKeyParas.metaSecretKey, secKeyParas.secretKey, secKeyParas.outdated);
405         if (status != Status::SUCCESS) {
406             store = nullptr;
407             return Status::CRYPT_ERROR;
408         }
409         // here callback is called twice
410         statusTmp = kvUserManager.GetKvStore(
411             options, kvParas.bundleName, kvParas.storeId, kvParas.uid, secKeyParas.secretKey, store);
412         if (secKeyParas.outdated) {
413             KvStoreMetaManager::GetInstance().ReKey(kvParas.userId, kvParas.bundleName, kvParas.storeId, path, store);
414         }
415     }
416 
417     // if kvstore damaged and no backup file, then return DB_ERROR
418     if (statusTmp != Status::SUCCESS && getKvStoreStatus == Status::CRYPT_ERROR) {
419         // if backup file not exist, dont need recover
420         if (!CheckBackupFileExist(kvParas.userId, kvParas.bundleName, kvParas.storeId, path)) {
421             return Status::CRYPT_ERROR;
422         }
423         // remove damaged database
424         if (DeleteKvStoreOnly(kvParas.storeId, kvParas.uid, kvParas.bundleName) != Status::SUCCESS) {
425             ZLOGE("DeleteKvStoreOnly failed.");
426             return Status::DB_ERROR;
427         }
428         // recover database
429         return RecoverKvStore(options, kvParas.bundleName, kvParas.storeId, secKeyParas.secretKey, store);
430     }
431     return statusTmp;
432 }
433 
GetSingleKvStoreFailDo(const Options & options,const KvStoreParam & kvParas,SecretKeyPara & secKeyParas,KvStoreUserManager & kvUserManager,sptr<SingleKvStoreImpl> & kvStore)434 Status KvStoreDataService::GetSingleKvStoreFailDo(const Options &options, const KvStoreParam &kvParas,
435     SecretKeyPara &secKeyParas, KvStoreUserManager &kvUserManager, sptr<SingleKvStoreImpl> &kvStore)
436 {
437     Status statusTmp = kvParas.status;
438     Status getKvStoreStatus = statusTmp;
439     int32_t path = KvStoreAppManager::ConvertPathType(kvParas.uid, kvParas.bundleName, options.securityLevel);
440     ZLOGW("getKvStore failed with status %d", static_cast<int>(getKvStoreStatus));
441     if (getKvStoreStatus == Status::CRYPT_ERROR && options.encrypt) {
442         if (secKeyParas.alreadyCreated != Status::SUCCESS) {
443             // create encrypted store failed, remove secret key
444             KvStoreMetaManager::GetInstance().RemoveSecretKey(kvParas.uid, kvParas.bundleName, kvParas.storeId);
445             return Status::ERROR;
446         }
447         // get existing encrypted store failed, retry with key stored in file
448         Status status = KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile(
449             secKeyParas.secretKeyFile, secKeyParas.metaSecretKey, secKeyParas.secretKey, secKeyParas.outdated);
450         if (status != Status::SUCCESS) {
451             kvStore = nullptr;
452             return Status::CRYPT_ERROR;
453         }
454         // here callback is called twice
455         statusTmp = kvUserManager.GetKvStore(
456             options, kvParas.bundleName, kvParas.storeId, kvParas.uid, secKeyParas.secretKey, kvStore);
457         if (secKeyParas.outdated) {
458             KvStoreMetaManager::GetInstance().ReKey(kvParas.userId, kvParas.bundleName, kvParas.storeId, path, kvStore);
459         }
460     }
461 
462     // if kvstore damaged and no backup file, then return DB_ERROR
463     if (statusTmp != Status::SUCCESS && getKvStoreStatus == Status::CRYPT_ERROR) {
464         // if backup file not exist, dont need recover
465         if (!CheckBackupFileExist(kvParas.userId, kvParas.bundleName, kvParas.storeId, path)) {
466             return Status::CRYPT_ERROR;
467         }
468         // remove damaged database
469         if (DeleteKvStoreOnly(kvParas.storeId, kvParas.uid, kvParas.bundleName) != Status::SUCCESS) {
470             ZLOGE("DeleteKvStoreOnly failed.");
471             return Status::DB_ERROR;
472         }
473         // recover database
474         return RecoverKvStore(options, kvParas.bundleName, kvParas.storeId, secKeyParas.secretKey, kvStore);
475     }
476     return statusTmp;
477 }
478 
CheckOptions(const Options & options,const std::vector<uint8_t> & metaKey) const479 bool KvStoreDataService::CheckOptions(const Options &options, const std::vector<uint8_t> &metaKey) const
480 {
481     ZLOGI("begin.");
482     KvStoreMetaData metaData;
483     metaData.version = 0;
484     Status statusTmp = KvStoreMetaManager::GetInstance().GetKvStoreMeta(metaKey, metaData);
485     if (statusTmp == Status::KEY_NOT_FOUND) {
486         ZLOGI("get metaKey not found.");
487         return true;
488     }
489     if (statusTmp != Status::SUCCESS) {
490         ZLOGE("get metaKey failed.");
491         return false;
492     }
493     ZLOGI("metaData encrypt is %d, kvStore type is %d, options encrypt is %d, kvStore type is %d",
494           static_cast<int>(metaData.isEncrypt), static_cast<int>(metaData.kvStoreType),
495           static_cast<int>(options.encrypt), static_cast<int>(options.kvStoreType));
496     if (options.encrypt != metaData.isEncrypt) {
497         ZLOGE("checkOptions encrypt type is not the same.");
498         return false;
499     }
500 
501     if (options.kvStoreType != metaData.kvStoreType && metaData.version != 0) {
502         ZLOGE("checkOptions kvStoreType is not the same.");
503         return false;
504     }
505     ZLOGI("end.");
506     return true;
507 }
508 
CheckBackupFileExist(const std::string & userId,const std::string & bundleName,const std::string & storeId,int pathType)509 bool KvStoreDataService::CheckBackupFileExist(const std::string &userId, const std::string &bundleName,
510                                               const std::string &storeId, int pathType)
511 {
512     std::initializer_list<std::string> backupFileNameList = {Constant::DEFAULT_GROUP_ID, "_",
513         bundleName, "_", storeId};
514     auto backupFileName = Constant::Concatenate(backupFileNameList);
515     std::initializer_list<std::string> backFileList = {BackupHandler::GetBackupPath(userId, pathType),
516         "/", BackupHandler::GetHashedBackupName(backupFileName)};
517     auto backFilePath = Constant::Concatenate(backFileList);
518     if (!BackupHandler::FileExists(backFilePath)) {
519         ZLOGE("BackupHandler file is not exist.");
520         return false;
521     }
522     return true;
523 }
524 template<typename  T>
RecoverKvStore(const Options & options,const std::string & bundleName,const std::string & storeId,const std::vector<uint8_t> & secretKey,sptr<T> & kvStore)525 Status KvStoreDataService::RecoverKvStore(const Options &options, const std::string &bundleName,
526     const std::string &storeId, const std::vector<uint8_t> &secretKey, sptr<T> &kvStore)
527 {
528     // restore database
529     std::string storeIdTmp = storeId;
530     Options optionsTmp = options;
531     optionsTmp.createIfMissing = true;
532     const int32_t uid = IPCSkeleton::GetCallingUid();
533     const std::string deviceAccountId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
534     auto it = deviceAccountMap_.find(deviceAccountId);
535     if (it == deviceAccountMap_.end()) {
536         ZLOGD("deviceAccountId not found");
537         return Status::INVALID_ARGUMENT;
538     }
539 
540     Status statusTmp = (it->second).GetKvStore(optionsTmp, bundleName, storeIdTmp, uid, secretKey, kvStore);
541     // restore database failed
542     if (statusTmp != Status::SUCCESS || kvStore == nullptr) {
543         ZLOGE("RecoverSingleKvStore reget GetSingleKvStore failed.");
544         return Status::DB_ERROR;
545     }
546     // recover database from backup file
547     bool importRet = kvStore->Import(bundleName);
548     if (!importRet) {
549         ZLOGE("RecoverSingleKvStore Import failed.");
550         return Status::RECOVER_FAILED;
551     }
552     ZLOGD("RecoverSingleKvStore Import success.");
553     return Status::RECOVER_SUCCESS;
554 }
555 
GetAllKvStoreId(const AppId & appId,std::function<void (Status,std::vector<StoreId> &)> callback)556 void KvStoreDataService::GetAllKvStoreId(
557     const AppId &appId, std::function<void(Status, std::vector<StoreId> &)> callback)
558 {
559     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
560     ZLOGI("GetAllKvStoreId begin.");
561     std::string bundleName = Constant::TrimCopy<std::string>(appId.appId);
562     std::vector<StoreId> storeIdList;
563     if (bundleName.empty() || bundleName.size() > MAX_APP_ID_LENGTH) {
564         ZLOGE("invalid appId.");
565         callback(Status::INVALID_ARGUMENT, storeIdList);
566         return;
567     }
568 
569     auto &metaKvStoreDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore();
570     if (metaKvStoreDelegate == nullptr) {
571         ZLOGE("metaKvStoreDelegate is null");
572         callback(Status::DB_ERROR, storeIdList);
573         return;
574     }
575 
576     const int32_t uid = IPCSkeleton::GetCallingUid();
577     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
578     std::vector<DistributedDB::Entry> dbEntries;
579     DistributedDB::DBStatus dbStatus;
580     DistributedDB::Key dbKey = KvStoreMetaRow::GetKeyFor(DeviceKvStoreImpl::GetLocalDeviceId() +
581         Constant::KEY_SEPARATOR + userId + Constant::KEY_SEPARATOR +
582         "default" + Constant::KEY_SEPARATOR + bundleName + Constant::KEY_SEPARATOR);
583     DdsTrace traceDelegate(std::string(LOG_TAG "Delegate::") + std::string(__FUNCTION__));
584     dbStatus = metaKvStoreDelegate->GetEntries(dbKey, dbEntries);
585     if (dbStatus != DistributedDB::DBStatus::OK) {
586         ZLOGE("GetEntries delegate return error: %d.", static_cast<int>(dbStatus));
587         if (dbEntries.empty()) {
588             callback(Status::SUCCESS, storeIdList);
589         } else {
590             callback(Status::DB_ERROR, storeIdList);
591         }
592         return;
593     }
594 
595     for (const auto &entry : dbEntries) {
596         std::string keyStr = std::string(entry.key.begin(), entry.key.end());
597         size_t pos = keyStr.find_last_of(Constant::KEY_SEPARATOR);
598         if (pos == std::string::npos) {
599             continue;
600         }
601         StoreId storeId;
602         storeId.storeId = keyStr.substr(pos + 1);
603         storeIdList.push_back(storeId);
604     }
605     callback(Status::SUCCESS, storeIdList);
606 }
607 
CloseKvStore(const AppId & appId,const StoreId & storeId)608 Status KvStoreDataService::CloseKvStore(const AppId &appId, const StoreId &storeId)
609 {
610     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
611     ZLOGI("begin.");
612     if (!appId.IsValid() || !storeId.IsValid()) {
613         ZLOGE("invalid bundleName.");
614         return Status::INVALID_ARGUMENT;
615     }
616 
617     const int32_t uid = IPCSkeleton::GetCallingUid();
618     std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid);
619     if (trueAppId.empty()) {
620         ZLOGW("check appId:%{public}s uid:%{public}d failed.", appId.appId.c_str(), uid);
621         return Status::PERMISSION_DENIED;
622     }
623     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
624     std::lock_guard<std::mutex> lg(accountMutex_);
625     auto it = deviceAccountMap_.find(userId);
626     if (it != deviceAccountMap_.end()) {
627         Status status = (it->second).CloseKvStore(appId.appId, storeId.storeId);
628         if (status != Status::STORE_NOT_OPEN) {
629             return status;
630         }
631     }
632     FaultMsg msg = {FaultType::RUNTIME_FAULT, "user", __FUNCTION__, Fault::RF_CLOSE_DB};
633     Reporter::GetInstance()->ServiceFault()->Report(msg);
634     ZLOGE("return STORE_NOT_OPEN.");
635     return Status::STORE_NOT_OPEN;
636 }
637 
638 /* close all opened kvstore */
CloseAllKvStore(const AppId & appId)639 Status KvStoreDataService::CloseAllKvStore(const AppId &appId)
640 {
641     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
642     ZLOGD("begin.");
643     if (!appId.IsValid()) {
644         ZLOGE("invalid bundleName.");
645         return Status::INVALID_ARGUMENT;
646     }
647     const int32_t uid = IPCSkeleton::GetCallingUid();
648     std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid);
649     if (trueAppId.empty()) {
650         ZLOGW("check appId:%{public}s uid:%{public}d failed.", appId.appId.c_str(), uid);
651         return Status::PERMISSION_DENIED;
652     }
653 
654     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
655     std::lock_guard<std::mutex> lg(accountMutex_);
656     auto it = deviceAccountMap_.find(userId);
657     if (it != deviceAccountMap_.end()) {
658         return (it->second).CloseAllKvStore(appId.appId);
659     }
660     ZLOGE("store not open.");
661     return Status::STORE_NOT_OPEN;
662 }
663 
DeleteKvStore(const AppId & appId,const StoreId & storeId)664 Status KvStoreDataService::DeleteKvStore(const AppId &appId, const StoreId &storeId)
665 {
666     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
667     if (!appId.IsValid()) {
668         ZLOGE("invalid bundleName.");
669         return Status::INVALID_ARGUMENT;
670     }
671     int32_t uid = IPCSkeleton::GetCallingUid();
672     if (!CheckerManager::GetInstance().IsValid(appId.appId, uid)) {
673         ZLOGE("get appId failed.");
674         return Status::PERMISSION_DENIED;
675     }
676 
677     // delete the backup file
678     std::initializer_list<std::string> backFileList = {
679         AccountDelegate::GetInstance()->GetCurrentAccountId(), "_", appId.appId, "_", storeId.storeId};
680     auto backupFileName = Constant::Concatenate(backFileList);
681     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
682     std::initializer_list<std::string> backPathListDE = {BackupHandler::GetBackupPath(userId,
683         KvStoreAppManager::PATH_DE), "/", BackupHandler::GetHashedBackupName(backupFileName)};
684     auto backFilePath = Constant::Concatenate(backPathListDE);
685     if (!BackupHandler::RemoveFile(backFilePath)) {
686         ZLOGE("DeleteKvStore RemoveFile backFilePath failed.");
687     }
688     std::initializer_list<std::string> backPathListCE = {BackupHandler::GetBackupPath(userId,
689         KvStoreAppManager::PATH_CE), "/", BackupHandler::GetHashedBackupName(backupFileName)};
690     backFilePath = Constant::Concatenate(backPathListCE);
691     if (!BackupHandler::RemoveFile(backFilePath)) {
692         ZLOGE("DeleteKvStore RemoveFile backFilePath failed.");
693     }
694     return DeleteKvStore(appId.appId, storeId);
695 }
696 
697 /* delete all kv store */
DeleteAllKvStore(const AppId & appId)698 Status KvStoreDataService::DeleteAllKvStore(const AppId &appId)
699 {
700     DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__));
701     ZLOGI("%s", appId.appId.c_str());
702     if (!appId.IsValid()) {
703         ZLOGE("invalid bundleName.");
704         return Status::INVALID_ARGUMENT;
705     }
706 
707     int32_t uid = IPCSkeleton::GetCallingUid();
708     if (!CheckerManager::GetInstance().IsValid(appId.appId, uid)) {
709         ZLOGE("check appId:%{public}s uid:%{public}d failed.", appId.appId.c_str(), uid);
710         return Status::PERMISSION_DENIED;
711     }
712 
713     Status statusTmp;
714     std::vector<StoreId> existStoreIds;
715     GetAllKvStoreId(appId, [&statusTmp, &existStoreIds](Status status, std::vector<StoreId> &storeIds) {
716         statusTmp = status;
717         existStoreIds = std::move(storeIds);
718     });
719 
720     if (statusTmp != Status::SUCCESS) {
721         ZLOGE("%s, error: %d ", appId.appId.c_str(), static_cast<int>(statusTmp));
722         return statusTmp;
723     }
724 
725     for (const auto &storeId : existStoreIds) {
726         statusTmp = DeleteKvStore(appId, storeId);
727         if (statusTmp != Status::SUCCESS) {
728             ZLOGE("%s, error: %d ", appId.appId.c_str(), static_cast<int>(statusTmp));
729             return statusTmp;
730         }
731     }
732 
733     return statusTmp;
734 }
735 
736 /* RegisterClientDeathObserver */
RegisterClientDeathObserver(const AppId & appId,sptr<IRemoteObject> observer)737 Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr<IRemoteObject> observer)
738 {
739     ZLOGD("begin.");
740     KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING);
741     if (!appId.IsValid()) {
742         ZLOGE("invalid bundleName.");
743         return Status::INVALID_ARGUMENT;
744     }
745 
746     int32_t uid = IPCSkeleton::GetCallingUid();
747     if (!CheckerManager::GetInstance().IsValid(appId.appId, uid)) {
748         ZLOGE("no permission bundleName:%{public}s, uid:%{public}d.", appId.appId.c_str(), uid);
749         return Status::PERMISSION_DENIED;
750     }
751 
752     std::lock_guard<std::mutex> lg(clientDeathObserverMutex_);
753     auto it = clientDeathObserverMap_.emplace(std::piecewise_construct, std::forward_as_tuple(appId.appId),
754         std::forward_as_tuple(appId, uid, *this, std::move(observer)));
755     ZLOGI("map size: %{public}zu.", clientDeathObserverMap_.size());
756     if (!it.second) {
757         ZLOGI("insert failed");
758         return Status::ERROR;
759     }
760     ZLOGI("insert success");
761     const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId();
762     KvStoreTuple kvStoreTuple {userId, CheckerManager::GetInstance().GetAppId(appId.appId, uid)};
763     AppThreadInfo appThreadInfo {IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()};
764     PermissionValidator::RegisterPermissionChanged(kvStoreTuple, appThreadInfo);
765     return Status::SUCCESS;
766 }
767 
AppExit(const AppId & appId,pid_t uid)768 Status KvStoreDataService::AppExit(const AppId &appId, pid_t uid)
769 {
770     ZLOGI("AppExit");
771     // memory of parameter appId locates in a member of clientDeathObserverMap_ and will be freed after
772     // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation.
773     AppId appIdTmp = appId;
774     {
775         std::lock_guard<std::mutex> lg(clientDeathObserverMutex_);
776         clientDeathObserverMap_.erase(appIdTmp.appId);
777         ZLOGI("map size: %zu.", clientDeathObserverMap_.size());
778     }
779 
780     std::string trueAppId = CheckerManager::GetInstance().GetAppId(appIdTmp.appId, uid);
781     if (trueAppId.empty()) {
782         ZLOGW("check appId:%{public}s uid:%{public}d failed.", appIdTmp.appId.c_str(), uid);
783         return Status::PERMISSION_DENIED;
784     }
785     const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId(appIdTmp.appId);
786     KvStoreTuple kvStoreTuple {userId, trueAppId};
787     PermissionValidator::UnregisterPermissionChanged(kvStoreTuple);
788 
789     CloseAllKvStore(appIdTmp);
790     return Status::SUCCESS;
791 }
792 
OnDump()793 void KvStoreDataService::OnDump()
794 {
795     ZLOGD("begin.");
796 }
797 
Dump(int fd,const std::vector<std::u16string> & args)798 int KvStoreDataService::Dump(int fd, const std::vector<std::u16string> &args)
799 {
800     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
801     const int maxUid = 10000;
802     if (uid > maxUid) {
803         return 0;
804     }
805     dprintf(fd, "------------------------------------------------------------------\n");
806     dprintf(fd, "DeviceAccount count : %u\n", static_cast<uint32_t>(deviceAccountMap_.size()));
807     for (const auto &pair : deviceAccountMap_) {
808         dprintf(fd, "DeviceAccountID    : %s\n", pair.first.c_str());
809         pair.second.Dump(fd);
810     }
811     return 0;
812 }
813 
AddPermission() const814 void KvStoreDataService::AddPermission() const
815 {
816     const PermissionDef permission {
817         .permissionName = "ohos.permission.DISTRIBUTED_DATASYNC",
818         .bundleName = "ohos.distributeddata",
819         .grantMode = GrantMode::SYSTEM_GRANT,
820         .availableScope = AVAILABLE_SCOPE_ALL,
821         .label = "distributeddata",
822         .labelId = 9527,
823         .description = "distributeddata service",
824         .descriptionId = 9528
825     };
826     const std::vector<PermissionDef> permissionDefs{ permission };
827     PermissionKit::AddDefPermissions({ permission });
828     std::vector<std::string> permissions;
829     permissions.push_back(permission.permissionName);
830     PermissionKit::AddSystemGrantedReqPermissions(permission.bundleName, permissions);
831     PermissionKit::GrantSystemGrantedPermission(permission.bundleName, permission.permissionName);
832 }
833 
OnStart()834 void KvStoreDataService::OnStart()
835 {
836     ZLOGI("distributeddata service onStart");
837     static constexpr int32_t RETRY_TIMES = 10;
838     static constexpr int32_t RETRY_INTERVAL = 500 * 1000; // unit is ms
839     for (BlockInteger retry(RETRY_INTERVAL); retry < RETRY_TIMES; ++retry) {
840         if (!DeviceKvStoreImpl::GetLocalDeviceId().empty()) {
841             break;
842         }
843         ZLOGE("GetLocalDeviceId failed, retry count:%{public}d", static_cast<int>(retry));
844     }
845     Initialize();
846     Bootstrap::GetInstance().LoadComponents();
847     Bootstrap::GetInstance().LoadDirectory();
848     Bootstrap::GetInstance().LoadCheckers();
849     Bootstrap::GetInstance().LoadNetworks();
850     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
851     if (samgr != nullptr) {
852         ZLOGI("samgr exist.");
853         auto remote = samgr->CheckSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
854         auto kvDataServiceProxy = iface_cast<IKvStoreDataService>(remote);
855         if (kvDataServiceProxy != nullptr) {
856             ZLOGI("service has been registered.");
857             return;
858         }
859     }
860     CreateRdbService();
861     StartService();
862 }
863 
StartService()864 void KvStoreDataService::StartService()
865 {
866     // register this to ServiceManager.
867     bool ret = SystemAbility::Publish(this);
868     if (!ret) {
869         FaultMsg msg = {FaultType::SERVICE_FAULT, "service", __FUNCTION__, Fault::SF_SERVICE_PUBLISH};
870         Reporter::GetInstance()->ServiceFault()->Report(msg);
871     }
872     Uninstaller::GetInstance().Init(this);
873 #ifndef UT_TEST
874     // add softbus permission.
875     AddPermission();
876 #endif
877     std::string backupPath = BackupHandler::GetBackupPath(
878         AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(getuid()), KvStoreAppManager::PATH_DE);
879     ZLOGI("backupPath is : %s ", backupPath.c_str());
880     if (!ForceCreateDirectory(backupPath)) {
881         ZLOGE("backup create directory failed");
882     }
883     // Initialize meta db delegate manager.
884     KvStoreMetaManager::GetInstance().InitMetaListener();
885     KvStoreMetaManager::GetInstance().SubscribeMeta(
886         KvStoreMetaRow::KEY_PREFIX, [this](const std::vector<uint8_t> &key, const std::vector<uint8_t> &value,
887                                         CHANGE_FLAG flag) { OnStoreMetaChanged(key, value, flag); });
888     UpgradeManager::GetInstance().Init();
889     UserDelegate::GetInstance().Init();
890 
891     // subscribe account event listener to EventNotificationMgr
892     AccountDelegate::GetInstance()->SubscribeAccountEvent();
893     auto permissionCheckCallback =
894         [this](const std::string &userId, const std::string &appId, const std::string
895         &storeId, const std::string &deviceId, uint8_t flag) -> bool {
896             // temp add permission whilelist for ddmp; this should be config in ddmp manifest.
897             ZLOGD("checking sync permission start appid:%s, stid:%s.", appId.c_str(), storeId.c_str());
898             return CheckPermissions(userId, appId, storeId, deviceId, flag);
899         };
900     auto dbStatus = KvStoreDelegateManager::SetPermissionCheckCallback(permissionCheckCallback);
901     if (dbStatus != DistributedDB::DBStatus::OK) {
902         ZLOGE("SetPermissionCheck callback failed.");
903     }
904     ZLOGI("autoLaunchRequestCallback start");
905     auto autoLaunchRequestCallback =
906         [this](const std::string &identifier, DistributedDB::AutoLaunchParam &param) -> bool {
907             return ResolveAutoLaunchParamByIdentifier(identifier, param);
908         };
909     KvStoreDelegateManager::SetAutoLaunchRequestCallback(autoLaunchRequestCallback);
910 
911     backup_ = std::make_unique<BackupHandler>(this);
912     backup_->BackSchedule();
913 
914     std::thread th = std::thread([]() {
915         sleep(TEN_SEC);
916         KvStoreAppAccessor::GetInstance().EnableKvStoreAutoLaunch();
917     });
918     th.detach();
919     ZLOGI("Publish ret: %{public}d", static_cast<int>(ret));
920 }
921 
OnStoreMetaChanged(const std::vector<uint8_t> & key,const std::vector<uint8_t> & value,CHANGE_FLAG flag)922 void KvStoreDataService::OnStoreMetaChanged(
923     const std::vector<uint8_t> &key, const std::vector<uint8_t> &value, CHANGE_FLAG flag)
924 {
925     if (flag != CHANGE_FLAG::UPDATE) {
926         return;
927     }
928     StoreMetaData metaData;
929     metaData.Unmarshall({ value.begin(), value.end() });
930     ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(),
931         metaData.storeId.c_str(), metaData.isDirty);
932     if (metaData.deviceId != DeviceKvStoreImpl::GetLocalDeviceId() || metaData.deviceId.empty()) {
933         ZLOGD("ignore other device change or invalid meta device");
934         return;
935     }
936     static constexpr const char *HARMONY_APP = "harmony";
937     if (!metaData.isDirty || metaData.appType != HARMONY_APP) {
938         return;
939     }
940     ZLOGI("dirty kv store. storeId:%{public}s", metaData.storeId.c_str());
941     CloseKvStore({ metaData.bundleName }, { metaData.storeId });
942     DeleteKvStore({ metaData.bundleName }, { metaData.storeId });
943 }
944 
ResolveAutoLaunchParamByIdentifier(const std::string & identifier,DistributedDB::AutoLaunchParam & param)945 bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(
946     const std::string &identifier, DistributedDB::AutoLaunchParam &param)
947 {
948     ZLOGI("start");
949     std::map<std::string, MetaData> entries;
950     if (!KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) {
951         ZLOGE("get full meta failed");
952         return false;
953     }
954     std::string localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId();
955     for (const auto &entry : entries) {
956         auto &storeMeta = entry.second.kvStoreMetaData;
957         if ((!param.userId.empty() && (param.userId != storeMeta.deviceAccountId))
958             || (localDeviceId != storeMeta.deviceId)) {
959             // judge local userid and local meta
960             continue;
961         }
962         const std::string &itemTripleIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(
963             storeMeta.userId, storeMeta.appId, storeMeta.storeId, false);
964         const std::string &itemDualIdentifier =
965             DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier("", storeMeta.appId, storeMeta.storeId, true);
966         if (identifier == itemTripleIdentifier) {
967             // old triple tuple identifier, should SetEqualIdentifier
968             ResolveAutoLaunchCompatible(entry.second, identifier);
969         }
970         if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) {
971             ZLOGI("identifier  find");
972             DistributedDB::AutoLaunchOption option;
973             option.createIfNecessary = false;
974             option.isEncryptedDb = storeMeta.isEncrypt;
975             DistributedDB::CipherPassword password;
976             const std::vector<uint8_t> &secretKey = entry.second.secretKeyMetaData.secretKey;
977             if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) {
978                 ZLOGE("Get secret key failed.");
979             }
980             option.passwd = password;
981             option.schema = storeMeta.schema;
982             option.createDirByStoreIdOnly = true;
983             option.dataDir = storeMeta.dataDir;
984             option.secOption = KvStoreAppManager::ConvertSecurity(storeMeta.securityLevel);
985             option.isAutoSync = storeMeta.isAutoSync;
986             option.syncDualTupleMode = true; // dual tuple flag
987             param.appId = storeMeta.appId;
988             param.storeId = storeMeta.storeId;
989             param.option = option;
990             return true;
991         }
992     }
993     ZLOGI("not find identifier");
994     return false;
995 }
996 
ResolveAutoLaunchCompatible(const MetaData & meta,const std::string & identifier)997 void KvStoreDataService::ResolveAutoLaunchCompatible(const MetaData &meta, const std::string &identifier)
998 {
999     ZLOGI("AutoLaunch:peer device is old tuple, begin to open store");
1000     if (meta.kvStoreType >= KvStoreType::MULTI_VERSION) {
1001         ZLOGW("no longer support multi or higher version store type");
1002         return;
1003     }
1004 
1005     // open store and SetEqualIdentifier, then close store after 60s
1006     auto &storeMeta = meta.kvStoreMetaData;
1007     auto *delegateManager = new (std::nothrow)
1008         DistributedDB::KvStoreDelegateManager(storeMeta.appId, storeMeta.deviceAccountId);
1009     if (delegateManager == nullptr) {
1010         ZLOGE("get store delegate manager failed");
1011         return;
1012     }
1013     delegateManager->SetKvStoreConfig({ storeMeta.dataDir });
1014     Options options = {
1015         .encrypt = storeMeta.isEncrypt,
1016         .autoSync = storeMeta.isAutoSync,
1017         .securityLevel = storeMeta.securityLevel,
1018         .kvStoreType = static_cast<KvStoreType>(storeMeta.kvStoreType),
1019         .dataOwnership = true,
1020     };
1021     DistributedDB::KvStoreNbDelegate::Option dbOptions;
1022     KvStoreAppManager::InitNbDbOption(options, meta.secretKeyMetaData.secretKey, dbOptions);
1023     DistributedDB::KvStoreNbDelegate *store = nullptr;
1024     delegateManager->GetKvStore(storeMeta.storeId, dbOptions,
1025         [&identifier, &store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate) {
1026             ZLOGI("temporary open db for equal identifier, ret:%{public}d", status);
1027             if (delegate != nullptr) {
1028                 KvStoreTuple tuple = { storeMeta.deviceAccountId, storeMeta.appId, storeMeta.storeId };
1029                 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP);
1030                 UpgradeManager::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP);
1031                 store = delegate;
1032             }
1033         });
1034     KvStoreTask delayTask([delegateManager, store]() {
1035         constexpr const int CLOSE_STORE_DELAY_TIME = 60; // unit: seconds
1036         std::this_thread::sleep_for(std::chrono::seconds(CLOSE_STORE_DELAY_TIME));
1037         ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied");
1038         delegateManager->CloseKvStore(store);
1039         delete delegateManager;
1040     });
1041     ExecutorFactory::GetInstance().Execute(std::move(delayTask));
1042 }
1043 
CheckPermissions(const std::string & userId,const std::string & appId,const std::string & storeId,const std::string & deviceId,uint8_t flag) const1044 bool KvStoreDataService::CheckPermissions(const std::string &userId, const std::string &appId,
1045                                           const std::string &storeId, const std::string &deviceId, uint8_t flag) const
1046 {
1047     ZLOGI("userId=%{public}.6s appId=%{public}s storeId=%{public}s flag=%{public}d deviceId=%{public}.4s",
1048           userId.c_str(), appId.c_str(), storeId.c_str(), flag, deviceId.c_str()); // only print 4 chars of device id
1049     auto &instance = KvStoreMetaManager::GetInstance();
1050     KvStoreMetaData metaData;
1051     auto localDevId = DeviceKvStoreImpl::GetLocalDeviceId();
1052     auto qstatus = instance.QueryKvStoreMetaDataByDeviceIdAndAppId(localDevId, appId, metaData);
1053     if (qstatus != Status::SUCCESS) {
1054         qstatus = instance.QueryKvStoreMetaDataByDeviceIdAndAppId("", appId, metaData); // local device id maybe null
1055         if (qstatus != Status::SUCCESS) {
1056             ZLOGW("query appId failed.");
1057             return false;
1058         }
1059     }
1060     if (metaData.appType.compare("default") == 0) {
1061         ZLOGD("default, dont check sync permission.");
1062         return true;
1063     }
1064     Status status = instance.CheckSyncPermission(userId, appId, storeId, flag, deviceId);
1065     if (status != Status::SUCCESS) {
1066         ZLOGW("PermissionCheck failed.");
1067         return false;
1068     }
1069 
1070     if (metaData.appType.compare("harmony") != 0) {
1071         ZLOGD("it's A app, dont check sync permission.");
1072         return true;
1073     }
1074 
1075     if (PermissionValidator::IsAutoLaunchEnabled(appId)) {
1076         return true;
1077     }
1078     bool ret = PermissionValidator::CheckSyncPermission(userId, appId, metaData.uid);
1079     ZLOGD("checking sync permission ret:%{public}d.", ret);
1080     return ret;
1081 }
1082 
OnStop()1083 void KvStoreDataService::OnStop()
1084 {
1085     ZLOGI("begin.");
1086     if (backup_ != nullptr) {
1087         backup_.reset();
1088         backup_ = nullptr;
1089     }
1090 }
1091 
KvStoreClientDeathObserverImpl(const AppId & appId,pid_t uid,KvStoreDataService & service,sptr<IRemoteObject> observer)1092 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl(
1093     const AppId &appId, pid_t uid, KvStoreDataService &service, sptr<IRemoteObject> observer)
1094     : appId_(appId), uid_(uid), dataService_(service), observerProxy_(std::move(observer)),
1095     deathRecipient_(new KvStoreDeathRecipient(*this))
1096 {
1097     ZLOGI("KvStoreClientDeathObserverImpl");
1098 
1099     if (observerProxy_ != nullptr) {
1100         ZLOGI("add death recipient");
1101         observerProxy_->AddDeathRecipient(deathRecipient_);
1102     } else {
1103         ZLOGW("observerProxy_ is nullptr");
1104     }
1105 }
1106 
~KvStoreClientDeathObserverImpl()1107 KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverImpl()
1108 {
1109     ZLOGI("~KvStoreClientDeathObserverImpl");
1110     if (deathRecipient_ != nullptr && observerProxy_ != nullptr) {
1111         ZLOGI("remove death recipient");
1112         observerProxy_->RemoveDeathRecipient(deathRecipient_);
1113     }
1114 }
1115 
NotifyClientDie()1116 void KvStoreDataService::KvStoreClientDeathObserverImpl::NotifyClientDie()
1117 {
1118     ZLOGI("appId: %{public}s uid:%{public}d", appId_.appId.c_str(), uid_);
1119     dataService_.AppExit(appId_, uid_);
1120 }
1121 
KvStoreDeathRecipient(KvStoreClientDeathObserverImpl & kvStoreClientDeathObserverImpl)1122 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvStoreDeathRecipient(
1123     KvStoreClientDeathObserverImpl &kvStoreClientDeathObserverImpl)
1124     : kvStoreClientDeathObserverImpl_(kvStoreClientDeathObserverImpl)
1125 {
1126     ZLOGI("KvStore Client Death Observer");
1127 }
1128 
~KvStoreDeathRecipient()1129 KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::~KvStoreDeathRecipient()
1130 {
1131     ZLOGI("KvStore Client Death Observer");
1132 }
1133 
OnRemoteDied(const wptr<IRemoteObject> & remote)1134 void KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::OnRemoteDied(
1135     const wptr<IRemoteObject> &remote)
1136 {
1137     ZLOGI("begin");
1138     kvStoreClientDeathObserverImpl_.NotifyClientDie();
1139 }
1140 
DeleteKvStore(const std::string & bundleName,const StoreId & storeId)1141 Status KvStoreDataService::DeleteKvStore(const std::string &bundleName, const StoreId &storeId)
1142 {
1143     ZLOGI("begin.");
1144     if (!storeId.IsValid()) {
1145         ZLOGE("invalid storeId.");
1146         return Status::INVALID_ARGUMENT;
1147     }
1148 
1149     const int32_t uid = IPCSkeleton::GetCallingUid();
1150     const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
1151     std::lock_guard<std::mutex> lg(accountMutex_);
1152     Status status;
1153     auto it = deviceAccountMap_.find(userId);
1154     if (it != deviceAccountMap_.end()) {
1155         status = (it->second).DeleteKvStore(bundleName, uid, storeId.storeId);
1156     } else {
1157         KvStoreUserManager kvStoreUserManager(userId);
1158         status = kvStoreUserManager.DeleteKvStore(bundleName, uid, storeId.storeId);
1159     }
1160 
1161     if (status == Status::SUCCESS) {
1162         auto metaKey = KvStoreMetaManager::GetMetaKey(userId, "default", bundleName, storeId.storeId);
1163         status = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, DELETE);
1164         if (status != Status::SUCCESS) {
1165             ZLOGW("Remove Kvstore Metakey failed.");
1166         }
1167         KvStoreMetaManager::GetInstance().RemoveSecretKey(uid, bundleName, storeId.storeId);
1168         KvStoreMetaManager::GetInstance().DeleteStrategyMeta(bundleName, storeId.storeId, userId);
1169     }
1170     return status;
1171 }
1172 
DeleteKvStoreOnly(const std::string & bundleName,pid_t uid,const std::string & storeId)1173 Status KvStoreDataService::DeleteKvStoreOnly(const std::string &bundleName, pid_t uid, const std::string &storeId)
1174 {
1175     ZLOGI("DeleteKvStoreOnly begin.");
1176     auto userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid);
1177     auto it = deviceAccountMap_.find(userId);
1178     if (it != deviceAccountMap_.end()) {
1179         return (it->second).DeleteKvStore(bundleName, uid, storeId);
1180     }
1181     KvStoreUserManager kvStoreUserManager(userId);
1182     return kvStoreUserManager.DeleteKvStore(bundleName, uid, storeId);
1183 }
1184 
AccountEventChanged(const AccountEventInfo & eventInfo)1185 void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo)
1186 {
1187     ZLOGI("account event %{public}d changed process, begin.", eventInfo.status);
1188     std::lock_guard<std::mutex> lg(accountMutex_);
1189     switch (eventInfo.status) {
1190         case AccountStatus::DEVICE_ACCOUNT_DELETE: {
1191             g_kvStoreAccountEventStatus = 1;
1192             // delete all kvstore belong to this device account
1193             for (auto &it : deviceAccountMap_) {
1194                 (it.second).DeleteAllKvStore();
1195             }
1196             auto it = deviceAccountMap_.find(eventInfo.deviceAccountId);
1197             if (it != deviceAccountMap_.end()) {
1198                 deviceAccountMap_.erase(eventInfo.deviceAccountId);
1199             }
1200             std::initializer_list<std::string> dirList = {Constant::ROOT_PATH_DE, "/",
1201                 Constant::SERVICE_NAME, "/", eventInfo.deviceAccountId};
1202             std::string deviceAccountKvStoreDataDir = Constant::Concatenate(dirList);
1203             ForceRemoveDirectory(deviceAccountKvStoreDataDir);
1204             dirList = {Constant::ROOT_PATH_CE, "/", Constant::SERVICE_NAME, "/", eventInfo.deviceAccountId};
1205             deviceAccountKvStoreDataDir = Constant::Concatenate(dirList);
1206             ForceRemoveDirectory(deviceAccountKvStoreDataDir);
1207             g_kvStoreAccountEventStatus = 0;
1208             break;
1209         }
1210         case AccountStatus::DEVICE_ACCOUNT_SWITCHED: {
1211             auto ret = DistributedDB::KvStoreDelegateManager::NotifyUserChanged();
1212             ZLOGI("notify delegate manager result:%{public}d", ret);
1213             break;
1214         }
1215         default: {
1216             break;
1217         }
1218     }
1219     ZLOGI("account event %{public}d changed process, end.", eventInfo.status);
1220 }
1221 
GetLocalDevice(DeviceInfo & device)1222 Status KvStoreDataService::GetLocalDevice(DeviceInfo &device)
1223 {
1224     auto tmpDevice = KvStoreUtils::GetProviderInstance().GetLocalBasicInfo();
1225     device = {tmpDevice.deviceId, tmpDevice.deviceName, tmpDevice.deviceType};
1226     return Status::SUCCESS;
1227 }
1228 
GetDeviceList(std::vector<DeviceInfo> & deviceInfoList,DeviceFilterStrategy strategy)1229 Status KvStoreDataService::GetDeviceList(std::vector<DeviceInfo> &deviceInfoList, DeviceFilterStrategy strategy)
1230 {
1231     auto devices = KvStoreUtils::GetProviderInstance().GetRemoteNodesBasicInfo();
1232     for (auto const &device : devices) {
1233         DeviceInfo deviceInfo = {device.deviceId, device.deviceName, device.deviceType};
1234         deviceInfoList.push_back(deviceInfo);
1235     }
1236     ZLOGD("strategy is %{public}d.", strategy);
1237     return Status::SUCCESS;
1238 }
1239 
InitSecurityAdapter()1240 void KvStoreDataService::InitSecurityAdapter()
1241 {
1242     auto ret = DATASL_OnStart();
1243     ZLOGI("datasl on start ret:%d", ret);
1244     security_ = std::make_shared<Security>();
1245     if (security_ == nullptr) {
1246         ZLOGD("Security is nullptr.");
1247         return;
1248     }
1249 
1250     auto dbStatus = DistributedDB::KvStoreDelegateManager::SetProcessSystemAPIAdapter(security_);
1251     ZLOGD("set distributed db system api adapter: %d.", static_cast<int>(dbStatus));
1252 
1253     auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(security_.get(), {"security"});
1254     if (status != AppDistributedKv::Status::SUCCESS) {
1255         ZLOGD("security register device change failed, status:%d", static_cast<int>(status));
1256     }
1257 }
1258 
StartWatchDeviceChange(sptr<IDeviceStatusChangeListener> observer,DeviceFilterStrategy strategy)1259 Status KvStoreDataService::StartWatchDeviceChange(sptr<IDeviceStatusChangeListener> observer,
1260                                                   DeviceFilterStrategy strategy)
1261 {
1262     if (observer == nullptr) {
1263         ZLOGD("observer is null");
1264         return Status::INVALID_ARGUMENT;
1265     }
1266     std::lock_guard<std::mutex> lck(deviceListenerMutex_);
1267     if (deviceListener_ == nullptr) {
1268         deviceListener_ = std::make_shared<DeviceChangeListenerImpl>(deviceListeners_);
1269         KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(deviceListener_.get(), {"serviceWatcher"});
1270     }
1271     IRemoteObject *objectPtr = observer->AsObject().GetRefPtr();
1272     auto listenerPair = std::make_pair(objectPtr, observer);
1273     deviceListeners_.insert(listenerPair);
1274     ZLOGD("strategy is %{public}d.", strategy);
1275     return Status::SUCCESS;
1276 }
1277 
StopWatchDeviceChange(sptr<IDeviceStatusChangeListener> observer)1278 Status KvStoreDataService::StopWatchDeviceChange(sptr<IDeviceStatusChangeListener> observer)
1279 {
1280     if (observer == nullptr) {
1281         ZLOGD("observer is null");
1282         return Status::INVALID_ARGUMENT;
1283     }
1284     std::lock_guard<std::mutex> lck(deviceListenerMutex_);
1285     IRemoteObject *objectPtr = observer->AsObject().GetRefPtr();
1286     auto it = deviceListeners_.find(objectPtr);
1287     if (it == deviceListeners_.end()) {
1288         return Status::ILLEGAL_STATE;
1289     }
1290     deviceListeners_.erase(it->first);
1291     return Status::SUCCESS;
1292 }
1293 
IsStoreOpened(const std::string & userId,const std::string & appId,const std::string & storeId)1294 bool KvStoreDataService::IsStoreOpened(const std::string &userId, const std::string &appId, const std::string &storeId)
1295 {
1296     auto it = deviceAccountMap_.find(userId);
1297     return it != deviceAccountMap_.end() && it->second.IsStoreOpened(appId, storeId);
1298 }
1299 
SetCompatibleIdentify(const AppDistributedKv::DeviceInfo & info) const1300 void KvStoreDataService::SetCompatibleIdentify(const AppDistributedKv::DeviceInfo &info) const
1301 {
1302     for (const auto &item : deviceAccountMap_) {
1303         item.second.SetCompatibleIdentify(info.deviceId);
1304     }
1305 }
1306 
CheckSyncActivation(const std::string & userId,const std::string & appId,const std::string & storeId)1307 bool KvStoreDataService::CheckSyncActivation(
1308     const std::string &userId, const std::string &appId, const std::string &storeId)
1309 {
1310     ZLOGD("user:%{public}s, app:%{public}s, store:%{public}s", userId.c_str(), appId.c_str(), storeId.c_str());
1311     std::vector<UserStatus> users = UserDelegate::GetInstance().GetLocalUserStatus();
1312     // active sync feature with single active user
1313     for (const auto &user : users) {
1314         if (userId == std::to_string(user.id)) {
1315             if (!user.isActive) {
1316                 ZLOGD("the store is not in active user");
1317                 return false;
1318             }
1319             // check store in other active user
1320             continue;
1321         }
1322         if (IsStoreOpened(std::to_string(user.id), appId, storeId)) {
1323             ZLOGD("the store already opened in user %{public}d", user.id);
1324             return false;
1325         }
1326     }
1327     ZLOGD("sync permitted");
1328     return true;
1329 }
1330 
CreateRdbService()1331 void KvStoreDataService::CreateRdbService()
1332 {
1333     rdbService_ = new(std::nothrow) DistributedRdb::RdbServiceImpl();
1334     if (rdbService_ != nullptr) {
1335         ZLOGI("create rdb service success");
1336     }
1337 }
1338 
GetRdbService()1339 sptr<DistributedRdb::IRdbService> KvStoreDataService::GetRdbService()
1340 {
1341     return rdbService_;
1342 }
1343 
GetKvStoreDiskSize(const std::string & storeId,uint64_t & size)1344 bool DbMetaCallbackDelegateMgr::GetKvStoreDiskSize(const std::string &storeId, uint64_t &size)
1345 {
1346     if (IsDestruct()) {
1347         return false;
1348     }
1349     DistributedDB::DBStatus ret = delegate_->GetKvStoreDiskSize(storeId, size);
1350     return (ret == DistributedDB::DBStatus::OK);
1351 }
1352 
GetKvStoreKeys(std::vector<StoreInfo> & dbStats)1353 void DbMetaCallbackDelegateMgr::GetKvStoreKeys(std::vector<StoreInfo> &dbStats)
1354 {
1355     if (IsDestruct()) {
1356         return;
1357     }
1358     DistributedDB::DBStatus dbStatusTmp;
1359     Option option {.createIfNecessary = true, .isMemoryDb = false, .isEncryptedDb = false};
1360     DistributedDB::KvStoreNbDelegate *kvStoreNbDelegatePtr = nullptr;
1361     delegate_->GetKvStore(
1362         Constant::SERVICE_META_DB_NAME, option,
1363         [&kvStoreNbDelegatePtr, &dbStatusTmp](DistributedDB::DBStatus dbStatus,
1364                                               DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate) {
1365             kvStoreNbDelegatePtr = kvStoreNbDelegate;
1366             dbStatusTmp = dbStatus;
1367         });
1368 
1369     if (dbStatusTmp != DistributedDB::DBStatus::OK) {
1370         return;
1371     }
1372     DistributedDB::Key dbKey = KvStoreMetaRow::GetKeyFor("");
1373     std::vector<DistributedDB::Entry> entries;
1374     kvStoreNbDelegatePtr->GetEntries(dbKey, entries);
1375     if (entries.empty()) {
1376         delegate_->CloseKvStore(kvStoreNbDelegatePtr);
1377         return;
1378     }
1379     for (auto const &entry : entries) {
1380         std::string key = std::string(entry.key.begin(), entry.key.end());
1381         std::vector<std::string> out;
1382         Split(key, Constant::KEY_SEPARATOR, out);
1383         if (out.size() >= VECTOR_SIZE) {
1384             StoreInfo storeInfo = {out[USER_ID], out[APP_ID], out[STORE_ID]};
1385             dbStats.push_back(std::move(storeInfo));
1386         }
1387     }
1388     delegate_->CloseKvStore(kvStoreNbDelegatePtr);
1389 }
1390 } // namespace OHOS::DistributedKv