• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #define LOG_TAG "Upgrade"
16 #include "upgrade.h"
17 
18 #include <chrono>
19 #include <cinttypes>
20 
21 #include "accesstoken_kit.h"
22 #include "device_manager_adapter.h"
23 #include "directory/directory_manager.h"
24 #include "kvdb_general_store.h"
25 #include "log_print.h"
26 #include "metadata/meta_data_manager.h"
27 #include "metadata/secret_key_meta_data.h"
28 namespace OHOS::DistributedKv {
29 using namespace OHOS::DistributedData;
30 using system_clock = std::chrono::system_clock;
31 using DMAdapter = DistributedData::DeviceManagerAdapter;
32 using DBKey = DistributedDB::Key;
33 
GetInstance()34 Upgrade &Upgrade::GetInstance()
35 {
36     static Upgrade upgrade;
37     return upgrade;
38 }
39 
UpdateStore(const StoreMeta & old,const StoreMeta & meta,const std::vector<uint8_t> & pwd)40 Upgrade::DBStatus Upgrade::UpdateStore(const StoreMeta &old, const StoreMeta &meta, const std::vector<uint8_t> &pwd)
41 {
42     if (old.version < StoreMeta::UUID_CHANGED_TAG && old.storeType == DEVICE_COLLABORATION) {
43         auto upStatus = Upgrade::GetInstance().UpdateUuid(old, meta, pwd);
44         if (upStatus != DBStatus::OK) {
45             return DBStatus::DB_ERROR;
46         }
47     }
48 
49     if (old.dataDir == meta.dataDir) {
50         return DBStatus::OK;
51     }
52 
53     if (!exporter_ || !cleaner_) {
54         return DBStatus::NOT_SUPPORT;
55     }
56 
57     DBPassword password;
58     auto backupFile = exporter_(old, password);
59     if (backupFile.empty()) {
60         return DBStatus::NOT_FOUND;
61     }
62 
63     auto kvStore = GetDBStore(meta, pwd);
64     if (kvStore == nullptr) {
65         return DBStatus::DB_ERROR;
66     }
67 
68     cleaner_(old);
69     return DBStatus::OK;
70 }
71 
ExportStore(const StoreMeta & old,const StoreMeta & meta)72 Upgrade::DBStatus Upgrade::ExportStore(const StoreMeta &old, const StoreMeta &meta)
73 {
74     if (old.dataDir == meta.dataDir) {
75         return DBStatus::OK;
76     }
77 
78     if (!exporter_) {
79         return DBStatus::NOT_SUPPORT;
80     }
81 
82     DBPassword password;
83     auto backupFile = exporter_(old, password);
84     if (backupFile.empty()) {
85         return DBStatus::NOT_FOUND;
86     }
87     return DBStatus::OK;
88 }
89 
UpdateUuid(const StoreMeta & old,const StoreMeta & meta,const std::vector<uint8_t> & pwd)90 Upgrade::DBStatus Upgrade::UpdateUuid(const StoreMeta &old, const StoreMeta &meta, const std::vector<uint8_t> &pwd)
91 {
92     auto kvStore = GetDBStore(meta, pwd);
93     if (kvStore == nullptr) {
94         return DBStatus::DB_ERROR;
95     }
96     kvStore->RemoveDeviceData();
97     auto uuid = GetEncryptedUuidByMeta(meta);
98     auto dbStatus = kvStore->UpdateKey([uuid](const DBKey &originKey, DBKey &newKey) {
99         newKey = originKey;
100         errno_t err = EOK;
101         err = memcpy_s(newKey.data(), newKey.size(), uuid.data(), uuid.size());
102         if (err != EOK) {
103             ZLOGE("memcpy_s failed, err:%{public}d", err);
104         }
105     });
106     if (dbStatus != DBStatus::OK) {
107         ZLOGE("fail to update Uuid, status:%{public}d", dbStatus);
108     }
109     return dbStatus;
110 }
111 
RegisterExporter(uint32_t version,Exporter exporter)112 bool Upgrade::RegisterExporter(uint32_t version, Exporter exporter)
113 {
114     (void)version;
115     exporter_ = std::move(exporter);
116     return exporter_ != nullptr;
117 }
118 
RegisterCleaner(uint32_t version,Cleaner cleaner)119 bool Upgrade::RegisterCleaner(uint32_t version, Cleaner cleaner)
120 {
121     (void)version;
122     cleaner_ = std::move(cleaner);
123     return cleaner_ != nullptr;
124 }
125 
GetDBStore(const StoreMeta & meta,const std::vector<uint8_t> & pwd)126 Upgrade::AutoStore Upgrade::GetDBStore(const StoreMeta &meta, const std::vector<uint8_t> &pwd)
127 {
128     DBManager manager(meta.appId, meta.user, meta.instanceId);
129     manager.SetKvStoreConfig({ DirectoryManager::GetInstance().GetStorePath(meta) });
130     auto release = [&manager](DBStore *store) { manager.CloseKvStore(store); };
131     DBPassword password;
132     password.SetValue(pwd.data(), pwd.size());
133     AutoStore dbStore(nullptr, release);
134     manager.GetKvStore(meta.storeId, KVDBGeneralStore::GetDBOption(meta, password),
135         [&dbStore](auto dbStatus, auto *tmpStore) {
136             dbStore.reset(tmpStore);
137         });
138     return dbStore;
139 }
140 
GetEncryptedUuidByMeta(const StoreMeta & meta)141 std::string Upgrade::GetEncryptedUuidByMeta(const StoreMeta &meta)
142 {
143     std::string keyUuid = meta.appId + meta.deviceId;
144     auto pair = calcUuid_.Find(keyUuid);
145     if (pair.first) {
146         return pair.second;
147     }
148     std::string uuid;
149     if (OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(meta.tokenId) ==
150         OHOS::Security::AccessToken::TOKEN_HAP) {
151         uuid = DMAdapter::GetInstance().CalcClientUuid(meta.appId, meta.deviceId);
152         calcUuid_.Insert(keyUuid, uuid);
153         return uuid;
154     }
155     uuid = DMAdapter::GetInstance().CalcClientUuid(" ", meta.deviceId);
156     calcUuid_.Insert(keyUuid, uuid);
157     return uuid;
158 }
159 } // namespace OHOS::DistributedKv