1 /*
2 * Copyright (c) 2023-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 "security_manager_addon.h"
17
18 #include <fcntl.h>
19 #include <fstream>
20 #include "cJSON.h"
21 #include "cjson_check.h"
22 #include "clipboard_policy.h"
23 #include "device_settings_proxy.h"
24 #include "edm_constants.h"
25 #include "edm_log.h"
26 #include "pixel_map_napi.h"
27
28 using namespace OHOS::EDM;
29
30 constexpr int64_t MAX_VALIDITY_PERIOD = 31536000000000; // 60 * 60 * 24 * 365 * 1000 * 1000
31 constexpr int32_t MAX_WATERMARK_IMAGE_SIZE = 512000; // 500 * 1024
32 static const std::string VALIDITY_PERIOD_OUT_OF_RANGE_ERROR = "validityPeriod out of range!";
33
Init(napi_env env,napi_value exports)34 napi_value SecurityManagerAddon::Init(napi_env env, napi_value exports)
35 {
36 napi_value nClipboardPolicy = nullptr;
37 NAPI_CALL(env, napi_create_object(env, &nClipboardPolicy));
38 CreateClipboardPolicyObject(env, nClipboardPolicy);
39 napi_value nPermissionManagedState = nullptr;
40 NAPI_CALL(env, napi_create_object(env, &nPermissionManagedState));
41 CreatePermissionManagedStateObject(env, nPermissionManagedState);
42 napi_property_descriptor property[] = {
43 DECLARE_NAPI_FUNCTION("getSecurityPatchTag", GetSecurityPatchTag),
44 DECLARE_NAPI_FUNCTION("getDeviceEncryptionStatus", GetDeviceEncryptionStatus),
45 DECLARE_NAPI_FUNCTION("setPasswordPolicy", SetPasswordPolicy),
46 DECLARE_NAPI_FUNCTION("getPasswordPolicy", GetPasswordPolicy),
47 DECLARE_NAPI_FUNCTION("getSecurityStatus", GetSecurityStatus),
48 DECLARE_NAPI_FUNCTION("installUserCertificate", InstallUserCertificate),
49 DECLARE_NAPI_FUNCTION("uninstallUserCertificate", UninstallUserCertificate),
50 DECLARE_NAPI_FUNCTION("getUserCertificates", GetUserCertificates),
51 DECLARE_NAPI_FUNCTION("setAppClipboardPolicy", SetAppClipboardPolicy),
52 DECLARE_NAPI_FUNCTION("getAppClipboardPolicy", GetAppClipboardPolicy),
53 DECLARE_NAPI_FUNCTION("setWatermarkImage", SetWatermarkImage),
54 DECLARE_NAPI_FUNCTION("cancelWatermarkImage", CancelWatermarkImage),
55 DECLARE_NAPI_FUNCTION("setPermissionManagedState", SetPermissionManagedState),
56 DECLARE_NAPI_FUNCTION("getPermissionManagedState", GetPermissionManagedState),
57 DECLARE_NAPI_PROPERTY("ClipboardPolicy", nClipboardPolicy),
58 DECLARE_NAPI_PROPERTY("PermissionManagedState", nPermissionManagedState),
59 };
60 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
61 return exports;
62 }
63
GetSecurityPatchTag(napi_env env,napi_callback_info info)64 napi_value SecurityManagerAddon::GetSecurityPatchTag(napi_env env, napi_callback_info info)
65 {
66 AddonMethodSign addonMethodSign;
67 addonMethodSign.name = "GetSecurityPatchTag";
68 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
69 addonMethodSign.methodAttribute = MethodAttribute::GET;
70 AdapterAddonData adapterAddonData{};
71 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
72 if (result == nullptr) {
73 return nullptr;
74 }
75 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
76 int32_t ret = securityManagerProxy->GetSecurityPatchTag(adapterAddonData.data, adapterAddonData.stringRet);
77 if (FAILED(ret)) {
78 napi_throw(env, CreateError(env, ret));
79 return nullptr;
80 }
81 napi_value securityPatchTag;
82 NAPI_CALL(env, napi_create_string_utf8(env, adapterAddonData.stringRet.c_str(),
83 adapterAddonData.stringRet.size(), &securityPatchTag));
84 return securityPatchTag;
85 }
86
GetDeviceEncryptionStatus(napi_env env,napi_callback_info info)87 napi_value SecurityManagerAddon::GetDeviceEncryptionStatus(napi_env env, napi_callback_info info)
88 {
89 AddonMethodSign addonMethodSign;
90 addonMethodSign.name = "GetDeviceEncryptionStatus";
91 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
92 addonMethodSign.methodAttribute = MethodAttribute::GET;
93 AdapterAddonData adapterAddonData{};
94 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
95 if (result == nullptr) {
96 return nullptr;
97 }
98 DeviceEncryptionStatus deviceEncryptionStatus;
99 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
100 int32_t ret = securityManagerProxy->GetDeviceEncryptionStatus(adapterAddonData.data, deviceEncryptionStatus);
101 if (FAILED(ret)) {
102 napi_throw(env, CreateError(env, ret));
103 return nullptr;
104 }
105 return ConvertDeviceEncryptionStatus(env, deviceEncryptionStatus);
106 }
107
ConvertDeviceEncryptionStatus(napi_env env,DeviceEncryptionStatus & deviceEncryptionStatus)108 napi_value SecurityManagerAddon::ConvertDeviceEncryptionStatus(napi_env env,
109 DeviceEncryptionStatus &deviceEncryptionStatus)
110 {
111 napi_value objDeviceEncryptionStatus = nullptr;
112 NAPI_CALL(env, napi_create_object(env, &objDeviceEncryptionStatus));
113 napi_value nIsEncrypted;
114 NAPI_CALL(env, napi_get_boolean(env, deviceEncryptionStatus.isEncrypted, &nIsEncrypted));
115 NAPI_CALL(env, napi_set_named_property(env, objDeviceEncryptionStatus, "isEncrypted", nIsEncrypted));
116 return objDeviceEncryptionStatus;
117 }
118
SetPasswordPolicy(napi_env env,napi_callback_info info)119 napi_value SecurityManagerAddon::SetPasswordPolicy(napi_env env, napi_callback_info info)
120 {
121 auto convertpasswordPolicy2Data = [](napi_env env, napi_value argv, MessageParcel &data,
122 const AddonMethodSign &methodSign) {
123 PasswordPolicy policy;
124 if (!JsObjectToString(env, argv, "complexityRegex", false, policy.complexityReg)) {
125 EDMLOGE("Parameter passwordPolicy error");
126 return false;
127 }
128 if (!JsObjectToLong(env, argv, "validityPeriod", false, policy.validityPeriod)) {
129 EDMLOGE("Parameter passwordPolicy error");
130 return false;
131 }
132 if (policy.validityPeriod > MAX_VALIDITY_PERIOD || policy.validityPeriod < 0) {
133 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, VALIDITY_PERIOD_OUT_OF_RANGE_ERROR));
134 return false;
135 }
136 if (!JsObjectToString(env, argv, "additionalDescription", false, policy.additionalDescription)) {
137 EDMLOGE("Parameter passwordPolicy error");
138 return false;
139 }
140 data.WriteString(policy.complexityReg);
141 data.WriteInt64(policy.validityPeriod);
142 data.WriteString(policy.additionalDescription);
143 return true;
144 };
145 AddonMethodSign addonMethodSign;
146 addonMethodSign.name = "SetPasswordPolicy";
147 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
148 addonMethodSign.argsConvert = {nullptr, convertpasswordPolicy2Data};
149 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
150 AdapterAddonData adapterAddonData{};
151 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
152 if (result == nullptr) {
153 return nullptr;
154 }
155 int32_t retCode = SecurityManagerProxy::GetSecurityManagerProxy()->SetPasswordPolicy(adapterAddonData.data);
156 if (FAILED(retCode)) {
157 napi_throw(env, CreateError(env, retCode));
158 }
159 return nullptr;
160 }
161
GetPasswordPolicy(napi_env env,napi_callback_info info)162 napi_value SecurityManagerAddon::GetPasswordPolicy(napi_env env, napi_callback_info info)
163 {
164 EDMLOGI("NAPI_GetPasswordPolicy called");
165 size_t argc = ARGS_SIZE_ONE;
166 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
167 napi_value thisArg = nullptr;
168 void* data = nullptr;
169 OHOS::AppExecFwk::ElementName elementName;
170 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
171
172 PasswordPolicy policy;
173 int32_t retCode = EdmReturnErrCode::SYSTEM_ABNORMALLY;
174 if (argc >= ARGS_SIZE_ONE) {
175 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
176 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
177 "Parameter admin error");
178 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->GetPasswordPolicy(elementName, policy);
179 } else {
180 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->GetPasswordPolicy(policy);
181 }
182
183 if (FAILED(retCode)) {
184 napi_throw(env, CreateError(env, retCode));
185 return nullptr;
186 }
187 napi_value ret;
188 napi_value complexityReg;
189 napi_value validityPeriod;
190 napi_value additionalDescription;
191 NAPI_CALL(env, napi_create_object(env, &ret));
192 NAPI_CALL(env, napi_create_string_utf8(env, policy.complexityReg.c_str(), NAPI_AUTO_LENGTH, &complexityReg));
193 NAPI_CALL(env, napi_create_int64(env, policy.validityPeriod, &validityPeriod));
194 NAPI_CALL(env,
195 napi_create_string_utf8(env, policy.additionalDescription.c_str(), NAPI_AUTO_LENGTH, &additionalDescription));
196 NAPI_CALL(env, napi_set_named_property(env, ret, "complexityRegex", complexityReg));
197 NAPI_CALL(env, napi_set_named_property(env, ret, "validityPeriod", validityPeriod));
198 NAPI_CALL(env, napi_set_named_property(env, ret, "additionalDescription", additionalDescription));
199 return ret;
200 }
201
GetSecurityStatus(napi_env env,napi_callback_info info)202 napi_value SecurityManagerAddon::GetSecurityStatus(napi_env env, napi_callback_info info)
203 {
204 EDMLOGI("NAPI_GetSecurityStatus called");
205 size_t argc = ARGS_SIZE_TWO;
206 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
207 napi_value thisArg = nullptr;
208 void* data = nullptr;
209 OHOS::AppExecFwk::ElementName elementName;
210 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
211 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
212 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter type error");
213 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string),
214 "The second parameter must be string.");
215 bool boolret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
216 ASSERT_AND_THROW_PARAM_ERROR(env, boolret, "element name param error");
217 EDMLOGD(
218 "EnableAdmin: elementName.bundlename %{public}s, "
219 "elementName.abilityname:%{public}s",
220 elementName.GetBundleName().c_str(),
221 elementName.GetAbilityName().c_str());
222 std::string item;
223 boolret = ParseString(env, item, argv[ARR_INDEX_ONE]);
224 ASSERT_AND_THROW_PARAM_ERROR(env, boolret, "param 'item' parse error");
225 std::string stringRet;
226 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
227 int32_t ret = ERR_OK;
228 if (item == EdmConstants::SecurityManager::PATCH) {
229 ret = securityManagerProxy->GetSecurityPatchTag(elementName, stringRet);
230 } else if (item == EdmConstants::SecurityManager::ENCRYPTION) {
231 DeviceEncryptionStatus deviceEncryptionStatus;
232 ret = securityManagerProxy->GetDeviceEncryptionStatus(elementName, deviceEncryptionStatus);
233 if (SUCCEEDED(ret)) {
234 ret = ConvertDeviceEncryptionToJson(env, deviceEncryptionStatus, stringRet);
235 }
236 } else if (item == EdmConstants::SecurityManager::ROOT) {
237 ret = securityManagerProxy->GetRootCheckStatus(elementName, stringRet);
238 } else {
239 ret = EdmReturnErrCode::INTERFACE_UNSUPPORTED;
240 }
241 if (FAILED(ret)) {
242 napi_throw(env, CreateError(env, ret));
243 return nullptr;
244 }
245 napi_value status;
246 NAPI_CALL(env, napi_create_string_utf8(env, stringRet.c_str(), stringRet.size(), &status));
247 return status;
248 }
249
ConvertDeviceEncryptionToJson(napi_env env,DeviceEncryptionStatus & deviceEncryptionStatus,std::string & stringRet)250 int32_t SecurityManagerAddon::ConvertDeviceEncryptionToJson(napi_env env,
251 DeviceEncryptionStatus &deviceEncryptionStatus, std::string &stringRet)
252 {
253 cJSON *json = nullptr;
254 CJSON_CREATE_OBJECT_AND_CHECK(json, EdmReturnErrCode::SYSTEM_ABNORMALLY);
255 cJSON_AddBoolToObject(json, "isEncrypted", deviceEncryptionStatus.isEncrypted);
256 char *jsonStr = cJSON_PrintUnformatted(json);
257 if (jsonStr == nullptr) {
258 cJSON_Delete(json);
259 return EdmReturnErrCode::SYSTEM_ABNORMALLY;
260 }
261 stringRet = std::string(jsonStr);
262 cJSON_Delete(json);
263 cJSON_free(jsonStr);
264 return ERR_OK;
265 }
266
InstallUserCertificateSync(napi_env env,napi_value argv,AsyncCertCallbackInfo * asyncCallbackInfo)267 napi_value SecurityManagerAddon::InstallUserCertificateSync(napi_env env, napi_value argv,
268 AsyncCertCallbackInfo *asyncCallbackInfo)
269 {
270 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv, napi_number),
271 "accountId type error");
272 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->certblobCA.accountId,
273 argv), "Parameter accountId error");
274 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
275 int32_t ret = securityManagerProxy->InstallUserCertificate(asyncCallbackInfo->elementName,
276 asyncCallbackInfo->certblobCA, asyncCallbackInfo->stringRet,
277 asyncCallbackInfo->innerCodeMsg);
278 if (FAILED(ret)) {
279 if (asyncCallbackInfo->innerCodeMsg.empty()) {
280 napi_throw(env, CreateError(env, ret));
281 } else {
282 napi_throw(env, CreateError(env, ret, asyncCallbackInfo->innerCodeMsg));
283 }
284 return nullptr;
285 }
286 napi_value status;
287 NAPI_CALL(env, napi_create_string_utf8(env, asyncCallbackInfo->stringRet.c_str(),
288 asyncCallbackInfo->stringRet.size(), &status));
289 return status;
290 }
291
InstallUserCertificate(napi_env env,napi_callback_info info)292 napi_value SecurityManagerAddon::InstallUserCertificate(napi_env env, napi_callback_info info)
293 {
294 EDMLOGI("NAPI_InstallUserCertificate called");
295 size_t argc = ARGS_SIZE_FOUR;
296 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
297 napi_value thisArg = nullptr;
298 void *data = nullptr;
299 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
300 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
301 bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object);
302 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter want error");
303 matchFlag = MatchValueType(env, argv[ARR_INDEX_ONE], napi_object);
304 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter certblob error");
305 auto asyncCallbackInfo = new (std::nothrow) AsyncCertCallbackInfo();
306 if (asyncCallbackInfo == nullptr) {
307 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
308 return nullptr;
309 }
310 std::unique_ptr<AsyncCertCallbackInfo> callbackPtr{asyncCallbackInfo};
311 bool retAdmin = ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]);
312 ASSERT_AND_THROW_PARAM_ERROR(env, retAdmin, "element name param error");
313 bool retCertBlob = ParseCertBlob(env, argv[ARR_INDEX_ONE], asyncCallbackInfo);
314 ASSERT_AND_THROW_PARAM_ERROR(env, retCertBlob, "element cert blob error");
315 if (argc > ARGS_SIZE_TWO) {
316 return InstallUserCertificateSync(env, argv[ARR_INDEX_TWO], asyncCallbackInfo);
317 }
318 napi_value asyncWorkReturn = HandleAsyncWork(env, asyncCallbackInfo, "InstallUserCertificate",
319 NativeInstallUserCertificate, NativeStringCallbackComplete);
320 callbackPtr.release();
321 return asyncWorkReturn;
322 }
323
NativeInstallUserCertificate(napi_env env,void * data)324 void SecurityManagerAddon::NativeInstallUserCertificate(napi_env env, void *data)
325 {
326 EDMLOGI("NAPI_NativeInstallUserCertificate called");
327 if (data == nullptr) {
328 EDMLOGE("data is nullptr");
329 return;
330 }
331 AsyncCertCallbackInfo *asyncCallbackInfo = static_cast<AsyncCertCallbackInfo *>(data);
332 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
333 asyncCallbackInfo->ret = securityManagerProxy->InstallUserCertificate(asyncCallbackInfo->elementName,
334 asyncCallbackInfo->certblobCA, asyncCallbackInfo->stringRet, asyncCallbackInfo->innerCodeMsg);
335 }
336
UninstallUserCertificate(napi_env env,napi_callback_info info)337 napi_value SecurityManagerAddon::UninstallUserCertificate(napi_env env, napi_callback_info info)
338 {
339 auto convertCertBlob2Data = [](napi_env env, napi_value argv, MessageParcel &data,
340 const AddonMethodSign &methodSign) {
341 std::string alias;
342 if (!ParseString(env, alias, argv)) {
343 EDMLOGE("element alias error");
344 return false;
345 }
346 data.WriteString(alias);
347 return true;
348 };
349 AddonMethodSign addonMethodSign;
350 addonMethodSign.name = "UninstallUserCertificate";
351 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
352 addonMethodSign.argsConvert = {nullptr, convertCertBlob2Data};
353 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
354 return AddonMethodAdapter(env, info, addonMethodSign, NativeUninstallUserCertificate, NativeVoidCallbackComplete);
355 }
356
NativeUninstallUserCertificate(napi_env env,void * data)357 void SecurityManagerAddon::NativeUninstallUserCertificate(napi_env env, void *data)
358 {
359 EDMLOGI("NAPI_NativeUninstallUserCertificate called");
360 if (data == nullptr) {
361 EDMLOGE("data is nullptr");
362 return;
363 }
364 AdapterAddonData *asyncCallbackInfo = static_cast<AdapterAddonData *>(data);
365 asyncCallbackInfo->ret = DeviceSettingsProxy::GetDeviceSettingsProxy()->UninstallUserCertificate(
366 asyncCallbackInfo->data, asyncCallbackInfo->innerCodeMsg);
367 }
368
GetUserCertificates(napi_env env,napi_callback_info info)369 napi_value SecurityManagerAddon::GetUserCertificates(napi_env env, napi_callback_info info)
370 {
371 EDMLOGI("NAPI_GetUserCertificates called");
372 AddonMethodSign addonMethodSign;
373 addonMethodSign.name = "GetUserCertificates";
374 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32};
375 addonMethodSign.methodAttribute = MethodAttribute::GET;
376 AdapterAddonData adapterAddonData{};
377 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
378 if (result == nullptr) {
379 return nullptr;
380 }
381 std::vector<std::string> uriList;
382 auto securityManagerProxy = SecurityManagerProxy::GetSecurityManagerProxy();
383 int32_t ret = securityManagerProxy->GetUserCertificates(adapterAddonData.data, uriList);
384 if (FAILED(ret)) {
385 napi_throw(env, CreateError(env, ret));
386 return nullptr;
387 }
388 napi_value jsUriList = nullptr;
389 NAPI_CALL(env, napi_create_array(env, &jsUriList));
390 ConvertStringVectorToJS(env, uriList, jsUriList);
391 return jsUriList;
392 }
393
ParseCertBlob(napi_env env,napi_value object,AsyncCertCallbackInfo * asyncCertCallbackInfo)394 bool SecurityManagerAddon::ParseCertBlob(napi_env env, napi_value object, AsyncCertCallbackInfo *asyncCertCallbackInfo)
395 {
396 napi_valuetype type = napi_undefined;
397 NAPI_CALL_BASE(env, napi_typeof(env, object, &type), false);
398 if (type != napi_object) {
399 EDMLOGE("type of param certblob is not object");
400 return false;
401 }
402 if (!JsObjectToU8Vector(env, object, "inData", asyncCertCallbackInfo->certblobCA.certArray)) {
403 EDMLOGE("uint8Array to vector failed");
404 return false;
405 }
406 return JsObjectToString(env, object, "alias", true, asyncCertCallbackInfo->certblobCA.alias);
407 }
408
SetAppClipboardPolicy(napi_env env,napi_callback_info info)409 napi_value SecurityManagerAddon::SetAppClipboardPolicy(napi_env env, napi_callback_info info)
410 {
411 EDMLOGI("NAPI_SetAppClipboardPolicy called");
412 size_t argc = ARGS_SIZE_FOUR;
413 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
414 napi_value thisArg = nullptr;
415 void *data = nullptr;
416 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
417 AddonMethodSign addonMethodSign;
418 if (argc == ARGS_SIZE_THREE) {
419 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32, EdmAddonCommonType::INT32};
420 EDMLOGI(" SetAppClipboardPolicy argc == ARGS_SIZE_THREE");
421 SetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::SET_HAS_TOKEN_ID);
422 } else if (argc > ARGS_SIZE_THREE) {
423 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING,
424 EdmAddonCommonType::INT32, EdmAddonCommonType::INT32};
425 EDMLOGI(" SetAppClipboardPolicy argc > ARGS_SIZE_THREE");
426 SetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::SET_HAS_BUNDLE_NAME);
427 } else {
428 EDMLOGI(" argc < ARGS_SIZE_THREE Parameter error");
429 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, "Parameter error"));
430 return nullptr;
431 }
432 addonMethodSign.name = "SetAppClipboardPolicy";
433 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
434 AdapterAddonData adapterAddonData{};
435 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
436 if (result == nullptr) {
437 return nullptr;
438 }
439 int32_t retCode =
440 SecurityManagerProxy::GetSecurityManagerProxy()->SetAppClipboardPolicy(adapterAddonData.data);
441 if (FAILED(retCode)) {
442 napi_throw(env, CreateError(env, retCode));
443 }
444 return nullptr;
445 }
446
SetClipboardPolicyParamHandle(AddonMethodSign & addonMethodSign,int flag)447 void SecurityManagerAddon::SetClipboardPolicyParamHandle(AddonMethodSign &addonMethodSign, int flag)
448 {
449 if (flag == ClipboardFunctionType::SET_HAS_TOKEN_ID) {
450 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
451 const AddonMethodSign &methodSign) {
452 int32_t tokenId;
453 if (!ParseInt(env, tokenId, argv)) {
454 EDMLOGE("element tokenId error");
455 return false;
456 }
457 data.WriteInt32(ClipboardFunctionType::SET_HAS_TOKEN_ID);
458 data.WriteInt32(tokenId);
459 return true;
460 };
461 addonMethodSign.argsConvert = {nullptr, convertData, nullptr};
462 }
463 if (flag == ClipboardFunctionType::SET_HAS_BUNDLE_NAME) {
464 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
465 const AddonMethodSign &methodSign) {
466 std::string bundleName;
467 if (!ParseString(env, bundleName, argv)) {
468 EDMLOGE("Parameter bundleName error");
469 return false;
470 }
471 data.WriteInt32(ClipboardFunctionType::SET_HAS_BUNDLE_NAME);
472 data.WriteString(bundleName);
473 return true;
474 };
475 addonMethodSign.argsConvert = {nullptr, convertData, nullptr, nullptr};
476 }
477 }
478
GetClipboardPolicyParamHandle(AddonMethodSign & addonMethodSign,int flag)479 void SecurityManagerAddon::GetClipboardPolicyParamHandle(AddonMethodSign &addonMethodSign, int flag)
480 {
481 if (flag == ClipboardFunctionType::GET_HAS_TOKEN_ID) {
482 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
483 const AddonMethodSign &methodSign) {
484 int32_t tokenId;
485 if (!ParseInt(env, tokenId, argv)) {
486 EDMLOGE("element tokenId error");
487 return false;
488 }
489 data.WriteInt32(ClipboardFunctionType::GET_HAS_TOKEN_ID);
490 data.WriteInt32(tokenId);
491 return true;
492 };
493 addonMethodSign.argsConvert = {nullptr, convertData};
494 }
495 if (flag == ClipboardFunctionType::GET_HAS_BUNDLE_NAME) {
496 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
497 const AddonMethodSign &methodSign) {
498 std::string bundleName;
499 if (!ParseString(env, bundleName, argv)) {
500 EDMLOGE("Parameter bundleName error");
501 return false;
502 }
503 data.WriteInt32(ClipboardFunctionType::GET_HAS_BUNDLE_NAME);
504 data.WriteString(bundleName);
505 return true;
506 };
507 addonMethodSign.argsConvert = {nullptr, convertData, nullptr};
508 }
509 if (flag == ClipboardFunctionType::GET_NO_TOKEN_ID) {
510 auto convertData = [](napi_env env, napi_value argv, MessageParcel &data,
511 const AddonMethodSign &methodSign) {
512 OHOS::AppExecFwk::ElementName elementName;
513 if (!ParseElementName(env, elementName, argv)) {
514 EDMLOGE("Parameter admin error");
515 return false;
516 }
517 data.WriteString(methodSign.apiVersionTag);
518 data.WriteInt32(HAS_ADMIN);
519 data.WriteParcelable(&elementName);
520 data.WriteInt32(ClipboardFunctionType::GET_NO_TOKEN_ID);
521 return true;
522 };
523 addonMethodSign.argsConvert = {convertData};
524 }
525 }
526
GetAppClipboardPolicy(napi_env env,napi_callback_info info)527 napi_value SecurityManagerAddon::GetAppClipboardPolicy(napi_env env, napi_callback_info info)
528 {
529 size_t argc = ARGS_SIZE_THREE;
530 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
531 napi_value thisArg = nullptr;
532 void *data = nullptr;
533 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
534 AddonMethodSign addonMethodSign;
535 if (argc == ARGS_SIZE_ONE) {
536 EDMLOGI(" GetAppClipboardPolicy argc == ARGS_SIZE_ONE");
537 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
538 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_NO_TOKEN_ID);
539 } else if (argc == ARGS_SIZE_TWO) {
540 EDMLOGI(" GetAppClipboardPolicy argc == ARGS_SIZE_TWO");
541 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::INT32};
542 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_HAS_TOKEN_ID);
543 } else if (argc >= ARGS_SIZE_THREE) {
544 EDMLOGI(" GetAppClipboardPolicy argc >= ARGS_SIZE_THREE");
545 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING, EdmAddonCommonType::INT32};
546 GetClipboardPolicyParamHandle(addonMethodSign, ClipboardFunctionType::GET_HAS_BUNDLE_NAME);
547 } else {
548 EDMLOGI(" argc < ARGS_SIZE_ONE Parameter error");
549 napi_throw(env, CreateError(env, EdmReturnErrCode::PARAM_ERROR, "Parameter error"));
550 return nullptr;
551 }
552 addonMethodSign.name = "GetAppClipboardPolicy";
553 addonMethodSign.methodAttribute = MethodAttribute::GET;
554 AdapterAddonData adapterAddonData{};
555 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
556 if (result == nullptr) {
557 return nullptr;
558 }
559 std::string policy;
560 int32_t retCode =
561 SecurityManagerProxy::GetSecurityManagerProxy()->GetAppClipboardPolicy(adapterAddonData.data, policy);
562 if (FAILED(retCode)) {
563 napi_throw(env, CreateError(env, retCode));
564 return nullptr;
565 }
566 napi_value clipboardPolicy;
567 NAPI_CALL(env, napi_create_string_utf8(env, policy.c_str(), NAPI_AUTO_LENGTH, &clipboardPolicy));
568 return clipboardPolicy;
569 }
570
CreatePermissionManagedStateObject(napi_env env,napi_value value)571 void SecurityManagerAddon::CreatePermissionManagedStateObject(napi_env env, napi_value value)
572 {
573 napi_value nDefault;
574 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ManagedState::DEFAULT), &nDefault));
575 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DEFAULT", nDefault));
576 napi_value nGranted;
577 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ManagedState::GRANTED), &nGranted));
578 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GRANTED", nGranted));
579 napi_value nDenied;
580 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ManagedState::DENIED), &nDenied));
581 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DENIED", nDenied));
582 }
583
CreateClipboardPolicyObject(napi_env env,napi_value value)584 void SecurityManagerAddon::CreateClipboardPolicyObject(napi_env env, napi_value value)
585 {
586 napi_value nDefault;
587 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::DEFAULT), &nDefault));
588 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "DEFAULT", nDefault));
589 napi_value nInApp;
590 NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::IN_APP), &nInApp));
591 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "IN_APP", nInApp));
592 napi_value nLocalDevice;
593 NAPI_CALL_RETURN_VOID(env,
594 napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::LOCAL_DEVICE), &nLocalDevice));
595 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "LOCAL_DEVICE", nLocalDevice));
596 napi_value nCrossDevice;
597 NAPI_CALL_RETURN_VOID(env,
598 napi_create_int32(env, static_cast<int32_t>(ClipboardPolicy::CROSS_DEVICE), &nCrossDevice));
599 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "CROSS_DEVICE", nCrossDevice));
600 }
601
SetWatermarkImage(napi_env env,napi_callback_info info)602 napi_value SecurityManagerAddon::SetWatermarkImage(napi_env env, napi_callback_info info)
603 {
604 EDMLOGI("NAPI_SetWatermarkImage called");
605 size_t argc = ARGS_SIZE_FOUR;
606 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
607 napi_value thisArg = nullptr;
608 void *data = nullptr;
609 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
610 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_FOUR, "parameter count error");
611 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
612
613 OHOS::AppExecFwk::ElementName elementName;
614 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
615 "Parameter admin error");
616 std::shared_ptr<WatermarkParam> paramPtr = nullptr;
617 napi_value ret = CheckBuildWatermarkParam(env, argv, paramPtr);
618 if (ret == nullptr) {
619 return nullptr;
620 }
621 int32_t retCode = -1;
622 NAPI_CALL(env, napi_get_value_int32(env, ret, &retCode));
623 if (FAILED(retCode)) {
624 return nullptr;
625 }
626 retCode = SecurityManagerProxy::GetSecurityManagerProxy()->SetWatermarkImage(elementName, paramPtr);
627 if (FAILED(retCode)) {
628 napi_throw(env, CreateError(env, retCode));
629 }
630 return nullptr;
631 }
632
CancelWatermarkImage(napi_env env,napi_callback_info info)633 napi_value SecurityManagerAddon::CancelWatermarkImage(napi_env env, napi_callback_info info)
634 {
635 AddonMethodSign addonMethodSign;
636 addonMethodSign.name = "CancelWatermarkImage";
637 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING, EdmAddonCommonType::INT32};
638 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
639 AdapterAddonData adapterAddonData{};
640 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
641 if (result == nullptr) {
642 return nullptr;
643 }
644 int32_t retCode =
645 SecurityManagerProxy::GetSecurityManagerProxy()->CancelWatermarkImage(adapterAddonData.data);
646 if (FAILED(retCode)) {
647 napi_throw(env, CreateError(env, retCode));
648 }
649 return nullptr;
650 }
651
Decode(const std::string url)652 std::shared_ptr<OHOS::Media::PixelMap> SecurityManagerAddon::Decode(const std::string url)
653 {
654 char canonicalPath[PATH_MAX + 1] = { 0 };
655 if (url.size() > PATH_MAX || realpath(url.c_str(), canonicalPath) == nullptr) {
656 EDMLOGE("realpath error");
657 return nullptr;
658 }
659 int fd = open(canonicalPath, O_RDONLY);
660 if (fd == -1) {
661 EDMLOGE("Decode Open file fail!");
662 return nullptr;
663 }
664 uint32_t ret = ERR_INVALID_VALUE;
665 std::shared_ptr<int> fdPtr(&fd, [](int *fd) {
666 close(*fd);
667 *fd = -1;
668 });
669 Media::SourceOptions sourceOption;
670 auto imageSourcePtr = Media::ImageSource::CreateImageSource(*fdPtr, sourceOption, ret);
671 if (ret != ERR_OK || imageSourcePtr == nullptr) {
672 EDMLOGE("CreateImageSource error");
673 return nullptr;
674 }
675 Media::DecodeOptions option;
676 auto pixelMapPtr = imageSourcePtr->CreatePixelMap(option, ret);
677 if (ret != ERR_OK) {
678 EDMLOGE("CreatePixelMap error");
679 return nullptr;
680 }
681 return std::shared_ptr<Media::PixelMap>(std::move(pixelMapPtr));
682 }
683
GetPixelMapData(std::shared_ptr<Media::PixelMap> pixelMap,std::shared_ptr<WatermarkParam> param)684 bool SecurityManagerAddon::GetPixelMapData(std::shared_ptr<Media::PixelMap> pixelMap,
685 std::shared_ptr<WatermarkParam> param)
686 {
687 param->size = pixelMap->GetByteCount();
688 if (param->size <= 0) {
689 EDMLOGE("GetPixelMapData size %{public}d", param->size);
690 return false;
691 }
692 void* data = malloc(param->size);
693 if (data == nullptr) {
694 EDMLOGE("GetPixelMapData malloc fail");
695 return false;
696 }
697 uint32_t ret = pixelMap->ReadPixels(param->size, reinterpret_cast<uint8_t*>(data));
698 param->SetPixels(data);
699 if (ret != ERR_OK) {
700 EDMLOGE("GetPixelMapData ReadPixels fail!");
701 return false;
702 }
703 param->width = pixelMap->GetWidth();
704 param->height = pixelMap->GetHeight();
705 return true;
706 }
707
CheckBuildWatermarkParam(napi_env env,napi_value * argv,std::shared_ptr<WatermarkParam> & paramPtr)708 napi_value SecurityManagerAddon::CheckBuildWatermarkParam(napi_env env, napi_value* argv,
709 std::shared_ptr<WatermarkParam> ¶mPtr)
710 {
711 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string), "bundleName type error");
712 napi_valuetype imageValueType = napi_undefined;
713 NAPI_CALL(env, napi_typeof(env, argv[ARR_INDEX_TWO], &imageValueType));
714 ASSERT_AND_THROW_PARAM_ERROR(env, imageValueType == napi_object || imageValueType == napi_string,
715 "image type error");
716 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_THREE], napi_number),
717 "accountId type error");
718 auto param = new (std::nothrow) WatermarkParam();
719 if (param == nullptr) {
720 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
721 return nullptr;
722 }
723 paramPtr = std::shared_ptr<WatermarkParam>(param, [](WatermarkParam *param) {
724 param->CheckAndFreePixels();
725 delete param;
726 });
727 std::shared_ptr<Media::PixelMap> pixelMap;
728
729 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, paramPtr->bundleName, argv[ARR_INDEX_ONE]),
730 "Parameter bundleName error");
731 if (imageValueType == napi_object) {
732 pixelMap = Media::PixelMapNapi::GetPixelMap(env, argv[ARR_INDEX_TWO]);
733 } else {
734 std::string url;
735 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, url, argv[ARR_INDEX_TWO]),
736 "Parameter pixelMap error");
737 pixelMap = Decode(url);
738 }
739 ASSERT_AND_THROW_PARAM_ERROR(env, pixelMap != nullptr &&
740 pixelMap->GetByteCount() <= MAX_WATERMARK_IMAGE_SIZE, "Parameter pixelMap error");
741 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, paramPtr->accountId, argv[ARR_INDEX_THREE]),
742 "Parameter accountId error");
743 if (!GetPixelMapData(pixelMap, paramPtr)) {
744 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
745 return nullptr;
746 }
747 napi_value ret;
748 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
749 return ret;
750 }
751
JsObjToManagedState(napi_env env,napi_value object,ManagedState & managedState)752 bool SecurityManagerAddon::JsObjToManagedState(napi_env env, napi_value object, ManagedState &managedState)
753 {
754 int32_t JsManagedState = 0;
755 if (ParseInt(env, JsManagedState, object)) {
756 switch (JsManagedState) {
757 case static_cast<int32_t>(ManagedState::DEFAULT):
758 managedState = ManagedState::DEFAULT;
759 return true;
760 case static_cast<int32_t>(ManagedState::GRANTED):
761 managedState = ManagedState::GRANTED;
762 return true;
763 case static_cast<int32_t>(ManagedState::DENIED):
764 managedState = ManagedState::DENIED;
765 return true;
766 default:
767 EDMLOGE("SecurityManagerAddon::JsObjToManagedState switch fail.");
768 return false;
769 }
770 }
771 EDMLOGE("SecurityManagerAddon::JsObjToManagedState parse fail.");
772 return false;
773 }
774
JsObjToApplicationInstance(napi_env env,napi_value object,MessageParcel & data)775 bool SecurityManagerAddon::JsObjToApplicationInstance(napi_env env, napi_value object, MessageParcel &data)
776 {
777 std::string appIdentifier;
778 int32_t accountId = 0;
779 int32_t appIndex = 0;
780 if (!JsObjectToString(env, object, "appIdentifier", true, appIdentifier) ||
781 !JsObjectToInt(env, object, "accountId", true, accountId) ||
782 !JsObjectToInt(env, object, "appIndex", true, appIndex)) {
783 EDMLOGE("SecurityManagerAddon::JsObjToApplicationInstance param error.");
784 return false;
785 }
786 data.WriteString(appIdentifier);
787 data.WriteInt32(accountId);
788 data.WriteInt32(appIndex);
789 return true;
790 }
791
SetPermissionManagedState(napi_env env,napi_callback_info info)792 napi_value SecurityManagerAddon::SetPermissionManagedState(napi_env env, napi_callback_info info)
793 {
794 EDMLOGI("NAPI_SetPermissionManagedState called");
795 auto convertApplicationInstance = [](napi_env env, napi_value argv, MessageParcel &data,
796 const AddonMethodSign &methodSign) {
797 return JsObjToApplicationInstance(env, argv, data);
798 };
799 auto convertManagedStateData = [](napi_env env, napi_value argv, MessageParcel &data,
800 const AddonMethodSign &methodSign) {
801 ManagedState managedState;
802 bool isUint = JsObjToManagedState(env, argv, managedState);
803 if (!isUint) {
804 EDMLOGE("SecurityManagerAddon SetPermissionManagedState JsObjToManagedState fail.");
805 return false;
806 }
807 data.WriteInt32(static_cast<int32_t>(managedState));
808 return true;
809 };
810 AddonMethodSign addonMethodSign;
811 addonMethodSign.name = "SetPermissionManagedState";
812 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM,
813 EdmAddonCommonType::ARRAY_STRING, EdmAddonCommonType::CUSTOM};
814 addonMethodSign.argsConvert = {nullptr, convertApplicationInstance,
815 nullptr, convertManagedStateData};
816 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
817 AdapterAddonData adapterAddonData{};
818 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
819 if (result == nullptr) {
820 return nullptr;
821 }
822 int32_t retCode = SecurityManagerProxy::GetSecurityManagerProxy()->SetPermissionManagedState(adapterAddonData.data);
823 if (FAILED(retCode)) {
824 napi_throw(env, CreateErrorWithUnknownCode(env, retCode));
825 }
826 return nullptr;
827 }
828
GetPermissionManagedState(napi_env env,napi_callback_info info)829 napi_value SecurityManagerAddon::GetPermissionManagedState(napi_env env, napi_callback_info info)
830 {
831 auto convertApplicationInstance = [](napi_env env, napi_value argv, MessageParcel &data,
832 const AddonMethodSign &methodSign) {
833 return JsObjToApplicationInstance(env, argv, data);
834 };
835 size_t argc = ARGS_SIZE_THREE;
836 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
837 napi_value thisArg = nullptr;
838 void *data = nullptr;
839 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
840 AddonMethodSign addonMethodSign;
841 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM, EdmAddonCommonType::STRING};
842 addonMethodSign.argsConvert = {nullptr, convertApplicationInstance, nullptr};
843 addonMethodSign.methodAttribute = MethodAttribute::GET;
844 AdapterAddonData adapterAddonData{};
845 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
846 if (result == nullptr) {
847 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
848 return nullptr;
849 }
850 int32_t policy = 0;
851 int32_t retCode =
852 SecurityManagerProxy::GetSecurityManagerProxy()->GetPermissionManagedState(adapterAddonData.data, policy);
853 if (FAILED(retCode)) {
854 napi_throw(env, CreateError(env, retCode));
855 return nullptr;
856 }
857 napi_value permissionManagedState;
858 NAPI_CALL(env, napi_create_int32(env, policy, &permissionManagedState));
859 return permissionManagedState;
860 }
861
862 static napi_module g_securityModule = {
863 .nm_version = 1,
864 .nm_flags = 0,
865 .nm_filename = nullptr,
866 .nm_register_func = SecurityManagerAddon::Init,
867 .nm_modname = "enterprise.securityManager",
868 .nm_priv = ((void *)0),
869 .reserved = {0},
870 };
871
SecurityManagerRegister()872 extern "C" __attribute__((constructor)) void SecurityManagerRegister()
873 {
874 napi_module_register(&g_securityModule);
875 }
876