• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &paramPtr)
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