1 /*
2 * Copyright (c) 2022-2023 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 #include "dm_config_manager.h"
16
17 #include <dlfcn.h>
18
19 #include "dm_anonymous.h"
20 #include "dm_constants.h"
21 #include "dm_log.h"
22 #include "json_config.h"
23 #include "nlohmann/json.hpp"
24
25 namespace OHOS {
26 namespace DistributedHardware {
from_json(const nlohmann::json & jsonObject,AdapterSoLoadInfo & soLoadInfo)27 void from_json(const nlohmann::json &jsonObject, AdapterSoLoadInfo &soLoadInfo)
28 {
29 if (!IsString(jsonObject, "name") || !IsString(jsonObject, "type") || !IsString(jsonObject, "version") ||
30 !IsString(jsonObject, "funcName") || !IsString(jsonObject, "soName") || !IsString(jsonObject, "soPath")) {
31 LOGE("AdapterSoLoadInfo json key Not complete");
32 return;
33 }
34 soLoadInfo.name = jsonObject["name"].get<std::string>();
35 soLoadInfo.type = jsonObject["type"].get<std::string>();
36 soLoadInfo.version = jsonObject["version"].get<std::string>();
37 soLoadInfo.funcName = jsonObject["funcName"].get<std::string>();
38 soLoadInfo.soName = jsonObject["soName"].get<std::string>();
39 soLoadInfo.soPath = jsonObject["soPath"].get<std::string>();
40 }
41
from_json(const nlohmann::json & jsonObject,AuthSoLoadInfo & soLoadInfo)42 void from_json(const nlohmann::json &jsonObject, AuthSoLoadInfo &soLoadInfo)
43 {
44 if (!IsString(jsonObject, "name") || !IsString(jsonObject, "type") || !IsString(jsonObject, "version") ||
45 !IsString(jsonObject, "funcName") || !IsString(jsonObject, "soName") || !IsString(jsonObject, "soPath") ||
46 !IsInt32(jsonObject, "authType")) {
47 LOGE("AdapterSoLoadInfo json key Not complete");
48 return;
49 }
50 soLoadInfo.authType = jsonObject["authType"].get<int32_t>();
51 soLoadInfo.name = jsonObject["name"].get<std::string>();
52 soLoadInfo.type = jsonObject["type"].get<std::string>();
53 soLoadInfo.version = jsonObject["version"].get<std::string>();
54 soLoadInfo.funcName = jsonObject["funcName"].get<std::string>();
55 soLoadInfo.soName = jsonObject["soName"].get<std::string>();
56 soLoadInfo.soPath = jsonObject["soPath"].get<std::string>();
57 }
58
GetInstance()59 DmConfigManager &DmConfigManager::GetInstance()
60 {
61 static DmConfigManager instance;
62 return instance;
63 }
64
ParseAdapterConfig()65 void DmConfigManager::ParseAdapterConfig()
66 {
67 nlohmann::json adapterJsonObject = nlohmann::json::parse(adapterJsonConfigString, nullptr, false);
68 if (adapterJsonObject.is_discarded()) {
69 LOGE("adapter json config string parse error");
70 return;
71 }
72 if (!IsArray(adapterJsonObject, ADAPTER_LOAD_JSON_KEY)) {
73 LOGE("adapter json config string key not exist");
74 return;
75 }
76 auto soLoadInfo = adapterJsonObject[ADAPTER_LOAD_JSON_KEY].get<std::vector<AdapterSoLoadInfo>>();
77 for (uint32_t i = 0; i < soLoadInfo.size(); i++) {
78 if (soLoadInfo[i].name.size() == 0 || soLoadInfo[i].type.size() == 0 || soLoadInfo[i].version.size() == 0 ||
79 soLoadInfo[i].funcName.size() == 0 || soLoadInfo[i].soName.size() == 0 ||
80 soLoadInfo[i].soPath.size() == 0) {
81 LOGE("adapter json config string exist invalid members");
82 continue;
83 }
84 soLoadInfo[i].soPath = std::string(LIB_LOAD_PATH);
85 soAdapterLoadInfo_[soLoadInfo[i].soName] = soLoadInfo[i];
86 LOGI("soAdapterLoadInfo name is: %s", soLoadInfo[i].name.c_str());
87 LOGI("soAdapterLoadInfo type is: %s", soLoadInfo[i].type.c_str());
88 LOGI("soAdapterLoadInfo version is: %s", soLoadInfo[i].version.c_str());
89 LOGI("soAdapterLoadInfo funcName is: %s", soLoadInfo[i].funcName.c_str());
90 LOGI("soAdapterLoadInfo soName is: %s", soLoadInfo[i].soName.c_str());
91 LOGI("soAdapterLoadInfo soPath is: %s", soLoadInfo[i].soPath.c_str());
92 }
93 }
94
ParseAuthConfig()95 void DmConfigManager::ParseAuthConfig()
96 {
97 nlohmann::json authJsonObject = nlohmann::json::parse(authJsonConfigString, nullptr, false);
98 if (authJsonObject.is_discarded()) {
99 LOGE("auth json config string parse error!\n");
100 return;
101 }
102 if (!IsArray(authJsonObject, AUTH_LOAD_JSON_KEY)) {
103 LOGE("auth json config string key not exist!\n");
104 return;
105 }
106 auto soLoadInfo = authJsonObject[AUTH_LOAD_JSON_KEY].get<std::vector<AuthSoLoadInfo>>();
107 for (uint32_t i = 0; i < soLoadInfo.size(); i++) {
108 if (soLoadInfo[i].name.size() == 0 || soLoadInfo[i].type.size() == 0 || soLoadInfo[i].version.size() == 0 ||
109 soLoadInfo[i].funcName.size() == 0 || soLoadInfo[i].soName.size() == 0 ||
110 soLoadInfo[i].soPath.size() == 0) {
111 LOGE("adapter json config string exist invalid members");
112 continue;
113 }
114 soLoadInfo[i].soPath = std::string(LIB_LOAD_PATH);
115 soAuthLoadInfo_[soLoadInfo[i].authType] = soLoadInfo[i];
116 LOGI("soAuthLoadInfo name is: %s", soLoadInfo[i].name.c_str());
117 LOGI("soAuthLoadInfo type is: %s", soLoadInfo[i].type.c_str());
118 LOGI("soAuthLoadInfo version is: %s", soLoadInfo[i].version.c_str());
119 LOGI("soAuthLoadInfo funcName is: %s", soLoadInfo[i].funcName.c_str());
120 LOGI("soAuthLoadInfo soName is: %s", soLoadInfo[i].soName.c_str());
121 LOGI("soAuthLoadInfo soPath is: %s", soLoadInfo[i].soPath.c_str());
122 LOGI("soAuthLoadInfo authType is: %d", soLoadInfo[i].authType);
123 }
124 }
125
DmConfigManager()126 DmConfigManager::DmConfigManager()
127 {
128 LOGI("DmConfigManager constructor");
129 do {
130 ParseAdapterConfig();
131 } while (0);
132
133 do {
134 ParseAuthConfig();
135 } while (0);
136 }
137
~DmConfigManager()138 DmConfigManager::~DmConfigManager()
139 {
140 void *so_handle = nullptr;
141 for (auto iter = soAdapterLoadInfo_.begin(); iter != soAdapterLoadInfo_.end(); iter++) {
142 char path[PATH_MAX + 1] = {0x00};
143 std::string soPathName = (iter->second).soPath + (iter->second).soName;
144 if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX) ||
145 (realpath(soPathName.c_str(), path) == nullptr)) {
146 LOGE("File %s canonicalization failed.", soPathName.c_str());
147 continue;
148 }
149 so_handle = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
150 if (so_handle != nullptr) {
151 dlclose(so_handle);
152 }
153 }
154 for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
155 char path[PATH_MAX + 1] = {0x00};
156 std::string soPathName = (iter->second).soPath + (iter->second).soName;
157 if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX) ||
158 (realpath(soPathName.c_str(), path) == nullptr)) {
159 LOGE("File %s canonicalization failed.", soPathName.c_str());
160 continue;
161 }
162 so_handle = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
163 if (so_handle != nullptr) {
164 dlclose(so_handle);
165 }
166 }
167 LOGI("DmAdapterManager destructor");
168 }
169
GetDecisionAdapter(const std::string & soName)170 std::shared_ptr<IDecisionAdapter> DmConfigManager::GetDecisionAdapter(const std::string &soName)
171 {
172 if (soName.empty()) {
173 LOGE("soName size is zero");
174 return nullptr;
175 }
176 auto soInfoIter = soAdapterLoadInfo_.find(soName);
177 if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != std::string(DECISION_JSON_TYPE_KEY)) {
178 LOGE("not find so info or type key not match");
179 return nullptr;
180 }
181 std::unique_lock<std::mutex> locker(decisionAdapterMutex_);
182 auto ptrIter = decisionAdapterPtr_.find(soName);
183 if (ptrIter != decisionAdapterPtr_.end()) {
184 return decisionAdapterPtr_[soName];
185 }
186 void *so_handle = nullptr;
187 char path[PATH_MAX + 1] = {0x00};
188 std::string soPathName = (soInfoIter->second).soPath + (soInfoIter->second).soName;
189 if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX) ||
190 (realpath(soPathName.c_str(), path) == nullptr)) {
191 LOGE("File %s canonicalization failed.", soPathName.c_str());
192 return nullptr;
193 }
194 so_handle = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
195 if (so_handle == nullptr) {
196 so_handle = dlopen(path, RTLD_NOW);
197 if (so_handle == nullptr) {
198 LOGE("load decision so %s failed", soName.c_str());
199 return nullptr;
200 }
201 }
202 dlerror();
203 auto func = (CreateIDecisionAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
204 if (dlerror() != nullptr || func == nullptr) {
205 LOGE("Create object function is not exist");
206 return nullptr;
207 }
208 std::shared_ptr<IDecisionAdapter> iDecisionAdapter(func());
209 decisionAdapterPtr_[soName] = iDecisionAdapter;
210 return decisionAdapterPtr_[soName];
211 }
212
GetCryptoAdapter(const std::string & soName)213 std::shared_ptr<ICryptoAdapter> DmConfigManager::GetCryptoAdapter(const std::string &soName)
214 {
215 if (soName.empty()) {
216 LOGE("soName size is zero");
217 return nullptr;
218 }
219
220 auto soInfoIter = soAdapterLoadInfo_.find(soName);
221 if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != std::string(CPYPTO_JSON_TYPE_KEY)) {
222 LOGE("not find so info or type key not match");
223 return nullptr;
224 }
225
226 std::unique_lock<std::mutex> locker(cryptoAdapterMutex_);
227 auto ptrIter = cryptoAdapterPtr_.find(soName);
228 if (ptrIter != cryptoAdapterPtr_.end()) {
229 return cryptoAdapterPtr_[soName];
230 }
231
232 void *so_handle = nullptr;
233 char path[PATH_MAX + 1] = {0x00};
234 std::string soPathName = (soInfoIter->second).soPath + (soInfoIter->second).soName;
235 if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX) ||
236 (realpath(soPathName.c_str(), path) == nullptr)) {
237 LOGE("File %s canonicalization failed.", soPathName.c_str());
238 return nullptr;
239 }
240 so_handle = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
241 if (so_handle == nullptr) {
242 so_handle = dlopen(path, RTLD_NOW);
243 if (so_handle == nullptr) {
244 LOGE("load crypto so %s failed", soName.c_str());
245 return nullptr;
246 }
247 }
248
249 dlerror();
250 auto func = (CreateICryptoAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
251 if (dlerror() != nullptr || func == nullptr) {
252 LOGE("Create object function is not exist");
253 return nullptr;
254 }
255
256 std::shared_ptr<ICryptoAdapter> iCryptoAdapter(func());
257 cryptoAdapterPtr_[soName] = iCryptoAdapter;
258 return cryptoAdapterPtr_[soName];
259 }
260
GetAuthAdapter(std::map<int32_t,std::shared_ptr<IAuthentication>> & authAdapter)261 void DmConfigManager::GetAuthAdapter(std::map<int32_t, std::shared_ptr<IAuthentication>> &authAdapter)
262 {
263 authAdapter.clear();
264 for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
265 if ((iter->second).type != std::string(AUTH_JSON_TYPE_KEY)) {
266 LOGE("type key not match");
267 continue;
268 }
269
270 void *so_handle = nullptr;
271 char path[PATH_MAX + 1] = {0x00};
272 std::string soPathName = (iter->second).soPath + (iter->second).soName;
273 if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX) ||
274 (realpath(soPathName.c_str(), path) == nullptr)) {
275 LOGE("File %s canonicalization failed.", soPathName.c_str());
276 continue;
277 }
278 so_handle = dlopen(path, RTLD_NOW | RTLD_NOLOAD);
279 if (so_handle == nullptr) {
280 so_handle = dlopen(path, RTLD_NOW);
281 if (so_handle == nullptr) {
282 LOGE("load auth so %s failed", (iter->second).soName.c_str());
283 continue;
284 }
285 }
286
287 dlerror();
288 auto func = (CreateIAuthAdapterFuncPtr)dlsym(so_handle, (iter->second).funcName.c_str());
289 if (dlerror() != nullptr || func == nullptr) {
290 LOGE("Create object function is not exist");
291 continue;
292 }
293
294 std::shared_ptr<IAuthentication> iAuthentication(func());
295 authAdapter[iter->first] = iAuthentication;
296 LOGI("so name: %s, auth type: %d", (iter->second).soName.c_str(), iter->first);
297 }
298 }
299 } // namespace DistributedHardware
300 } // namespace OHOS