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 {
43 }
44 
~ProcessSystemApiAdapterImpl()45 ProcessSystemApiAdapterImpl::~ProcessSystemApiAdapterImpl()
46 {
47     callback_ = nullptr;
48 }
49 
RegOnAccessControlledEvent(const OnAccessControlledEvent & callback)50 DBStatus ProcessSystemApiAdapterImpl::RegOnAccessControlledEvent(const OnAccessControlledEvent &callback)
51 {
52     callback_ = callback;
53     return OK;
54 }
55 
IsAccessControlled() const56 bool ProcessSystemApiAdapterImpl::IsAccessControlled() const
57 {
58     return isLocked_;
59 }
60 
SetSecurityOption(const std::string & filePath,const SecurityOption & option)61 DBStatus ProcessSystemApiAdapterImpl::SetSecurityOption(const std::string &filePath, const SecurityOption &option)
62 {
63     bool isExisted = OS::CheckPathExistence(filePath);
64     if (!isExisted) {
65         LOGE("SetSecurityOption to unexistence dir![%s]", filePath.c_str());
66         return NOT_FOUND;
67     }
68 
69     std::string dirName;
70     struct dirent *direntPtr = nullptr;
71     DIR *dirPtr = opendir(filePath.c_str());
72     if (dirPtr == nullptr) {
73         LOGD("set path secOpt![%s] [%d] [%d]", filePath.c_str(), option.securityFlag, option.securityLabel);
74         pathSecOptDic_[filePath] = option;
75         return OK;
76     }
77 
78     while (true) {
79         direntPtr = readdir(dirPtr);
80         // condition to exit the loop
81         if (direntPtr == nullptr) {
82             break;
83         }
84         // only remove all *.db files
85         std::string str(direntPtr->d_name);
86         if (str == "." || str == "..") {
87             continue;
88         }
89         dirName.clear();
90         dirName.append(filePath).append("/").append(str);
91         if (direntPtr->d_type == DT_DIR) {
92             SetSecurityOption(dirName, option);
93             std::lock_guard<std::mutex> lock(adapterlock_);
94             pathSecOptDic_[dirName] = option;
95             LOGD("set path secOpt![%s] [%d] [%d]", dirName.c_str(), option.securityFlag, option.securityLabel);
96         } else {
97             std::lock_guard<std::mutex> lock(adapterlock_);
98             pathSecOptDic_[dirName] = option;
99             LOGD("set path secOpt![%s] [%d] [%d]", dirName.c_str(), option.securityFlag, option.securityLabel);
100             continue;
101         }
102     }
103     closedir(dirPtr);
104     pathSecOptDic_[filePath] = option;
105     return OK;
106 }
107 
GetSecurityOption(const std::string & filePath,SecurityOption & option) const108 DBStatus ProcessSystemApiAdapterImpl::GetSecurityOption(const std::string &filePath, SecurityOption &option) const
109 {
110     if (getSecurityOptionCallBack_) {
111         return getSecurityOptionCallBack_(filePath, option);
112     }
113     std::map<const std::string, SecurityOption> temp = pathSecOptDic_; // For const interface only for test
114     if (temp.find(filePath) == temp.end()) {
115         LOGE("[ProcessSystemApiAdapterImpl]::[GetSecurityOption] path [%s] not set secOpt!", filePath.c_str());
116         option.securityLabel = NOT_SET;
117         option.securityFlag = 0;
118         return OK;
119     }
120     LOGD("[AdapterImpl] Get path secOpt![%s] [%d] [%d]", filePath.c_str(), option.securityFlag, option.securityLabel);
121     option = temp[filePath];
122     return OK;
123 }
124 
CheckDeviceSecurityAbility(const std::string & devId,const SecurityOption & option) const125 bool ProcessSystemApiAdapterImpl::CheckDeviceSecurityAbility(const std::string &devId,
126     const SecurityOption &option) const
127 {
128     LOGI("CheckDeviceSecurityAbility!!");
129     if (checkDeviceCallBack_) {
130         return checkDeviceCallBack_(devId, option);
131     }
132     if (createDb_) { // for close kvstore will close virtual communicator
133         KvStoreConfig config;
134         DistributedDBToolsUnitTest::TestDirInit(config.dataDir);
135 
136         g_mgr.SetKvStoreConfig(config);
137 
138         KvStoreNbDelegate::Option dbOption = {true, false, false};
139         g_mgr.GetKvStore("CheckDeviceSecurityAbilityMeta", dbOption, g_kvNbDelegateCallback);
140         g_mgr.CloseKvStore(g_kvNbDelegatePtr);
141     }
142     return true;
143 }
144 
SetLockStatus(bool isLock)145 void ProcessSystemApiAdapterImpl::SetLockStatus(bool isLock)
146 {
147     std::lock_guard<std::mutex> lock(adapterlock_);
148     if (callback_) {
149         callback_(isLock);
150     }
151     isLocked_ = isLock;
152 }
153 
SetNeedCreateDb(bool isCreate)154 void ProcessSystemApiAdapterImpl::SetNeedCreateDb(bool isCreate)
155 {
156     std::lock_guard<std::mutex> lock(adapterlock_);
157     createDb_ = isCreate;
158 }
159 
ResetSecOptDic()160 void ProcessSystemApiAdapterImpl::ResetSecOptDic()
161 {
162     pathSecOptDic_.clear();
163 }
164 
ResetAdapter()165 void ProcessSystemApiAdapterImpl::ResetAdapter()
166 {
167     ResetSecOptDic();
168     SetLockStatus(false);
169     g_mgr.DeleteKvStore("CheckDeviceSecurityAbilityMeta");
170 }
171 
ForkGetSecurityOption(std::function<DBStatus (const std::string &,SecurityOption &)> callBack)172 void ProcessSystemApiAdapterImpl::ForkGetSecurityOption(
173     std::function<DBStatus (const std::string &, SecurityOption &)> callBack)
174 {
175     getSecurityOptionCallBack_ = callBack;
176 }
177 
ForkCheckDeviceSecurityAbility(std::function<bool (const std::string &,const SecurityOption &)> callBack)178 void ProcessSystemApiAdapterImpl::ForkCheckDeviceSecurityAbility(
179     std::function<bool (const std::string &, const SecurityOption &)> callBack)
180 {
181     checkDeviceCallBack_ = callBack;
182 }
183 
GetExistSecOpt() const184 std::map<const std::string, SecurityOption> ProcessSystemApiAdapterImpl::GetExistSecOpt() const
185 {
186     std::lock_guard<std::mutex> autoLock(adapterlock_);
187     return pathSecOptDic_;
188 }
189 };
190