1 /*
2 * Copyright (c) 2021-2024 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
16 #include "os_account_plugin_manager.h"
17 #include <chrono>
18 #include <dlfcn.h>
19 #include <unistd.h>
20 #include <future>
21 #include <pthread.h>
22 #include <thread>
23
24 namespace OHOS {
25 namespace AccountSA {
26 namespace {
27 #ifdef _ARM64_
28 static const std::string OS_ACCOUNT_PLUGIN_LIB_PATH = "/system/lib64/platformsdk/";
29 #else
30 static const std::string OS_ACCOUNT_PLUGIN_LIB_PATH = "/system/lib/platformsdk/";
31 #endif
32 static const std::string OS_ACCOUNT_PLUGIN_LIB_NAME = "libactivation_lock_sdk.z.so";
33 }
34
OsAccountPluginManager()35 OsAccountPluginManager::OsAccountPluginManager()
36 {
37 LoaderLib(OS_ACCOUNT_PLUGIN_LIB_PATH, OS_ACCOUNT_PLUGIN_LIB_NAME);
38 ACCOUNT_LOGI("OsAccountPluginManager init end.");
39 }
40
~OsAccountPluginManager()41 OsAccountPluginManager::~OsAccountPluginManager()
42 {
43 CloseLib();
44 }
45
GetInstance()46 OsAccountPluginManager &OsAccountPluginManager::GetInstance()
47 {
48 static OsAccountPluginManager *instance = new (std::nothrow) OsAccountPluginManager();
49 return *instance;
50 }
51
GetMethodNameByEnum(OsPluginMethodEnum methondEnum)52 std::string GetMethodNameByEnum(OsPluginMethodEnum methondEnum)
53 {
54 switch (methondEnum) {
55 case OsPluginMethodEnum::VERIFY_ACTIVATION_LOCK:
56 return "VerifyActivationLock";
57 default:
58 ACCOUNT_LOGE("Find method name failed, enum=%{public}d.", methondEnum);
59 return "";
60 }
61 }
62
LoaderLib(const std::string & path,const std::string & libName)63 void OsAccountPluginManager::LoaderLib(const std::string &path, const std::string &libName)
64 {
65 if (IsPluginAvailable()) {
66 ACCOUNT_LOGE("LibHandle_ is not nullptr.");
67 return;
68 }
69 std::lock_guard<std::mutex> lock(libMutex_);
70 std::string soPath = path + libName;
71 libHandle_ = dlopen(soPath.c_str(), RTLD_LAZY);
72 if (libHandle_ == nullptr) {
73 ACCOUNT_LOGE("Call dlopen failed, error=%{public}s.", dlerror());
74 return;
75 }
76 for (auto i = 0; i < static_cast<int>(OsPluginMethodEnum::OS_ACCOUNT_PLUGIN_COUNT); ++i) {
77 std::string methodName = GetMethodNameByEnum(static_cast<OsPluginMethodEnum>(i));
78 if (methodName.empty()) {
79 ACCOUNT_LOGE("Call check methodName empty.");
80 dlclose(libHandle_);
81 libHandle_ = nullptr;
82 methodMap_.clear();
83 return;
84 }
85 dlerror();
86 void *func = dlsym(libHandle_, methodName.c_str());
87 const char *dlsym_error = dlerror();
88 if (dlsym_error) {
89 ACCOUNT_LOGE("Call check failed, method=%{public}s error=%{public}s.", methodName.c_str(), dlsym_error);
90 dlclose(libHandle_);
91 libHandle_ = nullptr;
92 methodMap_.clear();
93 return;
94 }
95 methodMap_.emplace(static_cast<OsPluginMethodEnum>(i), func);
96 }
97 ACCOUNT_LOGI("Load library success.");
98 }
99
CloseLib()100 void OsAccountPluginManager::CloseLib()
101 {
102 std::lock_guard<std::mutex> lock(libMutex_);
103 if (libHandle_ == nullptr) {
104 ACCOUNT_LOGE("LibHandle_ is nullptr.");
105 return;
106 }
107 dlclose(libHandle_);
108 libHandle_ = nullptr;
109 }
110
IsPluginAvailable()111 bool OsAccountPluginManager::IsPluginAvailable()
112 {
113 std::lock_guard<std::mutex> lock(libMutex_, std::adopt_lock);
114 return libHandle_ != nullptr;
115 }
116
PluginVerifyActivationLockFunc(bool & isAllowed)117 ErrCode OsAccountPluginManager::PluginVerifyActivationLockFunc(bool& isAllowed)
118 {
119 std::lock_guard<std::mutex> lock(libMutex_);
120 auto iter = methodMap_.find(OsPluginMethodEnum::VERIFY_ACTIVATION_LOCK);
121 if (iter == methodMap_.end() || iter->second == nullptr) {
122 ACCOUNT_LOGE("Caller method=%{public}d not exsit.", OsPluginMethodEnum::VERIFY_ACTIVATION_LOCK);
123 return ERR_OSACCOUNT_SERVICE_INNER_ACCOUNT_PLUGIN_NOT_EXIST_ERROR;
124 }
125
126 auto promise = std::make_shared<std::promise<bool>>();
127 auto future = promise->get_future();
128 auto callback = [promise] (bool isActivated) mutable -> int32_t {
129 promise->set_value(isActivated);
130 return ERR_OK;
131 };
132
133 int32_t res = (*reinterpret_cast<VerifyActivationLockFunc>(iter->second))(callback);
134 if (res != ERR_OK) {
135 ACCOUNT_LOGE("Call plugin method failed.");
136 return res;
137 }
138 isAllowed = future.get();
139 return ERR_OK;
140 }
141
IsCreationAllowed()142 bool OsAccountPluginManager::IsCreationAllowed()
143 {
144 #if defined(ACCOUNT_TEST) || defined(ACCOUNT_COVERAGE_TEST)
145 return true;
146 #else
147 if (!IsPluginAvailable()) {
148 ACCOUNT_LOGI("Plugin not availabel.");
149 return true;
150 }
151 bool isAllowed = false;
152 ACCOUNT_LOGI("Call plugin method start.");
153 ErrCode res = PluginVerifyActivationLockFunc(isAllowed);
154 ACCOUNT_LOGI("Call plugin method end.");
155 if (res != ERR_OK) {
156 ACCOUNT_LOGE("Call IsOsAccountCreationAllowed failed, ErrCode=%{public}d", res);
157 return false;
158 }
159 return isAllowed;
160 #endif
161 }
162 } // namespace AccountSA
163 } // namespace OHOS