• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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