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(DM_LIB_LOAD_PATH);
85         soAdapterLoadInfo_[soLoadInfo[i].soName] = soLoadInfo[i];
86         LOGI("soAdapterLoadInfo name is: %{public}s", soLoadInfo[i].name.c_str());
87         LOGI("soAdapterLoadInfo type is: %{public}s", soLoadInfo[i].type.c_str());
88         LOGI("soAdapterLoadInfo version is: %{public}s", soLoadInfo[i].version.c_str());
89         LOGI("soAdapterLoadInfo funcName is: %{public}s", soLoadInfo[i].funcName.c_str());
90         LOGI("soAdapterLoadInfo soName is: %{public}s", soLoadInfo[i].soName.c_str());
91         LOGI("soAdapterLoadInfo soPath is: %{public}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(DM_LIB_LOAD_PATH);
115         soAuthLoadInfo_[soLoadInfo[i].authType] = soLoadInfo[i];
116         LOGI("soAuthLoadInfo name is: %{public}s", soLoadInfo[i].name.c_str());
117         LOGI("soAuthLoadInfo type is: %{public}s", soLoadInfo[i].type.c_str());
118         LOGI("soAuthLoadInfo version is: %{public}s", soLoadInfo[i].version.c_str());
119         LOGI("soAuthLoadInfo funcName is: %{public}s", soLoadInfo[i].funcName.c_str());
120         LOGI("soAuthLoadInfo soName is: %{public}s", soLoadInfo[i].soName.c_str());
121         LOGI("soAuthLoadInfo soPath is: %{public}s", soLoadInfo[i].soPath.c_str());
122         LOGI("soAuthLoadInfo authType is: %{public}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         std::string soPathName = (iter->second).soName;
143         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
144             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
145             continue;
146         }
147         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
148         if (so_handle != nullptr) {
149             LOGI("DmConfigManager so_handle is not nullptr first.");
150             dlclose(so_handle);
151         }
152     }
153     for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
154         std::string soPathName = (iter->second).soName;
155         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
156             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
157             continue;
158         }
159         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
160         if (so_handle != nullptr) {
161             LOGI("DmConfigManager so_handle is not nullptr second.");
162             dlclose(so_handle);
163         }
164     }
165     LOGI("DmAdapterManager destructor");
166 }
167 
GetCryptoAdapter(const std::string & soName)168 std::shared_ptr<ICryptoAdapter> DmConfigManager::GetCryptoAdapter(const std::string &soName)
169 {
170     if (soName.empty()) {
171         LOGE("soName size is zero");
172         return nullptr;
173     }
174 
175     auto soInfoIter = soAdapterLoadInfo_.find(soName);
176     if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != std::string(CPYPTO_JSON_TYPE_KEY)) {
177         LOGE("not find so info or type key not match");
178         return nullptr;
179     }
180 
181     std::unique_lock<std::mutex> locker(cryptoAdapterMutex_);
182     auto ptrIter = cryptoAdapterPtr_.find(soName);
183     if (ptrIter != cryptoAdapterPtr_.end()) {
184         return cryptoAdapterPtr_[soName];
185     }
186 
187     void *so_handle = nullptr;
188     std::string soPathName = (soInfoIter->second).soName;
189     if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
190         LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
191         return nullptr;
192     }
193     so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE);
194     if (so_handle == nullptr) {
195         LOGE("load crypto so failed.");
196         return nullptr;
197     }
198 
199     dlerror();
200     auto func = (CreateICryptoAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
201     if (dlerror() != nullptr || func == nullptr) {
202         LOGE("Create object function is not exist");
203         return nullptr;
204     }
205 
206     std::shared_ptr<ICryptoAdapter> iCryptoAdapter(func());
207     cryptoAdapterPtr_[soName] = iCryptoAdapter;
208     return cryptoAdapterPtr_[soName];
209 }
210 
GetAuthAdapter(std::map<int32_t,std::shared_ptr<IAuthentication>> & authAdapter)211 void DmConfigManager::GetAuthAdapter(std::map<int32_t, std::shared_ptr<IAuthentication>> &authAdapter)
212 {
213     authAdapter.clear();
214     for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
215         if ((iter->second).type != std::string(AUTH_JSON_TYPE_KEY)) {
216             LOGE("type key not match");
217             continue;
218         }
219 
220         void *so_handle = nullptr;
221         std::string soPathName = (iter->second).soName;
222         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
223             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
224             continue;
225         }
226         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE);
227         if (so_handle == nullptr) {
228             LOGE("load auth so %{public}s failed", (iter->second).soName.c_str());
229             continue;
230         }
231 
232         dlerror();
233         auto func = (CreateIAuthAdapterFuncPtr)dlsym(so_handle, (iter->second).funcName.c_str());
234         if (dlerror() != nullptr || func == nullptr) {
235             LOGE("Create object function is not exist");
236             continue;
237         }
238 
239         std::shared_ptr<IAuthentication> iAuthentication(func());
240         authAdapter[iter->first] = iAuthentication;
241         LOGI("so name: %{public}s, auth type: %{public}d", (iter->second).soName.c_str(), iter->first);
242     }
243 }
244 } // namespace DistributedHardware
245 } // namespace OHOS