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