• 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_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