• 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     }
101 }
102 
ParseAuthConfig()103 void DmConfigManager::ParseAuthConfig()
104 {
105     JsonObject authJsonObject(authJsonConfigString);
106     if (authJsonObject.IsDiscarded()) {
107         LOGE("auth json config string parse error!\n");
108         return;
109     }
110     if (!IsArray(authJsonObject, AUTH_LOAD_JSON_KEY)) {
111         LOGE("auth json config string key not exist!\n");
112         return;
113     }
114     std::vector<AuthSoLoadInfo> soLoadInfo;
115     authJsonObject[AUTH_LOAD_JSON_KEY].Get(soLoadInfo);
116     for (uint32_t i = 0; i < soLoadInfo.size(); i++) {
117         if (soLoadInfo[i].name.size() == 0 || soLoadInfo[i].type.size() == 0 || soLoadInfo[i].version.size() == 0 ||
118             soLoadInfo[i].funcName.size() == 0 || soLoadInfo[i].soName.size() == 0 ||
119             soLoadInfo[i].soPath.size() == 0) {
120             LOGE("adapter json config string exist invalid members");
121             continue;
122         }
123         soLoadInfo[i].soPath = std::string(DM_LIB_LOAD_PATH);
124         soAuthLoadInfo_[soLoadInfo[i].authType] = soLoadInfo[i];
125     }
126 }
127 
DmConfigManager()128 DmConfigManager::DmConfigManager()
129 {
130     LOGI("DmConfigManager constructor");
131     do {
132         ParseAdapterConfig();
133     } while (0);
134 
135     do {
136         ParseAuthConfig();
137     } while (0);
138 }
139 
~DmConfigManager()140 DmConfigManager::~DmConfigManager()
141 {
142     void *so_handle = nullptr;
143     for (auto iter = soAdapterLoadInfo_.begin(); iter != soAdapterLoadInfo_.end(); iter++) {
144         std::string soPathName = (iter->second).soName;
145         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
146             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
147             continue;
148         }
149         so_handle = dlopen(soPathName.c_str(), 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         std::string soPathName = (iter->second).soName;
157         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
158             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
159             continue;
160         }
161         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NOLOAD);
162         if (so_handle != nullptr) {
163             LOGI("DmConfigManager so_handle is not nullptr second.");
164             dlclose(so_handle);
165         }
166     }
167     LOGI("DmAdapterManager destructor");
168 }
169 
GetCryptoAdapter(const std::string & soName)170 std::shared_ptr<ICryptoAdapter> DmConfigManager::GetCryptoAdapter(const std::string &soName)
171 {
172     if (soName.empty()) {
173         LOGE("soName size is zero");
174         return nullptr;
175     }
176 
177     auto soInfoIter = soAdapterLoadInfo_.find(soName);
178     if (soInfoIter == soAdapterLoadInfo_.end() || (soInfoIter->second).type != std::string(CPYPTO_JSON_TYPE_KEY)) {
179         LOGE("not find so info or type key not match");
180         return nullptr;
181     }
182 
183     std::unique_lock<std::mutex> locker(cryptoAdapterMutex_);
184     auto ptrIter = cryptoAdapterPtr_.find(soName);
185     if (ptrIter != cryptoAdapterPtr_.end()) {
186         return cryptoAdapterPtr_[soName];
187     }
188 
189     void *so_handle = nullptr;
190     std::string soPathName = (soInfoIter->second).soName;
191     if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
192         LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
193         return nullptr;
194     }
195     so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE | RTLD_NOLOAD);
196     if (so_handle == nullptr) {
197         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE);
198     }
199     if (so_handle == nullptr) {
200         LOGE("load crypto so failed.");
201         return nullptr;
202     }
203 
204     dlerror();
205     auto func = (CreateICryptoAdapterFuncPtr)dlsym(so_handle, (soInfoIter->second).funcName.c_str());
206     if (dlerror() != nullptr || func == nullptr) {
207         LOGE("Create object function is not exist");
208         return nullptr;
209     }
210 
211     std::shared_ptr<ICryptoAdapter> iCryptoAdapter(func());
212     cryptoAdapterPtr_[soName] = iCryptoAdapter;
213     return cryptoAdapterPtr_[soName];
214 }
215 
GetAuthAdapter(std::map<int32_t,std::shared_ptr<IAuthentication>> & authAdapter)216 void DmConfigManager::GetAuthAdapter(std::map<int32_t, std::shared_ptr<IAuthentication>> &authAdapter)
217 {
218     authAdapter.clear();
219     for (auto iter = soAuthLoadInfo_.begin(); iter != soAuthLoadInfo_.end(); iter++) {
220         if ((iter->second).type != std::string(AUTH_JSON_TYPE_KEY)) {
221             LOGE("type key not match");
222             continue;
223         }
224 
225         void *so_handle = nullptr;
226         std::string soPathName = (iter->second).soName;
227         if ((soPathName.length() == 0) || (soPathName.length() > PATH_MAX)) {
228             LOGE("File %{public}s canonicalization failed.", soPathName.c_str());
229             continue;
230         }
231         so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE | RTLD_NOLOAD);
232         if (so_handle == nullptr) {
233             so_handle = dlopen(soPathName.c_str(), RTLD_NOW | RTLD_NODELETE);
234         }
235         if (so_handle == nullptr) {
236             LOGE("load auth so %{public}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: %{public}s, auth type: %{public}d", (iter->second).soName.c_str(), iter->first);
250     }
251 }
252 } // namespace DistributedHardware
253 } // namespace OHOS