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