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 #include "process_system_api_adapter_impl.h"
17
18 #include <dirent.h>
19 #include <sys/types.h>
20
21 #include "distributeddb_tools_unit_test.h"
22 #include "distributeddb_data_generate_unit_test.h"
23 #include "log_print.h"
24 #include "platform_specific.h"
25
26 using namespace DistributedDBUnitTest;
27
28 namespace DistributedDB {
29 namespace {
30 KvStoreDelegateManager g_mgr(APP_ID, USER_ID);
31 // define the g_kvDelegateCallback, used to get some information when open a kv store.
32 DBStatus g_kvDelegateStatus = INVALID_ARGS;
33 KvStoreNbDelegate *g_kvNbDelegatePtr = nullptr;
34 auto g_kvNbDelegateCallback = bind(&DistributedDBToolsUnitTest::KvStoreNbDelegateCallback,
35 std::placeholders::_1, std::placeholders::_2, std::ref(g_kvDelegateStatus), std::ref(g_kvNbDelegatePtr));
36 }
37
ProcessSystemApiAdapterImpl()38 ProcessSystemApiAdapterImpl::ProcessSystemApiAdapterImpl()
39 : callback_(nullptr),
40 isLocked_(false),
41 createDb_(false),
42 needValidateBeforeSet_(false)
43 {
44 }
45
~ProcessSystemApiAdapterImpl()46 ProcessSystemApiAdapterImpl::~ProcessSystemApiAdapterImpl()
47 {
48 callback_ = nullptr;
49 }
50
RegOnAccessControlledEvent(const OnAccessControlledEvent & callback)51 DBStatus ProcessSystemApiAdapterImpl::RegOnAccessControlledEvent(const OnAccessControlledEvent &callback)
52 {
53 callback_ = callback;
54 return OK;
55 }
56
IsAccessControlled() const57 bool ProcessSystemApiAdapterImpl::IsAccessControlled() const
58 {
59 return isLocked_;
60 }
61
SetSecurityOptionInner(const std::string & filePath,const SecurityOption & option)62 bool ProcessSystemApiAdapterImpl::SetSecurityOptionInner(const std::string &filePath, const SecurityOption &option)
63 {
64 // file manager will return fail when trying to lower a secOpt
65 if (needValidateBeforeSet_ &&
66 pathSecOptDic_.find(filePath) != pathSecOptDic_.end() &&
67 pathSecOptDic_[filePath].securityLabel >= option.securityLabel) {
68 LOGW("[AdapterImpl] found path secOpt!");
69 return pathSecOptDic_[filePath] == option;
70 }
71 pathSecOptDic_[filePath] = option;
72 return true;
73 }
74
SetSecurityOption(const std::string & filePath,const SecurityOption & option)75 DBStatus ProcessSystemApiAdapterImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option)
76 {
77 bool isExisted = OS::CheckPathExistence(filePath);
78 if (!isExisted) {
79 LOGE("SetSecurityOption to unexistence dir![%s]", filePath.c_str());
80 return NOT_FOUND;
81 }
82
83 std::string dirName;
84 struct dirent *direntPtr = nullptr;
85 DIR *dirPtr = opendir(filePath.c_str());
86 if (dirPtr == nullptr) {
87 LOGD("set path secOpt![%s] [%d] [%d]", filePath.c_str(), option.securityFlag, option.securityLabel);
88 if (!SetSecurityOptionInner(filePath, option)) {
89 return DB_ERROR;
90 }
91 return OK;
92 }
93
94 bool success = true;
95 while (true) {
96 direntPtr = readdir(dirPtr);
97 // condition to exit the loop
98 if (direntPtr == nullptr) {
99 break;
100 }
101 // only remove all *.db files
102 std::string str(direntPtr->d_name);
103 if (str == "." || str == "..") {
104 continue;
105 }
106 dirName.clear();
107 dirName.append(filePath).append("/").append(str);
108 if (direntPtr->d_type == DT_DIR) {
109 SetSecurityOption(dirName, option);
110 std::lock_guard<std::mutex> lock(adapterlock_);
111 success = SetSecurityOptionInner(dirName, option) && success;
112 LOGD("set path secOpt![%s] [%d] [%d]", dirName.c_str(), option.securityFlag, option.securityLabel);
113 } else {
114 std::lock_guard<std::mutex> lock(adapterlock_);
115 success = SetSecurityOptionInner(dirName, option) && success;
116 LOGD("set path secOpt![%s] [%d] [%d]", dirName.c_str(), option.securityFlag, option.securityLabel);
117 continue;
118 }
119 }
120 closedir(dirPtr);
121 success = SetSecurityOptionInner(filePath, option) && success;
122 if (!success) {
123 return DB_ERROR;
124 }
125 return OK;
126 }
127
GetSecurityOption(const std::string & filePath,SecurityOption & option) const128 DBStatus ProcessSystemApiAdapterImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
129 {
130 if (getSecurityOptionCallBack_) {
131 return getSecurityOptionCallBack_(filePath, option);
132 }
133 std::map<const std::string, SecurityOption> temp = pathSecOptDic_; // For const interface only for test
134 if (temp.find(filePath) == temp.end()) {
135 LOGE("[ProcessSystemApiAdapterImpl]::[GetSecurityOption] path [%s] not set secOpt!", filePath.c_str());
136 option.securityLabel = NOT_SET;
137 option.securityFlag = 0;
138 return OK;
139 }
140 LOGD("[AdapterImpl] Get path secOpt![%s] [%d] [%d]", filePath.c_str(), option.securityFlag, option.securityLabel);
141 option = temp[filePath];
142 return OK;
143 }
144
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const145 bool ProcessSystemApiAdapterImpl::CheckDeviceSecurityAbility(const std::string &devId,
146 const SecurityOption &option) const
147 {
148 LOGI("CheckDeviceSecurityAbility!!");
149 if (checkDeviceCallBack_) {
150 return checkDeviceCallBack_(devId, option);
151 }
152 if (createDb_) { // for close kvstore will close virtual communicator
153 KvStoreConfig config;
154 DistributedDBToolsUnitTest::TestDirInit(config.dataDir);
155
156 g_mgr.SetKvStoreConfig(config);
157
158 KvStoreNbDelegate::Option dbOption = {true, false, false};
159 g_mgr.GetKvStore("CheckDeviceSecurityAbilityMeta", dbOption, g_kvNbDelegateCallback);
160 g_mgr.CloseKvStore(g_kvNbDelegatePtr);
161 }
162 return true;
163 }
164
SetLockStatus(bool isLock)165 void ProcessSystemApiAdapterImpl::SetLockStatus(bool isLock)
166 {
167 std::lock_guard<std::mutex> lock(adapterlock_);
168 if (callback_) {
169 callback_(isLock);
170 }
171 isLocked_ = isLock;
172 }
173
SetNeedCreateDb(bool isCreate)174 void ProcessSystemApiAdapterImpl::SetNeedCreateDb(bool isCreate)
175 {
176 std::lock_guard<std::mutex> lock(adapterlock_);
177 createDb_ = isCreate;
178 }
179
SetNeedValidateBeforeSet(bool needValid)180 void ProcessSystemApiAdapterImpl::SetNeedValidateBeforeSet(bool needValid)
181 {
182 std::lock_guard<std::mutex> lock(adapterlock_);
183 LOGW("[AdapterImpl] need valid before set is set to [%d]", needValid);
184 needValidateBeforeSet_ = needValid;
185 }
186
ResetSecOptDic()187 void ProcessSystemApiAdapterImpl::ResetSecOptDic()
188 {
189 pathSecOptDic_.clear();
190 }
191
ResetAdapter()192 void ProcessSystemApiAdapterImpl::ResetAdapter()
193 {
194 ResetSecOptDic();
195 SetLockStatus(false);
196 g_mgr.DeleteKvStore("CheckDeviceSecurityAbilityMeta");
197 }
198
ForkGetSecurityOption(std::function<DBStatus (const std::string &,SecurityOption &)> callBack)199 void ProcessSystemApiAdapterImpl::ForkGetSecurityOption(
200 std::function<DBStatus (const std::string &, SecurityOption &)> callBack)
201 {
202 getSecurityOptionCallBack_ = callBack;
203 }
204
ForkCheckDeviceSecurityAbility(std::function<bool (const std::string &,const SecurityOption &)> callBack)205 void ProcessSystemApiAdapterImpl::ForkCheckDeviceSecurityAbility(
206 std::function<bool (const std::string &, const SecurityOption &)> callBack)
207 {
208 checkDeviceCallBack_ = callBack;
209 }
210
GetExistSecOpt() const211 std::map<const std::string, SecurityOption> ProcessSystemApiAdapterImpl::GetExistSecOpt() const
212 {
213 std::lock_guard<std::mutex> autoLock(adapterlock_);
214 return pathSecOptDic_;
215 }
216 };
217