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 ¶m)
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 ¶m) -> 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 ¶m)
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